Is there a way in Verilog to refer to a slice of an array?...

K

Kevin Simonson

Guest
I\'ve got two Verilog modules that look like this:

module queue
( output [ 64:0] dataOut
, input reset
, input shift
, input [ 64:0] dataIn);
....
endmodule

and

module lessThan
( output lssThn
, input [ 48:0] leftOp
, input [ 48:0] rightOp);
....
endmodule

I\'ve got six instances of module (queue) and need to pipe the forty-nine most significant bits of the output of each of two (queue)s to the two inputs of (lessThan). Is there a way to refer to that forty-nine-bit slice? Or do I have to do something like this:

module hmm ();

wire rs, shLf, shRg;
wire lfOut [ 64:0], lfIn [ 64:0];
wire rgOut [ 64:0], rgIn [ 64:0];
wire rgMsbs [ 48:0], lfMsbs [ 48:0];

queue lfq( lfOut, rs, shLf, lfIn);
queue rgq( rgOut, rs, shRg, rgIn);

lessThan lfLtRg( result, lfMsbs, rgMsbs);

generate
for (bit = 0; bit <= 48; bit = bit + 1)
begin
assign lfMsbs[ bit] = lfOut[ bit + 16];
assign rgMsbs[ bit] = rgOut[ bit + 16];
end
endgenerate

endmodule
 
On 11/4/20 11:24 PM, Kevin Simonson wrote:
I\'ve got two Verilog modules that look like this:

module queue
( output [ 64:0] dataOut
, input reset
, input shift
, input [ 64:0] dataIn);
...
endmodule

and

module lessThan
( output lssThn
, input [ 48:0] leftOp
, input [ 48:0] rightOp);
...
endmodule

I\'ve got six instances of module (queue) and need to pipe the forty-nine most significant bits of the output of each of two (queue)s to the two inputs of (lessThan). Is there a way to refer to that forty-nine-bit slice? Or do I have to do something like this:

module hmm ();

wire rs, shLf, shRg;
wire lfOut [ 64:0], lfIn [ 64:0];
wire rgOut [ 64:0], rgIn [ 64:0];
wire rgMsbs [ 48:0], lfMsbs [ 48:0];

queue lfq( lfOut, rs, shLf, lfIn);
queue rgq( rgOut, rs, shRg, rgIn);

lessThan lfLtRg( result, lfMsbs, rgMsbs);

generate
for (bit = 0; bit <= 48; bit = bit + 1)
begin
assign lfMsbs[ bit] = lfOut[ bit + 16];
assign rgMsbs[ bit] = rgOut[ bit + 16];
end
endgenerate

endmodule

lesssThan lrLtRg(results, lfOut[64:16], rgOut[64:16))
 
On Thursday, November 5, 2020 at 4:20:22 AM UTC-8, Richard Damon wrote:

> lesssThan lrLtRg(results, lfOut[64:16], rgOut[64:16))

I tried this out with a pair of simpler modules, namely:
Code:
module lessThan
  ( output       lssThn
  , input [ 4:0] leftOp
  , input [ 4:0] rightOp);

assign lssThn = leftOp < rightOp;

endmodule
and
Code:
module check ();

reg left [ 8:0], right [ 8:0];
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
  left  = 9\'d287;
  right = 9\'d449;
  #5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
  #5 $finish;
end

endmodule
When I tried to get Icarus to simulate it I got:
Code:
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o check.vvp lessThan.sv check.sv
check.sv:6: error: Array cannot be indexed by a range.
check.sv:6: warning: Port 2 (leftOp) of lessThan expects 5 bits, got 1.
check.sv:6:        : Padding 4 high bits of the port.
check.sv:6: error: Array cannot be indexed by a range.
check.sv:6: warning: Port 3 (rightOp) of lessThan expects 5 bits, got 1.
check.sv:6:        : Padding 4 high bits of the port.
check.sv:10: error: Cannot assign to array left. Did you forget a word index?
check.sv:11: error: Cannot assign to array right. Did you forget a word index?
4 error(s) during elaboration.

D:\\Hf\\Verilog\\Unpacked\\Src>
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?
 
On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wrote:
On Thursday, November 5, 2020 at 4:20:22 AM UTC-8, Richard Damon wrote:

lesssThan lrLtRg(results, lfOut[64:16], rgOut[64:16))
I tried this out with a pair of simpler modules, namely:
Code:
module lessThan
( output lssThn
, input [ 4:0] leftOp
, input [ 4:0] rightOp);

assign lssThn = leftOp < rightOp;

endmodule
and
Code:
module check ();

reg left [ 8:0], right [ 8:0];
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
left = 9\'d287;
right = 9\'d449;
#5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
#5 $finish;
end

