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

📄 uart_testbench.v

📁 uart协议、实现、验证
💻 V
📖 第 1 页 / 共 4 页
字号:
  //    THR             ( /W | ADR 0 | DLAB 0)  //      [7:0] ----TX- "txdata" Transmitter Holding Register  //    ----------------  //    IER             (R/W | ADR 1 | DLAB 0)   //      [0]   -RX---- "1" Received Data Available & Receive Fifo Timeout  //      [1]   ----TX- "1" Transmitter Holding Register Empty  //      [2]   -RX---- "1" Receiver Line Status  //      [3]   -MODEM- "1" Modem Status  //    ----------------  //    IIR             (R/  | ADR 2)  //      [0]   ------- "0" Interrupt is Pending (decreasing priority level in following 3 bits)  //      [3:1] -RX---- "011" Receiver Line Status - Overrun, Parity, Framing error or Break int. ---> READ LSR  //      [3:1] -RX---- "010" Received Data Available - Fifo Trigger Level Reached ------------------> READ RBR (Fifo lower than trig.)  //      [3:1] -RX---- "110" Timeout Indication - Fifo not empty & no Fifo action for 4 char times -> READ RBR  //      [3:1] ----TX- "001" Transmitter Holding Register Empty - THR Empty ------------------------> READ IIR | WRITE THR  //      [3:1] -MODEM- "000" Modem Status - CTS, DSR, DCD changed or RI changed from '0' to '1' ----> READ MSR  //    ----------------  //    FCR             ( /W | ADR 2)  //      [1]   -RX---- "1" Clear only Receiver Fifo (not shift register)  //      [2]   ----TX- "1" Clear only Transmitter Fifo (not shift register)  //      [7:6] -RX---- "00"  1 BYTE  Receiver Fifo Interrupt trigger level  //      [7:6] -RX---- "01"  4 BYTEs Receiver Fifo Interrupt trigger level  //      [7:6] -RX---- "10"  8 BYTEs Receiver Fifo Interrupt trigger level  //      [7:6] -RX---- "11" 14 BYTEs Receiver Fifo Interrupt trigger level  //    ----------------  //    LCR             (R/W | ADR 3)  //      [1:0] -RX-TX- "00" 5 bits in each character  //      [1:0] -RX-TX- "01" 6 bits in each character  //      [1:0] -RX-TX- "10" 7 bits in each character  //      [1:0] -RX-TX- "11" 8 bits in each character  //      [2]   -RX-TX- "0" 1 stop bit  //      [2]   -RX-TX- "1" 1.5 stop bits (when 5 bits of char.) or 2 stop bits (when 6, 7 or 8 bits of char.)  //      [3]   -RX-TX- "1" Parity bit enabled  //      [5:4] -RX-TX- "00" NO Stick Parity & ODD Parity bit - ODD num. of '1's is transmitted  //      [5:4] -RX-TX- "01" NO Stick Parity & EVEN Parity bit - EVEN num. of '1's is transmitted  //      [5:4] -RX-TX- "10" Stick Parity bit - Stick '1' as Parity bit  //      [5:4] -RX-TX- "11" Stick Parity bit - Stick '0' as Parity bit  //      [6]   ----TX- "1" Break Control - Output is forced to '0'  //      [7]   ------- "1" DLAB - for access to DLL and DLM  //    ----------------  //    MCR             ( /W | ADR 4)  //      [0]   -MODEM- "1" Force DTR to '0' - in LoopBack connected to DSR input  //      [1]   -MODEM- "1" Force RTS to '0' - in LoopBack connected to CTS input  //      [2]   -MODEM- "1" Force N.C.1 to '0' - in LoopBack connected to RI input  //      [3]   -MODEM- "1" Force N.C.2 to '0' - in LoopBack connected to DCD input  //      [4]   -MODEM- "1" LoopBack mode  //    ----------------  //    LSR             (R/  | ADR 5)  //      [0]   -RX---- "1" Data Ready - At least 1 char. received and is in Fifo----------> READ RBR (Fifo empty)  //      [1]   -RX---- "1" Overrun Error - Fifo full & 1 char. received in shift reg. ----> READ LSR  //      [2]   -RX---- "1" Parity Error - top Fifo char. has invalid parity bit ----------> READ LSR  //      [3]   -RX---- "1" Framing Error - top Fifo char. has invalid stop bit -----------> READ LSR  //      [4]   -RX---- "1" Break Int. - top Fifo char. bits are '0' and it's ctrl. bits --> READ LSR  //      [5]   ----TX- "1" Transmitter Holding Register Empty - transmitter Fifo empty ---> WRITE THR  //      [6]   ----TX- "1" Transmitter EMpTy - transmitter Fifo empty & shift reg. empty -> WRITE THR  //      [7]   -RX---- "1" At least 1 Parity Error, Framing Error or Break Int. in Fifo --> READ LSR & No More Errors in Fifo  //    ----------------  //    MSR             (R/  | ADR 6)  //      [0]   -MODEM- "1" Delta CTS indicator - CTS has changed it's state --------------> READ MSR  //      [1]   -MODEM- "1" Delta DSR indicator - DSR has changed it's state --------------> READ MSR  //      [2]   -MODEM- "1" Trailing Edge of RI - RI has changed from '0' to '1' ----------> READ MSR  //      [3]   -MODEM- "1" Delta DCD indicator - DCD has changed it's state --------------> READ MSR  //      [4]   -MODEM- "x" Complement of CTS input | in LoopBack equal to RTS = MCR[1]  //      [5]   -MODEM- "x" Complement of DSR input | in LoopBack equal to DTR = MCR[0]  //      [6]   -MODEM- "x" Complement of RI input | in LoopBack equal to N.C.1 = MCR[2]  //      [7]   -MODEM- "x" Complement of DCD input | in LoopBack equal to N.C.2 = MCR[3]  //    ----------------  //    DLL             (R/W | ADR 0 | DLAB 1)  //      [7:0] ------- "dl[ 7:0]" LSB of DL Reg. written 2. - dl == '0' disables outputs / dl = 1/(T_wb_clk_period*16*BaudRate)  //    ----------------  //    DLM             (R/W | ADR 1 | DLAB 1)  //      [7:0] ------- "dl[15:8]" MSB of DL Reg. written 1. - dl == '0' disables outputs / dl = 1/(T_wb_clk_period*16*BaudRate)  //    ----------------  // Transparent UART registers  assign ier_reg[7:0] = {4'h0, testbench.i_uart_top.regs.ier      };  assign iir_reg[7:0] = {4'hC, testbench.i_uart_top.regs.iir      };  assign fcr_reg[7:0] = {      testbench.i_uart_top.regs.fcr, 6'h0};  assign lcr_reg[7:0] = {      testbench.i_uart_top.regs.lcr      }; // lcr_reg[7] == DLAB !!!  assign mcr_reg[7:0] = {3'h0, testbench.i_uart_top.regs.mcr      };  assign lsr_reg[7:0] = {      testbench.i_uart_top.regs.lsr      };  assign msr_reg[7:0] = {      testbench.i_uart_top.regs.msr      };  assign dll_reg[7:0] = {      testbench.i_uart_top.regs.dl[ 7:0] };  assign dlm_reg[7:0] = {      testbench.i_uart_top.regs.dl[15:8] };  // Tracking changes of registers  always@(ier_reg)  begin    -> ier_reg_changed;  end  always@(iir_reg)  begin    -> iir_reg_changed;  end  always@(fcr_reg)  begin    -> fcr_reg_changed;  end  always@(lcr_reg)  begin    -> lcr_reg_changed;  end  always@(mcr_reg)  begin    -> mcr_reg_changed;  end  always@(lsr_reg)  begin    -> lsr_reg_changed;  end  always@(msr_reg)  begin    -> msr_reg_changed;  end  always@(dll_reg)  begin    -> dll_reg_changed;  end  always@(dlm_reg)  begin    -> dlm_reg_changed;  end  // Tracking read/write access to registers  always@(wbs_cyc_i or wbs_stb_i or wbs_we_i or wbs_sel_i or wbs_adr_i or           wbs_dat_i /*or wbs_ack_o*/ /*or posedge wb_clk*/)  begin    if (wbs_cyc_i && wbs_stb_i)    begin      if (wbs_we_i /*&& wbs_ack_o*/) // WRITE      begin        // LOG's example of  detecting of register write:        //    ----------------        //    case (wbs_adr_i)        //    `UART_REG_TR: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!        //                    -> dll_reg_written;        //                  else        //                    -> thr_reg_written;        //    `UART_REG_IE: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!        //                    -> dlm_reg_written;        //                  else        //                    -> ier_reg_written;        //    `UART_REG_FC: -> fcr_reg_written;        //    `UART_REG_LC: -> lcr_reg_written;         //    `UART_REG_MC: -> mcr_reg_written;         //    default:      -> erroneous_write_location;        //    endcase        //    ----------------        reg_adr = wbs_adr_i;        reg_dat = wbs_dat_i;        reg_dlab = lcr_reg[7];        -> reg_written;        if (~reg_dlab && (reg_adr == `UART_REG_TR)) // write to FIFO          -> tx_reg_written;      end    end  end  always@(wbs_cyc_i or wbs_stb_i or wbs_we_i or wbs_sel_i or wbs_adr_i or           wbs_dat_o or wbs_ack_o /*or posedge wb_clk*/)  begin    if (wbs_cyc_i && wbs_stb_i)    begin      if (~wbs_we_i && wbs_ack_o) // READ      begin        // LOG's example of  detecting of register read:        //    ----------------        //    case (wbs_adr_i)        //    `UART_REG_RB: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!        //                    -> dll_reg_read;        //                  else        //                    -> rbr_reg_read;        //    `UART_REG_IE: if (lcr_reg[7]) // lcr_reg[7] == DLAB !!!        //                    -> dlm_reg_read;        //                  else        //                    -> ier_reg_read;        //    `UART_REG_II: -> iir_reg_read;        //    `UART_REG_LC: -> lcr_reg_read;        //    `UART_REG_LS: -> lsr_reg_read;        //    `UART_REG_MS: -> msr_reg_read;        //    default:      -> erroneous_read_location;        //    endcase         //    ----------------        reg_adr = wbs_adr_i;        reg_dat = wbs_dat_o;        reg_dlab = lcr_reg[7];        -> reg_read;        if (~reg_dlab && (reg_adr == `UART_REG_RB))          -> rx_reg_read;      end    end  end// UART register monitor//#######################  // Line Status Register    // Reading LSR register    initial    begin      lsr_reg_read = 0;      forever      begin        @(reg_read);        if (reg_adr == `UART_REG_LS)        begin          lsr_reg_read = 1'b1;          repeat (1) @(posedge wb_clk);          lsr_reg_read = 0;        end      end    end    // Bit 0 - Data Ready    initial    begin      lsr_reg_bit0_change_allowed = 0;      @(reset_released);      #10;      fork      begin: rx_fifo_status_changing        forever        begin          if (rx_fifo_status == 0)          begin            wait (rx_fifo_status > 0);            lsr_reg_bit0_change_allowed = 1'b1;            repeat (1) @(posedge wb_clk);            #2;            lsr_reg_bit0_change_allowed = 0;            if (~lsr_reg[0])            begin              `BENCH_ERROR("Bit 0 of LSR register not '1'!");              -> error_detected;            end          end          else          begin            wait (rx_fifo_status == 0);            lsr_reg_bit0_change_allowed = 1'b1;            repeat (1) @(posedge wb_clk);            #2;            lsr_reg_bit0_change_allowed = 0;            if (lsr_reg[0])            begin              `BENCH_ERROR("Bit 0 of LSR register not '0'!");              -> error_detected;            end          end        end      end      begin: lsr_reg_bit0_changing        forever        begin          wait (~lsr_reg_bit0_change_allowed);          begin            @(lsr_reg[0] or lsr_reg_bit0_change_allowed);            if (~lsr_reg_bit0_change_allowed)            begin              `BENCH_ERROR("Bit 0 of LSR register should not change!");              -> error_detected;            end          end        end      end      join    end    // Bit 1 - Overrun Error    initial    begin      lsr_reg_bit1_change_allowed = 0;      @(reset_released);      #10;      fork      begin: rx_overrun_err_occured_changing        forever        begin          if (~rx_overrun_err_occured)          begin            wait (rx_overrun_err_occured);            lsr_reg_bit1_change_allowed = 1'b1;            repeat (1) @(posedge wb_clk);            #2;            lsr_reg_bit1_change_allowed = 0;            if (~lsr_reg[1])            begin              `BENCH_ERROR("Bit 1 of LSR register not '1'!");              -> error_detected;            end          end          else          begin            wait (lsr_reg_read);            lsr_reg_bit1_change_allowed = 1'b1;            repeat (1) @(posedge wb_clk);            #2;            lsr_reg_bit1_change_allowed = 0;            rx_overrun_err_occured = 0;            if (lsr_reg[1])            begin              `BENCH_ERROR("Bit 1 of LSR register not '0'!");              -> error_detected;            end          end        end      end      begin: lsr_reg_bit1_changing        forever        begin          wait (~lsr_reg_bit1_change_allowed);          begin            @(lsr_reg[1] or lsr_reg_bit1_change_allowed);            if (~lsr_reg_bit1_change_allowed)            begin              `BENCH_ERROR("Bit 1 of LSR register should not change!");              -> error_detected;            end          end        end      end      join    end    // Bit 2 - Parity Error    initial    begin      lsr_reg_bit2_change_allowed = 0;      rx_fifo_par_rd_pointer      = 0;      @(reset_released);      #10;      fork      begin: rx_parity_err_changing        forever        begin          if (~rx_fifo_par[rx_fifo_par_rd_pointer])          begin            wait (rx_fifo_read);            lsr_reg_bit2_change_allowed = 1'b1;            repeat (1) @(posedge wb_clk);            #2;            lsr_reg_bit2_change_allowed = 0;            rx_fifo_par_rd_pointer = rx_fifo_par_rd_pointer + 1'b1;

⌨️ 快捷键说明

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