Verification Of UART Part - II

In

Device Under Test

   1 //-----------------------------------------------------

   2 // Design Name : uart

   3 // File Name   : uart.v

   4 // Function    : Simple UART

   5 // Coder       : Deepak Kumar Tala

   6 //-----------------------------------------------------

   7 module uart (

   8 reset          ,

   9 txclk          ,

  10 ld_tx_data     ,

  11 tx_data        ,

  12 tx_enable      ,

  13 tx_out         ,

  14 tx_empty       ,

  15 rxclk          ,

  16 uld_rx_data    ,

  17 rx_data        ,

  18 rx_enable      ,

  19 rx_in          ,

  20 rx_empty

  21 );

  22 // Port declarations

  23 input        reset          ;

  24 input        txclk          ;

  25 input        ld_tx_data     ;

  26 input  [7:0] tx_data        ;

  27 input        tx_enable      ;

  28 output       tx_out         ;

  29 output       tx_empty       ;

  30 input        rxclk          ;

  31 input        uld_rx_data    ;

  32 output [7:0] rx_data        ;

  33 input        rx_enable      ;

  34 input        rx_in          ;

  35 output       rx_empty       ;

  36

  37 // Internal Variables

  38 reg [7:0]    tx_reg         ;

  39 reg          tx_empty       ;

  40 reg          tx_over_run    ;

  41 reg [3:0]    tx_cnt         ;

  42 reg          tx_out         ;

  43 reg [7:0]    rx_reg         ;

  44 reg [7:0]    rx_data        ;

  45 reg [3:0]    rx_sample_cnt  ;

  46 reg [3:0]    rx_cnt         ; 

  47 reg          rx_frame_err   ;

  48 reg          rx_over_run    ;

  49 reg          rx_empty       ;

  50 reg          rx_d1          ;

  51 reg          rx_d2          ;

  52 reg          rx_busy        ;

  53

  54 // UART RX Logic

  55 always @ (posedge rxclk or posedge reset)

  56 if (reset) begin

  57   rx_reg        <= 0;

  58   rx_data       <= 0;

  59   rx_sample_cnt <= 0;

  60   rx_cnt        <= 0;

  61   rx_frame_err  <= 0;

  62   rx_over_run   <= 0;

  63   rx_empty      <= 1;

  64   rx_d1         <= 1;

  65   rx_d2         <= 1;

  66   rx_busy       <= 0;

  67 end else begin

  68   // Synchronize the asynch signal

  69   rx_d1 <= rx_in;

  70   rx_d2 <= rx_d1;

  71   // Uload the rx data

  72   if (uld_rx_data) begin

  73     rx_data  <= rx_reg;

  74     rx_empty <= 1;

  75   end

  76   // Receive data only when rx is enabled

  77   if (rx_enable) begin

  78     // Check if just received start of frame

  79     if ( ! rx_busy &&  ! rx_d2) begin

  80       rx_busy       <= 1;

  81       rx_sample_cnt <= 1;

  82       rx_cnt        <= 0;

  83     end

  84     // Start of frame detected, Proceed with rest of data

  85     if (rx_busy) begin

  86        rx_sample_cnt <= rx_sample_cnt + 1;

  87        // Logic to sample at middle of data

  88        if (rx_sample_cnt == 7) begin

  89           if ((rx_d2 == 1) && (rx_cnt == 0)) begin

  90             rx_busy <= 0;

  91           end else begin

  92             rx_cnt <= rx_cnt + 1;

  93             // Start storing the rx data

  94             if (rx_cnt > 0 && rx_cnt < 9) begin

  95               rx_reg[rx_cnt - 1] <= rx_d2;

  96             end

  97             if (rx_cnt == 9) begin

  98                rx_busy <= 0;

  99                // Check if End of frame received correctly

 100                if (rx_d2 == 0) begin

 101                  rx_frame_err <= 1;

 102                end else begin

 103                  rx_empty     <= 0;

 104                  rx_frame_err <= 0;

 105                  // Check if last rx data was not unloaded,

 106                  rx_over_run  <= (rx_empty) ? 0 : 1;

 107                end

 108             end

 109           end

 110        end

 111     end

 112   end

 113   if ( ! rx_enable) begin

 114     rx_busy <= 0;

 115   end

 116 end

 117

 118 // UART TX Logic

 119 always @ (posedge txclk or posedge reset)

 120 if (reset) begin

 121   tx_reg        <= 0;

 122   tx_empty      <= 1;

 123   tx_over_run   <= 0;

 124   tx_out        <= 1;

 125   tx_cnt        <= 0;

 126 end else begin

 127    if (ld_tx_data) begin

 128       if ( ! tx_empty) begin

 129         tx_over_run <= 0;

 130       end else begin

 131         tx_reg   <= tx_data;

 132         tx_empty <= 0;

 133       end

 134    end

 135    if (tx_enable &&  ! tx_empty) begin

 136      tx_cnt <= tx_cnt + 1;

 137      if (tx_cnt == 0) begin

 138        tx_out <= 0;

 139      end

 140      if (tx_cnt > 0 && tx_cnt < 9) begin

 141         tx_out <= tx_reg[tx_cnt -1];

 142      end

 143      if (tx_cnt == 9) begin

 144        tx_out <= 1;

 145        tx_cnt <= 0;

 146        tx_empty <= 1;

 147      end

 148    end

 149    if ( ! tx_enable) begin

 150      tx_cnt <= 0;

 151    end

 152 end

 153

 154 endmodule

