UART serial communication protocol

Keywords: FPGA

1, Communication characteristics

Asynchronous, serial, full duplex

Generally, the characteristics of a communication are: synchronous / asynchronous, serial / parallel, half duplex / full duplex
Synchronization: one chip is required to control the timing of another chip. Generally, at least one bus connection is adopted between the two to control the clock ("clock line"), in which the host actively controls the clock line (output through the clock line) and the slave passively receives the clock line (input through the clock line).
Asynchronous: both parties will not connect the clock through the bus. Asynchronous communication requires both parties to use an independent clock generation device (baud rate generator) to generate the same communication speed.
Serial: there is only one data line in each data direction. Only one bit of data is transmitted at a time. Parallelism: there are multiple data lines in each data direction. Multiple bits of data can be transmitted at a time (generally 8 / 16 bits)
Half duplex: there is only one group of data lines. At the same time, only one party controls the transmission of data lines and the other party receives data (that is, both parties cannot send data at the same time)
Full duplex: there are two or more groups of data lines. At the same time, both sides of communication can send data to each other.

2, Introduction to uart protocol

uart: universal asynchronous transceiver Universal asynchronous receiver / transmitter is a universal serial data bus used for asynchronous communication. uart can realize two-way communication. In embedded design, it is often used for communication between host and auxiliary equipment. uart includes RS232, RS449, RS432, RS422, RS485 and other interface standard specifications and bus standard specifications, that is, uart is the general name of asynchronous serial communication port. RS232 , RS449, RS432, RS422 and RS485 are interface standards and bus standards corresponding to various asynchronous serial communication ports. They specify the electrical characteristics, transmission rate, connection characteristics and mechanical characteristics of the communication port. In fact, they belong to the concept of physical layer (the lowest layer) in the communication network and have no direct relationship with the communication protocol. (the content comes from Building your digital building blocks - digital circuit and logic design)

3, This blog mainly introduces the code implementation of RS232 interface standard

Tools used: ISE Design Suite 14.7
FPGA Development board: Basys2
 Functions realized:
  Instruction 1: PC End sending I like FPGAļ¼ŒDevelopment board response I like FPGA, too. stay PC End display.
  Directive II: PC End sending I like Verilogļ¼ŒDevelopment board response I like Verilog, too. stay PC End display.
  RTL The view is as follows:


This blog post mainly records the code implementation, which will be sorted out in detail in the future. You are welcome to communicate and give advice

Top level design code
module top_uart_tx_rx(
	input					clk,
	input					rst_n,
	input					rs232_rx,
	
	output                  rs232_tx
    );
	//uart_rx
	wire		[7:0]   	rx_data;
	wire					rx_done;
	//uart_tx
	wire                    tx_finish;
	wire                    send_en;
    wire        [7:0]       data_tx;
	//rx_datadeal
	wire        tx_en1;
	wire        tx_en2;
	//tx_datadeal
	
	
	
uart_rx uart_rx(
     .clk     (clk) ,
	 .rst_n   (rst_n) ,
	 .rs232_rx(rs232_rx) ,
	 
	 .rx_data (rx_data) ,
	 .rx_done (rx_done) 
	);

uart_tx  uart_tx(
   .clk         (clk),              
   .rst_n       (rst_n),              
   .send_en     (send_en),              
   .data_tx     (data_tx),  
				
   .rs232_tx    (rs232_tx),              
   .tx_finish   (tx_finish)                           
);

tx_datadeal tx_datadeal( 
   .clk         (clk   ),              
   .rst_n       (rst_n ),
   .tx_en1      (tx_en1),
   .tx_en2      (tx_en2),
   .tx_finish   (tx_finish),   
   
   .send_en     (send_en),              
   .data_tx     (data_tx)
);

rx_datadeal rx_datadeal(
	.clk	   (clk)	,
	.rst_n     (rst_n)  ,
	.rx_data   (rx_data),
	.rx_done   (rx_done),
	
	.tx_en1    (tx_en1),
	.tx_en2    (tx_en2)
    );	
endmodule

