Samuel A. Falvo II wrote:
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.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, inI 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.
<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?
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.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]; endWhy 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
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.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.
<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
--------------------------------------------------
