You are on page 1of 14

**********************************

********BUFFER MODULE*************
**********************************
module buffer(
select_0,
select_1,
select_2,
data_rd_0,
data_rd_1,
data_rd_2,
rd,
wr,
//output
data_wr,
//inout
data
);
input select_0;
input select_1;
input select_2;
input rd;
input wr;
input [7:0] data_rd_0;
input [7:0] data_rd_1;
input [7:0] data_rd_2;
inout [7:0] data;

output [7:0] data_wr ;
reg [7:0] data_out;
reg [7:0] data_wr;
wire [7:0] data;
always @(rd or data_rd_0 or data_rd_1 or data_rd_2)
if(!rd) begin
if(select_0)
data_out = data_rd_0;
else if(select_1)
data_out = data_rd_1;
else if(select_2)
data_out = data_rd_2;
end
always @(wr)
if(!wr)
data_wr = data;

assign data=rd?8'hzz:data_out;
endmodule
**********************************
********COUNTER MODULE************
**********************************
module counter(
select,
data_wr,
load_counter_low,
load_counter_high,
load_over,
latch_count,
read_counter_low,
read_counter_high,
control_write,
gate,
clk,
data_rd,
out
);
input select;
input load_counter_low;
input load_counter_high;
input load_over;
input latch_count;
input read_counter_low;
input read_counter_high;
input control_write;
input gate;
input clk;
input [7:0] data_wr;

output out;
output [7:0] data_rd;

