如何在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它确实在模拟中起作用。你能检查一下这张照片吗?所有输出都正确生成。链接:模型在模拟中导致未定义的行为。如果它对你有效,这意味着要么你没有检查足够数量的病例,要么你只是幸运。如果
中的
仅设置了一个位,则它可能会正常工作。设置多个位可能会产生意外结果。