Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Verilog Case Statement With Continuous Assignment

I'm trying to perform continuous translation in Verilog from some greycode values to some binary values. That is, I'm trying to take a greycode value coming in on one bus and continually translate it to a binary value on another bus. I'm trying to do this in Verilog (cannot use SystemVerilog for other reasons).

I wanted to do something like this:

wire [DATA_SIZE - 1:0] binary_snap;
always @(greycode_snap) begin
case (greycode_snap)
    8'b00000000 : binary_snap = 0;
    8'b00000001 : binary_snap = 1;
    8'b00000011 : binary_snap = 2;
    8'b00000111 : binary_snap = 3;
    8'b00001111 : binary_snap = 4;
    8'b00011111 : binary_snap = 5;
    8'b00111111 : binary_snap = 6;
    8'b01111111 : binary_snap = 7;
    8'b11111111 : binary_snap = 8;
    8'b11111110 : binary_snap = 9;
    8'b11111100 : binary_snap = 10;
    8'b11111000 : binary_snap = 11;
    8'b11110000 : binary_snap = 12;
    8'b11100000 : binary_snap = 13;
    8'b11000000 : binary_snap = 14;
    8'b10000000 : binary_snap = 15;
    default     : binary_snap = 0;
endcase
end

Where greycode_snap is a wire.

As you may have guessed, this doesn't synthesize and produces the error:

Procedural assignment to a non-register binary_snap is not permitted, left-hand side should be reg/integer/time/genvar

I don't want to change binary_snap to a reg so next I tried this:

wire [DATA_SIZE - 1:0] binary_snap;
assign binary_snap = (greycode_snap == 8'b00000001) ? 1 :
                     (greycode_snap == 8'b00000011) ? 2 :
                     (greycode_snap == 8'b00000111) ? 3 :
                     (greycode_snap == 8'b00001111) ? 4 :
                     (greycode_snap == 8'b00011111) ? 5 :
                     (greycode_snap == 8'b00111111) ? 6 :
                     (greycode_snap == 8'b01111111) ? 7 :
                     (greycode_snap == 8'b11111111) ? 8 :
                     (greycode_snap == 8'b11111110) ? 9 :
                     (greycode_snap == 8'b11111100) ? 10 :
                     (greycode_snap == 8'b11111000) ? 11 :
                     (greycode_snap == 8'b11110000) ? 12 :
                     (greycode_snap == 8'b11100000) ? 13 :
                     (greycode_snap == 8'b11000000) ? 14 :
                     (greycode_snap == 8'b10000000) ? 15 : 0;

Again, greycode_snap is a wire.

Which the compiler accepts, but in my (limited) experience I believe this will synthesize into something gross (depending on the synthesis tool used). So I tried a little optimization:

wire [DATA_SIZE - 1:0] binary_snap;
assign binary_snap = (greycode_snap[0] == 0) ?
                            (greycode_snap[4] == 0) ?
                                (greycode_snap[2] == 0) ?
                                    (greycode_snap[1] == 0) ? 1 : 2
                                : //else
                                    (greycode_snap[3] == 0) ? 3 : 4
                            : // else
                                (greycode_snap[6] == 0) ?
                                    (greycode_snap[5] == 0) ? 5 : 6
                                : // else
                                    (greycode_snap[7] == 0) ? 7 : 8
                        : // else
                            (greycode_snap[4] == 1) ?
                                (greycode_snap[2] == 1) ?
                                    (greycode_snap[1] == 1) ? 9 : 10
                                : //else
                                    (greycode_snap[3] == 1) ? 11 : 12
                            : // else
                                (greycode_snap[6] == 1) ?
                                    (greycode_snap[5] == 1) ? 13 : 14
                                : // else
                                    (greycode_snap[7] == 1) ? 15 : 0;

Again, greycode_snap is a wire.

But this code is already extremely convoluted, rigid, and not maintainable.

How can I do this in a clean way? It may also be important in the future that this code is expandable. If you have any suggestions related to fast greycode counting/translation schemes, those would also be appreciated.

like image 439
Mindigo Avatar asked Nov 14 '25 23:11

Mindigo


1 Answers

Your code works if you change the declaration of binary_snap from wire to reg. But you can keep it as a wire and use your case statement if you put it into a function.

wire [DATA_SIZE - 1:0] binary_snap;
assign binary_snap = f(greycode);
function [DATA_SIZE - 1:0] f(input [7:0] reg code);
case (code)
    8'b00000000 : f = 0;
    8'b00000001 : f = 1;
    8'b00000011 : f = 2;
    8'b00000111 : f = 3;
    8'b00001111 : f = 4;
    8'b00011111 : f = 5;
    8'b00111111 : f = 6;
    8'b01111111 : f = 7;
    8'b11111111 : f = 8;
    8'b11111110 : f = 9;
    8'b11111100 : f = 10;
    8'b11111000 : f = 11;
    8'b11110000 : f = 12;
    8'b11100000 : f = 13;
    8'b11000000 : f = 14;
    8'b10000000 : f = 15;
    default     : f = 0;
endcase
endfunction
like image 92
dave_59 Avatar answered Nov 17 '25 21:11

dave_59