reg bcd;
reg out;
reg last_gate;
reg gate_rising;
reg count_en;
reg load_control;
reg data_load;
reg [2:0] mode;
reg [7:0] data_rd;
reg [15:0] count_initial;
reg [15:0] count_tmp;
reg [15:0] count_buffer;
reg [15:0] count;
function [15:0] countnew;
input [15:0] count;
input bcd;
reg [3:0] temp1,temp2,temp3,temp4;
begin
if(!bcd)
countnew = count - 1;
else begin
{temp4,temp3,temp2,temp1} = count;
temp1 = temp1-1;
if(temp1 == 4'b1111) begin
temp1 = 4'b1001;
temp2 = temp2-1;
if(temp2 == 4'b1111) begin
temp2 = 4'b1001;
temp3 = temp3-1;
if(temp3 == 4'b1111) begin
temp3 = 4'b1001;
temp4 = temp4-1;
if(temp4 == 4'b1111) begin
temp3 = 4'b1001;
end
end
end
end
countnew = {temp4,temp3,temp2,temp1};
end
end
endfunction
always @(posedge control_write or posedge load_counter_low or posedge load_coun
ter_high)
if(control_write && select)
count_initial <= 0;
else if(load_counter_low && select)
count_initial[7:0] <= data_wr;
else if(load_counter_high && select)
count_initial[15:8] <= data_wr;

always @(posedge latch_count or posedge control_write)
if(control_write && select)
count_buffer <= 16'b0;
else if(latch_count && select)
count_buffer <= count;
always @(posedge read_counter_low or posedge read_counter_high)
if(read_counter_low && select)
data_rd <= count_buffer[7:0];
else if(read_counter_high && select)
data_rd <= count_buffer[15:8];

always @(negedge clk or posedge load_over or posedge gate or posedge control_wr
ite)begin
if(!load_control && control_write && select) begin
bcd <= data_wr[0];
mode <= data_wr[3:1];
load_control <= 1;
data_load <= 0;

end
else if(!data_load && load_over && select)begin
data_load <= 1;
gate_rising <= 0;
end
else if(!gate_rising && gate && !last_gate)
gate_rising <= 1;
else begin
last_gate <= gate;
load_control <= 0;
if(mode == 3'b000)begin
if(data_load == 1)begin
count <= count_initial;
data_load <= 0;
count_en <= 1;
end
else if(gate && count && count_en)
count = countnew(count,bcd);

if(!count && count_en)
count_en <= 0;

if(load_control == 1)begin
out <= 0;
load_control <= 0;
end
else if(count_en && !count)
out <= 1;
end

if(mode == 3'b001)begin
if(gate_rising == 1)begin
count <= count_initial;
gate_rising <=0;
count_en <= 1;
end
else if(count && count_en)
count = countnew(count,bcd);

if(!count && count_en) begin
count_en <= 0;
out <=1;
end

if(load_control == 1)begin
out <= 1;
load_control <= 0;
end
else if(gate_rising)
out <= 0;
end
if(mode == 3'b010 || mode == 3'b110)begin

if(data_load && gate)begin
count_tmp <= count_initial;
data_load <= 0;
count_en <= 1;
end

if(!gate_rising && gate && count && count_en)
count = countnew(count,bcd);
else if(gate_rising == 1)begin
count <= count_tmp;
gate_rising <=0;
end
else if(gate && count_en)
count <= count_tmp;

if(load_control == 1)begin
out <= 1;
load_control <= 0;
end
else if(gate && count == 1)
out <= 0;
else
out <= 1;
end

if(mode == 3'b011 || mode == 3'b111)begin
if(data_load && gate)begin
count <= count_initial;
data_load <= 0;
count_en <= 1;
end

if(count==0 && count_en)
count=count_initial;
else if(gate_rising == 1)begin
count <= count_initial;
gate_rising <=0;
end
else if(gate && !count[0]&& count_en)begin
count = countnew(count,bcd);
count = countnew(count,bcd);
end
else if(gate && count[0]&& out&& count_en)
count = countnew(count,bcd);
else if(gate && count[0]&& !out && count_en)begin
count = countnew(count,bcd);
count = countnew(count,bcd);
count = countnew(count,bcd);
end

if(load_control == 1)begin
out <= 1;
load_control <= 0;
end
else if(count==0 && count_en)
out = ~out;
else if(!gate)
out = 1 ;
end

if(mode == 3'b100)begin
if(data_load == 1)begin
count <= count_initial;
data_load <= 0;
count_en <= 1;
end
else if(gate && count && count_en)
count = countnew(count,bcd);

if(load_control == 1)begin
out <= 1;
load_control <= 0;
end
else if(!count && out && count_en)begin
count_en <= 0;
out <= 0;
end
else
out <= 1;
end

if(mode == 3'b101)begin
if(gate_rising == 1)begin
count <= count_initial;
gate_rising <=0;
count_en <= 1;
end
else if(count_en)
count = countnew(count,bcd);

if(!count && count_en)begin
count <=count_initial;
count_en <= 0;
end

if(load_control == 1)begin
out <= 1;
load_control <= 0;
end
else if(count==0)
out <= 0;
else
out <= 1;
end
end
end
endmodule
**********************************
**********LOGIC MODULE************
**********************************
module logic(
rd,
wr,
a0,
a1,
rst_n,
data_wr,
state,
byte_high,
select_0,
select_1,
select_2
);

input rd;
input wr;
input a0;
input a1;
input rst_n;
input [7:0] data_wr;
output [2:0] state;
output byte_high;
output select_0;
output select_1;
output select_2;

reg [7:0] state;
reg byte_high_2;
reg byte_low_2;
reg byte_high_1;
reg byte_low_1;
reg byte_high_0;
reg byte_low_0;
reg byte_high;
reg byte_low;
reg select_0;
reg select_1;
reg select_2;
reg low;

parameter state_load_counter_low=3'd1;
parameter state_load_counter_high=3'd2;
parameter state_write_mode_word=3'd3;
parameter state_read_counter_latch=3'd4;
parameter state_read_counter_low=3'd5;
parameter state_read_counter_high=3'd6;
parameter disable_3_state=3'd7;
always @(rst_n or rd or wr or a1 or a0)
if(rst_n) begin
state = disable_3_state;
low = 0;
byte_high = 0;
byte_low = 0;
byte_high_0 = 0;
byte_low_0 = 0;
byte_high_1 = 0;
byte_low_1 = 0;
byte_high_2 = 0;
byte_low_2 = 0;
select_0 = 0;
select_1 = 0;
select_2 = 0;
end
else
case({rd,wr,a1,a0})
5'b01000: if(low && byte_high) begin
state = state_load_counter_high;
low = 0;
end
else if(byte_low) begin
state = state_load_counter_low;
if(byte_high) low = 1;
end
else if(byte_high)
state = state_load_counter_high;
else
state = disable_3_state;
5'b01001: if(low && byte_high) begin
state = state_load_counter_high;
low = 0;
end
else if(byte_low) begin
state = state_load_counter_low;
if(byte_high) low = 1;
end
else if(byte_high)
state = state_load_counter_high;
else
state = disable_3_state;
5'b01010: if(low && byte_high) begin
state = state_load_counter_high;
low = 0;
end
else if(byte_low) begin
state = state_load_counter_low;
if(byte_high) low = 1;
end
else if(byte_high)
state = state_load_counter_high;
else
state = disable_3_state;
5'b01011: begin
case(data_wr[7:6])
2'b00: begin
select_0 = 1;
select_1 = 0;
select_2 = 0;
end
2'b01: begin
select_0 = 0;
select_1 = 1;
select_2 = 0;
end
2'b10: begin
select_0 = 0;
select_1 = 0;
select_2 = 1;
end
default:begin
select_0 = 0;
select_1 = 0;
select_2 = 0;
end
endcase
byte_high = data_wr[5];
byte_low = data_wr[4];
if(!byte_low && !byte_high)begin
state = state_read_counter_latch;
end
else begin
state = state_write_mode_word;
case(data_wr[7:6])
2'b00: begin
byte_high_0 = byte_high;
byte_low_0 = byte_low;
end
2'b01: begin
byte_high_1 = byte_high;
byte_low_1 = byte_low;
end
2'b10: begin
byte_high_2 = byte_high;
byte_low_2 = byte_low;
end
endcase
end
end
5'b00100: if(low && byte_high_0) begin
state = state_read_counter_high;
low = 0;
end
else if(byte_low_0) begin
state = state_read_counter_low;
if(byte_high_0) low = 1;
end
else if(byte_high_0)
state = state_read_counter_high;
else
state = disable_3_state;
5'b00101: if(low && byte_high_1) begin
state = state_read_counter_high;
low = 0;
end
else if(byte_low_1) begin
state = state_read_counter_low;
if(byte_high_1) low = 1;
end
else if(byte_high_1)
state = state_read_counter_high;
else
state = disable_3_state;
5'b00110: if(low && byte_high_2) begin
state = state_read_counter_high;
low = 0;
end
else if(byte_low_2) begin
state = state_read_counter_low;
if(byte_high_2) low = 1;
end
else if(byte_high_2)
state = state_read_counter_high;
else
state = disable_3_state;
default: state = disable_3_state;
endcase

endmodule

**********************************
********CONTROL MODULE************
**********************************
module control(
state,
byte_high,
load_counter_low,
load_counter_high,
load_over,
latch_count,
read_counter_low,
read_counter_high,
control_write
);
input [2:0] state;

input byte_high;
output load_counter_low,load_counter_high,load_over,latch_count,
read_counter_low,read_counter_high,control_write;
reg load_counter_low,load_counter_high,load_over,latch_count,
read_counter_low,read_counter_high,control_write;

parameter state_load_counter_low=8'd1;
parameter state_load_counter_high=8'd2;
parameter state_write_mode_word=8'd3;
parameter state_read_counter_latch=8'd4;
parameter state_read_counter_low=8'd5;
parameter state_read_counter_high=8'd6;
parameter disable_3_state=8'd7;
always @(state)
case(state)
state_load_counter_low: begin
load_counter_low = 1;
load_counter_high = 0;
if(byte_high)
load_over = 0;
else
load_over = 1;
latch_count = 0;
read_counter_low = 0;
read_counter_high = 0;
control_write = 0;
end
state_load_counter_high: begin
load_counter_low = 0;
load_counter_high = 1;
load_over = 1;
latch_count = 0;
read_counter_low = 0;
read_counter_high = 0;
control_write = 0;

end
state_write_mode_word: begin
load_counter_low = 0;
load_counter_high = 0;
load_over = 0;
latch_count = 0;
read_counter_low = 0;
read_counter_high = 0;
control_write = 1;
end
state_read_counter_latch:begin
load_counter_low = 0;
load_counter_high = 0;
load_over = 0;
latch_count = 1;
read_counter_low = 0;
read_counter_high = 0;
control_write = 0;

end
state_read_counter_low: begin
load_counter_low = 0;
load_counter_high = 0;
load_over = 0;
latch_count = 0;
read_counter_low = 1;
read_counter_high = 0;
control_write = 0;
end
state_read_counter_high: begin
load_counter_low = 0;
load_counter_high = 0;
load_over = 0;
latch_count = 0;
read_counter_low = 0;
read_counter_high = 1;
control_write = 0;

end
default: begin
load_counter_low = 0;
load_counter_high = 0;
load_over = 0;
latch_count = 0;
read_counter_low = 0;
read_counter_high = 0;
control_write = 0;
end
endcase
endmodule
**********************************
**********C8253 MODULE************
**********************************
module C8253(
rst_n,
rd,
wr,
a0,
a1,
clk_0,
gate_0,
clk_1,
gate_1,
clk_2,
gate_2,
data,
out_0,
out_1,
out_2 );
input rst_n;
input rd;
input wr;
input a0;
input a1;
input clk_0;
input gate_0;
input clk_1;
input gate_1;
input clk_2;
input gate_2;
inout [7:0] data;
output out_0;
output out_1;
output out_2;

wire [2:0] state;
wire [7:0] data_wr;
wire [7:0] data;
wire [7:0] data_rd_0;
wire [7:0] data_rd_1;
wire [7:0] data_rd_2;
wire select_0;
wire select_1;
wire select_2;
wire load_counter_low;
wire load_counter_high;
wire load_over;
wire latch_count;
wire byte_high;
wire read_counter_low;
wire read_counter_high;
wire control_write;
wire out_0;
wire out_1;
wire out_2;
wire rd;
wire rst_n;
wire wr;
wire clk_0;
wire gate_0;
wire clk_1;
wire gate_1;
wire clk_2;
wire gate_2;
logic logic(
.rd(rd),
.wr(wr),
.a0(a0),
.a1(a1),
.rst_n(rst_n),
.data_wr(data),
.state(state),
.byte_high(byte_high),
.select_0(select_0),
.select_1(select_1),
.select_2(select_2)
);

control control(
.state(state),
.byte_high(byte_high),
.load_counter_low(load_counter_low),
.load_counter_high(load_counter_high),
.load_over(load_over),
.latch_count(latch_count),
.read_counter_low(read_counter_low),
.read_counter_high(read_counter_high),
.control_write(control_write)
);

counter counter0(
.select(select_0),
.data_wr(data_wr),
.load_counter_low(load_counter_low),
.load_counter_high(load_counter_high),
.load_over(load_over),
.latch_count(latch_count),
.read_counter_low(read_counter_low),
.read_counter_high(read_counter_high),
.control_write(control_write),
.gate(gate_0),
.clk(clk_0),
.data_rd(data_rd_0),
.out(out_0)
),
counter1(
.select(select_1),
.data_wr(data_wr),
.load_counter_low(load_counter_low),
.load_counter_high(load_counter_high),
.load_over(load_over),
.latch_count(latch_count),
.read_counter_low(read_counter_low),
.read_counter_high(read_counter_high),
.control_write(control_write),
.gate(gate_1),
.clk(clk_1),
.data_rd(data_rd_1),
.out(out_1)
),
counter2(
.select(select_2),
.data_wr(data_wr),
.load_counter_low(load_counter_low),
.load_counter_high(load_counter_high),
.load_over(load_over),
.latch_count(latch_count),
.read_counter_low(read_counter_low),
.read_counter_high(read_counter_high),
.control_write(control_write),
.gate(gate_2),
.clk(clk_2),
.data_rd(data_rd_2),
.out(out_2)
);

buffer buffer(
.select_0(select_0),
.select_1(select_1),
.select_2(select_2),
.data_rd_0(data_rd_0),
.data_rd_1(data_rd_1),
.data_rd_2(data_rd_2),
.rd(rd),
.wr(wr),
.data_wr(data_wr),
.data(data) );

endmodule