我尝试过这样做:
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
它在模拟中运行良好,但我不确定这是否可以合成。生成块将生成始终块的多个副本,我猜在out的先前值和out更新值之间将存在竞争条件。
我认为这个代码不能被合成是正确的吗?如果是,我该改变什么才能使它正确合成?
是的,您在模拟中确实有一个竞赛条件,它是不可合成的。不能让多个always
块并行分配给同一变量(当in
中设置了多个位时会发生这种情况(。您需要一个常规的过程for循环,而不是生成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
的工具
always_comb begin
bit Break;
Break = 0;
out = 'x; // don't care if no 'in' bits set
for (int i = 0;i < WIDTH;i++)
if (in[i]==1'b1 && !Break) begin
out = i;
Break = 1;
end
end
您可以通过初始化i=N-1 来避免中断
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 = N-1 ;i >=0;i--)
if (in[i]) begin
out = i;
end
end
endmodule