In this module, the received signal of RS232 serial port is converted into 8 bit data and passed the test.
First on the renderings:
sclk: system clock s_rst_n: System clock rx:rs232 serial port receives data rx_r1: delay one beat rx_r2: delay two beats
rx_r3: delay three beats rx_ Necessary: capture rx falling edge rx_flag: baud_cnt: baud rate setting 9600, 5208 clock cycles per bit_flag: when baud_ When CNT counts to half, pull up bit_cnt: count the number of bits transmitted from the serial port
rx_data: convert serial data to 8bit output po_flag: one byte transmission completion flag signal
Source code uart_rx.v:
module uart_rx( input sclk, //System input clock input s_rst_n, //System reset signal input rx, //Rs232 serial port receiving signal output reg [7:0] rx_data, //Data received output reg po_flag //Transmission completion signal ); //Synchronize cached data reg rx_r1; reg rx_r2; reg rx_r3; reg rx_flag; //Transmit data flag signal reg [12:0] baud_cnt; reg bit_flag; reg [3:0] bit_cnt; //-----------------Defining parameters----------------------------- //localparam BAUD_END = 13'd5207 ; localparam BAUD_END = 13'd56; localparam BIT_END = 4'd8; assign rx_negetive = ~rx_r2&rx_r3; //Capture the falling edge of rx to determine the transmission start always @(posedge sclk or negedge s_rst_n) if(!s_rst_n)begin rx_r1 <= 1'b1; rx_r2 <= 1'b1; rx_r3 <= 1'b1; end else begin rx_r1 <= rx; rx_r2 <= rx_r1; rx_r3 <= rx_r2; end //rx_flag always @(posedge sclk or negedge s_rst_n) if(!s_rst_n) rx_flag <= 1'b0; else if(rx_negetive==1'b1) rx_flag <= 1'b1; else if((baud_cnt==BAUD_END)&&(bit_cnt==4'd0)) rx_flag <= 1'b0; else rx_flag <= rx_flag; //baud_cnt always @(posedge sclk or negedge s_rst_n) if(!s_rst_n) baud_cnt <= 'd0; else if(baud_cnt==BAUD_END) baud_cnt <= 'd0; else if(rx_flag==1'b1) baud_cnt <= baud_cnt + 1'b1; else baud_cnt <= baud_cnt; //bit_flag always @(posedge sclk or negedge s_rst_n) if(!s_rst_n) bit_flag <= 1'b0; else if(baud_cnt==(BAUD_END/2)) bit_flag <= 1'b1; else bit_flag <= 1'b0; //bit_cnt always @(posedge sclk or negedge s_rst_n) if(!s_rst_n) bit_cnt <= 'd0; else if((bit_cnt==BIT_END)&&(bit_flag==1'b1)) bit_cnt <= 'd0; else if(bit_flag) bit_cnt <= bit_cnt + 1'b1; else bit_cnt <= bit_cnt; //rx_data always @(posedge sclk or negedge s_rst_n) if(!s_rst_n) rx_data <= 'd0; else if((bit_flag==1'b1)&&(bit_cnt>=1'b1)) rx_data <= {rx_r2,rx_data[7:1]}; else rx_data <= rx_data; //po_flag always @(posedge sclk or negedge s_rst_n) if(!s_rst_n) po_flag <= 1'b0; else if((bit_cnt==BIT_END)&&(bit_flag==1'b1)) po_flag <= 1'b1; else po_flag <= 1'b0; endmodule
Test code uart_rx_tb.v:
`timescale 1ns/1ns module uart_rx_tb(); reg sclk; reg s_rst_n; reg rx; reg [7:0] mem_a [3:0]; wire [7:0] rx_data; wire po_flag; initial begin sclk = 1'b1; s_rst_n = 1'b0; rx <= 1'b1; #100 s_rst_n = 1'b1; #100 tx_byte(); end always #5 sclk = ~sclk; initial $readmemh("./tx_data.txt",mem_a); task tx_byte(); integer i; for(i=0; i<4; i=i+1) begin tx_bit(mem_a[i]); end endtask task tx_bit( input [7:0] data ); integer i; for(i=0; i<10; i=i+1) begin case(i) 0: rx <= 1'b0; 1: rx <= data[0]; 2: rx <= data[1]; 3: rx <= data[2]; 4: rx <= data[3]; 5: rx <= data[4]; 6: rx <= data[5]; 7: rx <= data[6]; 8: rx <= data[7]; 9: rx <= 1'b1; default: rx <= 1'b1; endcase #560; end endtask uart_rx uart_rx( .sclk(sclk) , //System input clock .s_rst_n(s_rst_n) , //System reset signal .rx(rx) , //Rs232 serial port receiving signal .rx_data(rx_data) , //Data received .po_flag(po_flag) //Transmission completion signal ); endmodule
Create a TX in the same file directory as the test code_ data.txt File, enter 55 12 34 aa in the file as the test
Finally, we can see the waveform Rx_ 5512 34 aa appeared in data, which proved that the design of receiving module was normal.