I have a requirement to make a verilog module that takes a Gray code integer i and returns the Gray coded integer i-1 using combinatorial logic only. When I look up examples of Gray decoding, for instance, a lot of them use sequential logic. I also need it to work on integers of size >20 bits.
The solution I came up with is to write a Python script that generates a verilog file for the appropriate bit width. I first tried using a big case statement in an always @(*)
block as in this 3-bit example:
module gray_decrement(input [2:0] x, output [2:0] xm1);
always @(*) begin
case( x )
3'b001: xm1 = 3'b000;
3'b011: xm1 = 3'b001;
3'b010: xm1 = 3'b011;
3'b110: xm1 = 3'b010;
3'b111: xm1 = 3'b110;
3'b101: xm1 = 3'b111;
3'b100: xm1 = 3'b101;
default: xm1 = 0;
endcase
end
endmodule
That doesn't compile with an Error (10137): Verilog HDL Procedural Assignment error at graycode.v(1051): object "xm1" on left-hand side of assignment must have a variable data type.
If I make xm1
an output reg
it doesn't synthesize how I need it to. So I went back and redid it as a really big assign
statement using the ?
operator as in this 3-bit example:
module gray_decrement(input [2:0] x, output [2:0] xm1);
assign xm1 = x == 3'b001 ? 3'b000 :
x == 3'b011 ? 3'b001 :
x == 3'b010 ? 3'b011 :
x == 3'b110 ? 3'b010 :
x == 3'b111 ? 3'b110 :
x == 3'b101 ? 3'b111 :
x == 3'b100 ? 3'b101 :
3'd0;
endmodule
This works great and synthesizes properly, but after 10 bits (i.e. 1024 elements in my nested ?
operation), Quartus errors out with parser stack overflow error.
So the question is what is the best way to extend my assign
statement so that it could have ~2^20 lines in it? Is there some generate magic that I could use since the arithmetic is dirt simple? Or will I have to do some of the logic simplification in my Python preprocessor?
xml
must be a variable (reg
,integer
,etc.), not a net (wire
). Outputs default to beingwire
unless otherwise specified. \$\endgroup\$