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

📄 u_xmit.v

📁 带自适应波特率发生器UART实现
💻 V
字号:
////////////////////////////////////////////////////////////////////////
//                                                                    
//  Abstract: Uart has an auto-tuning baud rate generator 
//            This is the transmitter portion of the UART.                                              
//  Module  : U_XMIT.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_xmit (	                
                uart_clk,
	        rst,
                clk,
		txd,
		t_st,
		sbuf_t,
		ti
	        );

// Xmitter state definition
parameter	x_IDLE		= 3'b001,
		x_START		= 3'b010,
		x_WAIT		= 3'b011,
		x_SHIFT		= 3'b100,
		x_STOP		= 3'b101;


parameter       x_STARTbit      = 2'b00,
		x_STOPbit       = 2'b01,
		x_ShiftReg      = 2'b10;

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

// ******************************************
//
// PORT DEFINITIONS
//
// ******************************************
input	        uart_clk;	// system clock. Must be 16 x Baud
input	        rst;	        // syn reset
input           clk;
input		t_st;		// active high, Xmit command
input	[7:0]	sbuf_t;         // data to be xmitted

output	        ti;	        // status
output		txd;	        // this pin goes to the connector


// ******************************************
//
// MEMORY ELEMENT DEFINITIONS
//
// ******************************************
reg	[2:0]	next_state, state;
reg		load_shiftRegH;
reg		shiftEnaH;
reg	[4:0]	bitCell_cntrH;
reg		countEnaH;
reg	[7:0]	xmit_ShiftRegH;
reg	[3:0]	bitCountH;
reg		rst_bitCountH;
reg		ena_bitCountH;
reg	[1:0]	xmitDataSelH;
reg		txd;
reg		xmit_doneInH;
reg		xmit_doneH;
reg             uart_clkid;
reg             uart_clki;
reg             st;
reg             st_temp;
reg             st_temp2; 

wire            ti;
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); 

//serial data output
always @(xmit_ShiftRegH or xmitDataSelH)
  case (xmitDataSelH)
	x_STARTbit: txd = 1'b0;
	x_STOPbit:  txd = 1'b1;
	x_ShiftReg: txd = xmit_ShiftRegH[0];
	default:    txd = 1'bx;	
  endcase

// Bit Cell time Counter
always @(posedge clk )
  if (rst)
      bitCell_cntrH <= #delay 1'b0;
  else if(uart_clk_rising&&countEnaH)     
      bitCell_cntrH <= #delay bitCell_cntrH + 1;
  else if (uart_clk_rising)
      bitCell_cntrH <= #delay 1'b0;   

// Shift Register
// The LSB must be shifted out first
always @(posedge clk )
  if (rst) 
       xmit_ShiftRegH <= #delay 1'b0;    
 else if (uart_clk_rising&&load_shiftRegH)  
       xmit_ShiftRegH <= #delay sbuf_t;
  else if (uart_clk_rising&&shiftEnaH) 
	  begin
		xmit_ShiftRegH[6:0] <= #delay xmit_ShiftRegH[7:1];
		xmit_ShiftRegH[7]   <= #delay 1'b1;
	  end 
  else 
	xmit_ShiftRegH <= #delay xmit_ShiftRegH;

// Transmitted bit counter
always @(posedge clk )
  if (rst) 
        bitCountH <= #delay 1'b0;
  else if(uart_clk_rising&&rst_bitCountH)     
        bitCountH <= #delay 1'b0;
  else if(uart_clk_rising&&ena_bitCountH) 
        bitCountH <= #delay bitCountH + 1;

//modify t_st     
always @(posedge clk)
  if (rst)
        st_temp <= #delay 1'b0;
  else if (t_st)
        st_temp <= #delay 1'b1;
  else if (uart_clk_rising)     
        st_temp <= #delay 1'b0;

always @(posedge clk ) 
    if(rst)                    
        st_temp2 <= #delay 1'b0;  
    else if (uart_clk_rising)       
        st_temp2 <= #delay st_temp;
        
always @(posedge clk ) 
    if(rst)                    
        st <= #delay 1'b0;  
    else if (uart_clk_rising)       
        st <= #delay st_temp2;  

    
// STATE MACHINE
// State Variable
always @(posedge clk )
  if (rst) 
        state <= #delay x_IDLE;
  else if(uart_clk_rising) 
        state <= #delay next_state;  

// Next State, Output Decode
always @(state or st or bitCell_cntrH or bitCountH)
begin  
	// Defaults
	next_state 	= state;
	load_shiftRegH	= 1'b0;
	countEnaH       = 1'b0;
	shiftEnaH       = 1'b0;
	rst_bitCountH   = 1'b0;
	ena_bitCountH   = 1'b0;
        xmitDataSelH    = x_STOPbit;
	xmit_doneInH	= 1'b0;

	case (state)    	
		// x_IDLE
		// wait for the start command
		x_IDLE: 
		begin
			if (st) 
			   begin 
                              next_state = x_START;
			      load_shiftRegH = 1'b1;
			   end 
			else 
			   begin
			       next_state    = x_IDLE;
			       rst_bitCountH = 1'b1; 
                               xmit_doneInH  = 1'b0;
			   end
		end  
		// x_START
		// send start bit 
		x_START: 
		begin
                     xmitDataSelH    = x_STARTbit;
			if (bitCell_cntrH == 4'hF)
				next_state = x_WAIT;
			else 
			    begin 
				next_state = x_START;
				countEnaH  = 1'b1; // allow to count up
			    end				
		end
		// x_WAIT
		// wait 1 bit-cell time before sending
		// data on the xmit pin
		x_WAIT: 
		begin
                      xmitDataSelH    = x_ShiftReg;
			// 1 bit-cell time wait completed
			if (bitCell_cntrH == 4'hE) 
			    begin
				if (bitCountH == WORD_LEN)
					next_state = x_STOP;
				else 
				    begin
					next_state = x_SHIFT;
					ena_bitCountH = 1'b1; //1more bit sent
				    end
			// bit-cell wait not complete
			    end 
			else 
			    begin
				next_state = x_WAIT;
				countEnaH  = 1'b1;
			    end		
		 end
		// x_SHIFT
		// shift out the next bit		
		x_SHIFT: 
		begin
                        xmitDataSelH    = x_ShiftReg;
			next_state = x_WAIT;
			shiftEnaH  = 1'b1; // shift out next bit
		end
		// x_STOP
		// send stop bit		
		x_STOP: 
		begin
                        xmitDataSelH    = x_STOPbit;
			if (bitCell_cntrH == 4'hF) 
			    begin
				next_state   = x_IDLE;
                                xmit_doneInH = 1'b1;
			    end 
			else 
			    begin
				next_state = x_STOP;
				countEnaH = 1'b1; //allow bit cell cntr
			end
		 end

	default: 
	      begin
		   next_state     = 3'bxxx;
		   load_shiftRegH = 1'bx;
		   countEnaH      = 1'bx;
                   shiftEnaH      = 1'bx;
                   rst_bitCountH  = 1'bx;
                   ena_bitCountH  = 1'bx;
                   xmitDataSelH   = 2'bxx;
                   xmit_doneInH   = 1'bx;
	      end

    endcase

end

// register the state machine outputs
// to eliminate ciritical-path/glithces
always @(posedge clk )
  if (rst) 
       xmit_doneH <= #delay 1'b0;
  else 
       xmit_doneH <= #delay xmit_doneInH;

assign  ti = (!xmit_doneH) && xmit_doneInH;




endmodule

⌨️ 快捷键说明

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