首页 > 解决方案 > 如何在 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 块将生成always 块的多个副本,我猜在out的先前值和out的更新值之间会有竞争条件。

我是否正确假设无法合成此代码?如果是这样,我该怎么做才能使其正确合成?

标签: verilogsystem-verilogfpgahdlencoder-decoder

解决方案


是的,您在模拟中确实存在竞争条件,并且它是不可合成的。您不能让多个always块并行地对同一个变量进行赋值(当设置了多个位时会发生这种情况in)。您需要一个常规的过程 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工具

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

推荐阅读