cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Voyager
Voyager
406 Views
Registered: ‎04-12-2012

Parameterized register chain in Systemverilog

Jump to solution

Hello,

I want to generate a parameterized register chain in Systemverilog.
The goal is to have both the width and depth of the chain to be override-able compile time parameters.
I also want the register chain to have an asynchronous reset - and the "default_value" to also be a parameter.

1. Is the code below correct ?
2. How should I define "default_value" , "number_of_regs" , "width_reg" ?

 

module register_chain
#(
// default_value // 
// number_of_regs // 
// width_reg // 
)
(
    input arst ,
    input clock ,
    input [width_reg-1:0] in_data ,
    
    output logic [0:number_of_regs-1] [width_reg-1:0] out_data 
)

assign out_data [ 0 ] = in_data ;

always @ ( posedge clock or posedge arst )
begin
    if ( arst == 1'b0 )
        out_data = default_value ;   
    else
        for ( integer index = 0 ; index < number_of_regs - 1 ; index ++ ) 
            out_data [ index + 1 ] <= out_data [ index ] ; 
    end

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Scholar
Scholar
278 Views
Registered: ‎09-16-2009

Re: Parameterized register chain in Systemverilog

Jump to solution

@shaikon wrote:

My assignment using replication gives exactly 80 (not 88) bits.

Are you saying that this:

parameter default_value = { (11) { 8'haa } }

 Is equivalent to:

80'h aa aa aa aa aa aa aa aa aa aa ; // 10 sets of 0xaa

And not 

88'h aa aa aa aa aa aa aa aa aa aa aa ; // 11 sets of 0xaa

?


No, what I'm saying is that for my example:

module register_chain
#(
  parameter number_of_regs = 11,
  parameter width_reg = 8,

// Note index 0 does not get "default_value" since it is purely combinational according to your definition
  parameter default_value = { (number_or_regs-1){ 8'haa } }
)

number_of_reg = 11; width_reg=8.  

parameter default_value = { (number_or_regs-1){ 8'haa } } = { 10 { 8'haa } } = 80'haa_aa_aa_aa_aa_aa_aa_aa_aa_aa;

This all goes back to one of my original comments.  The shift register is 10 elements deep, not 11.  The way you originally coded it, and named the parameter as "number_or_reg" implied there are 11 sets of registers - however your logic combinationally fed through index 0, so the shift register is one element less than "number_or_regs".  This is, in my opinion, is more clear in the coding style I showed.  Or it is to me at least.

Regards,

Mark

View solution in original post

9 Replies
Highlighted
Scholar
Scholar
385 Views
Registered: ‎09-16-2009

Re: Parameterized register chain in Systemverilog

Jump to solution

Just define the parameters:

module register_chain
#(
  parameter number_of_regs = 11,
  parameter width_reg = 8,

// Note index 0 does not get "default_value" since it is purely combinational according to your definition
  parameter default_value = { (number_or_regs-1){ 8'haa } }
)
...

Also, make sure your out_data reset clause is completely non-blocking (you had mixed assignments, which should generate an error):

always @ ( posedge clock or posedge arst )
begin
    if ( arst == 1'b0 )
        out_data <= default_value;   
...

I'd change other things for style, but what you've done should work.  Just try it and see.

Regards,

Mark

Highlighted
Voyager
Voyager
371 Views
Registered: ‎04-12-2012

Re: Parameterized register chain in Systemverilog

Jump to solution

Thanks Mark!

I'd change other things for style

Please share your thoughts - What would you change ?

My purpose for this post is learning how to "do it better" (not just "make it work"...)

0 Kudos
Highlighted
Scholar
Scholar
360 Views
Registered: ‎09-16-2009

Re: Parameterized register chain in Systemverilog

Jump to solution

Well first things first - I'd change to a synchronous reset.  Async resets are very inefficient in todays FPGAs (for better or for worse).

Second thing, I'd change your output to:

output wire [number_of_regs-1:0] [width_reg-1:0] out_data 

I don't understand folks who mix MSB:LSB, and LSB:MSB through the various different array indices.  It all works, of course, but I find the consistency much easier on my brain.

I'd change the default_value to an input, instead of a parameter - it's more flexible, and clearer to inform the user how many "default" bits are needed.

I'd also remove the for loop, and just depend on the packed array assignments along with the replication operator.

Finally, I don't like the mixed assignment of continuous assignment, and procedural assignment to the single output variable "out_data".  Index 0 is driven via a continuous assignment, while the others indices are procedurally driven. A lint tool may flag this as error.  It's also not clear at first glance just how many FFs there are.  So my final version of this module would look like:

 

module register_chain
#(
  parameter number_of_regs = 11,
  parameter width_reg = 8
)
(
    input  wire rst,
    input  wire clock ,
    input  wire [width_reg-1:0] in_data ,
    input  wire [number_of_regs-1:1] [width_reg-1:0] default_val,
    output wire [number_of_regs-1:0] [width_reg-1:0] out_data 
);
  // Note number of bits for shift register FF (first array index stops at 1, not 0)
reg [number_of_regs-1:1] [width_reg-1:0] shift_data; always @( posedge clock) if( rst ) shift_data <= default_val; else shift_data <= { shift_data, in_data }; assign out_data = { shift_data, in_data }; endmodule

It's also clearer to me in this form, that your output is from the "D" side of the shift register FFs instead of the "Q".

Regards,

Mark

 

Highlighted
Voyager
Voyager
333 Views
Registered: ‎04-12-2012

Re: Parameterized register chain in Systemverilog

Jump to solution

Question 1: 

Do the parameters (number_of_regs, width_reg) have to be assigned a default value ?

Question 2:

Omitting the "for" loop does look cleaner...but I want to ask something about my original code.

for ( integer index = 0 ; index < number_of_regs - 1 ; index ++ )

Instead of using "number_of_regs" what attribute can we use to extract the number of registers from "default_value" ? 

Question 3:

parameter default_value = { (11) { 8'haa } }

As far as I understand - this creates an 11 element array with each element being 0xAA. Correct?

What if we wanted each register of the 11 to be assigned a different value ?

For example:

parameter default_value = { (11) { 8'haa , 8'hbb , 8'h12, etc...} }

What will be the correct syntax for that ?

 

0 Kudos
Highlighted
Scholar
Scholar
324 Views
Registered: ‎09-16-2009

Re: Parameterized register chain in Systemverilog

Jump to solution

@shaikon wrote:

Question 1: 

Do the parameters (number_of_regs, width_reg) have to be assigned a default value ?

In one of the recent versions of SystemVerilog, (I don't recall which) - I was surprised to learn that default values were made optional for parameter values.  Looking at my IEEE1800-2009 spec, I can't find it at the moment.  In any event support for this feature amount EDA tools is spotty at best.  I'm not entirely certain of the use case either.  In any event, in my book, and in almost all cases of code you'll see in the wild, a default value for a parameter will always be included.


@shaikon wrote:

Question 2:

Omitting the "for" loop does look cleaner...but I want to ask something about my original code.

 

for ( integer index = 0 ; index < number_of_regs - 1 ; index ++ )

 

Instead of using "number_of_regs" what attribute can we use to extract the number of registers from "default_value" ? 


It's not clear why you would want to do this.  The number of register isn't defined from default_value, really.  The number of FFs is strictly defined from the two parameters, "number_of_regs", and "width_reg". I'm unclear really what your intention is here in not using those parameters?

Regards,

Mark

Highlighted
Voyager
Voyager
314 Views
Registered: ‎04-12-2012

Re: Parameterized register chain in Systemverilog

Jump to solution


It's not clear why you would want to do this.  The number of register isn't defined from default_value, really.  The number of FFs is strictly defined from the two parameters, "number_of_regs", and "width_reg". I'm unclear really what your intention is here in not using those parameters?

 


It makes little practical little practical sense - the only purpose is learning to use Systemverilog attributes...

Can you also answer Q3 please ?

 

 

0 Kudos
Highlighted
Scholar
Scholar
297 Views
Registered: ‎09-16-2009

Re: Parameterized register chain in Systemverilog

Jump to solution

@shaikon wrote:

Question 3:

parameter default_value = { (11) { 8'haa } }

As far as I understand - this creates an 11 element array with each element being 0xAA. Correct?

What if we wanted each register of the 11 to be assigned a different value ?

For example:

parameter default_value = { (11) { 8'haa , 8'hbb , 8'h12, etc...} }

What will be the correct syntax for that ?


Not quite, you just need to set it to whatever default value you want, as long as it's wide enough.  For the default case, you want (11-1) * 8  = 80 bits for the "default_value".

My assignment using replication gives exactly 80 (not 88) bits.  In fact, my default would still work if you were to override JUST the "number_of_regs" value to any other value - it would still give you the requisite number of bits. (Note however, all indices would receive the same default)

So the following would work:

  • parameter default_value = { 8'haa, 8'hbb, 8'hcc, ..., 8'h33 };// 10 total, 8-bit values
  • parameter default_value = 80'haabbccddeeff00112233;
  • or any other literal, as long as it gave enough bits.  Too many bits would truncate, too few would 0 fill.

Regards,

Mark

Highlighted
Voyager
Voyager
291 Views
Registered: ‎04-12-2012

Re: Parameterized register chain in Systemverilog

Jump to solution

My assignment using replication gives exactly 80 (not 88) bits.

Are you saying that this:

parameter default_value = { (11) { 8'haa } }

 Is equivalent to:

80'h aa aa aa aa aa aa aa aa aa aa ; // 10 sets of 0xaa

And not 

88'h aa aa aa aa aa aa aa aa aa aa aa ; // 11 sets of 0xaa

?

 

 

 

 

0 Kudos
Highlighted
Scholar
Scholar
279 Views
Registered: ‎09-16-2009

Re: Parameterized register chain in Systemverilog

Jump to solution

@shaikon wrote:

My assignment using replication gives exactly 80 (not 88) bits.

Are you saying that this:

parameter default_value = { (11) { 8'haa } }

 Is equivalent to:

80'h aa aa aa aa aa aa aa aa aa aa ; // 10 sets of 0xaa

And not 

88'h aa aa aa aa aa aa aa aa aa aa aa ; // 11 sets of 0xaa

?


No, what I'm saying is that for my example:

module register_chain
#(
  parameter number_of_regs = 11,
  parameter width_reg = 8,

// Note index 0 does not get "default_value" since it is purely combinational according to your definition
  parameter default_value = { (number_or_regs-1){ 8'haa } }
)

number_of_reg = 11; width_reg=8.  

parameter default_value = { (number_or_regs-1){ 8'haa } } = { 10 { 8'haa } } = 80'haa_aa_aa_aa_aa_aa_aa_aa_aa_aa;

This all goes back to one of my original comments.  The shift register is 10 elements deep, not 11.  The way you originally coded it, and named the parameter as "number_or_reg" implied there are 11 sets of registers - however your logic combinationally fed through index 0, so the shift register is one element less than "number_or_regs".  This is, in my opinion, is more clear in the coding style I showed.  Or it is to me at least.

Regards,

Mark

View solution in original post