mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-20 09:44:38 +00:00
159 lines
4.8 KiB
Verilog
159 lines
4.8 KiB
Verilog
`timescale 1ns / 1ps
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Company:
|
|
// Engineer:
|
|
//
|
|
// Create Date: 09:58:45 02/25/2008
|
|
// Design Name:
|
|
// Module Name: i8253
|
|
// Project Name:
|
|
// Target Devices:
|
|
// Tool versions:
|
|
// Description:
|
|
//
|
|
// Dependencies:
|
|
//
|
|
// Revision:
|
|
// Revision 0.01 - File Created
|
|
// Additional Comments:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
module i8253(reset, clk, addr, data_out, data_in, cs, rd, wr, clk0, clk1, clk2, out0, out1, out2);
|
|
input reset;
|
|
input clk;
|
|
input [1:0] addr;
|
|
output[7:0] data_out;
|
|
input [7:0] data_in;
|
|
input cs, rd, wr;
|
|
input clk0, clk1, clk2;
|
|
output out0, out1, out2;
|
|
wire [1:0] addr;
|
|
wire [7:0] data_out, data_in;
|
|
wire cs, rd, wr;
|
|
wire clk0, clk1, clk2;
|
|
wire out0, out1, out2;
|
|
|
|
reg [7:0] mode0, mode1, mode2;
|
|
reg [15:0] max0, max1, max2;
|
|
reg [15:0] count0 = 0, count1 = 0, count2 = 0;
|
|
reg signal0 = 0, signal1 = 0, signal2 = 0;
|
|
reg read_hl0, read_hl1, read_hl2;
|
|
reg write_hl0, write_hl1, write_hl2;
|
|
reg [7:0] data;
|
|
|
|
always @(posedge clk or posedge reset) begin
|
|
if ( reset ) begin
|
|
mode0 <= 8'h00;
|
|
mode1 <= 8'h00;
|
|
mode2 <= 8'h00;
|
|
max0 <= 16'd1;
|
|
max1 <= 16'd1;
|
|
max2 <= 16'd1;
|
|
write_hl0 <= 1'b0;
|
|
write_hl1 <= 1'b0;
|
|
write_hl2 <= 1'b0;
|
|
read_hl0 <= 1'b0;
|
|
read_hl1 <= 1'b0;
|
|
read_hl2 <= 1'b0;
|
|
end else if ( cs ) begin
|
|
if ( addr == 2'd0 & wr ) begin
|
|
write_hl0 <= ( mode0[5:4] == 2'b00 | mode0[5:4] == 2'b11 ) ? ~write_hl0: write_hl0;
|
|
if ( ((mode0[5:4] == 2'b00 | mode0[5:4] == 2'b11) & write_hl0) | mode0[5:4] == 2'b10 )
|
|
max0[15:8] <= data_in;
|
|
else
|
|
max0[7:0] <= data_in;
|
|
end else if ( addr == 2'd1 & wr ) begin
|
|
write_hl1 <= ( mode1[5:4] == 2'b00 | mode1[5:4] == 2'b11 ) ? ~write_hl1: write_hl1;
|
|
if ( ((mode1[5:4] == 2'b00 | mode1[5:4] == 2'b11) & write_hl1) | mode1[5:4] == 2'b10 )
|
|
max1[15:8] <= data_in;
|
|
else
|
|
max1[7:0] <= data_in;
|
|
end else if ( addr == 2'd2 & wr ) begin
|
|
write_hl2 <= ( mode2[5:4] == 2'b00 | mode2[5:4] == 2'b11 ) ? ~write_hl2: write_hl2;
|
|
if ( ((mode2[5:4] == 2'b00 | mode2[5:4] == 2'b11) & write_hl2) | mode2[5:4] == 2'b10 )
|
|
max2[15:8] <= data_in;
|
|
else
|
|
max2[7:0] <= data_in;
|
|
end else if ( addr == 2'd3 & wr ) begin
|
|
if ( data_in[7:6] == 2'd0 ) begin
|
|
mode0 <= data_in;
|
|
read_hl0 <= data_in[5:4] == 2'b10 ? 1 : 0;
|
|
write_hl0 <= data_in[5:4] == 2'b10 ? 1 : 0;
|
|
end else if ( data_in[7:6] == 2'd1 ) begin
|
|
mode1 <= data_in;
|
|
read_hl1 <= data_in[5:4] == 2'b10 ? 1 : 0;
|
|
write_hl1 <= data_in[5:4] == 2'b10 ? 1 : 0;
|
|
end else if ( data_in[7:6] == 2'd2 ) begin
|
|
mode2 <= data_in;
|
|
read_hl2 <= data_in[5:4] == 2'b10 ? 1 : 0;
|
|
write_hl2 <= data_in[5:4] == 2'b10 ? 1 : 0;
|
|
end
|
|
end else if ( addr == 2'd0 & rd ) begin
|
|
read_hl0 <= ( mode0[5:4] == 2'b00 | mode0[5:4] == 2'b11 ) ? ~read_hl0: read_hl0;
|
|
data <= ~( ((mode0[5:4] == 2'b00 | mode0[5:4] == 2'b11 ) & read_hl0) | mode0[5:4] == 2'b10 ) ? count0[15:8] : count0[7:0];
|
|
end else if ( addr == 2'd1 & rd ) begin
|
|
read_hl1 <= ( mode1[5:4] == 2'b00 | mode1[5:4] == 2'b11 ) ? ~read_hl1: read_hl1;
|
|
data <= ~( ((mode1[5:4] == 2'b00 | mode1[5:4] == 2'b11 ) & read_hl1) | mode1[5:4] == 2'b10 ) ? count1[15:8] : count1[7:0];
|
|
end else if ( addr == 2'd2 & rd ) begin
|
|
read_hl2 <= ( mode2[5:4] == 2'b00 | mode2[5:4] == 2'b11 ) ? ~read_hl2: read_hl2;
|
|
data <= ~( ((mode2[5:4] == 2'b00 | mode2[5:4] == 2'b11 ) & read_hl2) | mode2[5:4] == 2'b10 ) ? count2[15:8] : count2[7:0];
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk0) begin
|
|
if ( count0 != 0 ) begin
|
|
count0 <= ( count0 <= max0 ) ? count0 - 1: max0;
|
|
if ( mode0[3:1] == 3'b000 | mode0[3:1] == 3'b001 ) // MODE0
|
|
signal0 <= 0;
|
|
end else begin
|
|
if ( mode0[3:1] == 3'b000 | mode0[3:1] == 3'b001 ) begin // MODE0
|
|
count0 <= max0;
|
|
signal0 <= 1;
|
|
end else begin
|
|
count0 <= max0;
|
|
signal0 <= ~signal0;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk1) begin
|
|
if ( count1 != 0 ) begin
|
|
count1 <= ( count1 <= max1 ) ? count1 - 1: max1;
|
|
if ( mode1[3:1] == 3'b000 | mode1[3:1] == 3'b001 ) // MODE0/1
|
|
signal1 <= 0;
|
|
end else begin
|
|
if ( mode1[3:1] == 3'b000 | mode1[3:1] == 3'b001 ) begin // MODE0/1
|
|
count1 <= max1;
|
|
signal1 <= 1;
|
|
end else begin
|
|
count1 <= max1;
|
|
signal1 <= ~signal1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk2) begin
|
|
if ( count2 != 0 ) begin
|
|
count2 <= ( count2 <= max2 ) ? count2 - 1: max2;
|
|
if ( mode2[3:1] == 3'b000 | mode2[3:1] == 3'b001 ) // MODE0/1
|
|
signal2 <= 0;
|
|
end else begin
|
|
if ( mode2[3:1] == 3'b000 | mode2[3:1] == 3'b001 ) begin // MODE0/1
|
|
count2 <= max2;
|
|
signal2 <= 1;
|
|
end else begin
|
|
count2 <= max2;
|
|
signal2 <= ~signal2;
|
|
end
|
|
end
|
|
end
|
|
|
|
assign out0 = signal0;
|
|
assign out1 = signal1;
|
|
assign out2 = signal2;
|
|
|
|
assign data_out = data;
|
|
|
|
endmodule
|