endmodule
When I tried to get Icarus to simulate it I got:
Code:
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o check.vvp lessThan.sv check.sv
check.sv:6: error: Array cannot be indexed by a range.
check.sv:6: warning: Port 2 (leftOp) of lessThan expects 5 bits, got 1.
check.sv:6: : Padding 4 high bits of the port.
check.sv:6: error: Array cannot be indexed by a range.
check.sv:6: warning: Port 3 (rightOp) of lessThan expects 5 bits, got 1.
check.sv:6: : Padding 4 high bits of the port.
check.sv:10: error: Cannot assign to array left. Did you forget a word index?
check.sv:11: error: Cannot assign to array right. Did you forget a word index?
4 error(s) during elaboration.

D:\\Hf\\Verilog\\Unpacked\\Src
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?

Yes--you have declared \'left\' and \'right\' with \"unpacked\" dimensions instead of \"packed\". Try this declaration:

reg [8:0] left, [8:0] right;

That should work.
 
On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote:
On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wrote:
....
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?
Yes--you have declared \'left\' and \'right\' with \"unpacked\" dimensions instead of \"packed\". Try this declaration:

reg [8:0] left, [8:0] right;

That should work.

Kevin Neilson, I copied your line of code into my code, giving me:
Code:
module neilson ();

reg [8:0] left, [8:0] right; 
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
  left  = 9\'d287;
  right = 9\'d449;
  #5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
  #5 $finish;
end

endmodule
Then I tried simulating, and got the following error messages:
[demo]
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o neilson.vvp lessThan.sv neilson.sv
neilson.sv:3: syntax error
neilson.sv:3: error: invalid module item.

D:\\Hf\\Verilog\\Unpacked\\Src>
[/demo]
Do you have any idea what Icarus means by \"syntax error\" or \"invalid module item\"? It looks like I\'ve still got problems with my code.
 
On Monday, November 9, 2020 at 2:39:02 PM UTC-7, Kevin Simonson wrote:
On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote:
On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wrote:
...
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?
Yes--you have declared \'left\' and \'right\' with \"unpacked\" dimensions instead of \"packed\". Try this declaration:

reg [8:0] left, [8:0] right;

That should work.
Kevin Neilson, I copied your line of code into my code, giving me:
Code:
module neilson ();
reg [8:0] left, [8:0] right;
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
left = 9\'d287;
right = 9\'d449;
#5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
#5 $finish;
end

endmodule
Then I tried simulating, and got the following error messages:
[demo]
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o neilson.vvp lessThan.sv neilson.sv
neilson.sv:3: syntax error
neilson.sv:3: error: invalid module item.
D:\\Hf\\Verilog\\Unpacked\\Src
[/demo]
Do you have any idea what Icarus means by \"syntax error\" or \"invalid module item\"? It looks like I\'ve still got problems with my code.

Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;
 
On Monday, November 9, 2020 at 2:11:11 PM UTC-8, Kevin Neilson wrote:
Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;

Thanks, Kevin Neilson! That did the trick. Now one post prior to that last one you said, \"Yes--you have declared \'left\' and \'right\' with \'unpacked\' dimensions instead of \'packed\'.\" So it would appear in order to refer to a slice of an array the array has to be packed. Is that right? When I began writing the project I\'m working on right now, all my arrays were packed, but somehow along the way I understood that would cause me problems, so I made all my arrays unpacked. But it\'s going to be pretty vital to my project to be able to specify that slice. So can you tell me what exactly the rules are about packed and unpacked arrays, and when I\'ll want to have them packed and when I\'ll want to have them unpacked?
 
On Monday, November 9, 2020 at 2:11:11 PM UTC-8, Kevin Neilson wrote:
On Monday, November 9, 2020 at 2:39:02 PM UTC-7, Kevin Simonson wrote:
On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote:
On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wrote:
...
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?
Yes--you have declared \'left\' and \'right\' with \"unpacked\" dimensions instead of \"packed\". Try this declaration:

reg [8:0] left, [8:0] right;

That should work.
Kevin Neilson, I copied your line of code into my code, giving me:
Code:
module neilson ();
reg [8:0] left, [8:0] right;
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
left = 9\'d287;
right = 9\'d449;
#5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
#5 $finish;
end

endmodule
Then I tried simulating, and got the following error messages:
[demo]
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o neilson.vvp lessThan.sv neilson.sv
neilson.sv:3: syntax error
neilson.sv:3: error: invalid module item.
D:\\Hf\\Verilog\\Unpacked\\Src
[/demo]
Do you have any idea what Icarus means by \"syntax error\" or \"invalid module item\"? It looks like I\'ve still got problems with my code.
Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;

On Monday, November 9, 2020 at 2:11:11 PM UTC-8, Kevin Neilson wrote:
Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;

