[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gEDA: Icarus Verilog: Is it bug??



EATON,JOHN (HP-Vancouver,ex1) wrote:
> Cadence verilogXL gives Error!  Identifier (x) not declared.
> 
> 
> It's not a bug. "a" and "b" are unknown so the "if" will fail and
> the "else" will resolve to a 0. I'ts easy to write code that resolves
> x's to a known value. It is also dangerous. Thats why we always check
> our designs by runing the same sims on the compiled gates. 

I employ an "if-free" verilog style when writing verilog intended for 
synthesis.  The problem is that if statements don't propagate the x 
state.  Thus, uninitialized state or any other type of x might not show 
up until you do gate sims, which are often very late in the design flow. 
  For FPGA work, that might be OK, but if you've already done P&R on a 
large block, doing the ECO and verifying the change can be costly.

My code uses a lot of the '?' operator, case, and casez.

     case (reset)
        1'b1:
            begin
            this <= #1 0;
            foo  <= #1 0;
            end
        1'b0:
            begin
            this <= #1 that;
            foo  <= #1 bar;
            end
        default:
            begin
            this <= #1 1'bx;
            foo  <= #1 1'bx;
            end
     endcase

or for this simple case

     this <= #1 (reset) ? 0 : that;
     foo  <= #1 (reset) ? 0 : bar;

if reset is 'bx, then this and foo will both get set to 'x.

A lot of people hate the style, although I've gotten used to it without 
much trouble.  On nice thing is that you can often handle large nests of 
if statements with a much more regular casez statement AND also 
propagate x's.

Oh, one more trick that can be useful.  Say you have an address decoder. 
  For a few specific cases, you want to perform some action, for all 
others you don't want to perform any actions, but if any of the address 
bits are x (or z) you want to propagate the unknowns.  Here's one way. 
Say that foo is a four bit wide control word.

     case (addr)
         `SOMEADDR1: foo = `ACTION1;
         `SOMEADDR2: foo = `ACTION2;
         `SOMEADDR3: foo = `ACTION3;
            default: foo = `DEFAULT_ACTION
                         ^ {4{ |(addr & ~addr) }};
     endcase

(addr & ~addr) should produce 16'b0 for any real value, but if any bit 
is X or Z, that bit position will become 'bx.  The OR reduction 
collapses all of the zeros to a 0 in the legal case, and x if any of the 
bits are X.

It seems like a lot of work, but once you get in the habit, it isn't any 
trouble.

If this didn't have to be synthesized, it can be stated much more directly:
             default: foo = (^addr === 1'bx) ? 4'bx : `DEFAULT_ACTION;

but synthesis would complain about that.