⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 u_rec.v

📁 带自适应波特率发生器UART实现
💻 V
字号:
////////////////////////////////////////////////////////////////////////
//                                                                    
//  Abstract: Uart has an auto-tuning baud rate generator 
//            This is the receiver portion of the UART.                                              
//  Module  : U_REC.v                              
//                                                                    
//  Version : ver 01.00                                  
//                                                                    
//  Modification History:                                            
//  Date By         Change Description                         
//  ----------------------------------------------------------------- 
//  2008/06/24  jackie                                         
//  YYYY/MM/DD  author     Revision content                           
//                                                                    
////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ns
module u_rec  (	
		rst,
		uart_clk,
                clk,			
		rxd,				
		sbuf_r,
		ri
              	);
								
// Receiver state definition
parameter      r_START 	   = 3'b001,
               r_CENTER	   = 3'b010,
               r_WAIT  	   = 3'b011,
               r_SAMPLE	   = 3'b100,
	       r_STOP  	   = 3'b101;

// *****************************
//
// Receiver Configuration
//
// *****************************

// Word length.  
// This defines the number of bits 
// in a "word".  Typcially 8.
// min=0, max=8

parameter       WORD_LEN    = 8;
parameter       delay       = 1'b1;

// ******************************************
//
// PORT DEFINITIONS
//
// ******************************************
input		rst;	        // syn reset
input		uart_clk;	// main clock must be 16 x Baud Rate
input           clk;
input		rxd;	        // goes to the UART pin

output	[7:0]	sbuf_r;	        // parallel received data
output		ri;	        // when high, new data is ok to be read


// ******************************************
//
// MEMORY ELEMENT DEFINITIONS
//
// ******************************************
reg	[2:0]	next_state, state;
reg		rec_datH, rec_datSyncH;
reg	[3:0]	bitCell_cntrH;
reg		cntr_resetH;
reg	[7:0]	rec_ShiftRegH;
reg		shiftH;
reg	[3:0]	recd_bitCntrH;
reg		countH;
reg		rstCountH;
reg		rec_readyH;
reg		rec_readyInH;
reg             uart_clkid;
reg             uart_clki;

wire	[7:0]	sbuf_r;
wire            ri;
wire            uart_clk_rising;

always @(posedge clk )
  if (rst) 
    begin
       uart_clkid  <= #delay  1'b1;
       uart_clki   <= #delay  1'b1;
    end 
  else 
    begin
       uart_clkid  <= #delay  uart_clk;
       uart_clki   <= #delay  uart_clkid;
    end

assign   uart_clk_rising = (uart_clkid) && (!uart_clki); 

//8 bit parallel data output  
assign   sbuf_r = rec_ShiftRegH;

// synchronize the asynchrnous input
// to the system clock domain
// dual-rank
always @(posedge clk )
  if (rst) 
     begin
        rec_datSyncH <= #delay  1'b1;
        rec_datH     <= #delay  1'b1;
     end 
  else
     begin
        rec_datSyncH <= #delay  rxd;
        rec_datH     <= #delay  rec_datSyncH;
     end

// Bit-cell counter
always @(posedge clk )
  if (rst) 
      bitCell_cntrH <= #delay  1'b0;
  else if(uart_clk_rising&&cntr_resetH)    
      bitCell_cntrH <= #delay  1'b0;
  else if(uart_clk_rising)
      bitCell_cntrH <= #delay  bitCell_cntrH + 1;
      

// Shifte Register to hold the incoming 
// serial data
// LSB is shifted in first
always @(posedge clk )
  if (rst) 
     rec_ShiftRegH <= #delay 1'b0;
  else if(uart_clk_rising&&shiftH)      
        begin
            rec_ShiftRegH[6:0] <= #delay  rec_ShiftRegH[7:1];
            rec_ShiftRegH[7]   <= #delay  rec_datH;
        end

// RECEIVED BIT Counter
// This coutner keeps track of the number of bits received
always @(posedge clk )
  if (rst) 
       recd_bitCntrH <= #delay  1'b0;
  else if(uart_clk_rising&&countH)  
       recd_bitCntrH <= #delay  recd_bitCntrH + 1;
  else if (uart_clk_rising&&rstCountH) 
       recd_bitCntrH <= #delay  1'b0;

// State Machine - Next State Assignment
always @(posedge clk )
  if (rst) 
       state <= #delay  r_START;
  else if(uart_clk_rising) 
       state <= #delay  next_state;

// State Machine - Next State and Output Decode
always @(state or rec_datH or bitCell_cntrH or recd_bitCntrH)
begin
  // default
  next_state  = state;
  cntr_resetH = 1'b1;
  shiftH      = 1'b0;
  countH      = 1'b0;
  rstCountH   = 1'b0;
  rec_readyInH= 1'b0;

  case (state)         
    // START
    // Wait for the start bit  
    r_START: 
    begin
       if (~rec_datH ) 
            next_state = r_CENTER;
       else 
          begin 
              next_state = r_START;
              rstCountH  = 1'b1;      // place the bit counter in rst state
              rec_readyInH = 1'b1;    // by default, we're ready
          end
     end
	// CENTER
	// Find the center of the bit-cell 
	// A bit cell is composed of 16 system-clock ticks	
    r_CENTER: 
    begin
       if (bitCell_cntrH == 4'h4) 
         begin
         // if after having waited 1/2 bit cell,
 	 // it is still 0, then it is a genuine start bit
            if (~rec_datH) 
                 next_state = r_WAIT;
		 // otherwise, could have been a false noise
            else 
                 next_state = r_START;
          end 
        else 
          begin
               next_state  = r_CENTER;
	       cntr_resetH = 1'b0;  // allow counter to tick          
          end
     end
	// WAIT
	// Wait a bit-cell time before sampling the
	// state of the data pin	
     r_WAIT: 
     begin
	if (bitCell_cntrH == 4'hE) 
	   begin
              if (recd_bitCntrH == WORD_LEN)
                   next_state = r_STOP; // we've sampled all 8 bits
              else 
                  begin
                      next_state = r_SAMPLE;
                  end
           end 
         else 
            begin
                 next_state  = r_WAIT;
                 cntr_resetH = 1'b0;  // allow counter to tick 
            end
     end
	// SAMPLE
	// Sample the state of the RECEIVE data pin    	
     r_SAMPLE: 
     begin
	  shiftH = 1'b1; // shift in the serial data
	  countH = 1'b1; // one more bit received
	  next_state = r_WAIT;
     end	
    // STOP
    // make sure that we've seen the stop bit   
     r_STOP: 
     begin
	  next_state = r_START;
          rec_readyInH = 1'b1;
     end

    default: 
      begin
       next_state    = 3'bxxx;
       cntr_resetH   = 1'bx;
       shiftH        = 1'bx;
       countH        = 1'bx;
       rstCountH     = 1'bx;
       rec_readyInH  = 1'bx;
       end
  endcase
end

// register the state machine outputs
// to eliminate ciritical-path/glithces
always @(posedge clk)
    if (rst)
        rec_readyH <= #delay  1'b1;
     else
        rec_readyH <= #delay  rec_readyInH;
        
assign   ri = (!rec_readyH) && rec_readyInH;        


        
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -