Verilog 2^n到n优先级编码器,带连续分配

Verilog 2^n到n优先级编码器,带连续分配,verilog,system-verilog,Verilog,System Verilog,n正在被参数化。我已经编写了这段代码,当我使用我自己编写的测试台运行时,它不起作用。如果向下滚动,可以查看所有内容 module p2_encoder #( parameter SIZE_OUT = 3, parameter SIZE_IN = 2 ** SIZE_OUT-1 ) ( input logic [SIZE_IN :0] encoder_in, output logic [SIZE_OUT:0] encoder_out, outp

n正在被参数化。我已经编写了这段代码,当我使用我自己编写的测试台运行时,它不起作用。如果向下滚动,可以查看所有内容

module p2_encoder
#(
    parameter SIZE_OUT = 3,
    parameter SIZE_IN  = 2 ** SIZE_OUT-1
)
(
    input logic [SIZE_IN :0]    encoder_in,
    output logic [SIZE_OUT:0]    encoder_out,
    output logic [7:0]    test_out
);

assign test_out = SIZE_OUT;
  
genvar i;
  
generate
  for(i = SIZE_IN; i >= 0; i = i - 1) begin
    assign encoder_out[i] = (encoder_in[i]) ? i : 0;
  end
endgenerate

endmodule
本例中,测试台如下所示,n=4,但它应在用户选择n的情况下工作:

module test;
parameter ENCODER_OUT  = 4;
parameter ENCODER_SIZE = (2 ** ENCODER_OUT) - 1;


logic clk = 0;
parameter   CLK_PERIOD = 10;    // clock period is 10 time units

////////////////////////

logic [ENCODER_SIZE:0] encoder_in, i, test_out;
logic [ENCODER_OUT:0] encoder_out;

// instantiation
p2_encoder encoder_1(.*);
// defining the parameter of this encoder
defparam encoder_1.SIZE_OUT = ENCODER_SIZE;

// test vectors
initial 

begin 

    $display("\n--------------------");
    // do an exhuastive test using ALL inputs
    // this for loop covers everything until
    // the last, highest input.
    // done this way to prevent infinite 
    // looping
    for(i=0; i <= 2*ENCODER_OUT; i = i + 1)
    begin
        encoder_in = i;
        #1
        $display("input =  %b, output = %d", encoder_in, encoder_out);
    end
    // the last, highest input value
    encoder_in = i;
        #1
    $display("input =  %b, output = %d", encoder_in, encoder_out);
   

    $display("\n --------------------\n");
        
 
    $stop;
end

endmodule
正确的结果应该是

# input = 0000000000000000, output = 0 
# input = 0000000000000001, output = 0 
# input = 0000000000000010, output = 1 
# input = 0000000000000011, output = 1 
# input = 0000000000000100, output = 2 
# input = 0000000000000101, output = 2 
# input = 0000000000000110, output = 2 
# input = 0000000000000111, output = 2 
# input = 0000000000001000, output = 3 
# input = 0000000000001001, output = 3

我知道错误在
assign encoder\u out[I]=(encoder\u in[I])行中?i:0
但我不知道如何更正它。

您无法使用生成块以算法方式进行更正。生成块在实际程序编译之前的预处理步骤中进行评估,因此不能基于动态变量进行调节

可以编写如下所示的表达式:

assign encoder_out = (encoder_in >> 1) == 1 ? 1 : (encoder_in >> 2) == 1 ? 2 (encoder_in >> 3) == 1 ? 3 : 0;  
如果可以看到它是递归的,那么需要手动展平递归级别,并且不能在生成块中使用循环的递归。您需要一个带有动态循环的动态函数

这里有一个建议。可以从assign语句调用函数。不确定这是否是可合成的,但它解释了always块的一种可能替代方法

  function logic [SIZE_OUT:0] encode(input  logic [SIZE_IN :0] encoder_in);
    for (int i = SIZE_IN-1; i >= 0; i--) begin
      if (encoder_in[i]) begin
        return i;
      end
    end
      return 0;
  endfunction
        
  assign encoder_out = encode(encoder_in);  

我还是SV的新手,没有意识到函数是一种选择。这段代码成功了!非常感谢你的帮助。
  function logic [SIZE_OUT:0] encode(input  logic [SIZE_IN :0] encoder_in);
    for (int i = SIZE_IN-1; i >= 0; i--) begin
      if (encoder_in[i]) begin
        return i;
      end
    end
      return 0;
  endfunction
        
  assign encoder_out = encode(encoder_in);