Width of Independent Functions

Is it possible to write a function that can automatically determine the width of the input data? For example, consider the parity function below:

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

When parity(data) is called, the input should be limited to 32 bits.

Alternatively, you can write a macro, such as `PARITY(data) , in which the system function $bits can determine the width of the data and make it independent of macros. Is it possible to have the same flexibility for functions?

Edit: I need my code to be synthesized.

+7
verilog system-verilog
source share
4 answers

You can create a parameterized function. See Section 13.8 in LRM . It seems that the function should be declared inside the class as follows:

 virtual class C #(parameter WIDTH=32); static function parity (input [WIDTH-1:0] data); parity=^data; endfunction endclass 

Then, when you call the function parameterized with the bits task:

 assign parity_bit = C#($bits(data))::parity(data); 

Working example on the EDA Playground .

+5
source share

It is possible to use unlimited arrays.

Unfortunately, SystemVerilog does not have decent support for unlimited arrays. It seems that LRM is equated with unlimited dynamics, which suggests that it is almost impossible to create something synthesized. VHDL has unlimited arrays that are supported by tools and incredibly useful, so it is unfortunate that SystemVerilog did not enable this feature properly.

Here is an example:

 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 

It works on Modelsim on EDAPlayground here: http://www.edaplayground.com/x/3tS

EDIT 1: updated the code - I just realized that you can call new[] on initialization and thus statically, so in theory synthesis tools can support this. It would be interesting to synthesize this and see ...

EDIT 2: I think that I will try to synthesize and not surprisingly, Quartus does not like:

Error (10170): Verilog HDL syntax error when testing .sv (10) next to the text "]"; waiting for the operand

Error (10170): Verilog HDL syntax error when testing .sv (18) next to the text "]"; waiting for the operand

Error (10112): Ignored "my_parity" design block when testing .sv (2) due to previous errors

+2
source share

You can use macros. A function can be declared as follows:

 `define PARITY(FUNC_name, WIDTH) \ function FUNC_name (input [WIDTH-1:0] data); \ begin \ FUNC_name = ^ data; \ end \ endfunction 

and you can call him:

 `PARITY(parity, 32); assign parity_bit = parity(data); 

This code is synthesized in xilinx, altera and synopsys tools

+2
source share

Interest Ask. According to my information, I do not think that this is possible. I would also stay away from macros (even more problems). I can offer a synthesized workaround:

  • When you call your parity function with a width smaller than your defined width, your data is 0 as follows: assign my_parity_bits = parity({16'd0, my_data}); Hopefully the synthesis tool will ignore these 0s, but you will have to test it yourself.
  • If you want to perform such an operation on large data buses in a convenient way, you will have to write a few more Verilog. For example. a module that takes the WIDTH parameter and the actual data as input vector. To do this, I would advise you to write a generic module that does exactly what your parity function does. Then write a module that will be parity wrapper . Inside this shell, I performed mathematical operations with the WIDTH input parameter to determine the number of parity modules needed for input and to create these modules in the generate loop.

Remember that Verilog is a hardware description language, so there are such limitations. Think about how your code will be synthesized when writing RTL.

0
source share

All Articles