Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Visitor
bandit
Posts: 12
Registered: ‎03-03-2011
0

Array of vectors into task/function

[ Edited ]

Hi,

 

Is there a way to pass a variable length signal to a task or function in verilog?

 

I have a small generate loop that flattens a signal (to pass an array of vectors into a module), but I have to flatten several signals. Is there a way to avoid all that code repetition? Especially because the module is heavily parametrized and I'll have to flatten "n" signals. So a function or task would be ideal.

 

Thanks

Super Contributor
markcurry
Posts: 117
Registered: ‎09-16-2009
0

Re: Array of vectors into task/function

 

You need Systemverilog.  Which ISE doesn't support. :(

 

Array of vectors etc are quite powerful tools - you just can't really use them effectively

with ISE as your finding out. 

 

We've learned to just flatten EVERYTHING, and just become efficient at indexing

into to flattened vector appropriately.

 

I.e. Lots of code like

 

parameter N = 10;

 

wire [ N * 32 - 1 : 0 ] foo_vector;

// wire[ N - 1: 0 ] [ 31 : 0 ] foo_array = foo_vector; // Systemverilog packed array - what we really want;

 

genvar i;

...

inst bar ( .a( foo_vector[ i * 32 +: 32 ] ), ... );

 

Array's of instances are handy too - if you're calling "N" identical submodules - just

want inputs/outputs vectored off of the flattened arrays:

 

inst bar[ N - 1 :0 ] ( .a( foo_vector ), .b( baz ) );

 

Parameterized function/tasks just aren't available - even in Systemverilog. 

The SystemVerilog working group even weasled out on adding it to the next version of

SystemVerilog by noting that you can work around it by sticking the functions

down as methods inside classes (which can be parameterized).  That

doesn't help for synthesizable code however.  Sigh.

 

--Mark

 

Visitor
bandit
Posts: 12
Registered: ‎03-03-2011
0

Re: Array of vectors into task/function

Hey mark, thanks for replying

 

Yeah I've noticed that ISE is quite picky syntax wise, sadly. Also while I was working I came across the notions of packed and unpacked arrays and etc. But I couldn't find a decent explanation of how they are indexed.

 

What's the difference between these;

 

reg [31:0] somesignal [5:0]

reg [31:0][5:0] somesignal

reg [31:0][5:0] somesignal [5:0]

 

and how can I index each group of bits as "rows"?

 

Also another thing, I have a nested generate (taken from ISE's code templates):

 

/////////////////////////////////////////////////////////////////

genvar i, j;
generate
for (i=0; i < NUM_OUTPUTS; i=i+1) begin: case_for //outter case loop
        
    for (j=0; j < NUM_INPUTS; j=j+1) begin : case_statements //case statements            
    
            if(reg_select[NUM_SEL_BITS + (NUM_SEL_BITS * i) : (NUM_SEL_BITS * i)] == j)
            begin
                assign `CHUNK(i,output_registers) = `CHUNK(j,input_registers);
                    //output_registers[i] <= input_registers[j];
            end

    end //end case_statements for

end//end case_for loop
endgenerate

/////////////////////////////////////////////////////////////////

 

Why does ISE complain about reg_select not being constant?? Before it also said "j" was a non reg so the assignment j=j+1 was invalid...

 

bandit

Super Contributor
markcurry
Posts: 117
Registered: ‎09-16-2009
0

Re: Array of vectors into task/function

 


bandit wrote:

Yeah I've noticed that ISE is quite picky syntax wise, sadly. Also while I was working I came across the notions of packed and unpacked arrays and etc. But I couldn't find a decent explanation of how they are indexed.

 

What's the difference between these;

 

reg [31:0] somesignal [5:0]

reg [31:0][5:0] somesignal

reg [31:0][5:0] somesignal [5:0]

 

and how can I index each group of bits as "rows"?

 


 

A brief intro to SystemVerilog arrays can be found here:

  http://www.doulos.com/knowhow/sysverilog/tutorial/datatypes/

 

All very good to know - however you can't use this with Xilinx :(

 


 

Also another thing, I have a nested generate (taken from ISE's code templates):

 

/////////////////////////////////////////////////////////////////

genvar i, j;
generate
for (i=0; i < NUM_OUTPUTS; i=i+1) begin: case_for //outter case loop
        
    for (j=0; j < NUM_INPUTS; j=j+1) begin : case_statements //case statements            
    
            if(reg_select[NUM_SEL_BITS + (NUM_SEL_BITS * i) : (NUM_SEL_BITS * i)] == j)
            begin
                assign `CHUNK(i,output_registers) = `CHUNK(j,input_registers);
                    //output_registers[i] <= input_registers[j];
            end

    end //end case_statements for

end//end case_for loop
endgenerate

/////////////////////////////////////////////////////////////////

 

Why does ISE complain about reg_select not being constant?? Before it also said "j" was a non reg so the assignment j=j+1 was invalid...

 


 

The array index you've got:

  reg_select[NUM_SEL_BITS + (NUM_SEL_BITS * i) : (NUM_SEL_BITS * i)]

 

 

Is NOT valid.  Yes, both you and I know that no matter what 'i' is the final selected range

of reg_select is always going to be NUM_SEL_BITS.  However it's a little

harder for the verilog compiler/synthesizer to know this.   So from early on verilog, this

type of indexing has been illegal.  In Verilog 2k, they added some new operators:

'+:' and '-:'

 

This allows you to do what you want.  Recode the above to:

  reg_select[ (i*NUM_SEL_BITS) +: NUM_SEL_BITS ]

 

The key to making this work is the left side of the index can be variable.

The right side of the '+:' must be a constant (or parameter).  This way

the compiler/synthesizer always knows the result will have a constant

width, and is happy.

 

--Mark

 

 

Visitor
jflinsb
Posts: 4
Registered: ‎03-14-2012
0

Re: Array of vectors into task/function

Minor point: the # of bits in:

  reg_select[NUM_SEL_BITS + (NUM_SEL_BITS * i) : (NUM_SEL_BITS * i)]

 

is of course, NUM_SEL_BITS+1