如何在Verilog上制作可合成的参数化编码器?
我尝试过这样做:如何在Verilog上制作可合成的参数化编码器?,verilog,system-verilog,fpga,hdl,encoder-decoder,Verilog,System Verilog,Fpga,Hdl,Encoder Decoder,我尝试过这样做: module encoder #( parameter WIDTH = 4 ) ( input wire [WIDTH-1: 0] in, output reg [$clog2(WIDTH)-1: 0] out ); genvar i; generate for (i = 0;i < WIDTH;i = i+1) begin :gen_block always @* begin
module encoder
#(
parameter WIDTH = 4
)
(
input wire [WIDTH-1: 0] in,
output reg [$clog2(WIDTH)-1: 0] out
);
genvar i;
generate
for (i = 0;i < WIDTH;i = i+1)
begin :gen_block
always @*
begin
if (in[i]==1'b1)
out = i;
end
end
endgenerate
endmodule
模块编码器
#(
参数宽度=4
)
(
输入线[WIDTH-1:0]英寸,
输出寄存器[$clog2(宽度)-1:0]输出
);
genvar i;
生成
对于(i=0;i
它在模拟中运行良好,但我不确定是否可以合成它。generate块将生成always块的多个副本,我猜在out的前一个值和out的更新值之间会有竞争条件
我假设这个代码不能被合成,对吗?如果是这样的话,我应该改变什么使它正确合成?是的,你在模拟中有一个竞争条件,它是不可合成的。不能让多个
始终
块并行地对同一变量进行赋值(当中的中设置了多个位时发生)。您需要的是常规的过程for循环,而不是generate for循环
module encoder
#(
parameter WIDTH = 4
)
(
input wire [WIDTH-1: 0] in,
output logic [$clog2(WIDTH)-1: 0] out
);
always_comb begin
out = 'x; // don't care if no 'in' bits set
for (int i = 0;i < WIDTH;i++)
if (in[i]==1'b1) begin
out = i;
break; // priority goes from LSB-to-MSB
end
end
endmodule
是的,你在模拟中有一个竞赛条件,它是不可合成的。不能让多个始终
块并行地对同一变量进行赋值(当
中的中设置了多个位时发生)。您需要的是常规的过程for循环,而不是generate for循环
module encoder
#(
parameter WIDTH = 4
)
(
input wire [WIDTH-1: 0] in,
output logic [$clog2(WIDTH)-1: 0] out
);
always_comb begin
out = 'x; // don't care if no 'in' bits set
for (int i = 0;i < WIDTH;i++)
if (in[i]==1'b1) begin
out = i;
break; // priority goes from LSB-to-MSB
end
end
endmodule
“break”可能不可合成。@Serge,它应该是可合成的。如果您的工具还不支持它,那么解决它非常简单。@dave_59您介意详细介绍一下解决方法吗?@dave_59我明白了,我认为“break”不可合成,这就是我没有使用它的原因。谢谢@AbhishekRevinipati我建议您首先尝试break
,如果它不起作用,您可以使用我刚才提供的解决方法。让我们知道什么是有效的。“break”可能不可合成。@Serge,它应该是可合成的。如果您的工具还不支持它,那么解决它非常简单。@dave_59您介意详细说明解决方法吗?@dave_59我知道,我假设“break”不可合成,这就是为什么我没有使用它的原因。谢谢@AbhishekRevinipati我建议您首先尝试break
,如果它不起作用,您可以使用我刚才提供的解决方法。让我们知道什么有效。我怀疑它在模拟中是否有效。你测试得不够。该代码仅为单个信号“out”生成锁存驱动程序的宽度数。由于这个原因,它是不可合成的。@Serge它确实在模拟中起作用。你能检查一下这张照片吗?所有输出都正确生成。链接:模型在模拟中导致未定义的行为。如果它对你有效,这意味着要么你没有检查足够数量的病例,要么你只是幸运。如果
中的仅设置了一个位,则它可能会正常工作。设置多个位可能会产生意想不到的结果。我怀疑它在模拟中是否有效。你测试得不够。该代码仅为单个信号“out”生成锁存驱动程序的宽度数。由于这个原因,它是不可合成的。@Serge它确实在模拟中起作用。你能检查一下这张照片吗?所有输出都正确生成。链接:模型在模拟中导致未定义的行为。如果它对你有效,这意味着要么你没有检查足够数量的病例,要么你只是幸运。如果
中的仅设置了一个位,则它可能会正常工作。设置多个位可能会产生意外结果。