[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: gEDA-user: HELP with Icarus Verilog, 0.7!
Hi,
Samuel A. Falvo II wrote:
On Tuesday 06 April 2004 11:30 am, Mike Jarabek wrote:
This situation usually indicates that there is contention on the
bus. If you have other structures like the three state assignment, in
I checked and I checked, and I checked again. According to the source
code, as I understand it, nothing should have been driving the bus while
writing to the registers (except the test bench, that is). There is no
reason that I can see for the registers to be loaded with uncertain
values.
Still, all the same, I'd like to know a known-good technique for modeling
three-state buses with Icarus. I've yet to find online or other
documentation relating to this. My introductory Verilog book has
constructs which are not supported by Icarus, so I cannot use those.
What you have done should work. Icarus has come a long way since 0.7, you
may wish to upgrade to a newer snapshot, some of the other constructs will
probably be supported now.
<SNIP>
I re-read this four times, and I can't make out what you are saying.
What do you mean by "same destination register?" And why would it
matter if they appeared in multiple always-blocks? I have one always
block for the reset, and one for the register writes. Is this what
you're referring to, possible contention of writing to the registers
while reseting?
always@(posedge CLK or negedge RST)
if(RST == 1'b0) begin
rxmask <= 16'h0000; /* Put your reset value here */
end
else begin
if(_RXMASKL_E == 0 )
rxmask[7:0] <= DB[7:0] ; /* Note that you can do a
part assign to a multi-bit register */
if( _RXMASKH_E == 0 )
rxmask[15:8] <= DB[7:0];
end
Why can't I write this instead:
always @(posedge CLK_I) begin
if( RXMASKL_E ) // changed to active high signal for convenience
rxmask[7:0] <= DAT_I[7:0];
if( RXMASKH_E )
rxmask[15:8] <= DAT_I[7:0];
end
always @(RST) // level sensitive, asynchronous reset
if( ~_RST )
rxmask <= 16'h0040;
end
This will work, however, the Verilog simulator is event based and free to
schedule the second block before the first. Should the Reset line change
values at the same time as the clock line goes and one of your enables is
true the value that rxmask takes on will be simulator dependant. For example,
Icarus Verilog will schedule the blocks from bottom to top, the second one
will fire first. Verilog XL schedules the top block first.
I figure that if the various _E signals are ANDed with _RST, then no race
condition can ever occur, as then the _E signals would be conveniently
ignored for as long as _RST is asserted.
Not quite true, the always block is only evaluated when something on the
sensitivity list changes. In this case, that only happens when RST changes.
When your clock changes the other always block will fire, depending on the
state of the _E signals, your register will be overwritten.
<soapbox>
This is somewhat bad form. Should your block get re-used the next user may
not be aware of the timing requirements between the signals. This could
lead to very difficult to trace bugs.
What I meant by the same destination register is that rxmask appears on the
left hand side of an assignement in more than one always block. Using this
style of coding can lead to race conditions in your code, avoid it if possible.
It also makes the synthesis tool's job much harder as it has to figure out
which condition should have priority when the gates are generated. Having
all the assignments into a register in one always block makes the final value
of the register absolutely clear to both the designer and the synthesis tool.
</soapbox>
Thanks for taking the time to reply. It's greatly appreciated. I'll
admit to being a total newbie at this, as this is my first foray into
programmable logic, ever. I'm still a discrete component TTL kind of
person. :)
--
Samuel A. Falvo II
--
--------------------------------------------------
Mike Jarabek
FPGA/ASIC Designer
http://www.istop.com/~mjarabek
--------------------------------------------------