Trung tâm đào tạo thiết kế vi mạch Semicon


  • ĐĂNG KÝ TÀI KHOẢN ĐỂ TRUY CẬP NHIỀU TÀI LIỆU HƠN!
  • Đăng ký
    *
    *
    *
    *
    *
    Fields marked with an asterisk (*) are required.
semi4_volunteering.jpg

REVIEW VERIFICATION OF FIFO

Email In PDF.
Xem kết quả: / 0
Bình thườngTuyệt vời 

ABSTRACT

An improved technique for fifo desigis to perform asynchronous comparisons between the fifo write and read pointers that are generated in

clock domains and asynchronous to each other. The asynchronous fifo pointer comparison technique uses fewer synchronization flip-flops to build the fifo. This method requires additional techniques to correctly synthesize and analyze the design, which are detailed in this paper. To increase the speed of the fifo, this design uses combined binary/Gray counters that take advantage of the built-in binary ripple carry logic. This fifo design is used to implement the AMBA AHB Compliant Memory Controller. This means, Advanced Microcontroller Bus Architecture compliant Microcontroller .The MC is designed for system memory control with the main memory consisting of STRAM and ROM.

 CONTENT

Verification Of FIFO Part - I

Verification Of FIFO Part - II

Verification Of FIFO Part - III

In this example, we verify a simple synchronous FIFO. Of course in real life we really don't get to verify a FIFO model, as in companies this are generated using script.

This testbench will slightly different from what we have seen till now.

So the verification components are split into following blocks

  • Push Generator
  • Pop Generator
  • Push Monitor
  • Pop Monitor
  • Scoreboard
  • E testbench top
  • HDL Testbench top

We are going to have some more components that like reset. Push/Pop Driver, Push/Pop Monitor are going to be part of fifo_driver.e

