//////////////////////////////////////////////////////////////////////////////// //Author Aviral Mittal //ISLI 2005/2006 //////////////////////////////////////////////////////////////////////////////// `timescale 1ns/1ps //module name = rx module rx (data_out, success, rx_in, clk); // Outputs and Inputs declaration Section output [7:0] data_out; output success; input clk; input rx_in; //parameters Declaration Section parameter delaynumber = 18; //to count 18 clock cycles, 1 bit/per 18 clocks parameter totalbytes = 15; //15 total no of bytes/word to be tranfered parameter bits_in_one_word = 10; //11 bits/word to be xfered including parity //reset, stop bit //parameters Declaration Section Ends // Outputs and Inputs declaration Section Ends // Regs declaration Section reg [bits_in_one_word:0] inp_reg; reg success; // reg success_del; // reg [4:0] delaycounter; //count 0->17, then again 0->17 and so on reg [4:0] bitcounter; //count 0->10 reg reset; reg [1:0] reset_ps; reg [1:0] reset_ns; reg [bits_in_one_word-3:0] data_out; reg [bits_in_one_word-3:0] fifo [totalbytes:0]; reg [4:0] ii; //loop variable // Regs declaration Section Ends //Wire declaration Section wire clk, rx_in; wire parity_rcvd; wire parity_gen; wire success_pulse; //Wire declaration Section Ends //The following machine generates a reset signal always @ (rx_in or reset_ps or bitcounter) case({rx_in,reset_ps}) 3'b100 : reset_ns = 2'b00; 3'b000 : reset_ns = 2'b01; 3'b001 : reset_ns = 2'b10; 3'b101 : reset_ns = 2'b00; 3'b010 : reset_ns = 2'b11; 3'b110 : reset_ns = 2'b00; 3'b011 : begin if(bitcounter == 11) reset_ns = 2'b00; else reset_ns = 2'b11; end 3'b111 : reset_ns = 2'b11; default : reset_ns = 2'b00; endcase always @ (posedge clk) reset_ps <= reset_ns; always @ (posedge clk) begin if(reset_ps == 2'b11) reset <= 1'b1; else reset <= 1'b0; end //The following procedure starts a 'delaycounter' //The dealycountr counts from 1to18 and then again 1to18 and so on //It starts counting when reset is '1'. The reset signal is in turn //generated when the 'rx_in' makes first transition from high to low always @ (posedge clk) begin if(reset == 0) //sync reset of the counter delaycounter <= 0; else if(delaycounter == delaynumber) delaycounter <= 1; else delaycounter <= delaycounter + 1; end //The following prodecure starts a 'bitcounter' to count the no of //bits received. //It counts from 0to11 and agin 0to11 and so on. always @ (posedge clk) begin if(reset == 0) //sync reset of the counter bitcounter <= 0; else if(delaycounter == delaynumber) if(bitcounter==bits_in_one_word+1) bitcounter <= bitcounter; else bitcounter <= bitcounter+1; end assign parity_rcvd = inp_reg[9]; assign parity_gen = ^inp_reg[8:1]; //Generation of Success signal //Success is generated if parity received = parity localy generated always @ (posedge clk) begin if(reset == 0) success <= 0; //since parity_rcvd = inp_reg[9] there fore, //It must be checked agains the parity_gen on a value of bitcounter=10 else if(bitcounter == 10 && delaycounter == 18 && parity_gen == parity_rcvd) success <= 1'b1; else if(bitcounter == 11 && delaycounter == 18) success <= 1'b0; end //following process delays 'success' by one clock so that a 1 clock //period wide pulse may be generated corresponding to a success //making a 0 to 1 transition always @ (posedge clk) begin success_del <= success; end assign success_pulse = success & ~success_del; //The inp_reg's LSB takes on the input value 'rx_in' //whenever the delaycounter == 9. //by this time, it is expected that the signal would have reached //from the transmitter to the receiver. always @ (posedge clk) begin if(delaycounter == 9) begin inp_reg[bits_in_one_word] <= rx_in; inp_reg[bits_in_one_word-1:0] <= inp_reg[bits_in_one_word:1]; end end //As per the specs, 'data_out' stores the last 'good' word received always @ (posedge clk) begin if(success_pulse) data_out <= inp_reg[8:1]; end //Store the 16 received data words in a fifo. always @ (posedge clk) begin if(success_pulse == 1) begin fifo[0] <= inp_reg[8:1]; for(ii=15;ii>0;ii=ii-1) fifo[ii] <= fifo[ii-1]; end end endmodule