Email: bknpk@hotmail.com Phone: +972-54-7649119


V

 

This page describes a cpp bench, which is used to verify a parallel fifo, using verilator.

  1. In order to practice cpp (c++) verification benches, with system verilog DPI, using a verilog DUT, I decided to download verilator and do some self study exercises.

  2. This cpp bench is based on an hierarchical Design Under Test and a time management cpp bench. Both cases are used as simple exercises to gain some experience with verilator.
    In addition to time management and VCD wave trace, this example also generates stimuli to the Design Under Test.
    This page describes the coding of a data stimuli generator, using verilator. More, complex benches, will come later.


  3. The Design Under Test is a FIFO. The data path of the FIFO is N (4 in this example) 8 bits flip-flops connected in parallel (direct connect between Qn-1 to Dn) to achieve the fastest FIFO on an FPGA.
    The control is also based on N 1 bit flip flops connected as shift register. The full and empty flags as well as other control is taken from this shift register. All outputs are registered to farther facilitate timing in an FPGA.




  4. The cpp bench is shown below. The changes, stimuli drive and generation, from previous example are marked. The DUT signals are accessed using verilator's pointer signal access (entry.fe=pipe_fifo->fe).

    1. #include "Vpipe_fifo.h"
    2. #include "verilated.h"
    3. //vcd traces
    4. #include "verilated_vcd_c.h"
    5. //cout
    6. #include <iostream>
    7. Vpipe_fifo *pipe_fifo; // Instantiation of module
    8. unsigned int main_time = 0; // Current simulation time
    9. double sc_time_stamp () { // Called by $time in Verilog
    10.   return main_time;
    11. }
    12. typedef struct _Entry{
    13.   unsigned int ti;
    14.   unsigned char rd;
    15.   unsigned char wr;
    16.   unsigned char fe;
    17.   unsigned char ff;
    18. } Entry;
    19. void gen(Entry& entry) {
    20.   entry.rd=0;
    21.   entry.wr=0;
    22.   if(entry.ti == 42) {
    23.     entry.rd=0;
    24.     entry.wr=1;
    25.   }
    26. }
    27. int main(int argc, char** argv) {
    28.   Verilated::commandArgs(argc, argv);
    29.   pipe_fifo = new Vpipe_fifo;
    30.   //vcd traces
    31.   Verilated::traceEverOn(true);
    32.   VerilatedVcdC* tfp = new VerilatedVcdC;
    33.   pipe_fifo->trace (tfp, 99);
    34.   tfp->open ("obj_dir/simx.vcd");
    35.   pipe_fifo->rst = 1;
    36.   pipe_fifo->rd = 0;
    37.   pipe_fifo->wr = 0;
    38.   pipe_fifo->DI = 16;
    39.   Entry entry;
    40.   while (!Verilated::gotFinish()) {
    41.     if (main_time > 10) {
    42.       pipe_fifo->rst = 0; // Deassert reset
    43.     }
    44.     if ((main_time % 10) == 1) {
    45.       pipe_fifo->clk = 1; // Toggle clock
    46.     }
    47.     if ((main_time % 10) == 6) {
    48.       pipe_fifo->clk = 0;
    49.     }
    50.     if (((main_time-1) % 10) == 1) {
    51.       //cout << "sim gen :time is " << main_time << endl; // Read a output
    52.       entry.ti=main_time;
    53.       entry.fe=pipe_fifo->fe;
    54.       entry.ff=pipe_fifo->ff;
    55.       gen(entry);
    56.       pipe_fifo->rd = entry.rd;
    57.       pipe_fifo->wr = entry.wr;
    58.     }
    59.     pipe_fifo->eval(); // Evaluate model
    60.     if(main_time > 200) break;
    61.     main_time++; // Time passes...
    62.     tfp->dump (main_time);
    63.   } //while
    64.   cout << "sim end :time is " << main_time << endl; // Read a output
    65.   tfp->close();
    66.   delete pipe_fifo;
    67.   exit(0);
    68. }


  5. The design is compiled and run by the following script:

    1. #!/bin/bash
    2. if [ -e obj_dir/Vpipe_fifo ] ; then
    3.   rm obj_dir/Vpipe_fifo
    4. fi
    5. clear;/usr/bin/verilator --trace --trace-depth 1 --cc pipe_fifo.v --exe sim_main.cpp
    6. #sed -i "s/VERILATOR_ROOT = \/usr\/bin/VERILATOR_ROOT = \/usr\/share\/verilator/" obj_dir/Vpipe_fifo.mk
    7. cd obj_dir
    8. make -j -f Vpipe_fifo.mk Vpipe_fifo && echo "make ended ok"

    Regression is run by the following script. An error is detected if ERROR is found or sim end okay is not found.

    1. #!/bin/bash
    2. for i in {1..50000} ; do
    3.   if [ -e run_reg.log ] ; then
    4.     rm -f run_reg.log
    5.   fi
    6.   seed=$RANDOM
    7.   cmd="./obj_dir/Vpipe_fifo_tool "$seed" > run_reg.log"
    8.   eval $cmd
    9.   grep ERROR run_reg.log >& /dev/null
    10.   if [ $? -eq 0 ] ; then
    11.     cmd="cp run_reg.log run_reg_"$seed".log"
    12.     eval $cmd
    13.   else
    14.     grep "sim end.*okay" run_reg.log >& /dev/null
    15.     if [ $? -eq 1 ] ; then
    16.       cmd="cp run_reg.log run_reg_"$seed".log"
    17.       eval $cmd
    18.     fi
    19.   fi
    20. done






  ...


Home

some memory VHDL models

my first experience with verilator.






Search This Site


Feedback This Site




new pages on this site