我如何在 Verilog 上制作可综合的参数化编码器?

How do i make a synthesizable parameterized encoder on Verilog?

我试过这样做:

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

在仿真中效果很好,但不知道能不能合成。 generate block 将生成 always block 的多个副本,我猜 [=] 的前一个值之间会有竞争条件17=]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