考虑以下我想要参数化的函数。我创建了一些参数来设置输入的宽度和输出的相应宽度参数。
parameter SELECT_WIDTH = 6;
parameter PRIENC_WIDTH = $clog2(SELECT_WIDTH+1);
function [PRIENC_WIDTH-1:0] prienc6;
input [SELECT_WIDTH-1:0] select;
reg [PRIENC_WIDTH-1:0] out;
begin
casex(select)
6'b000001: out = 3'b101; // Is it possible to parameterize the case statement with generate
6'b00001x: out = 3'b100;
6'b0001xx: out = 3'b011;
6'b001xxx: out = 3'b010;
6'b01xxxx: out = 3'b001;
6'b1xxxxx: out = 3'b000;
endcase
prienc6 = out ;
end
end function
显然,casex陈述案例不会按照书面形式进行扩展 所以我尝试了以下,没有正确编译,表明发现了意外的生成。
function [PRIENC_WIDTH-1:0] prienc_n;
input [SELECT_WIDTH-1:0] select;
reg [PRIENC_WIDTH-1:0] out;
begin
genvar gv_j;
casex(select)
for (gv_j = 0; gv_j < SELECT_WIDTH; gv_j = gv_j + 1)
begin
{{(SELECT_WIDTH-1)-gv_j{1'b0}},1'b1,{gv_j{1'bx}}} : out = (SELECT_WIDTH-1)-gv_j;
end
endcase
prienc_n = out ;
end
end function
我已经能够使用参数化if获得正确的行为,但似乎我应该能够参数化该casex语句。有关如何做到这一点的任何想法?我想接下来我将尝试将casex包装在generate循环中并创建6个casex语句,每个语句只有一个状态。
答案 0 :(得分:1)
由于您使用SystemVerilog标记了此问题,因此我将向您展示如何在没有case
语句或generate
function logic [PRIENC_WIDTH-1:0] prienc_n(
input [SELECT_WIDTH-1:0] select);
for (int j = 0; j < SELECT_WIDTH; j++) begin
if (select[SELECT_WIDTH-1]) return j;
select <<=1;
end
// if no 1 found
return ('x); // you did not specify this case
endfunction
如果您需要留在Verilog,则需要一个中间变量
function reg [PRIENC_WIDTH-1:0] prienc_n(
input [SELECT_WIDTH-1:0] select);
reg [PRIENC_WIDTH-1:0] out;
integer j;
begin
out = {PRIENC_WIDTH{1'bx}}; // what should be returned if no 1 found
for (j = 0; j < SELECT_WIDTH; j = j + 1) begin
if (select[SELECT_WIDTH-1]) begin
out = j;
select = 0;
end
select = select << 1;
end
prienc_n = out;
end
endfunction