mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			154 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| //-----------------------------------------------------
 | |
| // Design Name : uart 
 | |
| // File Name   : uart.v
 | |
| // Function    : Simple UART
 | |
| // Coder       : Deepak Kumar Tala
 | |
| //-----------------------------------------------------
 | |
| module uart (
 | |
| reset          ,
 | |
| txclk          ,
 | |
| ld_tx_data     ,
 | |
| tx_data        ,
 | |
| tx_enable      ,
 | |
| tx_out         ,
 | |
| tx_empty       ,
 | |
| rxclk          ,
 | |
| uld_rx_data    ,
 | |
| rx_data        ,
 | |
| rx_enable      ,
 | |
| rx_in          ,
 | |
| rx_empty
 | |
| );
 | |
| // Port declarations
 | |
| input        reset          ;
 | |
| input        txclk          ;
 | |
| input        ld_tx_data     ;
 | |
| input  [7:0] tx_data        ;
 | |
| input        tx_enable      ;
 | |
| output       tx_out         ;
 | |
| output       tx_empty       ;
 | |
| input        rxclk          ;
 | |
| input        uld_rx_data    ;
 | |
| output [7:0] rx_data        ;
 | |
| input        rx_enable      ;
 | |
| input        rx_in          ;
 | |
| output       rx_empty       ;
 | |
| 
 | |
| // Internal Variables 
 | |
| reg [7:0]    tx_reg         ;
 | |
| reg          tx_empty       ;
 | |
| reg          tx_over_run    ;
 | |
| reg [3:0]    tx_cnt         ;
 | |
| reg          tx_out         ;
 | |
| reg [7:0]    rx_reg         ;
 | |
| reg [7:0]    rx_data        ;
 | |
| reg [3:0]    rx_sample_cnt  ;
 | |
| reg [3:0]    rx_cnt         ;  
 | |
| reg          rx_frame_err   ;
 | |
| reg          rx_over_run    ;
 | |
| reg          rx_empty       ;
 | |
| reg          rx_d1          ;
 | |
| reg          rx_d2          ;
 | |
| reg          rx_busy        ;
 | |
| 
 | |
| // UART RX Logic
 | |
| always @ (posedge rxclk or posedge reset)
 | |
| if (reset) begin
 | |
|   rx_reg        <= 0; 
 | |
|   rx_data       <= 0;
 | |
|   rx_sample_cnt <= 0;
 | |
|   rx_cnt        <= 0;
 | |
|   rx_frame_err  <= 0;
 | |
|   rx_over_run   <= 0;
 | |
|   rx_empty      <= 1;
 | |
|   rx_d1         <= 1;
 | |
|   rx_d2         <= 1;
 | |
|   rx_busy       <= 0;
 | |
| end else begin
 | |
|   // Synchronize the asynch signal
 | |
|   rx_d1 <= rx_in;
 | |
|   rx_d2 <= rx_d1;
 | |
|   // Uload the rx data
 | |
|   if (uld_rx_data) begin
 | |
|     rx_data  <= rx_reg;
 | |
|     rx_empty <= 1;
 | |
|   end
 | |
|   // Receive data only when rx is enabled
 | |
|   if (rx_enable) begin
 | |
|     // Check if just received start of frame
 | |
|     if (!rx_busy && !rx_d2) begin
 | |
|       rx_busy       <= 1;
 | |
|       rx_sample_cnt <= 1;
 | |
|       rx_cnt        <= 0;
 | |
|     end
 | |
|     // Start of frame detected, Proceed with rest of data
 | |
|     if (rx_busy) begin
 | |
|        rx_sample_cnt <= rx_sample_cnt + 1;
 | |
|        // Logic to sample at middle of data
 | |
|        if (rx_sample_cnt == 7) begin
 | |
|           if ((rx_d2 == 1) && (rx_cnt == 0)) begin
 | |
|             rx_busy <= 0;
 | |
|           end else begin
 | |
|             rx_cnt <= rx_cnt + 1; 
 | |
|             // Start storing the rx data
 | |
|             if (rx_cnt > 0 && rx_cnt < 9) begin
 | |
|               rx_reg[rx_cnt - 1] <= rx_d2;
 | |
|             end
 | |
|             if (rx_cnt == 9) begin
 | |
|                rx_busy <= 0;
 | |
|                // Check if End of frame received correctly
 | |
|                if (rx_d2 == 0) begin
 | |
|                  rx_frame_err <= 1;
 | |
|                end else begin
 | |
|                  rx_empty     <= 0;
 | |
|                  rx_frame_err <= 0;
 | |
|                  // Check if last rx data was not unloaded,
 | |
|                  rx_over_run  <= (rx_empty) ? 0 : 1;
 | |
|                end
 | |
|             end
 | |
|           end
 | |
|        end 
 | |
|     end 
 | |
|   end
 | |
|   if (!rx_enable) begin
 | |
|     rx_busy <= 0;
 | |
|   end
 | |
| end
 | |
| 
 | |
| // UART TX Logic
 | |
| always @ (posedge txclk or posedge reset)
 | |
| if (reset) begin
 | |
|   tx_reg        <= 0;
 | |
|   tx_empty      <= 1;
 | |
|   tx_over_run   <= 0;
 | |
|   tx_out        <= 1;
 | |
|   tx_cnt        <= 0;
 | |
| end else begin
 | |
|    if (ld_tx_data) begin
 | |
|       if (!tx_empty) begin
 | |
|         tx_over_run <= 0;
 | |
|       end else begin
 | |
|         tx_reg   <= tx_data;
 | |
|         tx_empty <= 0;
 | |
|       end
 | |
|    end
 | |
|    if (tx_enable && !tx_empty) begin
 | |
|      tx_cnt <= tx_cnt + 1;
 | |
|      if (tx_cnt == 0) begin
 | |
|        tx_out <= 0;
 | |
|      end
 | |
|      if (tx_cnt > 0 && tx_cnt < 9) begin
 | |
|         tx_out <= tx_reg[tx_cnt -1];
 | |
|      end
 | |
|      if (tx_cnt == 9) begin
 | |
|        tx_out <= 1;
 | |
|        tx_cnt <= 0;
 | |
|        tx_empty <= 1;
 | |
|      end
 | |
|    end
 | |
|    if (!tx_enable) begin
 | |
|      tx_cnt <= 0;
 | |
|    end
 | |
| end
 | |
| 
 | |
| endmodule
 |