Device Under Test

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

   2 // Design Name : syn_fifo

   3 // File Name   : syn_fifo.v

   4 // Function    : Synchronous (single clock) FIFO

   5 // Coder       : Deepak Kumar Tala

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

   7 module syn_fifo (

   8 clk      // Clock input

   9 rst      // Active high reset

  10 wr_cs    // Write chip select

  11 rd_cs    // Read chipe select

  12 data_in  // Data input

  13 rd_en    // Read enable

  14 wr_en    // Write Enable

  15 data_out , // Data Output

  16 empty    // FIFO empty

  17 full       // FIFO full

  18 );   

  19 

  20 // FIFO constants

  21 parameter DATA_WIDTH = 8;

  22 parameter ADDR_WIDTH = 8;

  23 parameter RAM_DEPTH = (1 << ADDR_WIDTH);

  24 // Port Declarations

  25 input clk ;

  26 input rst ;

  27 input wr_cs ;

  28 input rd_cs ;

  29 input rd_en ;

  30 input wr_en ;

  31 input [DATA_WIDTH-1:0] data_in ;

  32 output full ;

  33 output empty ;

  34 output [DATA_WIDTH-1:0] data_out ;

  35

  36 //-----------Internal variables-------------------

  37 reg [ADDR_WIDTH-1:0] wr_pointer;

  38 reg [ADDR_WIDTH-1:0] rd_pointer;

  39 reg [ADDR_WIDTH :0] status_cnt;

  40 reg [DATA_WIDTH-1:0] data_out ;

  41 wire [DATA_WIDTH-1:0] data_ram ;

  42

  43 //-----------Variable assignments---------------

  44 assign full = (status_cnt == (RAM_DEPTH-1));

  45 assign empty = (status_cnt == 0);

  46

  47 //-----------Code Start---------------------------

  48 always @ (posedge clk or posedge rst)

  49 begin : WRITE_POINTER

  50   if (rst) begin

  51     wr_pointer <= 0;

  52   end else if (wr_cs && wr_en ) begin

  53     wr_pointer <= wr_pointer + 1;

  54   end

  55 end

  56

  57 always @ (posedge clk or posedge rst)

  58 begin : READ_POINTER

  59   if (rst) begin

  60     rd_pointer <= 0;

  61   end else if (rd_cs && rd_en ) begin

  62     rd_pointer <= rd_pointer + 1;

  63   end

  64 end

  65

  66 always  @ (posedge clk or posedge rst)

  67 begin : READ_DATA

  68   if (rst) begin

  69     data_out <= 0;

  70   end else if (rd_cs && rd_en ) begin

  71     data_out <= data_ram;

  72   end

  73 end

  74

  75 always @ (posedge clk or posedge rst)

  76 begin : STATUS_COUNTER

  77   if (rst) begin

  78     status_cnt <= 0;

  79   // Read but no write.

  80   end else if ((rd_cs && rd_en) &&  (wr_cs && wr_en)

  81                 && (status_cnt  ! = 0)) begin

  82     status_cnt <= status_cnt - 1;

  83   // Write but no read.

  84   end else if ((wr_cs && wr_en) &&  (rd_cs && rd_en)

  85                && (status_cnt  ! = RAM_DEPTH)) begin

  86     status_cnt <= status_cnt + 1;

  87   end

  88 end

  89   

  90 ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (

  91 .address_0 (wr_pointer) , // address_0 input

  92 .data_0    (data_in)    // data_0 bi-directional

  93 .cs_0      (wr_cs)      // chip select

  94 .we_0      (wr_en)      // write enable

  95 .oe_0      (1'b0)       // output enable

  96 .address_1 (rd_pointer) , // address_q input

  97 .data_1    (data_ram)   // data_1 bi-directional

  98 .cs_1      (rd_cs)      // chip select

  99 .we_1      (1'b0)       // Read enable

 100 .oe_1      (rd_en)        // output enable

 101 );    

 102

 103 endmodule

 

  1 //-----------------------------------------------------
  2 // Design Name : ram_dp_ar_aw
  3 // File Name   : ram_dp_ar_aw.v
  4 // Function    : Asynchronous read write RAM
  5 // Coder       : Deepak Kumar Tala
  6 //-----------------------------------------------------
  7 module ram_dp_ar_aw (
  8 address_0 , // address_0 Input
  9 data_0    , // data_0 bi-directional
 10 cs_0      , // Chip Select
 11 we_0      , // Write Enable/Read Enable
 12 oe_0      , // Output Enable
 13 address_1 , // address_1 Input
 14 data_1    , // data_1 bi-directional
 15 cs_1      , // Chip Select
 16 we_1      , // Write Enable/Read Enable
 17 oe_1        // Output Enable
 18 ); 
 19 
 20 parameter DATA_WIDTH = 8 ;
 21 parameter ADDR_WIDTH = 8 ;
 22 parameter RAM_DEPTH = 1 << ADDR_WIDTH;
 23 
 24 //--------------Input Ports----------------------- 
 25 input [ADDR_WIDTH-1:0] address_0 ;
 26 input cs_0 ;
 27 input we_0 ;
 28 input oe_0 ; 
 29 input [ADDR_WIDTH-1:0] address_1 ;
 30 input cs_1 ;
 31 input we_1 ;
 32 input oe_1 ; 
 33 
 34 //--------------Inout Ports----------------------- 
 35 inout [DATA_WIDTH-1:0] data_0 ; 
 36 inout [DATA_WIDTH-1:0] data_1 ;
 37 
 38 //--------------Internal variables---------------- 
 39 reg [DATA_WIDTH-1:0] data_0_out ; 
 40 reg [DATA_WIDTH-1:0] data_1_out ;
 41 reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
 42 
 43 //--------------Code Starts Here------------------ 
 44 // Memory Write Block 
 45 // Write Operation : When we_0 = 1, cs_0 = 1
 46 always @ (address_0 or cs_0 or we_0 or data_0
 47 or address_1 or cs_1 or we_1 or data_1)
 48 begin : MEM_WRITE
 49   if ( cs_0 && we_0 ) begin
 50      mem[address_0] <= data_0;
 51   end else if  (cs_1 && we_1) begin
 52      mem[address_1] <= data_1;
 53   end
 54 end
 55 
 56 // Tri-State Buffer control 
 57 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
 58 assign data_0 = (cs_0 && oe_0 &&  ! we_0) ? data_0_out : 8'bz; 
 59 
 60 // Memory Read Block 
 61 // Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1
 62 always @ (address_0 or cs_0 or we_1 or oe_0)
 63 begin : MEM_READ_0
 64   if (cs_0 &&  ! we_0 && oe_0) begin
 65     data_0_out <= mem[address_0]; 
 66   end else begin
 67     data_0_out <= 0; 
 68   end
 69 end 
 70 
 71 //Second Port of RAM
 72 // Tri-State Buffer control 
 73 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
 74 assign data_1 = (cs_1 && oe_1 &&  ! we_1) ? data_1_out : 8'bz; 
 75 // Memory Read Block 1 
 76 // Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1
 77 always @ (address_1 or cs_1 or we_1 or oe_1)
 78 begin : MEM_READ_1
 79   if (cs_1 &&  ! we_1 && oe_1) begin
 80     data_1_out <= mem[address_1]; 
 81   end else begin
 82     data_1_out <= 0; 
 83   end
 84 end
 85 
 86 endmodule // End of Module ram_dp_ar_aw

HDL Testbench Top

  1 `include "ram_dp_ar_aw.v"
  2 `include "syn_fifo.v"
  3 
  4 module top();
  5 
  6 parameter DATA_WIDTH = 8;
  7 parameter ADDR_WIDTH = 3;
  8 
  9 reg clk, rst, wr_cs, rd_cs;
 10 reg rd_en, wr_en;
 11 reg [DATA_WIDTH-1:0] data_in ;
 12 wire full, empty;
 13 wire [DATA_WIDTH-1:0] data_out ;
 14 
 15 initial begin
 16   clk = 0;
 17   rst = 0;
 18   wr_cs = 0;
 19   rd_cs = 0;
 20   rd_en = 0;
 21   wr_en = 0;
 22   data_in = 0;
 23 end
 24 
 25 always  #1  clk  = ~clk;
 26 
 27 syn_fifo #(DATA_WIDTH,ADDR_WIDTH) fifo(
 28 .clk      (clk),     // Clock input
 29 .rst      (rst),     // Active high reset
 30 .wr_cs    (wr_cs),   // Write chip select
 31 .rd_cs    (rd_cs),   // Read chipe select
 32 .data_in  (data_in), // Data input
 33 .rd_en    (rd_en),   // Read enable
 34 .wr_en    (wr_en),   // Write Enable
 35 .data_out (data_out),// Data Output
 36 .empty    (empty),   // FIFO empty
 37 .full     (full)     // FIFO full
 38 );
 39 
 40 endmodule
E Testbench Top
  1 <'
  2 import fifo_clk.e;
  3 import fifo_sb.e;
  4 import fifo_driver.e;
  5 
  6 struct fifo_tb {
  7   scoreboard : fifo_sb;
  8 
  9   driver     : fifo_driver;
 10     keep driver.sb == scoreboard;
 11 
 12   go()@sys.clk is {
 13      start driver.go();
 14   };
 15 };
 16 
 17 extend sys {
 18   tb  : fifo_tb;
 19   run() is also {
 20     start tb.go();
 21   };
 22 };
 23 '>

FIFO Clock

.
1 <'
 2 extend sys {
 3   event clk is rise('top.clk') @sim;
 4 };
 5 '>Device Under Test
  1 //-----------------------------------------------------

   2 // Design Name : syn_fifo

   3 // File Name   : syn_fifo.v

   4 // Function    : Synchronous (single clock) FIFO

   5 // Coder       : Deepak Kumar Tala

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

   7 module syn_fifo (

   8 clk      // Clock input

   9 rst      // Active high reset

  10 wr_cs    // Write chip select

  11 rd_cs    // Read chipe select

  12 data_in  // Data input

  13 rd_en    // Read enable

  14 wr_en    // Write Enable

  15 data_out , // Data Output

  16 empty    // FIFO empty

  17 full       // FIFO full

  18 );   

  19 

  20 // FIFO constants

  21 parameter DATA_WIDTH = 8;

  22 parameter ADDR_WIDTH = 8;

  23 parameter RAM_DEPTH = (1 << ADDR_WIDTH);

  24 // Port Declarations

  25 input clk ;

  26 input rst ;

  27 input wr_cs ;

  28 input rd_cs ;

  29 input rd_en ;

  30 input wr_en ;

  31 input [DATA_WIDTH-1:0] data_in ;

  32 output full ;

  33 output empty ;

  34 output [DATA_WIDTH-1:0] data_out ;

  35

  36 //-----------Internal variables-------------------

  37 reg [ADDR_WIDTH-1:0] wr_pointer;

  38 reg [ADDR_WIDTH-1:0] rd_pointer;

  39 reg [ADDR_WIDTH :0] status_cnt;

  40 reg [DATA_WIDTH-1:0] data_out ;

  41 wire [DATA_WIDTH-1:0] data_ram ;

  42

  43 //-----------Variable assignments---------------

  44 assign full = (status_cnt == (RAM_DEPTH-1));

  45 assign empty = (status_cnt == 0);

  46

  47 //-----------Code Start---------------------------

  48 always @ (posedge clk or posedge rst)

  49 begin : WRITE_POINTER

  50   if (rst) begin

  51     wr_pointer <= 0;

  52   end else if (wr_cs && wr_en ) begin

  53     wr_pointer <= wr_pointer + 1;

  54   end

  55 end

  56

  57 always @ (posedge clk or posedge rst)

  58 begin : READ_POINTER

  59   if (rst) begin

  60     rd_pointer <= 0;

  61   end else if (rd_cs && rd_en ) begin

  62     rd_pointer <= rd_pointer + 1;

  63   end

  64 end

  65

  66 always  @ (posedge clk or posedge rst)

  67 begin : READ_DATA

  68   if (rst) begin

  69     data_out <= 0;

  70   end else if (rd_cs && rd_en ) begin

  71     data_out <= data_ram;

  72   end

  73 end

  74

  75 always @ (posedge clk or posedge rst)

  76 begin : STATUS_COUNTER

  77   if (rst) begin

  78     status_cnt <= 0;

  79   // Read but no write.

  80   end else if ((rd_cs && rd_en) &&  (wr_cs && wr_en)

  81                 && (status_cnt  ! = 0)) begin

  82     status_cnt <= status_cnt - 1;

  83   // Write but no read.

  84   end else if ((wr_cs && wr_en) &&  (rd_cs && rd_en)

  85                && (status_cnt  ! = RAM_DEPTH)) begin

  86     status_cnt <= status_cnt + 1;

  87   end

  88 end

  89   

  90 ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (

  91 .address_0 (wr_pointer) , // address_0 input

  92 .data_0    (data_in)    // data_0 bi-directional

  93 .cs_0      (wr_cs)      // chip select

  94 .we_0      (wr_en)      // write enable

  95 .oe_0      (1'b0)       // output enable

  96 .address_1 (rd_pointer) , // address_q input

  97 .data_1    (data_ram)   // data_1 bi-directional

  98 .cs_1      (rd_cs)      // chip select

  99 .we_1      (1'b0)       // Read enable

 100 .oe_1      (rd_en)        // output enable

 101 );    

 102

 103 endmodule

 

  1 //-----------------------------------------------------
  2 // Design Name : ram_dp_ar_aw
  3 // File Name   : ram_dp_ar_aw.v
  4 // Function    : Asynchronous read write RAM
  5 // Coder       : Deepak Kumar Tala
  6 //-----------------------------------------------------
  7 module ram_dp_ar_aw (
  8 address_0 , // address_0 Input
  9 data_0    , // data_0 bi-directional
 10 cs_0      , // Chip Select
 11 we_0      , // Write Enable/Read Enable
 12 oe_0      , // Output Enable
 13 address_1 , // address_1 Input
 14 data_1    , // data_1 bi-directional
 15 cs_1      , // Chip Select
 16 we_1      , // Write Enable/Read Enable
 17 oe_1        // Output Enable
 18 ); 
 19 
 20 parameter DATA_WIDTH = 8 ;
 21 parameter ADDR_WIDTH = 8 ;
 22 parameter RAM_DEPTH = 1 << ADDR_WIDTH;
 23 
 24 //--------------Input Ports----------------------- 
 25 input [ADDR_WIDTH-1:0] address_0 ;
 26 input cs_0 ;
 27 input we_0 ;
 28 input oe_0 ; 
 29 input [ADDR_WIDTH-1:0] address_1 ;
 30 input cs_1 ;
 31 input we_1 ;
 32 input oe_1 ; 
 33 
 34 //--------------Inout Ports----------------------- 
 35 inout [DATA_WIDTH-1:0] data_0 ; 
 36 inout [DATA_WIDTH-1:0] data_1 ;
 37 
 38 //--------------Internal variables---------------- 
 39 reg [DATA_WIDTH-1:0] data_0_out ; 
 40 reg [DATA_WIDTH-1:0] data_1_out ;
 41 reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
 42 
 43 //--------------Code Starts Here------------------ 
 44 // Memory Write Block 
 45 // Write Operation : When we_0 = 1, cs_0 = 1
 46 always @ (address_0 or cs_0 or we_0 or data_0
 47 or address_1 or cs_1 or we_1 or data_1)
 48 begin : MEM_WRITE
 49   if ( cs_0 && we_0 ) begin
 50      mem[address_0] <= data_0;
 51   end else if  (cs_1 && we_1) begin
 52      mem[address_1] <= data_1;
 53   end
 54 end
 55 
 56 // Tri-State Buffer control 
 57 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
 58 assign data_0 = (cs_0 && oe_0 &&  ! we_0) ? data_0_out : 8'bz; 
 59 
 60 // Memory Read Block 
 61 // Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1
 62 always @ (address_0 or cs_0 or we_1 or oe_0)
 63 begin : MEM_READ_0
 64   if (cs_0 &&  ! we_0 && oe_0) begin
 65     data_0_out <= mem[address_0]; 
 66   end else begin
 67     data_0_out <= 0; 
 68   end
 69 end 
 70 
 71 //Second Port of RAM
 72 // Tri-State Buffer control 
 73 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
 74 assign data_1 = (cs_1 && oe_1 &&  ! we_1) ? data_1_out : 8'bz; 
 75 // Memory Read Block 1 
 76 // Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1
 77 always @ (address_1 or cs_1 or we_1 or oe_1)
 78 begin : MEM_READ_1
 79   if (cs_1 &&  ! we_1 && oe_1) begin
 80     data_1_out <= mem[address_1]; 
 81   end else begin
 82     data_1_out <= 0; 
 83   end
 84 end
 85 
 86 endmodule // End of Module ram_dp_ar_aw

HDL Testbench Top

  1 `include "ram_dp_ar_aw.v"
  2 `include "syn_fifo.v"
  3 
  4 module top();
  5 
  6 parameter DATA_WIDTH = 8;
  7 parameter ADDR_WIDTH = 3;
  8 
  9 reg clk, rst, wr_cs, rd_cs;
 10 reg rd_en, wr_en;
 11 reg [DATA_WIDTH-1:0] data_in ;
 12 wire full, empty;
 13 wire [DATA_WIDTH-1:0] data_out ;
 14 
 15 initial begin
 16   clk = 0;
 17   rst = 0;
 18   wr_cs = 0;
 19   rd_cs = 0;
 20   rd_en = 0;
 21   wr_en = 0;
 22   data_in = 0;
 23 end
 24 
 25 always  #1  clk  = ~clk;
 26 
 27 syn_fifo #(DATA_WIDTH,ADDR_WIDTH) fifo(
 28 .clk      (clk),     // Clock input
 29 .rst      (rst),     // Active high reset
 30 .wr_cs    (wr_cs),   // Write chip select
 31 .rd_cs    (rd_cs),   // Read chipe select
 32 .data_in  (data_in), // Data input
 33 .rd_en    (rd_en),   // Read enable
 34 .wr_en    (wr_en),   // Write Enable
 35 .data_out (data_out),// Data Output
 36 .empty    (empty),   // FIFO empty
 37 .full     (full)     // FIFO full
 38 );
 39 
 40 endmodule
E Testbench Top
  1 <'
  2 import fifo_clk.e;
  3 import fifo_sb.e;
  4 import fifo_driver.e;
  5 
  6 struct fifo_tb {
  7   scoreboard : fifo_sb;
  8 
  9   driver     : fifo_driver;
 10     keep driver.sb == scoreboard;
 11 
 12   go()@sys.clk is {
 13      start driver.go();
 14   };
 15 };
 16 
 17 extend sys {
 18   tb  : fifo_tb;
 19   run() is also {
 20     start tb.go();
 21   };
 22 };
 23 '>

FIFO Clock

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

FIFO Scoreboard

  1 <'
  2 struct fifo_sb {
  3     ! fifo : list of byte;
  4 
  5    addItem(data : byte) is {
  6      if (fifo.size() == 7) {
  7        outf("%dns : ERROR : Over flow detected, current occupancy %d\n",
  8          sys.time, fifo.size());
  9      } else {
 10        fifo.push(data);
 11      };
 12    };
 13 
 14    compareItem (data : byte) is {
 15      var cdata : byte = 0;
 16      if (fifo.size() == 0) {
 17        outf("%dns : ERROR : Under flow detected\n", sys.time);
 18      } else {
 19        cdata = fifo.pop0();
 20        if (data  ! = cdata) {
 21          outf("%dns : ERROR : Data mismatch, Expected %x Got %x\n", 
 22            sys.time, cdata, data );
 23        };
 24      };
 25    };
 26 };
 27 '>

FIFO Driver

   1 <'
   2 struct fifo_driver {
   3   sb : fifo_sb;
   4 
   5   rd_wt     : uint [0..100];
   6   rd_nop_wt : uint [0..100];
   7   wr_wt     : uint [0..100];
   8   wr_nop_wt : uint [0..100];
   9 
  10   keep soft wr_wt == 50;
  11   keep soft rd_wt == 100;
  12   keep soft wr_nop_wt == 100;
  13   keep soft rd_nop_wt == 50;
  14 
  15   rd        : bit;
  16   wr        : bit;
  17 
  18   rd_cmds    : uint;
  19     keep rd_cmds == 100;
  20   wr_cmds    : uint;
  21     keep wr_cmds == 100;
  22 
  23    ! rdDone : bool;
  24    ! wrDone : bool;
  25   
  26   monitorPush()@sys.clk is {
  27     var data : byte = 0;
  28     while (TRUE) {
  29       wait cycle;
  30       if ('top.wr_cs' == 1 &&  'top.wr_en' == 1) {
  31         data = 'top.data_in';
  32         sb.addItem(data);
  33         outf("%dns : Write posting to scoreboard data = %x\n",sys.time, data);
  34       };
  35     };
  36   };
  37 
  38   monitorPop()@sys.clk is {
  39     var data  : byte = 0;
  40     while (TRUE) {
  41       wait cycle;
  42       if ('top.rd_cs' == 1 &&  'top.rd_en' == 1) {
  43         data = 'top.data_out';
  44         sb.compareItem(data);
  45         outf("%dns : Read posting to scoreboard data = %x\n",sys.time, data);
  46       };
  47     };
  48   };
  49 
  50   go()@sys.clk is {
  51     // Assert reset first
  52     reset();
  53     // Start the monitors
  54     wait [5]*cycle;
  55     outf("%dns : Starting Pop and Push monitors\n",sys.time);
  56     start monitorPop();
  57     start monitorPush();
  58     outf("%dns : Starting Pop and Push generators\n",sys.time);
  59     start genPush();
  60     start genPop();
  61 
  62     while ( ! rdDone &&  ! wrDone) {
  63       wait cycle;
  64     };
  65     wait [10]*cycle;
  66     outf("%dns : Terminating simulations\n",sys.time);
  67     stop_run();
  68   };
  69 
  70   reset()@sys.clk is {
  71     wait [5]*cycle;
  72     outf("%dns : Asserting reset\n",sys.time);
  73     'top.rst' = 1'b1;
  74     // Init all variables
  75     rdDone = FALSE;
  76     wrDone = FALSE;
  77     wait [5]*cycle;
  78     'top.rst' = 1'b0;
  79     outf("%dns : Done asserting reset\n",sys.time);
  80   };
  81 
  82   genPush()@sys.clk is {
  83     var data : byte = 0;
  84     for {var i : uint = 0; i < wr_cmds; i = i + 1} do {
  85        gen wr keeping {
  86          soft it == select {
  87            wr_wt     : 1;
  88            wr_nop_wt : 0;
  89          };
  90        };
  91        gen data;
  92        wait cycle;
  93        while ('top.full' == 1'b1) {
  94         'top.wr_cs'   = 1'b0;
  95         'top.wr_en'   = 1'b0;
  96         'top.data_in' = 8'b0;
  97         wait cycle; 
  98        };
  99        if (wr == 1) {
 100          'top.wr_cs'   = 1'b1;
 101          'top.wr_en'   = 1'b1;
 102          'top.data_in' = data;
 103        } else {
 104          'top.wr_cs'   = 1'b0;
 105          'top.wr_en'   = 1'b0;
 106          'top.data_