Использование Verilog Case Statement с непрерывным назначением - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь выполнить непрерывный перевод в Verilog от некоторых значений серого кода до некоторых двоичных значений.То есть я пытаюсь принять значение серого кода, поступающее на одну шину, и постоянно преобразовывать его в двоичное значение на другой шине.Я пытаюсь сделать это в Verilog (не могу использовать SystemVerilog по другим причинам).

Я хотел сделать что-то вроде этого:

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

Где greycode_snap это wire.

Как вы уже догадались, это не синтезирует и выдает ошибку:

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

Я не хочу менять binary_snap на reg, так что следующий япопробовал это:

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;

Опять же, greycode_snap - это wire.

, который принимает компилятор, но в моем (ограниченном) опыте я верю, что это превратится в нечто грубое (в зависимости от используемого инструмента синтеза).Поэтому я попробовал небольшую оптимизацию:

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;

Опять же, greycode_snap - это wire.

Но этот код уже чрезвычайно запутанный, жесткий и не подлежит обслуживанию.

Как вы уже поняли, я не эксперт по Verilog (вероятно, упускаю что-то невероятно очевидное), но я хочу сделать это правильно.Как я могу сделать это чистым способом?В будущем также может быть важно, чтобы этот код расширялся.Если у вас есть какие-либо предложения, касающиеся быстрых схем подсчета / перевода серых кодов, они также будут оценены!Спасибо!

1 Ответ

0 голосов
/ 08 июня 2018

Ваш код работает, если вы измените объявление binary_snap с reg на wire.Но вы можете сохранить его как wire и использовать оператор case, если поместите его в функцию.

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