2^n 到 n 优先级编码器,带连续分配
2^n to n priority encoder w/ continuous assignments
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
testbench 结果给出了错误的结果,如下所示。我怎样才能更正我的代码以获得正确的结果?
# input = 0000000000000000, output = 0
# input = 0000000000000001, output = 0
# input = 0000000000000010, output = 2
# input = 0000000000000011, output = 2
# input = 0000000000000100, output = 0
# input = 0000000000000101, output = 0
# input = 0000000000000110, output = 2
# input = 0000000000000111, output = 2
# input = 0000000000001000, output = 8
# input = 0000000000001001, output = 8
正确的结果应该类似于...
# 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_out[i] = (encoder_in[i]) ? i : 0
行,但我不知道如何更正它。
您不能使用生成块以算法方式完成此操作。生成块在实际程序编译之前的 pre-processing 步进行评估,因此不能基于动态变量进行调节。
您可以编写如下表达式:
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);
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
testbench 结果给出了错误的结果,如下所示。我怎样才能更正我的代码以获得正确的结果?
# input = 0000000000000000, output = 0
# input = 0000000000000001, output = 0
# input = 0000000000000010, output = 2
# input = 0000000000000011, output = 2
# input = 0000000000000100, output = 0
# input = 0000000000000101, output = 0
# input = 0000000000000110, output = 2
# input = 0000000000000111, output = 2
# input = 0000000000001000, output = 8
# input = 0000000000001001, output = 8
正确的结果应该类似于...
# 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_out[i] = (encoder_in[i]) ? i : 0
行,但我不知道如何更正它。
您不能使用生成块以算法方式完成此操作。生成块在实际程序编译之前的 pre-processing 步进行评估,因此不能基于动态变量进行调节。
您可以编写如下表达式:
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);