[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: gEDA-user: Icarus/NC mismatch -- who's right?
Ah yes... some instrumentation (below) demonstrated it. Thanks!
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;
$display("%m : initial done.");
end
// Compute FIFO fill level
always @(pi or ci) begin
$display("%m : level evaluation.");
fill = (pi - ci);
$display("%m : fill updated to %0d",fill);
end
// Drain FIFO whenever not empty
always @(fill) begin
$display("%m : drain evaluation.");
while (fill > 0) begin
$display("%m : fill seen as %0d",fill);
read_word(my_word);
$display("%m : got word 0x%h\n",my_word);
end
end
task read_word;
output [31:0] word;
begin
$display("%m : entering task.");
word = fifo[ci[2:0]];
ci <= ci + 1;
@(ci);
$display("%m : leaving task.");
end
endtask // read_word
endmodule
Gave me this:
junk : initial done.
junk : level evaluation.
junk : fill updated to 4
junk : drain evaluation.
junk : fill seen as 4
junk.read_word : entering task.
junk.read_word : leaving task.
junk : got word 0x00000001
junk : fill seen as 4
junk.read_word : entering task.
junk : level evaluation.
junk : fill updated to 3
junk.read_word : leaving task.
junk : got word 0x00000002
junk : fill seen as 3
junk.read_word : entering task.
junk : level evaluation.
junk : fill updated to 2
junk.read_word : leaving task.
junk : got word 0x00000003
junk : fill seen as 2
junk.read_word : entering task.
junk : level evaluation.
junk : fill updated to 1
junk.read_word : leaving task.
junk : got word 0x00000004
junk : fill seen as 1
junk.read_word : entering task.
junk : level evaluation.
junk : fill updated to 0
junk.read_word : leaving task.
junk : got word 0x00000005
junk : level evaluation.
junk : fill updated to 15
junk : drain evaluation.
junk : fill seen as 15
junk.read_word : entering task.
junk.read_word : leaving task.
junk : got word 0x00000006
junk : fill seen as 15
junk.read_word : entering task.
junk : level evaluation.
junk : fill updated to 14
junk.read_word : leaving task.
Evan Lavelle wrote:
Mark Schellhorn wrote:
Who's right? It kind of looks like the read_word() task fails to wait
for @(ci) before leaving???
They're both right - you've got a race between your fill calculation and
the inner read/display loop. for your code to work, the '@(ci)' timing
control must lead immediately to a new fill level calculation, but
there's no guarantee of this in Verilog. For Icarus, when the first
@(ci) is hit, the drain process is rescheduled; for subsequent @(ci)'s,
the fill level process is scheduled. This means that you go around the
inner loop 5 times in Icarus (but presumably 4 times in NC-Verilog).
After 5 iterations the FIFO has underflowed, so you carry on for ever
(since regs are unsigned).
Evan