File: t_queue_void_ops.v

package info (click to toggle)
verilator 5.038-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 162,552 kB
  • sloc: cpp: 139,204; python: 20,931; ansic: 10,222; yacc: 6,000; lex: 1,925; makefile: 1,260; sh: 494; perl: 282; fortran: 22
file content (196 lines) | stat: -rw-r--r-- 6,348 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0

module t
  (/*AUTOARG*/
   // Inputs
   clk
   );

  input clk;

  int   cyc = 0;


  // Test for https://github.com/verilator/verilator/issues/3364
  // Make sure all SV queue API is supported and verilator can generate
  // compile-able C++ models for it.

  // simple queue
  logic [31:0] my_int_queue [$];

  // On the functions and tasks, the my_int_queue.pop_[front|back]() call will
  // have nodep->firstAbovep() != nullptr. Because the pop_front or pop_back is
  // the first node on the "list".
  // To fix this, V3Width.cpp will not use firstAbovep(), and instead us
  // isStandalongStmt() -- which checks if the pop_front or pop_back is
  // 2nd or later, or if it's first in the list that it's in a "block" of code.
  // For functions/tasks, that is checked with:
  // VN_IS(backp(), NodeFTask)=True, so even though
  function automatic void f_pop_back__my_int_queue();
    void'(my_int_queue.pop_back());
  endfunction : f_pop_back__my_int_queue

  function automatic void f_pop_front__my_int_queue();
    void'(my_int_queue.pop_front());
  endfunction : f_pop_front__my_int_queue

  task automatic t_pop_back__my_int_queue();
    void'(my_int_queue.pop_back());
  endtask : t_pop_back__my_int_queue

  task automatic t_pop_front__my_int_queue();
    void'(my_int_queue.pop_front());
  endtask : t_pop_front__my_int_queue


  task automatic do_random_queue_operation();
    bit [7:0] rand_op;
    int       rand_index;
    logic [31:0] item;


    rand_op = 8'($urandom_range(32, 0));
    case(rand_op)
    8'd0: ; // nop

    // pushes (2x of these)
    8'd1, 8'd2: my_int_queue.push_back($urandom);
    8'd3, 8'd4: my_int_queue.push_front($urandom);

    // delete:
    8'd5: my_int_queue.delete();

    // insert(index, item):
    8'd6: begin
      rand_index = $urandom_range(my_int_queue.size());
      my_int_queue.insert(rand_index, item);
    end

    // shuffle
    8'd7: my_int_queue.shuffle();

    // Various pops for rand_op >= 8:
    // pops to var
    // V3Width debug -- firstAbovep()=ASSIGN (which I guess does the ; for us
    //                                        so we don't need the queue op to
    //                                        do it.)
    // isStandalongStmt() will ignore ASSIGN, return false (NodeAssign is
    // child of AstNodeStmt)
    8'd8: if (my_int_queue.size() > 0) item = my_int_queue.pop_front();
    8'd9: if (my_int_queue.size() > 0) item = my_int_queue.pop_back();

    // pops to the void
    // V3Width debug -- firstAbovep()=IF
    // This is fixed with isStandalongStmt() -- VN_IS(backp(), NodeIf)=True
    8'd10: if (my_int_queue.size() > 0) void'(my_int_queue.pop_front());
    8'd11: if (my_int_queue.size() > 0) void'(my_int_queue.pop_back());

    // pop result to the lhs of a condition, and do something with it.
    8'd12:
      if (my_int_queue.size() > 0)
        // V3Width debug -- firstAbovep()=LTE (good we don't want a ; here)
        if (my_int_queue.pop_front() <= 2022)
          my_int_queue.push_front(3022); // living in the year 3022.

    // pop result to the rhs of a condition, and do something with it.
    8'd13:
      if (my_int_queue.size() > 0)
        // V3Width debug -- firstAbovep()=GT (good we don't want a ; here)
        if (4022 > my_int_queue.pop_front())
          my_int_queue.push_front(3023); // living in the year 3023.

    // pops to the void after yet another case:
    // V3Width debug -- firstAbovep()=CASEITEM (not a nullptr)
    // This is fixed with isStandalongStmt() -- VN_IS(backp(), CaseItem)=True
    8'd14:
      case (my_int_queue.size() > 0)
      0: ;
      1: void'(my_int_queue.pop_front());
      default: ;
      endcase // case (my_int_queue.size() > 0)

    // V3Width debug -- firstAbovep()=CASEITEM (not a nullptr)
    // backp()->nextp()=CASEITEM (different one)
    // This is fixed with isStandalongStmt() -- VN_IS(backp(), CaseItem)=True
    8'd15:
      case (my_int_queue.size() > 0)
      0: ;
      1: void'(my_int_queue.pop_back());
      default;
      endcase // case (my_int_queue.size() > 0)

    // pops in a function or task
    8'd16: if (my_int_queue.size() > 0) f_pop_back__my_int_queue();
    8'd17: if (my_int_queue.size() > 0) f_pop_front__my_int_queue();
    8'd18: if (my_int_queue.size() > 0) t_pop_back__my_int_queue();
    8'd19: if (my_int_queue.size() > 0) t_pop_front__my_int_queue();

    // But what if we put some dummy code before the pop_back() or pop_front():
    8'd20: begin
      if (my_int_queue.size() > 0) begin
        ; // dummy line
        // V3Width debug -- firstAbovep()=BEGIN (is not nullptr).
        // This is fixed with isStandalongStmt() -- VN_IS(backp(), NodeIf)=True
        void'(my_int_queue.pop_back());
      end
    end
    8'd21: begin
      automatic int temp_int = 0;
      if (my_int_queue.size() > 0) begin
        temp_int = 5; // dummy line
        // V3Width debug -- firstAbovep()=nullptr (good)
        void'(my_int_queue.pop_back());
      end
    end
    8'd22: begin
      if (my_int_queue.size() > 0) begin
        automatic int some_temp_dummy_int;
        some_temp_dummy_int = 42;
        // V3Width debug -- firstAbovep()=nullptr (good)
        void'(my_int_queue.pop_back());
      end
    end
    8'd23: begin
      if (my_int_queue.size() > 0) begin
        // no dummy here, just a 'begin' helper before it.
        // V3Width debug -- firstAbovep()=BEGIN (is not nullptr).
        // This is fixed with isStandalongStmt() -- VN_IS(backp(), NodeIf)=True
        void'(my_int_queue.pop_back());
      end
    end

    // What about an if of something else, followed by a pop_front?
    8'd24: begin
      automatic int temp_int = 0;
      if (my_int_queue.size() == 0) begin // dummy
        temp_int = 1000;
      end
      void'(my_int_queue.pop_front()); // firstAbovep() should be nullptr here.
    end


    default: ; // nop
    endcase // case (rand_op)

  endtask : do_random_queue_operation



  always @ (posedge clk) begin : main
    cyc <= cyc + 1;

    do_random_queue_operation();

    if (cyc > 100) begin
      $write("*-* All Finished *-*\n");
      $finish();
    end
  end



endmodule : t