我试图在Verilog中从一些greycode值到一些二进制值执行连续转换。也就是说,我试图在一条总线上输入一个greycode值,并不断将其转换为另一条总线上的二进制值。我试图在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专家(可能遗漏了一些非常明显的东西),但我想这样做。我怎么能以干净的方式做到这一点?将来,此代码可扩展也很重要。如果您对快速greycode计数/翻译计划有任何建议,那么也将不胜感激!谢谢!
答案 0 :(得分:2)
如果您将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