为了能够在部分切片后缀中使用可变索引,您必须将 for 块包含在生成块中,如下所示:
gen var i;
generate
for (i=0;i<7;i=i+1) begin :gen_slices
always @* begin
... do whatever with in[7:i+1]
end
end
问题在于,将其应用到您的模块中,它的编写方式会导致其他错误。你重写的模块看起来像这样(警告:这也不起作用)
module enc (
input wire [7:0] in,
output reg [2:0] out // I believe you wanted this to be 3 bits width, not 4.
);
genvar i; //a generate block needs a genvar
generate
for (i=0;i<7;i=i+1) begin :gen_block
always @* begin
if (in[i]==1'b1 && in[7:i+1]=='b0) // now this IS allowed :)
out = i;
else
out = 3'b0;
end
end
endgenerate
endmodule
这将引发关于out 由多个来源驱动的综合错误。这意味着分配给out 的值同时来自多个来源,这是不允许的。
这是因为for 块展开为如下内容:
always @* begin
if (in[0]==1'b1 && in[7:1]=='b0)
out = 0;
else
out = 3'b0;
end
always @* begin
if (in[1]==1'b1 && in[7:2]=='b0)
out = 1;
else
out = 3'b0;
end
always @* begin
if (in[2]==1'b1 && in[7:3]=='b0)
out = 2;
else
out = 3'b0;
end
.... and so on...
所以现在您有多个组合块 (always @*) 尝试将值设置为 out。它们都将同时工作,并且无论if 块评估为true 还是false,它们都将尝试为out 赋予特定值。回想一下,每个 if 语句的条件相对于其他 if 条件是互斥的(即只有一个 if 必须评估为 true)。
因此,避免这种多源情况的一种快速而肮脏的方法(我相信有更优雅的方法可以解决这个问题)是如果if 块不打算为其分配值,则将其设为高阻抗.像这样的:
module enc (
input wire [7:0] in,
output reg [2:0] out // I believe you wanted this to be 3 bits width, not 4.
);
genvar i; //a generate block needs a genvar
generate
for (i=0;i<7;i=i+1) begin :gen_block
always @* begin
if (in[i]==1'b1 && in[7:i+1]=='b0) // now this IS allowed :)
out = i;
else
out = 3'bZZZ;
end
end
endgenerate
always @* begin
if (in[7]) // you missed the case in which in[7] is high
out = 3'd7;
else
out = 3'bZZZ;
end
endmodule
另一方面,如果您只需要一个优先级编码器,并且您的设计使用固定和小宽度的输入和输出,您可以这样编写编码器:
module enc (
input wire [7:0] in,
output reg [2:0] out
);
always @* begin
casex (in)
8'b1xxxxxxx : out = 3'd7;
8'b01xxxxxx : out = 3'd6;
8'b001xxxxx : out = 3'd5;
8'b0001xxxx : out = 3'd4;
8'b00001xxx : out = 3'd3;
8'b000001xx : out = 3'd2;
8'b0000001x : out = 3'd1;
8'b00000001 : out = 3'd0;
default : out = 3'd0;
endcase
end
endmodule
(尽管似乎有理由不在设计中使用casex。阅读@Tim 在另一个问题中发布的评论:How can I assign a "don't care" value to an output in a combinational module in Verilog)
总结:恐怕我没有满足您要求的防弹设计(如果我们考虑到 Tim 在他的评论中链接的论文的内容),但至少,您现在知道为什么 @987654344 @ 在部分切片后缀中是不允许的。
另一方面,您可以通过研究我提供的作为另一个 SO 问题答案的代码来完成一半的工作。在这种情况下,模块像优先级编码器一样工作,参数化并且没有casex 语句,只有输出不是二进制的,而是单热编码的。
How to parameterize a case statement with don't cares?