Thanks, Kevin Neilson! That did the trick. Now one post prior to that last one you said, \"Yes--you have declared \'left\' and \'right\' with \'unpacked\' dimensions instead of \'packed\'.\" So it would appear in order to refer to a slice of an array the array has to be packed. Is that right? When I began writing the project I\'m working on right now, all my arrays were packed, but somehow along the way I understood that would cause me problems, so I made all my arrays unpacked. But it\'s going to be pretty vital to my project to be able to specify that slice. So can you tell me what exactly the rules are about packed and unpacked arrays, and when I\'ll want to have them packed and when I\'ll want to have them unpacked?

I guess I could just convert every array in my project back to being packed and then see if the compiler likes that, but I\'m not sure that\'s the best way to do it.
 
On Tuesday, November 10, 2020 at 2:46:02 PM UTC-7, Kevin Simonson wrote:
On Monday, November 9, 2020 at 2:11:11 PM UTC-8, Kevin Neilson wrote:
On Monday, November 9, 2020 at 2:39:02 PM UTC-7, Kevin Simonson wrote:
On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote:
On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wrote:
...
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?
Yes--you have declared \'left\' and \'right\' with \"unpacked\" dimensions instead of \"packed\". Try this declaration:

reg [8:0] left, [8:0] right;

That should work.
Kevin Neilson, I copied your line of code into my code, giving me:
Code:
module neilson ();
reg [8:0] left, [8:0] right;
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
left = 9\'d287;
right = 9\'d449;
#5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
#5 $finish;
end

endmodule
Then I tried simulating, and got the following error messages:
[demo]
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o neilson.vvp lessThan.sv neilson.sv
neilson.sv:3: syntax error
neilson.sv:3: error: invalid module item.
D:\\Hf\\Verilog\\Unpacked\\Src
[/demo]
Do you have any idea what Icarus means by \"syntax error\" or \"invalid module item\"? It looks like I\'ve still got problems with my code.
Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;
On Monday, November 9, 2020 at 2:11:11 PM UTC-8, Kevin Neilson wrote:
Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;
Thanks, Kevin Neilson! That did the trick. Now one post prior to that last one you said, \"Yes--you have declared \'left\' and \'right\' with \'unpacked\' dimensions instead of \'packed\'.\" So it would appear in order to refer to a slice of an array the array has to be packed. Is that right? When I began writing the project I\'m working on right now, all my arrays were packed, but somehow along the way I understood that would cause me problems, so I made all my arrays unpacked. But it\'s going to be pretty vital to my project to be able to specify that slice. So can you tell me what exactly the rules are about packed and unpacked arrays, and when I\'ll want to have them packed and when I\'ll want to have them unpacked?
I guess I could just convert every array in my project back to being packed and then see if the compiler likes that, but I\'m not sure that\'s the best way to do it.

Packed/unpacked is probably a whole topic, but in general, if you just have one dimension, you almost always want packed:

reg [7:0] one_byte;

and to model something like a RAM, use one dimension of each type:

reg [7:0] ram [0:31]; // 32-byte RAM

In the above case, ram[31][7:4] would be the most-significant 4 bits of the last byte in the RAM.
 
poniedziałek, 9 listopada 2020 o 23:11:11 UTC+1 Kevin Neilson napisał(a):
On Monday, November 9, 2020 at 2:39:02 PM UTC-7, Kevin Simonson wrote:
On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote:
On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wrote:
...
Can anyone tell me what I\'m doing wrong? Do I have the syntax wrong for expressing a slice of arguments (left) and (right)?
Yes--you have declared \'left\' and \'right\' with \"unpacked\" dimensions instead of \"packed\". Try this declaration:

reg [8:0] left, [8:0] right;

That should work.
Kevin Neilson, I copied your line of code into my code, giving me:
Code:
module neilson ();
reg [8:0] left, [8:0] right;
wire result;

lessThan ltc( result, left[ 8:4], right[ 8:4]);

initial
begin
left = 9\'d287;
right = 9\'d449;
#5 $display( \"left: %d, right: %d, result: %d.\", left, right, result);
#5 $finish;
end

endmodule
Then I tried simulating, and got the following error messages:
[demo]
D:\\Hf\\Verilog\\Unpacked\\Src>\\HdlTools\\Icarus\\bin\\iverilog -g2009 -o neilson.vvp lessThan.sv neilson.sv
neilson.sv:3: syntax error
neilson.sv:3: error: invalid module item.
D:\\Hf\\Verilog\\Unpacked\\Src
[/demo]
Do you have any idea what Icarus means by \"syntax error\" or \"invalid module item\"? It looks like I\'ve still got problems with my code.
Sorry; I guess you can\'t redeclare the bus width on the same lane. It\'s probably best to just use two lines:

reg [8:0] left;
reg [8:0] right;
reg [8:0] left = 0, right = 0;
You could just make it as above, which creates two 9-bit arrays with proper data init...
 

Welcome to EDABoard.com

Sponsor

Back
Top