1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-20 09:44:38 +00:00
2019-07-22 23:42:05 +02:00

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