data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v
None: at end of input
1: b'%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:49: Cannot find include file: uart_defines.v\n`include "uart_defines.v" \n         ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog,data/full_repos/permissive/17099167/uart_defines.v\n             data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog,data/full_repos/permissive/17099167/uart_defines.v.v\n             data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog,data/full_repos/permissive/17099167/uart_defines.v.sv\n             uart_defines.v\n             uart_defines.v.v\n             uart_defines.v.sv\n             obj_dir/uart_defines.v\n             obj_dir/uart_defines.v.v\n             obj_dir/uart_defines.v.sv\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:50: Cannot find include file: uart_testbench_defines.v\n`include "uart_testbench_defines.v" \n         ^~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:51: Cannot find include file: wb_model_defines.v\n`include "wb_model_defines.v" \n         ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:52: Cannot find include file: timescale.v\n`include "timescale.v" \n         ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:67: Define or directive not defined: \'`UART_ADDR_WIDTH\'\n    wire [`UART_ADDR_WIDTH-1:0]  wbs_adr_i;\n          ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:68: Define or directive not defined: \'`UART_DATA_WIDTH\'\n    wire [`UART_DATA_WIDTH-1:0]  wbs_dat_i;\n          ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:69: Define or directive not defined: \'`UART_DATA_WIDTH\'\n    wire [`UART_DATA_WIDTH-1:0]  wbs_dat_o;\n          ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:108: Unsupported: event data types\n    event        reset_aserted;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:109: Unsupported: event data types\n    event        reset_released;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:110: Unsupported: event data types\n    event        int_aserted;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:111: Unsupported: event data types\n    event        int_released;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:113: Unsupported: event data types\n    event        error_detected;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:190: Unsupported: event data types\n    event        ier_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:191: Unsupported: event data types\n    event        iir_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:192: Unsupported: event data types\n    event        fcr_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:193: Unsupported: event data types\n    event        lcr_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:194: Unsupported: event data types\n    event        mcr_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:195: Unsupported: event data types\n    event        lsr_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:196: Unsupported: event data types\n    event        msr_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:197: Unsupported: event data types\n    event        dll_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:198: Unsupported: event data types\n    event        dlm_reg_changed;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:200: Define or directive not defined: \'`UART_ADDR_WIDTH\'\n    reg   [`UART_ADDR_WIDTH-1:0] reg_adr;\n           ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:201: Define or directive not defined: \'`UART_DATA_WIDTH\'\n    reg   [`UART_DATA_WIDTH-1:0] reg_dat;\n           ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:203: Unsupported: event data types\n    event        reg_written;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:204: Unsupported: event data types\n    event        tx_reg_written;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:205: Unsupported: event data types\n    event        reg_read;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:206: Unsupported: event data types\n    event        rx_reg_read;\n    ^~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:210: Define or directive not defined: \'`UART_DATA_WIDTH\'\nuart_top                #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH) i_uart_top\n                          ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:210: Define or directive not defined: \'`UART_ADDR_WIDTH\'\nuart_top                #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH) i_uart_top\n                                            ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:254: Define or directive not defined: \'`UART_DATA_WIDTH\'\nwb_master_model         #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH, 4) i_wb_master_model\n                          ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:254: Define or directive not defined: \'`UART_ADDR_WIDTH\'\nwb_master_model         #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH, 4) i_wb_master_model\n                                            ^~~~~~~~~~~~~~~~\n%Warning-STMTDLY: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:310: Unsupported: Ignoring delay on this delayed statement.\n      #(T_wb_clk_period / 2) wb_clk = 1\'b0;\n      ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Warning-STMTDLY: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:313: Unsupported: Ignoring delay on this delayed statement.\n      #(T_wb_clk_period / 2) wb_clk = 1\'b1;\n      ^\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:321: syntax error, unexpected ->\n    -> reset_aserted;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:323: syntax error, unexpected ->\n    -> reset_released;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:327: syntax error, unexpected ->\n    -> int_aserted;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:329: syntax error, unexpected ->\n    -> int_released;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:428: syntax error, unexpected ->\n    -> ier_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:432: syntax error, unexpected ->\n    -> iir_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:436: syntax error, unexpected ->\n    -> fcr_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:440: syntax error, unexpected ->\n    -> lcr_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:444: syntax error, unexpected ->\n    -> mcr_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:448: syntax error, unexpected ->\n    -> lsr_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:452: syntax error, unexpected ->\n    -> msr_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:456: syntax error, unexpected ->\n    -> dll_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:460: syntax error, unexpected ->\n    -> dlm_reg_changed;\n    ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:492: syntax error, unexpected ->\n        -> reg_written;\n        ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:493: Define or directive not defined: \'`UART_REG_TR\'\n        if (~reg_dlab && (reg_adr == `UART_REG_TR))  \n                                     ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:493: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n        if (~reg_dlab && (reg_adr == `UART_REG_TR))  \n                                                 ^\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:527: syntax error, unexpected ->\n        -> reg_read;\n        ^~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:528: Define or directive not defined: \'`UART_REG_RB\'\n        if (~reg_dlab && (reg_adr == `UART_REG_RB))\n                                     ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/17099167/system/hardware/cores/uart16550/bench/verilog/uart_testbench.v:528: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n        if (~reg_dlab && (reg_adr == `UART_REG_RB))\n                                                 ^\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module testbench;


