C
Charles Gardiner
Guest
Hi,
first a brief description of what I am trying to do in verilog (I have to convert
one of my VHDL solutions for a customer who only has a verilgo tool suite):
In my logic I have a reset counter which has the function of extending the reset
pulse for sixteen clocks after the reset is deactivated. Since I like to reset
everything to zero, my solution is that the counter counts up. On reaching the
maximum value the reset should be deactivated. Since I have this construct in
different places, and different counters might have different widths, I don't want
to always have to check that my vector width for counter max comparison is
correct. So, to stop the counter, I compare the inverted counter with zero. My
verilog code for the extended reset is:
reg s_hot_reset;
reg [3:0] s_hot_reset_count;
214 always @(posedge i_clk_125 or negedge i_rst_n) begin
215 if (i_rst_n == 1'b0) begin
. . .
220 s_hot_reset <= 1'b0;
221 s_hot_reset_count <= 'b0;
222 end
223 else begin
. . .
228 s_hot_reset <= (~s_hot_reset_count == 'b0) ? 1'b0 : 1'b1;
229
230 if ((s_dl_up_d2_prev == 1'b1) && (s_dl_up_d2 == 1'b0))
231 // A falling dl_up edge activates hot reset
232 s_hot_reset_count <= 'b0;
233 else
234 if (~s_hot_reset_count != 'b0)
235 s_hot_reset_count <= s_hot_reset_count + 1;
236 end
237 end
Now the fun starts:
My own simulator works the way I expect this to work, i.e. for instance in line
228, s_hot_reset is set to 1'b0 when the counter has reached it's max. value
(inverted counter compared with a vector having all bits set to '0')
On my customer's simulator, line 228 never gets set to 1'b0 and line 234 never
goes true. I am currently having a heated (email) discussion with the support for
my customer's simulator. He has been chucking quotes from LRM-2005 section 2.5 at
me explaining why he thinks he is doing it correctly. My objection that the unary
operator '~' must be evaluated completely first (i.e. before comparison and the
operand expansion induced by the '==' operator) is falling on deaf ears.
Essentially he is explaining to me that for instance in line 228, when the counter
has reached 4'b1111, it is forcebly extended to 32'h0000000F (due to the operator
expansion rules in 5.4) then inverted (to 32'hFFFFFFF0) and then compared to
32'h0, which of course indeed is never true.
So may I ask what the experts here think? Should operator expansion (induced by
the '==' or '!=' operator) have precedence over the unary '~' operator or not. If
so, what exactly is then the meaning of operator precedence in Verilog. Why for
instance should
if (~s_hot_reset_count != 'b0)
simulate differently to
assign s_hot_reset_count_bar = ~s_hot_reset_count;
if (s_hot_reset_count_bar != 'b0)
(This is so much easier in VHDL. Comparing two unequal length vectors is always
false. Full stop. To match the lengths you have nice helpers like 'length, resize
etc. etc. Yes, it might be verbose but tool manufacturers from A to Z (and
therefore users as well) know there is only one way to do it correctly.)
first a brief description of what I am trying to do in verilog (I have to convert
one of my VHDL solutions for a customer who only has a verilgo tool suite):
In my logic I have a reset counter which has the function of extending the reset
pulse for sixteen clocks after the reset is deactivated. Since I like to reset
everything to zero, my solution is that the counter counts up. On reaching the
maximum value the reset should be deactivated. Since I have this construct in
different places, and different counters might have different widths, I don't want
to always have to check that my vector width for counter max comparison is
correct. So, to stop the counter, I compare the inverted counter with zero. My
verilog code for the extended reset is:
reg s_hot_reset;
reg [3:0] s_hot_reset_count;
214 always @(posedge i_clk_125 or negedge i_rst_n) begin
215 if (i_rst_n == 1'b0) begin
. . .
220 s_hot_reset <= 1'b0;
221 s_hot_reset_count <= 'b0;
222 end
223 else begin
. . .
228 s_hot_reset <= (~s_hot_reset_count == 'b0) ? 1'b0 : 1'b1;
229
230 if ((s_dl_up_d2_prev == 1'b1) && (s_dl_up_d2 == 1'b0))
231 // A falling dl_up edge activates hot reset
232 s_hot_reset_count <= 'b0;
233 else
234 if (~s_hot_reset_count != 'b0)
235 s_hot_reset_count <= s_hot_reset_count + 1;
236 end
237 end
Now the fun starts:
My own simulator works the way I expect this to work, i.e. for instance in line
228, s_hot_reset is set to 1'b0 when the counter has reached it's max. value
(inverted counter compared with a vector having all bits set to '0')
On my customer's simulator, line 228 never gets set to 1'b0 and line 234 never
goes true. I am currently having a heated (email) discussion with the support for
my customer's simulator. He has been chucking quotes from LRM-2005 section 2.5 at
me explaining why he thinks he is doing it correctly. My objection that the unary
operator '~' must be evaluated completely first (i.e. before comparison and the
operand expansion induced by the '==' operator) is falling on deaf ears.
Essentially he is explaining to me that for instance in line 228, when the counter
has reached 4'b1111, it is forcebly extended to 32'h0000000F (due to the operator
expansion rules in 5.4) then inverted (to 32'hFFFFFFF0) and then compared to
32'h0, which of course indeed is never true.
So may I ask what the experts here think? Should operator expansion (induced by
the '==' or '!=' operator) have precedence over the unary '~' operator or not. If
so, what exactly is then the meaning of operator precedence in Verilog. Why for
instance should
if (~s_hot_reset_count != 'b0)
simulate differently to
assign s_hot_reset_count_bar = ~s_hot_reset_count;
if (s_hot_reset_count_bar != 'b0)
(This is so much easier in VHDL. Comparing two unequal length vectors is always
false. Full stop. To match the lengths you have nice helpers like 'length, resize
etc. etc. Yes, it might be verbose but tool manufacturers from A to Z (and
therefore users as well) know there is only one way to do it correctly.)