module rw_logic
(data_io,  //'mode inout' 8254 data I/O port
ctr_din,   //'mode output'connects to counters input data bus
creg_select, //'mode output'control register select signal
ctr0_rd,   //'mode output'counter0 read signal.
ctr1_rd,   //'mode output'counter1 read signal.
ctr2_rd,   //'mode output'counter2 read signal.
ctr0_wr,   //'mode output'counter0 write signal.
ctr1_wr,   //'mode output'counter1 write signal.
ctr2_wr,   //'mode output'counter2 write signal.
ctr_dout, //'mode input'connects to counters output data bus
cs,//'mode input'chip select signal for 8254
a0,//'mode input'a1 and a0(addr) are address lines that selects any counter or control word register to R/W
a1, //'mode input'a1 and a0(addr) are address lines that selects any counter or control word register to R/W
wr,//'mode input'input write signal to 8254
rd //'mode input'input read signal to 8254
);
inout [7:0]data_io;
input [7:0]ctr_dout;
input cs,wr,rd,a0,a1;
output [7:0]ctr_din;
output creg_select,ctr0_rd,ctr1_rd,ctr2_rd,ctr0_wr,ctr1_wr,ctr2_wr;
reg creg_select,ctr0_rd,ctr1_rd,ctr2_rd,ctr0_wr,ctr1_wr,ctr2_wr;
reg [1:0] addr;

assign data_io = ((!cs && !rd)?ctr_dout:8'bZZZZZZZZ);
assign ctr_din = ((!cs && !wr)?data_io:8'bZZZZZZZZ);

always@(cs)
       begin
       if (!cs && !rd)
	   begin
	   addr[1:0] <= {a1,a0};    
	   if (addr == 2'b00)
               begin
	       ctr0_rd <= 1'b1;
               ctr1_rd <= 1'b0;
	       ctr2_rd <= 1'b0;
               end
	    else
	        begin
	        if (addr == 2'b01)
                    begin
	            ctr1_rd <= 1'b1;
                    ctr0_rd <= 1'b0;
	            ctr2_rd <= 1'b0;
                    end
	        else
	            begin
	            if (addr == 2'b10)
                        begin
	                ctr2_rd <= 1'b1;
                        ctr1_rd <= 1'b0;
	                ctr0_rd <= 1'b0;
                        end   
	            else
	                begin
	                ctr0_rd <= 1'b0;
	                ctr1_rd <= 1'b0;
	                ctr2_rd <= 1'b0;
	                end
	             end
	           end
	        end
	    else
	        begin
	        if (!cs && !wr) 
	            begin
	            addr[1:0] <= {a1,a0};    
	            if (addr == 2'b00)
                        begin
	                ctr0_wr <= 1'b1;
                        ctr1_wr <= 1'b0;
	                ctr2_wr <= 1'b0;
	                creg_select <= 1'b0;
                        end
	            else
	                begin
	                if (addr == 2'b01)
                           begin
	                   ctr1_wr <= 1'b1;
                           ctr0_wr <= 1'b0;
	                   ctr2_wr <= 1'b0;
	                   creg_select <= 1'b0;
                           end
	                else
	                    begin
	                    if (addr == 2'b10)
                                begin  	                       
                                ctr2_wr <= 1'b1;
                                ctr1_wr <= 1'b0;
                                ctr0_wr <= 1'b0;
                                creg_select <= 1'b0;
                                end
	                    else
	                        begin
	                        if (addr == 2'b11)
	                            begin
                                    creg_select <= 1'b1;
                                    ctr2_wr <= 1'b0;
                                    ctr1_wr <= 1'b0;
                                    ctr0_wr <= 1'b0;
				    end
	                        else
	                            begin
	                            ctr0_wr <= 1'b0;
	                            ctr1_wr <= 1'b0;
	                            ctr2_wr <= 1'b0;
	                            creg_select <= 1'b0;
	                            end
	                        end
	                    end
	                end
	            end
	        else
	            begin
	            ctr0_rd <= 1'bZ;
	            ctr1_rd <= 1'bZ;
	            ctr2_rd <= 1'bZ;
	            ctr0_wr <= 1'bZ;
	            ctr1_wr <= 1'bZ;
	            ctr2_wr <= 1'bZ;
	            creg_select <= 1'bZ;
	            addr [1:0] <= 2'bXX;
	            end
	        end
	    end
endmodule