parameter max_wait_cnt = 20000;








    wire                         wb_int_o;
    wire [`UART_ADDR_WIDTH-1:0]  wbs_adr_i;
    wire [`UART_DATA_WIDTH-1:0]  wbs_dat_i;
    wire [`UART_DATA_WIDTH-1:0]  wbs_dat_o;
    wire                  [3:0]  wbs_sel_i;
    wire                         wbs_cyc_i;
    wire                         wbs_stb_i;
    wire                  [2:0]  wbs_cti_i;
    wire                  [1:0]  wbs_bte_i;
    wire                         wbs_we_i;
    wire                         wbs_ack_o;
    wire                         wbs_rty_o = 1'b0;
    wire                         wbs_err_o = 1'b0;





    wire                         stx_pad_o;
    wire                         srx_pad_i;

    wire                         rts_pad_o;
    wire                         cts_pad_i;
    wire                         dtr_pad_o;
    wire                         dsr_pad_i;
    wire                         ri_pad_i;
    wire                         dcd_pad_i;
  `ifdef UART_HAS_BAUDRATE_OUTPUT
    wire                         baud_o;
  `endif





    reg          wb_clk;

    reg          wb_clk_en = 1'b1;

    real         T_wb_clk_period = 20;

    reg          wb_reset;
    event        reset_aserted;
    event        reset_released;
    event        int_aserted;
    event        int_released;

    event        error_detected;






      reg          lsr_reg_read;

      reg          lsr_reg_bit0_change_allowed;

      reg          lsr_reg_bit1_change_allowed;

      reg          lsr_reg_bit2_change_allowed;
      reg   [4:0]  rx_fifo_par_rd_pointer;
      integer      i2;

      reg          lsr_reg_bit3_change_allowed;
      reg   [4:0]  rx_fifo_frm_rd_pointer;
      integer      i3;

      reg          lsr_reg_bit4_change_allowed;
      reg   [4:0]  rx_fifo_brk_rd_pointer;
      integer      i4;

      reg          lsr_reg_bit5_change_allowed;

      reg          lsr_reg_bit6_change_allowed;

      reg          lsr_reg_bit7_change_allowed;





    reg   [7:0]  tx_shift_reg;
    reg          tx_shift_reg_empty;
    reg          tx_start_bit_edge;
    reg   [7:0]  tx_fifo [0:31]; 
    reg   [4:0]  tx_fifo_wr_pointer;
    reg   [4:0]  tx_fifo_rd_pointer;
    reg   [4:0]  tx_fifo_status;





    reg   [7:0]  rx_shift_reg;
    reg          rx_shift_reg_full;
    reg          rx_parity_err;
    reg          rx_framing_err;
    reg          rx_framing_glitch;
    reg          rx_break_int;
    reg          rx_overrun_err_occured;
    reg   [7:0]  rx_fifo_data [0:31]; 
    reg  [31:0]  rx_fifo_par; 
    reg  [31:0]  rx_fifo_frm; 
    reg  [31:0]  rx_fifo_brk; 
    reg   [4:0]  rx_fifo_wr_pointer;
    reg   [4:0]  rx_fifo_rd_pointer;
    reg   [4:0]  rx_fifo_status;
    reg          rx_fifo_read;





    wire  [7:0]  ier_reg;
    wire  [7:0]  iir_reg;
    wire  [7:0]  fcr_reg;
    wire  [7:0]  lcr_reg;
    wire  [7:0]  mcr_reg;
    wire  [7:0]  lsr_reg;
    wire  [7:0]  msr_reg;
    wire  [7:0]  dll_reg;
    wire  [7:0]  dlm_reg;

    event        ier_reg_changed;
    event        iir_reg_changed;
    event        fcr_reg_changed;
    event        lcr_reg_changed;
    event        mcr_reg_changed;
    event        lsr_reg_changed;
    event        msr_reg_changed;
    event        dll_reg_changed;
    event        dlm_reg_changed;

    reg   [`UART_ADDR_WIDTH-1:0] reg_adr;
    reg   [`UART_DATA_WIDTH-1:0] reg_dat;
    reg          reg_dlab;
    event        reg_written;
    event        tx_reg_written;
    event        reg_read;
    event        rx_reg_read;



uart_top                #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH) i_uart_top
(
    .wb_clk_i           (wb_clk),
    .wb_rst_i           (wb_reset),
    .int_o              (wb_int_o),

    .wb_cyc_i           (wbs_cyc_i),
    .wb_stb_i           (wbs_stb_i),
    .wb_we_i            (wbs_we_i),
    .wb_sel_i           (wbs_sel_i),
    .wb_adr_i           (wbs_adr_i),
    .wb_dat_i           (wbs_dat_i),
    .wb_dat_o           (wbs_dat_o),
    .wb_ack_o           (wbs_ack_o),

    .stx_pad_o          (stx_pad_o),
    .srx_pad_i          (srx_pad_i),

    .rts_pad_o          (rts_pad_o),
    .cts_pad_i          (cts_pad_i),
    .dtr_pad_o          (dtr_pad_o),
    .dsr_pad_i          (dsr_pad_i),
    .ri_pad_i           (ri_pad_i),
    .dcd_pad_i          (dcd_pad_i)
`ifdef UART_HAS_BAUDRATE_OUTPUT
    ,
    .baud_o             (baud_o)
`endif
); 

uart_device             i_uart_device
(

    .stx_i              (stx_pad_o),
    .srx_o              (srx_pad_i),

    .rts_i              (rts_pad_o),
    .cts_o              (cts_pad_i),
    .dtr_i              (dtr_pad_o),
    .dsr_o              (dsr_pad_i),
    .ri_o               (ri_pad_i),
    .dcd_o              (dcd_pad_i)
);

wb_master_model         #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH, 4) i_wb_master_model
(
    .wb_rst_i           (wb_reset),
    .wb_clk_i           (wb_clk),
    .wbm_cyc_o          (wbs_cyc_i),
    .wbm_cti_o          (),
    .wbm_bte_o          (),
    .wbm_stb_o          (wbs_stb_i),
    .wbm_we_o           (wbs_we_i),
    .wbm_adr_o          (wbs_adr_i),
    .wbm_sel_o          (wbs_sel_i),
    .wbm_dat_o          (wbs_dat_i),
    .wbm_dat_i          (wbs_dat_o),
    .wbm_ack_i          (wbs_ack_o),
    .wbm_err_i          (wbs_err_o),
    .wbm_rty_i          (wbs_rty_o)
);


initial
begin:system

  wb_reset = 1'b1;
  wb_clk = 1'b0;
end





























  always@(posedge wb_clk)
    if (wb_clk_en)
      #(T_wb_clk_period / 2) wb_clk = 1'b0;
  always@(negedge wb_clk)
    if (wb_clk_en)
      #(T_wb_clk_period / 2) wb_clk = 1'b1;






  always@(posedge wb_reset)
    -> reset_aserted;
  always@(negedge wb_reset)
    -> reset_released;


  always@(posedge wb_int_o)
    -> int_aserted;
  always@(negedge wb_int_o)
    -> int_released;





















































































  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      };
  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] };


  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


  always@(wbs_cyc_i or wbs_stb_i or wbs_we_i or wbs_sel_i or wbs_adr_i or 
          wbs_dat_i)
  begin
    if (wbs_cyc_i && wbs_stb_i)
    begin
      if (wbs_we_i)
      begin


















        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))
          -> 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)
  begin
    if (wbs_cyc_i && wbs_stb_i)
    begin
      if (~wbs_we_i && wbs_ack_o)
      begin



















        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







    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

    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

    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

    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;

            if (~lsr_reg[2] && rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[2] && ~rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read);
            lsr_reg_bit2_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit2_change_allowed = 0;
            if (rx_fifo_par_rd_pointer < rx_fifo_rd_pointer)
            begin
              for (i2 = rx_fifo_par_rd_pointer; i2 <= rx_fifo_rd_pointer; i2 = i2 + 1)
                rx_fifo_par[i2] = 0;
              rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
            end
            else if (rx_fifo_par_rd_pointer > rx_fifo_rd_pointer)
            begin
              for (i2 = rx_fifo_par_rd_pointer; i2 <= 31; i2 = i2 + 1)
                rx_fifo_par[i2] = 0;
              for (i2 = 0; i2 <= rx_fifo_rd_pointer; i2 = i2 + 1)
                rx_fifo_par[i2] = 0;
              rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
            end
            else
            begin
              rx_fifo_par = 0;
              rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
            end

            if (~lsr_reg[2] && rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[2] && ~rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit2_changing
        forever
        begin
          wait (~lsr_reg_bit2_change_allowed);
          begin
            @(lsr_reg[2] or lsr_reg_bit2_change_allowed);
            if (~lsr_reg_bit2_change_allowed)
            begin
              `BENCH_ERROR("Bit 2 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit3_change_allowed = 0;
      rx_fifo_frm_rd_pointer      = 0;
      @(reset_released);
      #10;
      fork
      begin: rx_framing_err_changing
        forever
        begin
          if (~rx_fifo_frm[rx_fifo_frm_rd_pointer])
          begin
            wait (rx_fifo_read);
            lsr_reg_bit3_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit3_change_allowed = 0;
            rx_fifo_frm_rd_pointer = rx_fifo_frm_rd_pointer + 1'b1;

            if (~lsr_reg[3] && rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[3] && ~rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read);
            lsr_reg_bit3_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit3_change_allowed = 0;
            if (rx_fifo_frm_rd_pointer < rx_fifo_rd_pointer)
            begin
              for (i3 = rx_fifo_frm_rd_pointer; i3 <= rx_fifo_rd_pointer; i3 = i3 + 1)
                rx_fifo_frm[i3] = 0;
              rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
            end
            else if (rx_fifo_frm_rd_pointer > rx_fifo_rd_pointer)
            begin
              for (i3 = rx_fifo_frm_rd_pointer; i3 <= 31; i3 = i3 + 1)
                rx_fifo_frm[i3] = 0;
              for (i3 = 0; i3 <= rx_fifo_rd_pointer; i3 = i3 + 1)
                rx_fifo_frm[i3] = 0;
              rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
            end
            else
            begin
              rx_fifo_frm = 0;
              rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
            end

            if (~lsr_reg[3] && rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[3] && ~rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit3_changing
        forever
        begin
          wait (~lsr_reg_bit3_change_allowed);
          begin
            @(lsr_reg[3] or lsr_reg_bit3_change_allowed);
            if (~lsr_reg_bit3_change_allowed)
            begin
              `BENCH_ERROR("Bit 3 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit4_change_allowed = 0;
      rx_fifo_brk_rd_pointer      = 0;
      @(reset_released);
      #10;
      fork
      begin: rx_break_int_changing
        forever
        begin
          if (~rx_fifo_brk[rx_fifo_brk_rd_pointer])
          begin
            wait (rx_fifo_read);
            lsr_reg_bit4_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit4_change_allowed = 0;
            rx_fifo_brk_rd_pointer = rx_fifo_brk_rd_pointer + 1'b1;

            if (~lsr_reg[4] && rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[4] && ~rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read);
            lsr_reg_bit4_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit4_change_allowed = 0;
            if (rx_fifo_brk_rd_pointer < rx_fifo_rd_pointer)
            begin
              for (i4 = rx_fifo_brk_rd_pointer; i4 <= rx_fifo_rd_pointer; i4 = i4 + 1)
                rx_fifo_brk[i4] = 0;
              rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
            end
            else if (rx_fifo_brk_rd_pointer > rx_fifo_rd_pointer)
            begin
              for (i4 = rx_fifo_brk_rd_pointer; i4 <= 31; i4 = i4 + 1)
                rx_fifo_brk[i4] = 0;
              for (i4 = 0; i4 <= rx_fifo_rd_pointer; i4 = i4 + 1)
                rx_fifo_brk[i4] = 0;
              rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
            end
            else
            begin
              rx_fifo_brk = 0;
              rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
            end

            if (~lsr_reg[4] && rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[4] && ~rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit4_changing
        forever
        begin
          wait (~lsr_reg_bit4_change_allowed);
          begin
            @(lsr_reg[4] or lsr_reg_bit4_change_allowed);
            if (~lsr_reg_bit4_change_allowed)
            begin
              `BENCH_ERROR("Bit 4 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit5_change_allowed = 0;
      @(reset_released);
      #10;
      fork
      begin: tx_fifo_status_changing
        forever
        begin
          if (tx_fifo_status == 0)
          begin

            wait (tx_fifo_status > 0);
            lsr_reg_bit5_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit5_change_allowed = 0;
            if (lsr_reg[5])
            begin
              `BENCH_ERROR("Bit 5 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (tx_fifo_status == 0);
            lsr_reg_bit5_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit5_change_allowed = 0;
            if (~lsr_reg[5])
            begin
              `BENCH_ERROR("Bit 5 of LSR register not '1'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit5_changing
        forever
        begin
          wait (~lsr_reg_bit5_change_allowed);
          begin
            @(lsr_reg[5] or lsr_reg_bit5_change_allowed);
            if (~lsr_reg_bit5_change_allowed)
            begin
              `BENCH_ERROR("Bit 5 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit6_change_allowed = 0;
      @(reset_released);
      #10;
      fork
      begin: tx_fifo_status_and_shift_reg_changing
        forever
        begin
          if ((tx_fifo_status == 0) && tx_shift_reg_empty)
          begin

            wait (tx_fifo_status > 0);
            lsr_reg_bit6_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit6_change_allowed = 0;
            if (lsr_reg[6])
            begin
              `BENCH_ERROR("Bit 6 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait ((tx_fifo_status == 0) && tx_shift_reg_empty);
            lsr_reg_bit6_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit6_change_allowed = 0;
            if (~lsr_reg[6])
            begin
              `BENCH_ERROR("Bit 6 of LSR register not '1'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit6_changing
        forever
        begin
          wait (~lsr_reg_bit6_change_allowed);
          begin
            @(lsr_reg[6] or lsr_reg_bit6_change_allowed);
            if (~lsr_reg_bit6_change_allowed)
            begin
              `BENCH_ERROR("Bit 6 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit7_change_allowed = 0;
      @(reset_released);
      #10;
      fork
      begin: error_changing
        forever
        begin
          if ((rx_fifo_par == 0) && (rx_fifo_frm == 0) && (rx_fifo_brk == 0))
          begin
            wait (rx_parity_err || rx_framing_err || rx_framing_glitch || rx_break_int);
            lsr_reg_bit7_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit7_change_allowed = 0;

            if (~lsr_reg[7])
            begin
              `BENCH_ERROR("Bit 7 of LSR register not '1'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read && (rx_fifo_par == 0) && (rx_fifo_frm == 0) && (rx_fifo_brk == 0));
            lsr_reg_bit7_change_allowed = 1'b1;
            repeat (2) @(posedge wb_clk);
            #2;
            lsr_reg_bit7_change_allowed = 0;

            if (lsr_reg[7])
            begin
              `BENCH_ERROR("Bit 7 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit7_changing
        forever
        begin
          wait (~lsr_reg_bit7_change_allowed);
          begin
            @(lsr_reg[7] or lsr_reg_bit7_change_allowed);
            if (~lsr_reg_bit7_change_allowed)
            begin
              `BENCH_ERROR("Bit 7 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end






  always@(tx_fifo_wr_pointer or tx_fifo_rd_pointer)
  begin
    if (tx_fifo_wr_pointer >= tx_fifo_rd_pointer)
      tx_fifo_status = tx_fifo_wr_pointer - tx_fifo_rd_pointer;
    else
      tx_fifo_status = (5'h1F - tx_fifo_rd_pointer) + tx_fifo_wr_pointer;
  end

  initial
  begin
    tx_fifo_wr_pointer = 0;
    tx_fifo_rd_pointer = 0;
    tx_shift_reg_empty = 1;
    tx_fifo_status     = 0;
    tx_start_bit_edge  = 1;
    fork
    begin:write_tx_shift_reg_read_tx_fifo
      forever
      begin
        wait ((tx_fifo_status !== 0) && tx_shift_reg_empty && tx_start_bit_edge && ~stx_pad_o);
        tx_start_bit_edge  = 0;
        tx_shift_reg = tx_fifo[tx_fifo_rd_pointer];
        tx_shift_reg_empty = 0;
        @(testbench.i_uart_device.device_received_last_bit);
        repeat (16393) @(posedge wb_clk);
        tx_fifo_rd_pointer = tx_fifo_rd_pointer + 1'b1;
        @(posedge wb_clk);
        if (tx_fifo_status == 0)
        begin
          `BENCH_MSG("TX FIFO is empty!");
        end
      end
    end
    begin:write_tx_fifo
      forever
      begin
        @(tx_reg_written);
        repeat (1) @(posedge wb_clk);
        if (tx_fifo_status <= 5'h0F)
        begin
          tx_fifo[tx_fifo_wr_pointer] = reg_dat;
          tx_fifo_wr_pointer = tx_fifo_wr_pointer + 1'b1;
        end
        else
        begin
          `BENCH_WARNING("TX FIFO overflow!");
        end
      end
    end
    begin:empty_tx_fifo
      forever
      begin
        wait (fcr_reg[2]);
        tx_fifo_wr_pointer = 0;
        tx_fifo_rd_pointer = 0;
        @(posedge wb_clk);
        if (tx_fifo_status == 0)
        begin
          `BENCH_MSG("TX FIFO is empty!");
        end
      end
    end
    begin:read_tx_shift_reg
      forever
      begin
        @(testbench.i_uart_device.device_received_packet);

        if (tx_shift_reg != testbench.i_uart_device.rx_data)
        begin
          `BENCH_ERROR("TX data has ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("TX data correct!");
        if (testbench.i_uart_device.rx_parity_error)
        begin
          `BENCH_ERROR("TX data has parity ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("TX data parity correct!");
        if (testbench.i_uart_device.rx_framing_error)
        begin
          `BENCH_ERROR("TX data has framing ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("TX data framing correct!");

        tx_start_bit_edge  = 1;
        repeat (7) @(wb_clk);
        if (tx_shift_reg_empty == 0)
        begin
          tx_shift_reg_empty = 1'b1;
        end
        else
        begin
          `BENCH_ERROR("TX shift register empty while transmiting data!");
          -> error_detected;
        end
      end
    end
    join
  end






  always@(rx_fifo_wr_pointer or rx_fifo_rd_pointer)
  begin
    if (rx_fifo_wr_pointer >= rx_fifo_rd_pointer)
      rx_fifo_status = rx_fifo_wr_pointer - rx_fifo_rd_pointer;
    else
      rx_fifo_status = (5'h1F - rx_fifo_rd_pointer) + rx_fifo_wr_pointer;
  end

  initial
  begin
    rx_parity_err      = 0;
    rx_framing_err     = 0;
    rx_framing_glitch  = 0;
    rx_break_int       = 0;
    rx_overrun_err_occured = 0;
    rx_fifo_par        = 0;
    rx_fifo_frm        = 0;
    rx_fifo_brk        = 0;
    rx_shift_reg_full  = 0;
    rx_fifo_wr_pointer = 0;
    rx_fifo_rd_pointer = 0;
    rx_fifo_status     = 0;
    fork
    begin:write_rx_shift_reg
      forever
      begin
        @(testbench.i_uart_device.device_sent_packet);
        repeat (1) @(posedge wb_clk);
        rx_shift_reg   = testbench.i_uart_device.sent_data;
        rx_parity_err  = testbench.i_uart_device.tx_parity_enabled && 
                         (testbench.i_uart_device.tx_parity_wrong || 
                          (
                           ((testbench.i_uart_device.tx_glitch_num == (3 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (5 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (7 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (9 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (11 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (13 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (15 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (17 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (19 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (21 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (23 * 8 * testbench.i_uart_device.T_divisor))) &&
                           (testbench.i_uart_device.tx_glitch_num[23:0] < ((testbench.i_uart_device.tx_length + 2'h1) *
                             16 * testbench.i_uart_device.T_divisor))
                         ));
        rx_framing_err = testbench.i_uart_device.tx_framing_wrong;
        rx_framing_glitch = (testbench.i_uart_device.tx_glitch_num == ((((testbench.i_uart_device.tx_length + 2'h2 +
                               testbench.i_uart_device.tx_parity_enabled) * 
                                2) - 1'b1) * 8 * testbench.i_uart_device.T_divisor));
        rx_break_int   = testbench.i_uart_device.tx_break_enable && 
                         (testbench.i_uart_device.tx_break_num[15:0] >= ((testbench.i_uart_device.tx_length + 2'h2 +
                            testbench.i_uart_device.tx_parity_enabled) * 
                           16 * testbench.i_uart_device.T_divisor));
        -> testbench.i_uart_device.sent_packet_received;
        if (rx_fifo_status > 5'h0F)
          rx_overrun_err_occured = 1'b1;
        rx_shift_reg_full = 1'b1;
      end
    end
    begin:write_rx_fifo_read_rx_shift_reg
      forever
      begin
        wait (rx_shift_reg_full);
        if (rx_fifo_status <= 5'h0F)
        begin
          rx_fifo_data[rx_fifo_wr_pointer] = testbench.i_uart_device.sent_data;
          rx_fifo_par[rx_fifo_wr_pointer]  = rx_parity_err; 
          rx_fifo_frm[rx_fifo_wr_pointer]  = rx_framing_err || rx_framing_glitch; 
          rx_fifo_brk[rx_fifo_wr_pointer]  = rx_break_int; 
          rx_fifo_wr_pointer = rx_fifo_wr_pointer + 1'b1;
        end
        else
        begin
          `BENCH_WARNING("RX FIFO overflow!");
        end
        repeat (1) @(posedge wb_clk);
        rx_shift_reg_full = 0;
      end
    end
    begin:empty_rx_fifo
      forever
      begin
        wait (fcr_reg[1]);
        rx_fifo_wr_pointer = 0;
        rx_fifo_rd_pointer = 0;



        @(posedge wb_clk);
        if (rx_fifo_status == 0)
        begin
          `BENCH_MSG("RX FIFO is empty!");
        end
      end
    end
    begin:read_rx_fifo
      rx_fifo_read = 0;
      forever
      begin
        @(rx_reg_read);
        if (rx_fifo_status > 0)
        begin
          rx_fifo_read = 1'b1;

          if (rx_fifo_data[rx_fifo_rd_pointer] != reg_dat)
          begin
            `BENCH_ERROR("RX data has ERROR!");
            -> error_detected;
          end
          else
          begin
            `BENCH_MSG("RX data correct!");
          end

          repeat (1) @(posedge wb_clk);
          rx_fifo_read = 0;
          rx_fifo_rd_pointer = rx_fifo_rd_pointer + 1'b1;
        end
        else
        begin
          `BENCH_WARNING("Reading RX FIFO while RX FIFO is empty!");
        end


        if ((~rx_fifo_frm[rx_fifo_rd_pointer] && lsr_reg[3]) ||
            (rx_fifo_frm[rx_fifo_rd_pointer] && ~lsr_reg[3]))
        begin
          `BENCH_ERROR("RX data has wrong framing ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("RX data has correct framing error!");

        repeat (1) @(posedge wb_clk);
        rx_fifo_read = 0;
        if (rx_fifo_status > 0)
        begin



          rx_fifo_rd_pointer = rx_fifo_rd_pointer + 1'b1;
        end
      end
    end
    join
  end








endmodule
module testbench;



parameter max_wait_cnt = 20000;








    wire                         wb_int_o;
    wire [`UART_ADDR_WIDTH-1:0]  wbs_adr_i;
    wire [`UART_DATA_WIDTH-1:0]  wbs_dat_i;
    wire [`UART_DATA_WIDTH-1:0]  wbs_dat_o;
    wire                  [3:0]  wbs_sel_i;
    wire                         wbs_cyc_i;
    wire                         wbs_stb_i;
    wire                  [2:0]  wbs_cti_i;
    wire                  [1:0]  wbs_bte_i;
    wire                         wbs_we_i;
    wire                         wbs_ack_o;
    wire                         wbs_rty_o = 1'b0;
    wire                         wbs_err_o = 1'b0;





    wire                         stx_pad_o;
    wire                         srx_pad_i;

    wire                         rts_pad_o;
    wire                         cts_pad_i;
    wire                         dtr_pad_o;
    wire                         dsr_pad_i;
    wire                         ri_pad_i;
    wire                         dcd_pad_i;
  `ifdef UART_HAS_BAUDRATE_OUTPUT
    wire                         baud_o;
  `endif





    reg          wb_clk;

    reg          wb_clk_en = 1'b1;

    real         T_wb_clk_period = 20;

    reg          wb_reset;
    event        reset_aserted;
    event        reset_released;
    event        int_aserted;
    event        int_released;

    event        error_detected;






      reg          lsr_reg_read;

      reg          lsr_reg_bit0_change_allowed;

      reg          lsr_reg_bit1_change_allowed;

      reg          lsr_reg_bit2_change_allowed;
      reg   [4:0]  rx_fifo_par_rd_pointer;
      integer      i2;

      reg          lsr_reg_bit3_change_allowed;
      reg   [4:0]  rx_fifo_frm_rd_pointer;
      integer      i3;

      reg          lsr_reg_bit4_change_allowed;
      reg   [4:0]  rx_fifo_brk_rd_pointer;
      integer      i4;

      reg          lsr_reg_bit5_change_allowed;

      reg          lsr_reg_bit6_change_allowed;

      reg          lsr_reg_bit7_change_allowed;





    reg   [7:0]  tx_shift_reg;
    reg          tx_shift_reg_empty;
    reg          tx_start_bit_edge;
    reg   [7:0]  tx_fifo [0:31]; 
    reg   [4:0]  tx_fifo_wr_pointer;
    reg   [4:0]  tx_fifo_rd_pointer;
    reg   [4:0]  tx_fifo_status;





    reg   [7:0]  rx_shift_reg;
    reg          rx_shift_reg_full;
    reg          rx_parity_err;
    reg          rx_framing_err;
    reg          rx_framing_glitch;
    reg          rx_break_int;
    reg          rx_overrun_err_occured;
    reg   [7:0]  rx_fifo_data [0:31]; 
    reg  [31:0]  rx_fifo_par; 
    reg  [31:0]  rx_fifo_frm; 
    reg  [31:0]  rx_fifo_brk; 
    reg   [4:0]  rx_fifo_wr_pointer;
    reg   [4:0]  rx_fifo_rd_pointer;
    reg   [4:0]  rx_fifo_status;
    reg          rx_fifo_read;





    wire  [7:0]  ier_reg;
    wire  [7:0]  iir_reg;
    wire  [7:0]  fcr_reg;
    wire  [7:0]  lcr_reg;
    wire  [7:0]  mcr_reg;
    wire  [7:0]  lsr_reg;
    wire  [7:0]  msr_reg;
    wire  [7:0]  dll_reg;
    wire  [7:0]  dlm_reg;

    event        ier_reg_changed;
    event        iir_reg_changed;
    event        fcr_reg_changed;
    event        lcr_reg_changed;
    event        mcr_reg_changed;
    event        lsr_reg_changed;
    event        msr_reg_changed;
    event        dll_reg_changed;
    event        dlm_reg_changed;

    reg   [`UART_ADDR_WIDTH-1:0] reg_adr;
    reg   [`UART_DATA_WIDTH-1:0] reg_dat;
    reg          reg_dlab;
    event        reg_written;
    event        tx_reg_written;
    event        reg_read;
    event        rx_reg_read;



uart_top                #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH) i_uart_top
(
    .wb_clk_i           (wb_clk),
    .wb_rst_i           (wb_reset),
    .int_o              (wb_int_o),

    .wb_cyc_i           (wbs_cyc_i),
    .wb_stb_i           (wbs_stb_i),
    .wb_we_i            (wbs_we_i),
    .wb_sel_i           (wbs_sel_i),
    .wb_adr_i           (wbs_adr_i),
    .wb_dat_i           (wbs_dat_i),
    .wb_dat_o           (wbs_dat_o),
    .wb_ack_o           (wbs_ack_o),

    .stx_pad_o          (stx_pad_o),
    .srx_pad_i          (srx_pad_i),

    .rts_pad_o          (rts_pad_o),
    .cts_pad_i          (cts_pad_i),
    .dtr_pad_o          (dtr_pad_o),
    .dsr_pad_i          (dsr_pad_i),
    .ri_pad_i           (ri_pad_i),
    .dcd_pad_i          (dcd_pad_i)
`ifdef UART_HAS_BAUDRATE_OUTPUT
    ,
    .baud_o             (baud_o)
`endif
); 

uart_device             i_uart_device
(

    .stx_i              (stx_pad_o),
    .srx_o              (srx_pad_i),

    .rts_i              (rts_pad_o),
    .cts_o              (cts_pad_i),
    .dtr_i              (dtr_pad_o),
    .dsr_o              (dsr_pad_i),
    .ri_o               (ri_pad_i),
    .dcd_o              (dcd_pad_i)
);

wb_master_model         #(`UART_DATA_WIDTH, `UART_ADDR_WIDTH, 4) i_wb_master_model
(
    .wb_rst_i           (wb_reset),
    .wb_clk_i           (wb_clk),
    .wbm_cyc_o          (wbs_cyc_i),
    .wbm_cti_o          (),
    .wbm_bte_o          (),
    .wbm_stb_o          (wbs_stb_i),
    .wbm_we_o           (wbs_we_i),
    .wbm_adr_o          (wbs_adr_i),
    .wbm_sel_o          (wbs_sel_i),
    .wbm_dat_o          (wbs_dat_i),
    .wbm_dat_i          (wbs_dat_o),
    .wbm_ack_i          (wbs_ack_o),
    .wbm_err_i          (wbs_err_o),
    .wbm_rty_i          (wbs_rty_o)
);


initial
begin:system

  wb_reset = 1'b1;
  wb_clk = 1'b0;
end





























  always@(posedge wb_clk)
    if (wb_clk_en)
      #(T_wb_clk_period / 2) wb_clk = 1'b0;
  always@(negedge wb_clk)
    if (wb_clk_en)
      #(T_wb_clk_period / 2) wb_clk = 1'b1;






  always@(posedge wb_reset)
    -> reset_aserted;
  always@(negedge wb_reset)
    -> reset_released;


  always@(posedge wb_int_o)
    -> int_aserted;
  always@(negedge wb_int_o)
    -> int_released;





















































































  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      };
  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] };


  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


  always@(wbs_cyc_i or wbs_stb_i or wbs_we_i or wbs_sel_i or wbs_adr_i or 
          wbs_dat_i)
  begin
    if (wbs_cyc_i && wbs_stb_i)
    begin
      if (wbs_we_i)
      begin


















        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))
          -> 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)
  begin
    if (wbs_cyc_i && wbs_stb_i)
    begin
      if (~wbs_we_i && wbs_ack_o)
      begin



















        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







    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

    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

    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

    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;

            if (~lsr_reg[2] && rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[2] && ~rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read);
            lsr_reg_bit2_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit2_change_allowed = 0;
            if (rx_fifo_par_rd_pointer < rx_fifo_rd_pointer)
            begin
              for (i2 = rx_fifo_par_rd_pointer; i2 <= rx_fifo_rd_pointer; i2 = i2 + 1)
                rx_fifo_par[i2] = 0;
              rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
            end
            else if (rx_fifo_par_rd_pointer > rx_fifo_rd_pointer)
            begin
              for (i2 = rx_fifo_par_rd_pointer; i2 <= 31; i2 = i2 + 1)
                rx_fifo_par[i2] = 0;
              for (i2 = 0; i2 <= rx_fifo_rd_pointer; i2 = i2 + 1)
                rx_fifo_par[i2] = 0;
              rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
            end
            else
            begin
              rx_fifo_par = 0;
              rx_fifo_par_rd_pointer = rx_fifo_rd_pointer;
            end

            if (~lsr_reg[2] && rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[2] && ~rx_fifo_par[rx_fifo_par_rd_pointer])
            begin
              `BENCH_ERROR("Bit 2 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit2_changing
        forever
        begin
          wait (~lsr_reg_bit2_change_allowed);
          begin
            @(lsr_reg[2] or lsr_reg_bit2_change_allowed);
            if (~lsr_reg_bit2_change_allowed)
            begin
              `BENCH_ERROR("Bit 2 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit3_change_allowed = 0;
      rx_fifo_frm_rd_pointer      = 0;
      @(reset_released);
      #10;
      fork
      begin: rx_framing_err_changing
        forever
        begin
          if (~rx_fifo_frm[rx_fifo_frm_rd_pointer])
          begin
            wait (rx_fifo_read);
            lsr_reg_bit3_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit3_change_allowed = 0;
            rx_fifo_frm_rd_pointer = rx_fifo_frm_rd_pointer + 1'b1;

            if (~lsr_reg[3] && rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[3] && ~rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read);
            lsr_reg_bit3_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit3_change_allowed = 0;
            if (rx_fifo_frm_rd_pointer < rx_fifo_rd_pointer)
            begin
              for (i3 = rx_fifo_frm_rd_pointer; i3 <= rx_fifo_rd_pointer; i3 = i3 + 1)
                rx_fifo_frm[i3] = 0;
              rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
            end
            else if (rx_fifo_frm_rd_pointer > rx_fifo_rd_pointer)
            begin
              for (i3 = rx_fifo_frm_rd_pointer; i3 <= 31; i3 = i3 + 1)
                rx_fifo_frm[i3] = 0;
              for (i3 = 0; i3 <= rx_fifo_rd_pointer; i3 = i3 + 1)
                rx_fifo_frm[i3] = 0;
              rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
            end
            else
            begin
              rx_fifo_frm = 0;
              rx_fifo_frm_rd_pointer = rx_fifo_rd_pointer;
            end

            if (~lsr_reg[3] && rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[3] && ~rx_fifo_frm[rx_fifo_frm_rd_pointer])
            begin
              `BENCH_ERROR("Bit 3 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit3_changing
        forever
        begin
          wait (~lsr_reg_bit3_change_allowed);
          begin
            @(lsr_reg[3] or lsr_reg_bit3_change_allowed);
            if (~lsr_reg_bit3_change_allowed)
            begin
              `BENCH_ERROR("Bit 3 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit4_change_allowed = 0;
      rx_fifo_brk_rd_pointer      = 0;
      @(reset_released);
      #10;
      fork
      begin: rx_break_int_changing
        forever
        begin
          if (~rx_fifo_brk[rx_fifo_brk_rd_pointer])
          begin
            wait (rx_fifo_read);
            lsr_reg_bit4_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit4_change_allowed = 0;
            rx_fifo_brk_rd_pointer = rx_fifo_brk_rd_pointer + 1'b1;

            if (~lsr_reg[4] && rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[4] && ~rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read);
            lsr_reg_bit4_change_allowed = 1'b1;
            repeat (1) @(posedge wb_clk);
            #2;
            lsr_reg_bit4_change_allowed = 0;
            if (rx_fifo_brk_rd_pointer < rx_fifo_rd_pointer)
            begin
              for (i4 = rx_fifo_brk_rd_pointer; i4 <= rx_fifo_rd_pointer; i4 = i4 + 1)
                rx_fifo_brk[i4] = 0;
              rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
            end
            else if (rx_fifo_brk_rd_pointer > rx_fifo_rd_pointer)
            begin
              for (i4 = rx_fifo_brk_rd_pointer; i4 <= 31; i4 = i4 + 1)
                rx_fifo_brk[i4] = 0;
              for (i4 = 0; i4 <= rx_fifo_rd_pointer; i4 = i4 + 1)
                rx_fifo_brk[i4] = 0;
              rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
            end
            else
            begin
              rx_fifo_brk = 0;
              rx_fifo_brk_rd_pointer = rx_fifo_rd_pointer;
            end

            if (~lsr_reg[4] && rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '1'!");
              -> error_detected;
            end
            else if (lsr_reg[4] && ~rx_fifo_brk[rx_fifo_brk_rd_pointer])
            begin
              `BENCH_ERROR("Bit 4 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit4_changing
        forever
        begin
          wait (~lsr_reg_bit4_change_allowed);
          begin
            @(lsr_reg[4] or lsr_reg_bit4_change_allowed);
            if (~lsr_reg_bit4_change_allowed)
            begin
              `BENCH_ERROR("Bit 4 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit5_change_allowed = 0;
      @(reset_released);
      #10;
      fork
      begin: tx_fifo_status_changing
        forever
        begin
          if (tx_fifo_status == 0)
          begin

            wait (tx_fifo_status > 0);
            lsr_reg_bit5_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit5_change_allowed = 0;
            if (lsr_reg[5])
            begin
              `BENCH_ERROR("Bit 5 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (tx_fifo_status == 0);
            lsr_reg_bit5_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit5_change_allowed = 0;
            if (~lsr_reg[5])
            begin
              `BENCH_ERROR("Bit 5 of LSR register not '1'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit5_changing
        forever
        begin
          wait (~lsr_reg_bit5_change_allowed);
          begin
            @(lsr_reg[5] or lsr_reg_bit5_change_allowed);
            if (~lsr_reg_bit5_change_allowed)
            begin
              `BENCH_ERROR("Bit 5 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit6_change_allowed = 0;
      @(reset_released);
      #10;
      fork
      begin: tx_fifo_status_and_shift_reg_changing
        forever
        begin
          if ((tx_fifo_status == 0) && tx_shift_reg_empty)
          begin

            wait (tx_fifo_status > 0);
            lsr_reg_bit6_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit6_change_allowed = 0;
            if (lsr_reg[6])
            begin
              `BENCH_ERROR("Bit 6 of LSR register not '0'!");
              -> error_detected;
            end
          end
          else
          begin
            wait ((tx_fifo_status == 0) && tx_shift_reg_empty);
            lsr_reg_bit6_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit6_change_allowed = 0;
            if (~lsr_reg[6])
            begin
              `BENCH_ERROR("Bit 6 of LSR register not '1'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit6_changing
        forever
        begin
          wait (~lsr_reg_bit6_change_allowed);
          begin
            @(lsr_reg[6] or lsr_reg_bit6_change_allowed);
            if (~lsr_reg_bit6_change_allowed)
            begin
              `BENCH_ERROR("Bit 6 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end

    initial
    begin
      lsr_reg_bit7_change_allowed = 0;
      @(reset_released);
      #10;
      fork
      begin: error_changing
        forever
        begin
          if ((rx_fifo_par == 0) && (rx_fifo_frm == 0) && (rx_fifo_brk == 0))
          begin
            wait (rx_parity_err || rx_framing_err || rx_framing_glitch || rx_break_int);
            lsr_reg_bit7_change_allowed = 1'b1;
            repeat (3) @(posedge wb_clk);
            #2;
            lsr_reg_bit7_change_allowed = 0;

            if (~lsr_reg[7])
            begin
              `BENCH_ERROR("Bit 7 of LSR register not '1'!");
              -> error_detected;
            end
          end
          else
          begin
            wait (lsr_reg_read && (rx_fifo_par == 0) && (rx_fifo_frm == 0) && (rx_fifo_brk == 0));
            lsr_reg_bit7_change_allowed = 1'b1;
            repeat (2) @(posedge wb_clk);
            #2;
            lsr_reg_bit7_change_allowed = 0;

            if (lsr_reg[7])
            begin
              `BENCH_ERROR("Bit 7 of LSR register not '0'!");
              -> error_detected;
            end
          end
        end
      end
      begin: lsr_reg_bit7_changing
        forever
        begin
          wait (~lsr_reg_bit7_change_allowed);
          begin
            @(lsr_reg[7] or lsr_reg_bit7_change_allowed);
            if (~lsr_reg_bit7_change_allowed)
            begin
              `BENCH_ERROR("Bit 7 of LSR register should not change!");
              -> error_detected;
            end
          end
        end
      end
      join
    end






  always@(tx_fifo_wr_pointer or tx_fifo_rd_pointer)
  begin
    if (tx_fifo_wr_pointer >= tx_fifo_rd_pointer)
      tx_fifo_status = tx_fifo_wr_pointer - tx_fifo_rd_pointer;
    else
      tx_fifo_status = (5'h1F - tx_fifo_rd_pointer) + tx_fifo_wr_pointer;
  end

  initial
  begin
    tx_fifo_wr_pointer = 0;
    tx_fifo_rd_pointer = 0;
    tx_shift_reg_empty = 1;
    tx_fifo_status     = 0;
    tx_start_bit_edge  = 1;
    fork
    begin:write_tx_shift_reg_read_tx_fifo
      forever
      begin
        wait ((tx_fifo_status !== 0) && tx_shift_reg_empty && tx_start_bit_edge && ~stx_pad_o);
        tx_start_bit_edge  = 0;
        tx_shift_reg = tx_fifo[tx_fifo_rd_pointer];
        tx_shift_reg_empty = 0;
        @(testbench.i_uart_device.device_received_last_bit);
        repeat (16393) @(posedge wb_clk);
        tx_fifo_rd_pointer = tx_fifo_rd_pointer + 1'b1;
        @(posedge wb_clk);
        if (tx_fifo_status == 0)
        begin
          `BENCH_MSG("TX FIFO is empty!");
        end
      end
    end
    begin:write_tx_fifo
      forever
      begin
        @(tx_reg_written);
        repeat (1) @(posedge wb_clk);
        if (tx_fifo_status <= 5'h0F)
        begin
          tx_fifo[tx_fifo_wr_pointer] = reg_dat;
          tx_fifo_wr_pointer = tx_fifo_wr_pointer + 1'b1;
        end
        else
        begin
          `BENCH_WARNING("TX FIFO overflow!");
        end
      end
    end
    begin:empty_tx_fifo
      forever
      begin
        wait (fcr_reg[2]);
        tx_fifo_wr_pointer = 0;
        tx_fifo_rd_pointer = 0;
        @(posedge wb_clk);
        if (tx_fifo_status == 0)
        begin
          `BENCH_MSG("TX FIFO is empty!");
        end
      end
    end
    begin:read_tx_shift_reg
      forever
      begin
        @(testbench.i_uart_device.device_received_packet);

        if (tx_shift_reg != testbench.i_uart_device.rx_data)
        begin
          `BENCH_ERROR("TX data has ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("TX data correct!");
        if (testbench.i_uart_device.rx_parity_error)
        begin
          `BENCH_ERROR("TX data has parity ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("TX data parity correct!");
        if (testbench.i_uart_device.rx_framing_error)
        begin
          `BENCH_ERROR("TX data has framing ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("TX data framing correct!");

        tx_start_bit_edge  = 1;
        repeat (7) @(wb_clk);
        if (tx_shift_reg_empty == 0)
        begin
          tx_shift_reg_empty = 1'b1;
        end
        else
        begin
          `BENCH_ERROR("TX shift register empty while transmiting data!");
          -> error_detected;
        end
      end
    end
    join
  end






  always@(rx_fifo_wr_pointer or rx_fifo_rd_pointer)
  begin
    if (rx_fifo_wr_pointer >= rx_fifo_rd_pointer)
      rx_fifo_status = rx_fifo_wr_pointer - rx_fifo_rd_pointer;
    else
      rx_fifo_status = (5'h1F - rx_fifo_rd_pointer) + rx_fifo_wr_pointer;
  end

  initial
  begin
    rx_parity_err      = 0;
    rx_framing_err     = 0;
    rx_framing_glitch  = 0;
    rx_break_int       = 0;
    rx_overrun_err_occured = 0;
    rx_fifo_par        = 0;
    rx_fifo_frm        = 0;
    rx_fifo_brk        = 0;
    rx_shift_reg_full  = 0;
    rx_fifo_wr_pointer = 0;
    rx_fifo_rd_pointer = 0;
    rx_fifo_status     = 0;
    fork
    begin:write_rx_shift_reg
      forever
      begin
        @(testbench.i_uart_device.device_sent_packet);
        repeat (1) @(posedge wb_clk);
        rx_shift_reg   = testbench.i_uart_device.sent_data;
        rx_parity_err  = testbench.i_uart_device.tx_parity_enabled && 
                         (testbench.i_uart_device.tx_parity_wrong || 
                          (
                           ((testbench.i_uart_device.tx_glitch_num == (3 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (5 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (7 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (9 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (11 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (13 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (15 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (17 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (19 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (21 * 8 * testbench.i_uart_device.T_divisor)) ||
                            (testbench.i_uart_device.tx_glitch_num == (23 * 8 * testbench.i_uart_device.T_divisor))) &&
                           (testbench.i_uart_device.tx_glitch_num[23:0] < ((testbench.i_uart_device.tx_length + 2'h1) *
                             16 * testbench.i_uart_device.T_divisor))
                         ));
        rx_framing_err = testbench.i_uart_device.tx_framing_wrong;
        rx_framing_glitch = (testbench.i_uart_device.tx_glitch_num == ((((testbench.i_uart_device.tx_length + 2'h2 +
                               testbench.i_uart_device.tx_parity_enabled) * 
                                2) - 1'b1) * 8 * testbench.i_uart_device.T_divisor));
        rx_break_int   = testbench.i_uart_device.tx_break_enable && 
                         (testbench.i_uart_device.tx_break_num[15:0] >= ((testbench.i_uart_device.tx_length + 2'h2 +
                            testbench.i_uart_device.tx_parity_enabled) * 
                           16 * testbench.i_uart_device.T_divisor));
        -> testbench.i_uart_device.sent_packet_received;
        if (rx_fifo_status > 5'h0F)
          rx_overrun_err_occured = 1'b1;
        rx_shift_reg_full = 1'b1;
      end
    end
    begin:write_rx_fifo_read_rx_shift_reg
      forever
      begin
        wait (rx_shift_reg_full);
        if (rx_fifo_status <= 5'h0F)
        begin
          rx_fifo_data[rx_fifo_wr_pointer] = testbench.i_uart_device.sent_data;
          rx_fifo_par[rx_fifo_wr_pointer]  = rx_parity_err; 
          rx_fifo_frm[rx_fifo_wr_pointer]  = rx_framing_err || rx_framing_glitch; 
          rx_fifo_brk[rx_fifo_wr_pointer]  = rx_break_int; 
          rx_fifo_wr_pointer = rx_fifo_wr_pointer + 1'b1;
        end
        else
        begin
          `BENCH_WARNING("RX FIFO overflow!");
        end
        repeat (1) @(posedge wb_clk);
        rx_shift_reg_full = 0;
      end
    end
    begin:empty_rx_fifo
      forever
      begin
        wait (fcr_reg[1]);
        rx_fifo_wr_pointer = 0;
        rx_fifo_rd_pointer = 0;



        @(posedge wb_clk);
        if (rx_fifo_status == 0)
        begin
          `BENCH_MSG("RX FIFO is empty!");
        end
      end
    end
    begin:read_rx_fifo
      rx_fifo_read = 0;
      forever
      begin
        @(rx_reg_read);
        if (rx_fifo_status > 0)
        begin
          rx_fifo_read = 1'b1;

          if (rx_fifo_data[rx_fifo_rd_pointer] != reg_dat)
          begin
            `BENCH_ERROR("RX data has ERROR!");
            -> error_detected;
          end
          else
          begin
            `BENCH_MSG("RX data correct!");
          end

          repeat (1) @(posedge wb_clk);
          rx_fifo_read = 0;
          rx_fifo_rd_pointer = rx_fifo_rd_pointer + 1'b1;
        end
        else
        begin
          `BENCH_WARNING("Reading RX FIFO while RX FIFO is empty!");
        end


        if ((~rx_fifo_frm[rx_fifo_rd_pointer] && lsr_reg[3]) ||
            (rx_fifo_frm[rx_fifo_rd_pointer] && ~lsr_reg[3]))
        begin
          `BENCH_ERROR("RX data has wrong framing ERROR!");
          -> error_detected;
        end
        else
          `BENCH_MSG("RX data has correct framing error!");

        repeat (1) @(posedge wb_clk);
        rx_fifo_read = 0;
        if (rx_fifo_status > 0)
        begin



          rx_fifo_rd_pointer = rx_fifo_rd_pointer + 1'b1;
        end
      end
    end
    join
  end








endmodule