是否可以编写一个可以自动检测输入数据宽度的函数?例如,考虑下面的奇偶校验功能:
function parity;
input [31:0] data;
parity = ^ data;
endfunction
调用parity(data)
时,输入数据应限制为32位。
或者,可以编写一个宏,例如`PARITY(data)
,其中系统函数$bits
可以检测数据的宽度并使宏与宽度无关。是否可以为功能提供相同的灵活性?
编辑:我需要我的代码可以合成。
答案 0 :(得分:5)
您可以创建参数化功能。见LRM中的第13.8节。看起来函数必须在这样的类中声明:
virtual class C #(parameter WIDTH=32);
static function parity (input [WIDTH-1:0] data);
parity=^data;
endfunction
endclass
然后当您使用bits
任务调用函数参数化时:
assign parity_bit = C#($bits(data))::parity(data);
EDA Playground上的工作示例。
答案 1 :(得分:2)
可以使用无界数组。
不幸的是,SystemVerilog对无界数组没有很好的支持。 LRM似乎等同于无限的动态,这表明创造可合成的东西几乎是不可能的。 VHDL具有无限数组,这些数组由工具支持并且非常有用,因此很遗憾SystemVerilog没有正确地包含此功能。
以下是一个例子:
function automatic logic parity(input logic data[]);
logic p = 0;
for (int i=0; i<data.size(); i++)
p ^= data[i];
return p;
//return = ^data; <--- not allowd on unpacked arrays?
endfunction
logic [7:0] data_in;
logic result;
logic data_in_unpacked [] = new[$bits(data_in)];
always_comb begin
// Convert to unpacked array (better way to do this?)
for (int i=0; i<$bits(data_in); i++)
data_in_unpacked[i] = data_in[i];
result = parity(data_in_unpacked);
end
这是在EDAPlayground上的Modelsim上运行的:http://www.edaplayground.com/x/3tS
编辑1:更新了代码 - 我刚刚意识到可以在初始化时调用new[]
,因此静态调用,因此在理论上,综合工具可以支持这一点。合成这个并看到......会很有趣。
编辑2:我以为我会尝试合成并且毫不奇怪Quartus不喜欢这样:
错误(10170):test.sv(10)附近文本“]”的Verilog HDL语法错误;期待操作数
错误(10170):test.sv(18)附近文本“]”的Verilog HDL语法错误;期待操作数
错误(10112):由于先前的错误,在testing.sv(2)处忽略了设计单元“my_parity”
答案 2 :(得分:2)
您可以使用宏。该函数可以声明为:
`define PARITY(FUNC_name, WIDTH) \
function FUNC_name (input [WIDTH-1:0] data); \
begin \
FUNC_name = ^ data; \
end \
endfunction
你可以用:
来调用它`PARITY(parity, 32);
assign parity_bit = parity(data);
此代码可在xilinx,altera和synopsys工具中进行综合
答案 3 :(得分:0)
有趣的问题。据我所知,我不认为这是可能的。我也会远离宏(甚至更多的问题)。我可以提出一个可综合的解决方法:
assign my_parity_bits = parity({16'd0, my_data});
希望,综合工具会忽略那些0,但你必须自己检查。WIDTH
参数和实际数据作为input
向量。为此,我建议您编写一个通用模块,它完全符合您的函数parity
。然后,编写一个parity wrapper
的模块。在这个包装器中,我将对输入WIDTH
参数执行数学运算,以确定输入数据所需的parity
模块数,并在generate
循环中实例化这些模块。请记住,Verilog是一种硬件描述语言,因此存在这样的局限性。想一想在编写RTL时你的代码会合成什么。