HDL Testbench Top

  1 `include "uart.v"
  2 module top();
  3 
  4 reg        reset          ;
  5 reg        txclk          ;
  6 reg        ld_tx_data     ;
  7 reg  [7:0] tx_data        ;
  8 reg        tx_enable      ;
  9 wire       tx_out         ;
 10 wire       tx_empty       ;
 11 reg        rxclk          ;
 12 reg        uld_rx_data    ;
 13 wire [7:0] rx_data        ;
 14 reg        rx_enable      ;
 15 wire       rx_in          ;
 16 wire       rx_empty       ;
 17 reg        loopback       ; 
 18 reg        rx_tb_in       ;
 19 
 20 initial begin
 21   reset       = 0;
 22   txclk       = 0;
 23   ld_tx_data  = 0;
 24   tx_data     = 0;
 25   tx_enable   = 0;
 26   rxclk       = 0;
 27   uld_rx_data = 0;
 28   rx_enable   = 0;
 29   loopback    = 0;
 30   rx_tb_in    = 1;
 31 end
 32 // Loopback control logic
 33 assign rx_in = (loopback) ? tx_out : rx_tb_in;
 34 // RX and TX Clock generation
 35 always  #1  rxclk = ~rxclk;
 36 always  #16  txclk = ~txclk;
 37 
 38 // DUT Connected here
 39 uart U (
 40 .reset          (reset),
 41 .txclk          (txclk),
 42 .ld_tx_data     (ld_tx_data),
 43 .tx_data        (tx_data),
 44 .tx_enable      (tx_enable),
 45 .tx_out         (tx_out),
 46 .tx_empty       (tx_empty),
 47 .rxclk          (rxclk),
 48 .uld_rx_data    (uld_rx_data),
 49 .rx_data        (rx_data),
 50 .rx_enable      (rx_enable),
 51 .rx_in          (rx_in),
 52 .rx_empty       (rx_empty)
 53 );
 54 
 55 endmodule

E Testbench Top

  1 <'
  2 import uart_clk.e;
  3 import uart_sb.e;
  4 import uart_txgen.e;
  5 
  6 struct uart_tb {
  7 
  8   sb    : uart_sb;
  9   txgen : uart_txgen;
 10     keep txgen.sb == sb;
 11 
 12   go()@sys.any is {
 13     start txgen.goTxgen();
 14     start terminate();
 15   };
 16 
 17   terminate()@sys.txclk is {
 18     var timeout : uint = 0;
 19     while ( ! txgen.isDone()) {
 20       wait cycle;
 21     };
 22     wait [20]*cycle;
 23     outf("%dns : Termintating the simulation\n",sys.time);
 24     stop_run();
 25   };
 26 };
 27 
 28 extend sys {
 29   tb  : uart_tb;
 30   run() is also {
 31     start tb.go();
 32   };
 33 };
 34 '>

UART Clock

1 <'
 2 extend sys {
 3   event rxclk is rise('top.rxclk') @sim;
 4   event txclk is rise('top.txclk') @sim;
 5 };
 6 '>

   Bạn Có Đam Mê Với Vi Mạch hay Nhúng      -     Bạn Muốn Trau Dồi Thêm Kĩ Năng

Mong Muốn Có Thêm Cơ Hội Trong Công Việc

Và Trở Thành Một Người Có Giá Trị Hơn

Bạn Chưa Biết Phương Thức Nào Nhanh Chóng Để Đạt Được Chúng

Hãy Để Chúng Tôi Hỗ Trợ Cho Bạn. SEMICON  

Lần cập nhật cuối ( Thứ ba, 03 Tháng 5 2022 19:36 )