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
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?