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

Re: gEDA-user: HELP with Icarus Verilog, 0.7!



Hi,

When $display prints `X' that usually means that one or more bits in the value have a valid level, while others have contention. If you print the value in binary, you will probably find that some bits are `1' or `0' while others have `x'.

This situation usually indicates that there is contention on the bus. If you have other structures like the three state assignment, in other modules, dump a waveform and check to see that none of the other enables are accidentally `on'. There is probably another driver on the bus.

<Design_practice>
If this is meant to be synthesisable code, you might want to re-code your block to be synchronous. i.e. add a system clock and use the positive edge along with strobe signals to enable synchronous flip-flops, like this: (Your code had a race condition on writing the register. If both _RXMASKx_E signals changed state during the same time step, the results written back into the register will be simulator dependant. This is because the same destination register appears in more than one always block and Verilog does not guarentee which one will be executed 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];

end
</Design_practice>

Mike Jarabek
Samuel A. Falvo II wrote:

Greetings.

This is my first time using Verilog, and unfortunately, I'm not having much luck trying to get several modules to talk to each other via a tri-stated bus interface. If anyone can offer some tips or tricks that is portable to other Verilog environments, that'd be great.

I can't disclose my modules here, due to their size. But maybe I can host the heads of each module. Here is the head of the module giving me problems:

module Kestrel_UART_RX( RXD, RBF, _RES, RXC, DB, _RXDATAL_E, _RXDATAH_E, _RXMASKL_E, _RXMASKH_E );
input RXD, _RES, RXC, _RXDATAL_E, _RXDATAH_E, _RXMASKL_E, _RXMASKH_E;
output RBF;
inout [7:0] DB; // <-- I need this to be a real tri-state bus

reg RBF;
reg [7:0] DBout;
reg [15:0] shiftRegister;
reg inFrame;
wire rxc_div_8;

reg [15:0] rxdata;
reg [15:0] rxmask;
wire [15:0] startDetect;
wire rd;

assign startDetect = rxmask & shiftRegister;
assign rd = ( _RXDATAL_E === 0 ) || ( _RXDATAH_E === 0 );
assign DB = rd? DBout : 8'bzzzzzzzz; // <-- technique seems to work in TB, but not here. Why?

Whenever a write the the RXMASK* registers is performed, as evidenced by _RXMASK*_E signals going low, the value loaded into the registers are always 16'hxxxx or 16'hxxXX or some such (what is the difference between x and X in this context?), as reported by $display. Here is the assignment code for those registers (yes, the value of DB is "valid" in the testbench before asserting the appropriate register enables):

// Writable UART registers.

always @(_RXMASKL_E) begin
if( _RXMASKL_E === 0 ) begin
rxmask = { rxmask[15:8], DB[7:0] };
end
end

always @(_RXMASKH_E) begin
if( _RXMASKH_E === 0 ) begin
rxmask = { DB[7:0], rxmask[7:0] };
end
end

Any ideas why rxmask is being assigned undefined values?

Thanks for your help. It's greatly appreciated.

--
Samuel A. Falvo II



--
--------------------------------------------------
                             Mike Jarabek
                               FPGA/ASIC Designer
http://www.istop.com/~mjarabek
--------------------------------------------------