Receive data processing code
module rx_datadeal(
	input									clk			,
	input									rst_n       ,
	input					[7:0]			rx_data     ,
	input									rx_done     ,
	
	output reg 	                            tx_en1      ,
	output reg                              tx_en2
    );
	
    reg [3:0] data_cnt;
	reg [3:0] flag1;
	reg [3:0] flag2;
	
	always@(posedge clk or negedge rst_n)
	 begin
	   if(!rst_n)
	     data_cnt <= 4'd0;
	   else if(flag1 == 4'd11 || flag2 == 4'd14 )
	     data_cnt <= 4'd0;
	   else if(rx_done)
	     data_cnt <= data_cnt + 1'b1;
	 end
	
	//Enable signal to tx
	always@(posedge clk or negedge rst_n)
	begin
	 if(!rst_n)
	  begin
	   tx_en1 <= 1'b0;
	   tx_en2 <= 1'b0;
      end
	 else if(flag1 == 4'd11)
	   tx_en1 <= 1'b1;
	 else if(flag2 == 4'd14)
	   tx_en2 <= 1'b1;
	 else 
	    begin
	   tx_en1 <= 1'b0;
	   tx_en2 <= 1'b0;
      end
	end
	
	always@(posedge clk or negedge rst_n)
	 begin
	   if(!rst_n)
	     begin
		  flag1 <= 4'd0;
		  flag2 <= 4'd0;
		 end
	   else if(flag1 == 4'd11)
	      flag1 <= 4'd0;
	   else if(flag2 == 4'd14)
	      flag2 <= 4'd0;
	   else 
	     begin
		  case(data_cnt)
		    4'd0 :  begin 
		              if(rx_data == "I")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end
				    end
		    4'd1 :  begin 
		              if(rx_data == " ")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		 
		    4'd2 :  begin 
		              if(rx_data == "L")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		 
		    4'd3 :  begin 
		              if(rx_data == "i")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
			4'd4 :  begin 
		              if(rx_data == "k")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end
				    end
		    4'd5 :  begin 
		              if(rx_data == "e")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		 
		    4'd6 :  begin 
		              if(rx_data == " ")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		 
		    4'd7 :  begin 
		              if(rx_data == "F")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= 4'd0;
		                end
					  else if(rx_data == "V")
					     begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end		
					
			4'd8 :  begin 
		              if(rx_data == "P")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= 4'd0;
		                end
					  else if(rx_data == "e")
					     begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end
				    end
		    4'd9 :  begin 
		              if(rx_data == "G")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= 4'd0;
		                end
					  else if(rx_data == "r")
					     begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		 
		    4'd10 :  begin 
		              if(rx_data == "A")
					    begin
						 flag1 <= flag1 + 1'b1;
		                 flag2 <= 4'd0;
		                end
					  else if(rx_data == "i")
					     begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		 
		    4'd11 :  begin 
					  if(rx_data == "l")
					     begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end		
			4'd12 :  begin 
		               if(rx_data == "o")
					     begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end
				    end
		    4'd13 :  begin
                      if(rx_data == "g")
					    begin
						 flag1 <= 4'd0;
		                 flag2 <= flag2 + 1'b1;
		                end
		              else
		                begin
						 flag1 <= flag1;
		                 flag2 <= flag2;
		                end 
		            end
		    default : begin
			                flag1 <= 4'd0;
							flag2 <= 4'd0;
					   end
		   endcase
		 end
	 
	 
	 end
	


endmodule
Receive code
module uart_rx(clk,rst_n,rs232_rx,rx_data,rx_done);
     input                 clk;
	 input                 rst_n;
	 input                 rs232_rx;
	 output   reg  [7:0]   rx_data;
	 output   reg          rx_done;
	 
	 reg  [1:0]s_rs232_rx;//Elimination of metastability
	 reg  [1:0]tmp_rs232_rx;//Data register
	 
	 wire      nedge;
	 reg  [15:0]div_cnt;//Frequency division counter
	 reg       bps_clk;
	 reg       uart_state;
	 reg  [7:0]bps_cnt;
	 
	 reg  [2:0]start_bit;
	 reg  [2:0]stop_bit;
	 reg  [2:0]rx_data_t [7:0];
	 //                    Address width
	 always@(posedge clk or negedge rst_n)
	  if(!rst_n)
	    s_rs232_rx <= 0;
	  else  begin
	    s_rs232_rx[0] <= rs232_rx;
		s_rs232_rx[1] <= s_rs232_rx[0];
	   end
	   
	always@(posedge clk or negedge rst_n)
	  if(!rst_n)
	    tmp_rs232_rx <= 0;
	  else  begin
	    tmp_rs232_rx[0] <= s_rs232_rx[1];
		tmp_rs232_rx[1] <= tmp_rs232_rx[0];
	   end
	 assign nedge = tmp_rs232_rx[1] & ~tmp_rs232_rx[0];
	 
	 
	 always@(posedge clk or negedge rst_n)
	  if(!rst_n)
	   div_cnt <= 16'd0;
	  else if(uart_state == 1) begin
	    if(div_cnt == 325)
	     div_cnt <= 16'd0;
	    else 
	     div_cnt <= div_cnt + 1;
	   end
	  else 
	    div_cnt <= 0;
		
	 always@(posedge clk or negedge rst_n) 
	   if(!rst_n)
	     bps_clk <= 1'b0;
	   else if(div_cnt == 16'b1)
	     bps_clk <= 1'b1;
	   else 
	     bps_clk <= 1'b0;
	  
	 always@(posedge clk or negedge rst_n)
	   if(!rst_n)
	     uart_state <= 1'b0;
	   else if(nedge)
	     uart_state <= 1'b1;
	   else if(rx_done || (bps_cnt == 8'd12 && start_bit > 2))
	     uart_state <= 1'b0;
	   else
	     uart_state <= uart_state;
	
		 
	 always@(posedge clk or negedge rst_n)
	   if(!rst_n)
	     bps_cnt <= 0;
	   else if(bps_cnt == 8'd159 | (bps_cnt == 8'd12 && start_bit > 2))
	     bps_cnt <= 0;
	   else if(bps_clk == 1)
	     bps_cnt <= bps_cnt + 1;
	   else 
	     bps_cnt <= bps_cnt;
	 
	 always@(posedge clk or negedge rst_n)
	   if(!rst_n) begin
	     rx_done <= 1'b0;
		end
	   else if(bps_cnt == 8'd159) begin
	     rx_done <= 1'b1;
        end
	   else  begin
	     rx_done <= 1'b0;
		end
	 
	 always@(posedge clk or negedge rst_n)
	   if(!rst_n)  begin
	     start_bit <= 3'd0;
	     rx_data_t[0] <= 3'd0;
		 rx_data_t[1] <= 3'd0;
		 rx_data_t[2] <= 3'd0;
		 rx_data_t[3] <= 3'd0;
		 rx_data_t[4] <= 3'd0;
		 rx_data_t[5] <= 3'd0;
		 rx_data_t[6] <= 3'd0;
		 rx_data_t[7] <= 3'd0;
		 stop_bit <= 3'd0;
		end
	   else if(bps_clk == 1) begin
	     case(bps_cnt)
		   0:begin
		      start_bit <= 3'd0;
	          rx_data_t[0] <= 3'd0;
		      rx_data_t[1] <= 3'd0;
		      rx_data_t[2] <= 3'd0;
		      rx_data_t[3] <= 3'd0;
		      rx_data_t[4] <= 3'd0;
		      rx_data_t[5] <= 3'd0;
		      rx_data_t[6] <= 3'd0;
		      rx_data_t[7] <= 3'd0;
		      stop_bit <= 3'd0;
			 end
           5,6,7,8,9,10: start_bit <= start_bit + s_rs232_rx[1];
           21,22,23,24,25,26: rx_data_t[0] <= rx_data_t[0] + s_rs232_rx[1];	
           37,38,39,40,41,42: rx_data_t[1] <= rx_data_t[1] + s_rs232_rx[1];	
           53,54,55,56,57,58: rx_data_t[2] <= rx_data_t[2] + s_rs232_rx[1];	
           69,70,71,72,73,74: rx_data_t[3] <= rx_data_t[3] + s_rs232_rx[1];	
           85,86,87,88,89,90: rx_data_t[4] <= rx_data_t[4] + s_rs232_rx[1];	
           101,102,103,104,105,106: rx_data_t[5] <= rx_data_t[5] + s_rs232_rx[1];
           117,119,120,121,122,123: rx_data_t[6] <= rx_data_t[6] + s_rs232_rx[1];
           133,135,136,137,138,139:	rx_data_t[7] <= rx_data_t[7] + s_rs232_rx[1];	
		   149,151,152,153,154,155: stop_bit <= stop_bit + s_rs232_rx[1];
         endcase		   
	    end
	    
     always@(posedge clk or negedge rst_n)
      if(!rst_n)
       	rx_data <= 8'd0;
	  else if(bps_cnt == 159)  begin
	    rx_data[0] <= rx_data_t[0][2];
		rx_data[1] <= rx_data_t[1][2];
		rx_data[2] <= rx_data_t[2][2];
		rx_data[3] <= rx_data_t[3][2];
		rx_data[4] <= rx_data_t[4][2];
		rx_data[5] <= rx_data_t[5][2];
		rx_data[6] <= rx_data_t[6][2];
		rx_data[7] <= rx_data_t[7][2];
	   end
	 
endmodule
Send data processing code
module tx_datadeal(
 input    		clk,
 input 			rst_n,
 input 			tx_finish,
 input          tx_en1,
 input          tx_en2,
 
 output reg 		send_en,
 output reg [7:0]   data_tx
 
    );
//define	
reg [4:0] data_cnt;
reg tx_state1;
reg tx_state2;

always@(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   begin
     tx_state1 <= 1'b0;
	 tx_state2 <= 1'b0;
   end
  else if(tx_en1)
     tx_state1 <= 1'b1;
  else if(tx_en2)
     tx_state2 <= 1'b1;
  else if(data_cnt  == 5'd15)
     tx_state1 <= 1'b0;  
  else if(data_cnt  == 5'd18)
     tx_state2 <= 1'b0; 
  else 
    begin
     tx_state1 <= tx_state1;
	 tx_state2 <= tx_state2;
   end
 
 end
 
 //data_cnt
always@(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   data_cnt <= 5'd0;
  else if(tx_state1 == 1'b1 && data_cnt == 5'd15)
   data_cnt <= 5'd0;
  else if(tx_state2 == 1'b1 && data_cnt == 5'd18)
   data_cnt <= 5'd0;
  else if(tx_finish)
   data_cnt <= data_cnt + 1'b1;
  else 
   data_cnt <= data_cnt;
end 

 //send_en
always@(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   send_en <= 1'b0;
  else if(tx_en1 || tx_en2)
   send_en <= 1'b1;
  else if(tx_finish)
    begin
		if(tx_state1)
		  begin
            if(data_cnt < 5'd14)
                send_en <= 1'b1;
            else
                send_en <= 1'b0;
		  end
		else if(tx_state2)
		  begin
            if(data_cnt < 5'd17)
                send_en <= 1'b1;
            else
                send_en <= 1'b0;
		  end
    end
   else
         send_en <= 1'b0;
    end
 
always@(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   data_tx <= 8'd0;
  else if(tx_state1) 
    begin 
     case(data_cnt)
	  5'd0 : data_tx <= "I";
	  5'd1 : data_tx <= " ";
	  5'd2 : data_tx <= "L";
	  5'd3 : data_tx <= "i";
	  5'd4 : data_tx <= "k";
	  5'd5 : data_tx <= "e";
	  5'd6 : data_tx <= " ";
	  5'd7 : data_tx <= "F";
	  5'd8 : data_tx <= "P";
	  5'd9 : data_tx <= "G";
	  5'd10 : data_tx <= "A";
	  5'd11 : data_tx <= ",";
	  5'd12 : data_tx <= "t";
	  5'd13 : data_tx <= "o";
	  5'd14 : data_tx <= "o";
      default : data_tx <= 8'd0;
    endcase
   end
  else if(tx_state2) 
   begin 
    case(data_cnt)
	  5'd0 : data_tx <= "I";
	  5'd1 : data_tx <= " ";
	  5'd2 : data_tx <= "L";
	  5'd3 : data_tx <= "i";
	  5'd4 : data_tx <= "k";
	  5'd5 : data_tx <= "e";
	  5'd6 : data_tx <= " ";
	  5'd7 : data_tx <= "V";
	  5'd8 : data_tx <= "e";
	  5'd9 : data_tx <= "r";
	  5'd10 : data_tx <= "i";
	  5'd11 : data_tx <= "l";
	  5'd12 : data_tx <= "o";
	  5'd13 : data_tx <= "g";
	  5'd14 : data_tx <= ",";
	  5'd15 : data_tx <= "t";
	  5'd16 : data_tx <= "o";
	  5'd17 : data_tx <= "o";
     default : data_tx <= 8'd0;
    endcase
   end
  else
    data_tx <= 8'd0;
 end
endmodule

Send code
module uart_tx(clk,rst_n,tx_finish,send_en,rs232_tx,uart_state,data_tx);
    input                               clk                        ;
    input                               rst_n                      ;
    input                               send_en                    ;//Send enable signal
    input              [   7:0]         data_tx                    ;//Send byte
	
    output reg                          rs232_tx                   ;
    output reg                          tx_finish                  ;
    output reg                          uart_state                 ;

reg                                     bps_clk                    ;//baud rate clock 
reg                    [  15:0]         div_cnt                    ;//Frequency division counter
reg                    [  15:0]         bps_DR = 5207              ;//Maximum frequency division count
reg                    [   3:0]         bps_cnt                    ;//Baud rate counting clock
reg                    [   7:0]         r_data_tx                  ;
	
localparam                              START_BYTE = 1'b0          ;
localparam                              STOP_BYTE  = 1'b1          ;
	
	//control signal
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        uart_state <= 1'b0;
    else if(send_en)
        uart_state <= 1'b1;
    else if(bps_cnt == 4'd11)
        uart_state <= 1'b0;
    else
        uart_state <= uart_state;
		
	//The register stores the transmission information
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        r_data_tx <= 1'b0;
    else if(uart_state)
        r_data_tx <= data_tx;
    else
        r_data_tx <= r_data_tx;
	
	//counter
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        div_cnt <= 16'd0;
    else if(uart_state)
    begin
        if(div_cnt == bps_DR)
            div_cnt <= 16'd0;
        else
            div_cnt <= div_cnt + 1'b1;
    end
    else
        div_cnt <= 16'd0;
	//Generate bps_clk
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        bps_clk <= 1'b0;
    else if(div_cnt == 16'd1)
        bps_clk <= 1'd1;
    else
        bps_clk <= 1'b0;
		
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        bps_cnt <= 4'd0;
    else if(bps_cnt == 4'd11)
        bps_cnt <= 4'd0;
    else if(bps_clk)
        bps_cnt <= bps_cnt + 1'b1;
    else
        bps_cnt <= bps_cnt;
	//Generate transmission completion signal
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        tx_finish <= 1'b0;
    else if(bps_cnt == 4'd11)
        tx_finish <= 1'b1;
    else
        tx_finish <= 1'b0;
	//Sending module
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        rs232_tx <= 1'b1;
    else
    begin
        case(bps_cnt)
            0:rs232_tx <= 1'b1;
            1:rs232_tx <= START_BYTE;                               //0
            2:rs232_tx <= r_data_tx[0];
            3:rs232_tx <= r_data_tx[1];
            4:rs232_tx <= r_data_tx[2];
            5:rs232_tx <= r_data_tx[3];
            6:rs232_tx <= r_data_tx[4];
            7:rs232_tx <= r_data_tx[5];
            8:rs232_tx <= r_data_tx[6];
            9:rs232_tx <= r_data_tx[7];
            10:rs232_tx <= STOP_BYTE;                               //1
            default:rs232_tx <= 1'b1;
        endcase
    end
endmodule

TESTBENCH
module tb_uart_tx_rx;

	// Inputs
	reg clk;
	reg rst_n;
	reg rs232_rx;

	// Outputs
	wire rs232_tx;

	// Instantiate the Unit Under Test (UUT)
	top_uart_tx_rx uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.rs232_rx(rs232_rx), 
		.rs232_tx(rs232_tx)
	);
   	parameter period=20,
			  RST_ING=1'b0,
			  BPS_9600=32'd104_167;
	initial begin
		// Initialize Inputs
		clk = 0;
		forever
			#(period/2)clk=~clk;
	end


	
	reg	[4:0]	cnt;
	reg	[7:0]	data_tx;
	initial	begin
	rst_n = RST_ING;
	#5000;
	rst_n = ~RST_ING;
	
	rs232_rx = 1'b1;
	
//I Like FPGA	
	#1000_000;
	data_tx = "I";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = " ";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "L";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "i";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "k";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "e";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = " ";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "F";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "P";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "G";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "A";
	tx_task(data_tx);

	//I Like Verilog
	#100_000_000;
	data_tx = "I";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = " ";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "L";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "i";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "k";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "e";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = " ";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "V";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "e";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "r";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "i";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "l";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "o";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "g";
	tx_task(data_tx);

//I Like FPGA	
	#100_000_000;
	data_tx = "I";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = " ";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "L";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "i";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "k";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "e";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = " ";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "F";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "P";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "G";
	tx_task(data_tx);
	
	#1000_000;
	data_tx = "A";
	tx_task(data_tx);
	end	
   	
	task tx_task;
		input	[7:0]	rs232_tx;
		integer i;
		begin
			rs232_rx = 0;
			#BPS_9600;
			for(i = 0;i < 8;i = i+1)	begin
				rs232_rx = data_tx[i];
				#BPS_9600;
			end
			rs232_rx = 1;
			#BPS_9600;
		end
	endtask

endmodule

The simulation diagram is as follows:

This blog post is used to record your study. If you reprint it, please indicate the source.

Posted by sathyan on Mon, 29 Nov 2021 16:54:35 -0800