Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Best way to write VHDL-style functions in SystemVerilog

Status
Not open for further replies.

vGoodtimes

Advanced Member level 4
Joined
Feb 16, 2015
Messages
1,089
Helped
307
Reputation
614
Reaction score
303
Trophy points
83
Activity points
8,730
I was brushing up on SystemVerilog and decided to try porting some of my old VHDL packages, just to see how different they would be. But I quickly hit an interesting (to me) problem with functions. Here is an example of what I mean:
Code:
-- I didn't double check the logic in the function, doing this from memory.
function makeMatrix(taps : std_logic_vector; N : natural) return std_logic_vector is
  constant R : natural := taps'length;
  variable state : std_logic_vector(R-1 downto 0);
  variable op : std_logic_vector(R*N-1 downto 0);
begin
  state := taps;
  for i in 0 to R-1 loop
    op(N*i+R-1 downto N*i) := state;
    if state(0) = '1' then
      state := ('0' & state(C-1 downto 1)) xor taps;
    else
      state := '0' & state(C-1 downto 1);
    end if;
  end loop;
  return op;
end function;

I was wondering if SystemVerilog had some equivalent structure. Mainly that the size of inputs/outputs/intermediates could be something that was parametized in some way.

It seems that, if the functions were declared inside a module, things might be ok as long as the function isn't called with more than one type of args. But can this be relaxed in a nice way or not?

For example, you can do whatever you want if you use the pre-processor, or have a code generator tool. But that isn't my preferred solution.

It also seems that a module would work in some cases, but removes the function syntax.

Interfaces as arguements might solve the issues with the input, maybe. I'm still looking into what the tools actually allow. I'm not even certain you can construct a new interface as an intermediate term at the moment.

Having the function be a member function of an interface might work as well.



Any comments/experience on pro's/con's of these approaches, or on others you might know.

(In this example, a large vector is created as a constant. This will later be used in another function. The tools can optimize the result into optimal logic fairly easily. It isn't an insane software approach or anything like that, just a way to generate the constants inside the tool.)
 

You can always parameterize the function and stick it where you like. You can use the $size system function to get the size of any input.

No access to any tools atm, but is it the unknown length of the input slv you're worried about?
 

I'm concerned about many things -- both the inputs and output are parameterized. I couldn't find any simple syntax for declaring the output as being size [N*R-1:0], or the input as [N-1:0] where N,R were defined specifically for the function. It gets easier if the parameters of the function come directly from parameters/constants in the module. This is probably enough for most cases, but it does seem like an annoying restriction.
 

An update:

I managed to find out how this is possible while trying to find a version of the SystemVerilog LRM that I could just download without having to send it to an email address. Instead, I found a powerpoint showing the new 2012 features. This showed me a link to https://bradpierce.wordpress.com/20...parameterized-functions-with-let-expressions/ .

Basically, you can define a virtual class that has parameters, and has a static member function. Then you use "let" to create shorthand for defining the parameters based on the arguments.

Code:
// The ugly syntax version seems ok.
virtual class makeMatrixVc;
  parameter N = 2;
  parameter R = 2; // must be initialized to a _valid_ value even if never used.

  static function logic[R*N-1:0] makeMatrixImpl(logic[R-1:0] taps);
    //automatics
    logic[R-1:0] state = taps;
    integer idx = 0; // Vivado had issues if I moved this line.

    for (idx = 0; idx < N; idx = idx+1) begin
      makeMatrixImpl[R*idx+:R] = state;
      state = {1'b0, state[R-1:1]} ^ (state[0] ? taps : 0);     
    end

  endfunction 

  // Not supported in Vivado2015.3, but would make things easier.
  // Can still use the longer syntax, or preprocessor.
  //let makeMatrix(taps, num) = makeMatrixVc#(.N(num), .R($bits(taps)))::makeMatrixImpl(taps);
endclass
 

I don't know how useful this week be, as I doubt altera or quartus would support classes in synthesis as they are really seen as a verification thing.

I'm surprised others haven't replied. I don't have any verilog synth experienced, ive only used it for verification.
 

When I tried Vivado, it had no issues with "virtual" or "class", only with "new". The static member function doesn't require "new" nor would it work with the class being declared virtual. Not sure about quartus though.

When I look at SystemVerilog for synthesis, I get the feeling that wasn't a design goal. For example, "interface" seems useful for more than just connecting modules together. It feels weird having interfaces that don't connect modules.
 

Vivado doesn't support all SV constructs. Xilinx-Vivado maintains a list of the supported SV constructs and I recommend to consult it before writing out your RTL.

I remember during the end of 2014 I was trying to implement a 32bit uP designed with SV on a Spartan6 and had issues at the simulation level itself with the .sv files. Initially I did some manual conversions for SV to V but gave up when the complexity increased. The Vivado (ver 2014.x) at that time was not able to handle it.
Then somehow we managed to obtain Synopsys VCS and everything went smooth with the simulations. For synthesis again we used Mentor Precision for FPGA synth. I had used Vivado only PnR/Impl and bit-stream creation. That was my first and last (till date) encounter with SV.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top