宽度独立功能

时间:2014-03-27 19:02:56

标签: verilog system-verilog

是否可以编写一个可以自动检测输入数据宽度的函数?例如,考虑下面的奇偶校验功能:

function parity;
  input [31:0] data;
  parity = ^ data;
endfunction

调用parity(data)时,输入数据应限制为32位。

或者,可以编写一个宏,例如`PARITY(data),其中系统函数$bits可以检测数据的宽度并使宏与宽度无关。是否可以为功能提供相同的灵活性?

编辑:我需要我的代码可以合成。

4 个答案:

答案 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)

有趣的问题。据我所知,我不认为这是可能的。我也会远离宏(甚至更多的问题)。我可以提出一个可综合的解决方法:

  1. 当你的函数奇偶校验宽度小于你定义的宽度时,你的数据就像这样:0 assign my_parity_bits = parity({16'd0, my_data});希望,综合工具会忽略那些0,但你必须自己检查。
  2. 如果您想以方便的方式在大型数据总线上执行此类操作,则必须编写更多Verilog。例如。一个模块,它接受WIDTH参数和实际数据作为input向量。为此,我建议您编写一个通用模块,它完全符合您的函数parity。然后,编写一个parity wrapper的模块。在这个包装器中,我将对输入WIDTH参数执行数学运算,以确定输入数据所需的parity模块数,并在generate循环中实例化这些模块。
  3. 请记住,Verilog是一种硬件描述语言,因此存在这样的局限性。想一想在编写RTL时你的代码会合成什么。