mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +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
 |