FPGA学习——UART串口模块

  1 `timescale 1ns / 1ps
  2 
  3 /******************************************************************************
  4  *
  5  *            Module    :     rx_module
  1 `timescale 1ns / 1ps
  2 //////////////////////////////////////////////////////////////////////////////////
  3 // Company: 
  4 // Engineer: 
  5 // 
  6 // Create Date:    17:36:30 03/27/2013 
  7 // Design Name: 
  8 // Module Name:    uart_tx 
  9 // Project Name: 
 10 // Target Devices: 
 11 // Tool versions: 
 12 // Description: 
 13 //
 14 // Dependencies: 
 15 //
 16 // Revision: 
 17 // Revision 0.01 - File Created
 18 // Additional Comments: 
 19 //
 20 ////////////////////////////////////////////////////////////////////////////////// 
 21 
 22 module tx_module(
 23      input               clk16x,       /*       transmit clock,16×115200                 */
 24      input               rst_n,        /*        glabol reset signal                     */
 25      input               TransEn,      /*            transmit enable                     */
 26      input [7:0]         DataToTrans,  /*        Data prepared for transmitting          */
 27     
 28      output reg          BufFull,      /*       Data buffer is full                      */
 29      output reg          tx            /*           serial data out                      */
 30 );
 31 
 32 /*    capture the rising edge of TransEn    */
 33 reg TransEn_r;
 34 wire pos_tri;
 35 always@(posedge clk16x or negedge rst_n)
 36 begin
 37     if(!rst_n)
 38         TransEn_r <= 1'b0;
 39     else
 40         TransEn_r <= TransEn;
 41 end
 42 assign pos_tri = ~TransEn_r & TransEn;
 43 
 44 /*
 45 *    when the rising edge of DataEn comes up, load the Data to buffer
 46 */
 47 reg [7:0] ShiftReg;
 48 always@(posedge pos_tri or negedge rst_n)
 49 begin
 50     if(!rst_n)
 51         ShiftReg <= 8'b0;
 52     else
 53         ShiftReg <= DataToTrans;
 54 end
 55 //----------------------------------------------    
 56 /*     counter control      */
 57 reg cnt_en;
 58 always@(posedge clk16x or negedge rst_n)
 59 begin
 60     if(!rst_n)
 61         begin
 62             cnt_en  <= 1'b0;
 63             BufFull <= 1'b0;
 64         end
 65     else if(pos_tri==1'b1)
 66         begin
 67             cnt_en  <=1'b1;
 68             BufFull <=1'b1;
 69         end
 70     else if(cnt==8'd160)
 71         begin
 72             cnt_en<=1'b0;
 73             BufFull <=1'b0;
 74         end
 75 end
 76 
 77 //---------------------------------------------
 78 /*      counter module        */
 79 reg [7:0] cnt; 
 80 always@(posedge clk16x or negedge rst_n)
 81 begin
 82     if(!rst_n)
 83         cnt<=8'd0;
 84     else if(cnt_en)
 85         cnt<=cnt+1'b1;
 86     else
 87         cnt<=8'd0;
 88 end
 89 
 90 //---------------------------------------------
 91 /*      transmit module        */
 92 
 93 always@(posedge clk16x or negedge rst_n)
 94 begin
 95     if(!rst_n)
 96         begin
 97             tx <= 1'b1;
 98         end
 99     else if(cnt_en)
100         case(cnt)
101         'd0   :  tx <= 1'b0;
102         'd16  :  tx <= ShiftReg[0];
103         'd32  :  tx <= ShiftReg[1];
104         'd48  :  tx <= ShiftReg[2];
105         'd64  :  tx <= ShiftReg[3];
106         'd80  :  tx <= ShiftReg[4];
107         'd96  :  tx <= ShiftReg[5];
108         'd112 :  tx <= ShiftReg[6];
109         'd128 :  tx <= ShiftReg[7];
110         'd144 :  tx <= 1'b1;
111         endcase
112     else
113         tx <= 1'b1;
114 end
115 
116 
117 endmodule

testBench
 1 `timescale 1ns / 1ps
 2 
 3 ////////////////////////////////////////////////////////////////////////////////
 4 // Company: 
 5 // Engineer:
 6 //
 7 // Create Date:   19:29:39 03/27/2013
 8 // Design Name:   tx_module
 9 // Module Name:   E:/my_project/Xilinx/ad_lvds/UART/tb_uarttx.v
10 // Project Name:  UART
11 // Target Device:  
12 // Tool versions:  
13 // Description: 
14 //
15 // Verilog Test Fixture created by ISE for module: tx_module
16 //
17 // Dependencies:
18 // 
19 // Revision:
20 // Revision 0.01 - File Created
21 // Additional Comments:
22 // 
23 ////////////////////////////////////////////////////////////////////////////////
24 
25 module tb_uart;
26 
27     // Inputs
28     reg clk16x;
29     reg rst_n;
30     reg TransEn;
31     reg [7:0] DataToTrans;
32 
33     // Outputs
34     wire BufFull;
35     wire tx;
36     wire [7:0] rx_DataReceived;
37     wire rx_dataReady;
38     // Instantiate the Unit Under Test (UUT)
39     tx_module uut (
40         .clk16x(clk16x), 
41         .rst_n(rst_n), 
42         .TransEn(TransEn), 
43         .DataToTrans(DataToTrans), 
44         .BufFull(BufFull), 
45         .tx(tx)
46     );
47     rx_module rx_uut(
48       .GClk(clk16x),         /*       system topest clock                      */
49      .clk16x(clk16x),       /*       sample clock,16×115200                   */
50      .rst_n(rst_n),        /*        glabol reset signal                     */
51      .rx(tx),           /*           serial data in                       */
52      .DataReady(rx_dataReady),    /*       a complete byte has been received        */
53      .DataReceived(rx_DataReceived)  /*       Bytes received                           */
54     );
55     always #5 clk16x = ~clk16x;
56     initial begin
57         // Initialize Inputs
58         clk16x = 0;
59         rst_n =0;
60         TransEn = 0;
61         DataToTrans = 0;
62         // Wait 100 ns for global reset to finish
63         #100;
64       rst_n = 1;
65         TransEn = 1;
66         DataToTrans = 8'b0000_1111;
67         #5000;
68         TransEn = 0;
69         #160;
70         TransEn = 1;
71         DataToTrans = 8'b1111_0000;
72         #5000;
73         $stop;
74     end
75       
76 endmodule
  6  *          File Name   :     rx_module.v
  7  *            Author    :     JC_Wang
  8  *            Version   :     1.0
  9  *            Date      :     2012/12/5
 10  *         Description  :     UART接收模块
 11  *           
 12  *
 13  ********************************************************************************/
 14  
 15  module rx_module(
 16      input               GClk,         /*       system topest clock                      */
 17      input               clk16x,       /*       sample clock,16×115200                   */
 18      input               rst_n,        /*        glabol reset signal                     */
 19      input               rx,           /*           serial data in                       */
 20      output reg          DataReady,    /*       a complete byte has been received        */
 21      output reg[7:0]     DataReceived  /*       Bytes received                           */
 22  );
 23  
 24   
 25  /*  捕获rx的下降沿,即起始信号  */    
 26  reg trigger_r0;
 27  wire neg_tri;
 28  always@(posedge GClk or negedge rst_n)  /*下降沿使用全局时钟来捕获的,其实用clk16x来捕获也可以*/
 29  begin
 30      if(!rst_n)
 31          begin
 32              trigger_r0<=1'b0;
 33          end
 34      else
 35          begin    
 36              trigger_r0<=rx;
 37          end
 38  end
 39  
 40  assign neg_tri = trigger_r0 & ~rx;
 41  
 42  //----------------------------------------------    
 43  /*     counter control      */
 44  reg cnt_en;
 45  always@(posedge GClk or negedge rst_n)
 46  begin
 47      if(!rst_n)
 48          cnt_en<=1'b0;
 49      else if(neg_tri==1'b1)      /*如果捕获到下降沿,则开始计数*/
 50          cnt_en<=1'b1;
 51      else if(cnt==8'd152)
 52          cnt_en<=1'b0;
 53     
 54  end
 55  //---------------------------------------------
 56  /*      counter module ,对采样时钟进行计数       */
 57  reg [7:0] cnt;
 58  always@(posedge clk16x or negedge rst_n)
 59  begin
 60      if(!rst_n)
 61          cnt<=8'd0;
 62      else if(cnt_en)
 63          cnt<=cnt+1'b1;
 64      else
 65          cnt<=8'd0;
 66  
 67  end
 68  //---------------------------------------------
 69  /*      receive module        */
 70  reg StopBit_r;
 71  always@(posedge clk16x or negedge rst_n)
 72  begin
 73      if(!rst_n)
 74          begin
 75              DataReceived<=8'b0;
 76          end
 77      else if(cnt_en)
 78          case(cnt)
 79              8'd24:   DataReceived[0] <= rx;    /*在各个采样时刻,读取接收到的数据*/
 80              8'd40:   DataReceived[1] <= rx;
 81              8'd56:   DataReceived[2] <= rx;
 82              8'd72:   DataReceived[3] <= rx;
 83              8'd88:   DataReceived[4] <= rx;
 84              8'd104:  DataReceived[5] <= rx;
 85              8'd120:  DataReceived[6] <= rx;
 86              8'd136:  DataReceived[7] <= rx;
 87              
 88          endcase
 89  
 90  end
 91  
 92  always@(posedge clk16x or negedge rst_n)
 93  begin
 94      if(!rst_n)
 95          DataReady<=1'b0;
 96      else if (cnt==8'd152)
 97          DataReady<=1'b1;       //接收到停止位后,给出数据准备好标志位
 98      else 
 99          DataReady<=1'b0;
100  end
101  
102  endmodule
原文地址:https://www.cnblogs.com/121792730applllo/p/2986509.html