[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: gEDA-user: Icarus/NC mismatch -- who's right?



This variant does the same thing in both simulators...

module junk;

   reg [3:0] pi, ci, fill;
   reg [31:0] my_word;
   reg [31:0] fifo [0:7];

   initial begin
      // Put some data in a fifo.
      fifo[0] = 1;
      fifo[1] = 2;
      fifo[2] = 3;
      fifo[3] = 4;
      fifo[4] = 5;
      fifo[5] = 6;
      fifo[6] = 7;
      fifo[7] = 8;

      // Initialize Producer Index and Consumer Index
      pi <= 4;
      ci <= 0;
   end

   // Compute FIFO fill level
   always @(pi or ci) begin
      fill = (pi - ci);
   end

   // Drain FIFO whenever not empty
   always @(fill) begin
      while (fill > 0) begin
	 read_word(my_word);
	 $display("%m : got word 0x%h",my_word);
      end
   end

   task read_word;

      output [31:0] word;

      begin
	 word = fifo[ci[2:0]];
	 ci <= ci + 1;
	 @(fill);      // ********Changed here.
      end
   endtask // read_word

endmodule

It looks like the always @(pi or ci) block doesn't get visited if I do an @(ci) but it does if I do an @(fill) then it forces icarus to visit the @(pi or ci) block?



Mark Schellhorn wrote:
Oops.. left a syntax error in the verilog. Corrected:

module junk;

   reg [3:0] pi, ci, fill;
   reg [31:0] my_word;
   reg [31:0] fifo [0:7];

   initial begin
      // Put some data in a fifo.
      fifo[0] = 1;
      fifo[1] = 2;
      fifo[2] = 3;
      fifo[3] = 4;
      fifo[4] = 5;
      fifo[5] = 6;
      fifo[6] = 7;
      fifo[7] = 8;

      // Initialize Producer Index and Consumer Index
      pi <= 4;
      ci <= 0;
   end

   // Compute FIFO fill level
   always @(pi or ci) begin
      fill = (pi - ci);
   end

   // Drain FIFO whenever not empty
   always @(fill) begin
      while (fill > 0) begin
     read_word(my_word);
     $display("%m : got word 0x%h",my_word);
      end
   end

   task read_word;

      output [31:0] word;

      begin
     word = fifo[ci[2:0]];
     ci <= ci + 1;
     @(ci);
      end
   endtask // read_word

endmodule



Mark Schellhorn wrote:

When I simulate the following module with NC I get the expected result, when I simulate with Icarus 0.8.1 the simulator goes into an infinite zero-time loop.

What I expect to see is that after the initial block puts four entries into fifo, the always @(fill) block reads them out one at a time until fifo is empty. At this point there is nothing else to do so the simulation ends.

// -------------------- Module begin
module junk;

   reg [3:0] pi, ci, fill;
   reg [31:0] my_word;
   reg [31:0] fifo [0:7];

   initial begin
      // Put some data in a fifo.
      fifo[0] = 1;
      fifo[1] = 2;
      fifo[2] = 3;
      fifo[3] = 4;
      fifo[4] = 5;
      fifo[5] = 6;
      fifo[6] = 7;
      fifo[7] = 8;

      // Initialize Producer Index and Consumer Index
      pi <= 4;
      ci <= 0;
   end

   // Compute FIFO fill level
   always @(pi or ci) begin
      fill = (pi - ci);
   end

   // Drain FIFO whenever not empty
   always @(fill) begin
      while (fill > 0) begin
     read_word(my_word);
     $display("%m : got word 0x%h",my_word);
      end
   end

   task read_word;

      output [31:0] word;

      begin
     word = fifo[ci[15:0]];
     ci <= ci + 1;
     @(ci);
      end
   endtask // read_word

endmodule
// -------------------- Module end

NC-verilog log file:

ncsim> run
junk : got word 0x00000001
junk : got word 0x00000002
junk : got word 0x00000003
junk : got word 0x00000004
ncsim: *W,RNQUIE: Simulation is complete.

Icarus log file:

junk : got word 0x00000001
junk : got word 0x00000002
junk : got word 0x00000003
junk : got word 0x00000004
junk : got word 0x00000005
junk : got word 0x00000006
junk : got word 0x00000007
junk : got word 0x00000008
junk : got word 0x00000001
junk : got word 0x00000002
junk : got word 0x00000003
junk : got word 0x00000004
etc. etc. forever

Who's right? It kind of looks like the read_word() task fails to wait for @(ci) before leaving???

     Mark