forked from tanchou/Verilog
		
	uart_rx valid
This commit is contained in:
		| @@ -1,4 +1,4 @@ | ||||
| module uart_rx | ||||
| module other_uart_rx | ||||
| #( | ||||
| 	parameter CLK_FRE = 27,      //clock frequency(Mhz) | ||||
| 	parameter BAUD_RATE = 115200 //serial baud rate | ||||
|   | ||||
							
								
								
									
										133
									
								
								Semaine_4/UART/IP/verilog/other_tx.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								Semaine_4/UART/IP/verilog/other_tx.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| module other_uart_tx | ||||
| #( | ||||
| 	parameter CLK_FRE = 27,      //clock frequency(Mhz) | ||||
| 	parameter BAUD_RATE = 115200 //serial baud rate | ||||
| ) | ||||
| ( | ||||
| 	input                        clk,              //clock input | ||||
| 	input                        rst_n,            //asynchronous reset input, low active  | ||||
| 	input[7:0]                   tx_data,          //data to send | ||||
| 	input                        tx_data_valid,    //data to be sent is valid | ||||
| 	output reg                   tx_data_ready,    //send ready | ||||
| 	output                       tx_pin            //serial data output | ||||
| ); | ||||
| //calculates the clock cycle for baud rate  | ||||
| localparam                       CYCLE = CLK_FRE * 1000000 / BAUD_RATE; | ||||
| //state machine code | ||||
| localparam                       S_IDLE       = 1; | ||||
| localparam                       S_START      = 2;//start bit | ||||
| localparam                       S_SEND_BYTE  = 3;//data bits | ||||
| localparam                       S_STOP       = 4;//stop bit | ||||
| reg[2:0]                         state; | ||||
| reg[2:0]                         next_state; | ||||
| reg[15:0]                        cycle_cnt; //baud counter | ||||
| reg[2:0]                         bit_cnt;//bit counter | ||||
| reg[7:0]                         tx_data_latch; //latch data to send | ||||
| reg                              tx_reg; //serial data output | ||||
| assign tx_pin = tx_reg; | ||||
| always@(posedge clk or negedge rst_n) | ||||
| begin | ||||
| 	if(rst_n == 1'b0) | ||||
| 		state <= S_IDLE; | ||||
| 	else | ||||
| 		state <= next_state; | ||||
| end | ||||
|  | ||||
| always@(*) | ||||
| begin | ||||
| 	case(state) | ||||
| 		S_IDLE: | ||||
| 			if(tx_data_valid == 1'b1) | ||||
| 				next_state <= S_START; | ||||
| 			else | ||||
| 				next_state <= S_IDLE; | ||||
| 		S_START: | ||||
| 			if(cycle_cnt == CYCLE - 1) | ||||
| 				next_state <= S_SEND_BYTE; | ||||
| 			else | ||||
| 				next_state <= S_START; | ||||
| 		S_SEND_BYTE: | ||||
| 			if(cycle_cnt == CYCLE - 1  && bit_cnt == 3'd7) | ||||
| 				next_state <= S_STOP; | ||||
| 			else | ||||
| 				next_state <= S_SEND_BYTE; | ||||
| 		S_STOP: | ||||
| 			if(cycle_cnt == CYCLE - 1) | ||||
| 				next_state <= S_IDLE; | ||||
| 			else | ||||
| 				next_state <= S_STOP; | ||||
| 		default: | ||||
| 			next_state <= S_IDLE; | ||||
| 	endcase | ||||
| end | ||||
| always@(posedge clk or negedge rst_n) | ||||
| begin | ||||
| 	if(rst_n == 1'b0) | ||||
| 		begin | ||||
| 			tx_data_ready <= 1'b0; | ||||
| 		end | ||||
| 	else if(state == S_IDLE) | ||||
| 		if(tx_data_valid == 1'b1) | ||||
| 			tx_data_ready <= 1'b0; | ||||
| 		else | ||||
| 			tx_data_ready <= 1'b1; | ||||
| 	else if(state == S_STOP && cycle_cnt == CYCLE - 1) | ||||
| 			tx_data_ready <= 1'b1; | ||||
| end | ||||
|  | ||||
|  | ||||
| always@(posedge clk or negedge rst_n) | ||||
| begin | ||||
| 	if(rst_n == 1'b0) | ||||
| 		begin | ||||
| 			tx_data_latch <= 8'd0; | ||||
| 		end | ||||
| 	else if(state == S_IDLE && tx_data_valid == 1'b1) | ||||
| 			tx_data_latch <= tx_data; | ||||
| 		 | ||||
| end | ||||
|  | ||||
| always@(posedge clk or negedge rst_n) | ||||
| begin | ||||
| 	if(rst_n == 1'b0) | ||||
| 		begin | ||||
| 			bit_cnt <= 3'd0; | ||||
| 		end | ||||
| 	else if(state == S_SEND_BYTE) | ||||
| 		if(cycle_cnt == CYCLE - 1) | ||||
| 			bit_cnt <= bit_cnt + 3'd1; | ||||
| 		else | ||||
| 			bit_cnt <= bit_cnt; | ||||
| 	else | ||||
| 		bit_cnt <= 3'd0; | ||||
| end | ||||
|  | ||||
|  | ||||
| always@(posedge clk or negedge rst_n) | ||||
| begin | ||||
| 	if(rst_n == 1'b0) | ||||
| 		cycle_cnt <= 16'd0; | ||||
| 	else if((state == S_SEND_BYTE && cycle_cnt == CYCLE - 1) || next_state != state) | ||||
| 		cycle_cnt <= 16'd0; | ||||
| 	else | ||||
| 		cycle_cnt <= cycle_cnt + 16'd1;	 | ||||
| end | ||||
|  | ||||
| always@(posedge clk or negedge rst_n) | ||||
| begin | ||||
| 	if(rst_n == 1'b0) | ||||
| 		tx_reg <= 1'b1; | ||||
| 	else | ||||
| 		case(state) | ||||
| 			S_IDLE,S_STOP: | ||||
| 				tx_reg <= 1'b1;  | ||||
| 			S_START: | ||||
| 				tx_reg <= 1'b0;  | ||||
| 			S_SEND_BYTE: | ||||
| 				tx_reg <= tx_data_latch[bit_cnt]; | ||||
| 			default: | ||||
| 				tx_reg <= 1'b1;  | ||||
| 		endcase | ||||
| end | ||||
|  | ||||
| endmodule  | ||||
| @@ -1,3 +1,3 @@ | ||||
| @echo off | ||||
| echo === Lancement de GTKWave === | ||||
| gtkwave runs/uart_loopback.vcd | ||||
| gtkwave runs/uart_rx.vcd | ||||
|   | ||||
| @@ -6,7 +6,7 @@ setlocal enabledelayedexpansion | ||||
| set OUT=runs/sim.vvp | ||||
|  | ||||
| :: Top-level testbench module | ||||
| set TOP=tb_uart_tx | ||||
| set TOP=tb_uart_rx | ||||
|  | ||||
| :: Répertoires contenant des fichiers .v | ||||
| set DIRS=src/verilog tests/verilog IP/verilog | ||||
|   | ||||
							
								
								
									
										145
									
								
								Semaine_4/UART/src/verilog/uart_rx.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Semaine_4/UART/src/verilog/uart_rx.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| module uart_rx #( | ||||
| 	parameter CLK_FREQ = 27_000_000, | ||||
| 	parameter BAUD_RATE = 115200 | ||||
| )( | ||||
| 	input                        clk,               //clock input | ||||
| 	input                        rst_p,             //asynchronous reset input, high active  | ||||
| 	input                        rx_enable,     //data receiver module ready | ||||
| 	input                        rx_pin,             //serial data input | ||||
|  | ||||
|     output reg[7:0]              rx_data,           //received serial data | ||||
| 	output reg                   rx_received     //received serial data is valid | ||||
| ); | ||||
|   | ||||
| localparam                       CYCLE = CLK_FREQ / BAUD_RATE; | ||||
|  | ||||
| //state machine code | ||||
| localparam                       S_IDLE      = 1; | ||||
| localparam                       S_START     = 2;   //start bit | ||||
| localparam                       S_REC_BYTE  = 3;   //data bits | ||||
| localparam                       S_STOP      = 4;   //stop bit | ||||
| localparam                       S_DATA      = 5; | ||||
|  | ||||
| reg[2:0]                         state; | ||||
| reg[2:0]                         next_state; | ||||
|  | ||||
| reg                              rx_d0;             //delay 1 clock for rx_pin | ||||
| reg                              rx_d1;             //delay 1 clock for rx_d0 | ||||
| wire                             rx_negedge;        //negedge of rx_pin | ||||
| reg[7:0]                         rx_bits;           //temporary storage of received data | ||||
| reg[15:0]                        cycle_cnt;         //baud counter | ||||
| reg[2:0]                         bit_cnt;           //bit counter | ||||
|  | ||||
| assign rx_negedge = rx_d1 && ~rx_d0;    // Front déscendant | ||||
|  | ||||
| always@(posedge clk or posedge rst_p)   // Filtrage du signial | ||||
| begin | ||||
| 	if(rst_p == 1'b1)begin | ||||
| 		rx_d0 <= 1'b0; | ||||
| 		rx_d1 <= 1'b0;	 | ||||
|          | ||||
| 	end else begin | ||||
| 		rx_d0 <= rx_pin; | ||||
| 		rx_d1 <= rx_d0; | ||||
| 	end | ||||
| end | ||||
|  | ||||
|  | ||||
| always@(posedge clk or posedge rst_p)begin  // Compteur d'etat | ||||
| 	if(rst_p == 1'b1) | ||||
| 		state <= S_IDLE; | ||||
| 	else | ||||
| 		state <= next_state; | ||||
| end | ||||
|  | ||||
| always@(*)begin | ||||
| 	case(state) | ||||
| 		S_IDLE: | ||||
| 			if(rx_negedge)                  // Detection du start bit | ||||
| 				next_state = S_START; | ||||
| 			else | ||||
| 				next_state = S_IDLE; | ||||
|  | ||||
| 		S_START: | ||||
| 			if(cycle_cnt == CYCLE - 1)      //one data cycle  | ||||
| 				next_state = S_REC_BYTE; | ||||
| 			else | ||||
| 				next_state = S_START; | ||||
|  | ||||
| 		S_REC_BYTE: | ||||
| 			if(cycle_cnt == CYCLE - 1  && bit_cnt == 3'd7)  //receive 8bit data | ||||
| 				next_state = S_STOP; | ||||
| 			else | ||||
| 				next_state = S_REC_BYTE; | ||||
|  | ||||
| 		S_STOP: | ||||
| 			if(cycle_cnt == CYCLE/2 - 1)    //half bit cycle,to avoid missing the next byte receiver | ||||
| 				next_state = S_DATA; | ||||
| 			else | ||||
| 				next_state = S_STOP; | ||||
|  | ||||
| 		S_DATA: | ||||
| 			if(rx_enable)               //data receive complete | ||||
| 				next_state = S_IDLE; | ||||
| 			else | ||||
| 				next_state = S_DATA; | ||||
|  | ||||
| 		default: | ||||
| 			next_state = S_IDLE; | ||||
| 	endcase | ||||
| end | ||||
|  | ||||
| always@(posedge clk or posedge rst_p) | ||||
| begin | ||||
| 	if(rst_p == 1'b1) | ||||
| 		rx_received <= 1'b0; | ||||
| 	else if(state == S_STOP && next_state != state) | ||||
| 		rx_received <= 1'b1; | ||||
| 	else if(state == S_DATA && rx_enable) | ||||
| 		rx_received <= 1'b0; | ||||
| end | ||||
|  | ||||
| always@(posedge clk or posedge rst_p) | ||||
| begin | ||||
| 	if(rst_p == 1'b1) | ||||
| 		rx_data <= 8'd0; | ||||
| 	else if(state == S_STOP && next_state != state) | ||||
| 		rx_data <= rx_bits;//latch received data | ||||
| end | ||||
|  | ||||
| always@(posedge clk or posedge rst_p) | ||||
| begin | ||||
| 	if(rst_p == 1'b1) | ||||
| 		begin | ||||
| 			bit_cnt <= 3'd0; | ||||
| 		end | ||||
| 	else if(state == S_REC_BYTE) | ||||
| 		if(cycle_cnt == CYCLE - 1) | ||||
| 			bit_cnt <= bit_cnt + 3'd1; | ||||
| 		else | ||||
| 			bit_cnt <= bit_cnt; | ||||
| 	else | ||||
| 		bit_cnt <= 3'd0; | ||||
| end | ||||
|  | ||||
|  | ||||
| always@(posedge clk or posedge rst_p) | ||||
| begin | ||||
| 	if(rst_p == 1'b1) | ||||
| 		cycle_cnt <= 16'd0; | ||||
| 	else if((state == S_REC_BYTE && cycle_cnt == CYCLE - 1) || next_state != state) | ||||
| 		cycle_cnt <= 16'd0; | ||||
| 	else | ||||
| 		cycle_cnt <= cycle_cnt + 16'd1;	 | ||||
| end | ||||
| //receive serial data bit data | ||||
| always@(posedge clk or posedge rst_p) | ||||
| begin | ||||
| 	if(rst_p == 1'b1) | ||||
| 		rx_bits <= 8'd0; | ||||
| 	else if(state == S_REC_BYTE && cycle_cnt == CYCLE/2 - 1) | ||||
| 		rx_bits[bit_cnt] <= rx_pin; | ||||
| 	else | ||||
| 		rx_bits <= rx_bits;  | ||||
| end | ||||
| endmodule  | ||||
							
								
								
									
										67
									
								
								Semaine_4/UART/tests/verilog/tb_uart_rx.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Semaine_4/UART/tests/verilog/tb_uart_rx.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| `timescale 1ns / 1ps | ||||
|  | ||||
| module tb_uart_rx; | ||||
|  | ||||
|     reg clk = 0; | ||||
|     reg rx;   | ||||
|     reg [7:0] data_in; | ||||
|     reg [7:0] data_out; | ||||
|  | ||||
|     reg tx_data_valid; | ||||
|     reg tx_data_ready; | ||||
|  | ||||
|     reg rx_received; | ||||
|     wire rx_enable = 1'b1; // Enable the receiver | ||||
|  | ||||
|     localparam CLK_FREQ = 27_000_000; | ||||
|     localparam BAUD_RATE = 115_200; | ||||
|     localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE;  | ||||
|     localparam CLK_PERIOD_NS = 1000000000 / CLK_FREQ;  | ||||
|  | ||||
|     other_uart_tx tx_instance ( | ||||
|         .clk(clk), | ||||
|         .tx_pin(rx), | ||||
|         .tx_data(data_in), | ||||
|         .tx_data_valid(tx_data_valid), | ||||
|         .tx_data_ready(tx_data_ready), | ||||
|         .rst_n(1'b1) | ||||
|     ); | ||||
|  | ||||
|     uart_rx #( | ||||
|         .CLK_FREQ(CLK_FREQ), | ||||
|         .BAUD_RATE(BAUD_RATE) | ||||
|     ) rx_instance ( | ||||
|         .clk(clk), | ||||
|         .rx_pin(rx), | ||||
|         .rx_data(data_out), | ||||
|         .rx_received(rx_received), | ||||
|         .rx_enable(rx_enable) | ||||
|     ); | ||||
|  | ||||
|     always #(CLK_PERIOD_NS/2) clk = ~clk; | ||||
|  | ||||
|     initial begin | ||||
|         $dumpfile("runs/uart_rx.vcd"); | ||||
|         $dumpvars(0, tb_uart_rx); | ||||
|         $display("======== Start UART RX test ========="); | ||||
|         #100;  | ||||
|  | ||||
|         data_in = 8'd123; // Data to send | ||||
|         wait(tx_data_ready); // Wait for the transmitter to be ready | ||||
|         #1; // Small delay to ensure the data is latched | ||||
|  | ||||
|         tx_data_valid = 1'b1; // Indicate that the data is valid | ||||
|          | ||||
|         wait(tx_data_ready == 0); | ||||
|  | ||||
|         tx_data_valid = 1'b0; // Clear the valid signal | ||||
|  | ||||
|         wait(rx_received); // Wait for the receiver to receive the data | ||||
|  | ||||
|         $display("Data sent: %d", data_in); | ||||
|         $display("Data received: %d", data_out); // Display the received data | ||||
|  | ||||
|         $display("======== END UART RX test ========="); | ||||
|         $finish; | ||||
|     end | ||||
| endmodule | ||||
| @@ -13,7 +13,7 @@ module tb_uart_tx; | ||||
|  | ||||
|     always #18.5 clk = ~clk; | ||||
|  | ||||
|     uart_rx rx_instance( | ||||
|     other_uart_rx rx_instance( | ||||
|         .clk(clk), | ||||
|         .rx_pin(tx), // tx is connected to rx for testing | ||||
|         .rst_n(1'b1), | ||||
| @@ -38,6 +38,8 @@ module tb_uart_tx; | ||||
|         $dumpfile("runs/uart_tx.vcd"); | ||||
|         $dumpvars(0, tb_uart_tx); | ||||
|  | ||||
|         $display("======== Start UART TX test ========="); | ||||
|  | ||||
|         #100; | ||||
|  | ||||
|         data_in <= 8'd234;   // 234 | ||||
| @@ -66,6 +68,8 @@ module tb_uart_tx; | ||||
|         $display("Data received: %d", data_out); // Afficher la valeur recu | ||||
|         $display("Data expected: %d", data_in); // Afficher la valeur envoyee | ||||
|  | ||||
|         $display("======== END UART TX test ========="); | ||||
|  | ||||
|         #1000; | ||||
|         $stop; | ||||
|     end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user