Forums

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

Started by Kevin Simonson November 5, 2020
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 mo=
st 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 =3D 0; bit <=3D 48; bit =3D bit + 1)
  begin
    assign lfMsbs[ bit] =3D lfOut[ bit + 16];
    assign rgMsbs[ bit] =3D 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 [/code] 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 [/code] 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> [/code] 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 > [/code] > 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 > [/code] > 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> > [/code] > 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 [/code] 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 > [/code] > 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 p=
robably best to just use two lines:=20
>=20 > reg [8:0] left;=20 > 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' di= mensions instead of 'packed'." So it would appear in order to refer to a sl= ice of an array the array has to be packed. Is that right? When I began wri= ting the project I'm working on right now, all my arrays were packed, but s= omehow along the way I understood that would cause me problems, so I made a= ll my arrays unpacked. But it's going to be pretty vital to my project to b= e 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 a= nd 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:=20 > > On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote=
:=20
> > > On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wro=
te:=20
> > ...=20 > > > > Can anyone tell me what I'm doing wrong? Do I have the syntax wrong=
for expressing a slice of arguments (left) and (right)?=20
> > > Yes--you have declared 'left' and 'right' with "unpacked" dimensions =
instead of "packed". Try this declaration:=20
> > >=20 > > > reg [8:0] left, [8:0] right;=20 > > >=20 > > > That should work.=20 > > Kevin Neilson, I copied your line of code into my code, giving me:=20 > > [code]=20 > > module neilson ();=20 > > reg [8:0] left, [8:0] right;=20 > > wire result;=20 > >=20 > > lessThan ltc( result, left[ 8:4], right[ 8:4]);=20 > >=20 > > initial=20 > > begin=20 > > left =3D 9'd287;=20 > > right =3D 9'd449;=20 > > #5 $display( "left: %d, right: %d, result: %d.", left, right, result);=
=20
> > #5 $finish;=20 > > end=20 > >=20 > > endmodule=20 > > [/code]=20 > > Then I tried simulating, and got the following error messages:=20 > > [demo]=20 > > D:\Hf\Verilog\Unpacked\Src>\HdlTools\Icarus\bin\iverilog -g2009 -o neil=
son.vvp lessThan.sv neilson.sv=20
> > neilson.sv:3: syntax error=20 > > neilson.sv:3: error: invalid module item.=20 > > D:\Hf\Verilog\Unpacked\Src>=20 > > [/demo]=20 > > Do you have any idea what Icarus means by "syntax error" or "invalid mo=
dule 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 p=
robably best to just use two lines:=20
>=20 > reg [8:0] left;=20 > 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 p=
robably best to just use two lines:=20
>=20 > reg [8:0] left;=20 > 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' di= mensions instead of 'packed'." So it would appear in order to refer to a sl= ice of an array the array has to be packed. Is that right? When I began wri= ting the project I'm working on right now, all my arrays were packed, but s= omehow along the way I understood that would cause me problems, so I made a= ll my arrays unpacked. But it's going to be pretty vital to my project to b= e 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 a= nd 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:=20 > > On Monday, November 9, 2020 at 2:39:02 PM UTC-7, Kevin Simonson wrote:=
=20
> > > On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wro=
te:=20
> > > > On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson w=
rote:=20
> > > ...=20 > > > > > Can anyone tell me what I'm doing wrong? Do I have the syntax wro=
ng for expressing a slice of arguments (left) and (right)?=20
> > > > Yes--you have declared 'left' and 'right' with "unpacked" dimension=
s instead of "packed". Try this declaration:=20
> > > >=20 > > > > reg [8:0] left, [8:0] right;=20 > > > >=20 > > > > That should work.=20 > > > Kevin Neilson, I copied your line of code into my code, giving me:=20 > > > [code]=20 > > > module neilson ();=20 > > > reg [8:0] left, [8:0] right;=20 > > > wire result;=20 > > >=20 > > > lessThan ltc( result, left[ 8:4], right[ 8:4]);=20 > > >=20 > > > initial=20 > > > begin=20 > > > left =3D 9'd287;=20 > > > right =3D 9'd449;=20 > > > #5 $display( "left: %d, right: %d, result: %d.", left, right, result)=
;=20
> > > #5 $finish;=20 > > > end=20 > > >=20 > > > endmodule=20 > > > [/code]=20 > > > Then I tried simulating, and got the following error messages:=20 > > > [demo]=20 > > > D:\Hf\Verilog\Unpacked\Src>\HdlTools\Icarus\bin\iverilog -g2009 -o ne=
ilson.vvp lessThan.sv neilson.sv=20
> > > neilson.sv:3: syntax error=20 > > > neilson.sv:3: error: invalid module item.=20 > > > D:\Hf\Verilog\Unpacked\Src>=20 > > > [/demo]=20 > > > 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.=20
> > Sorry; I guess you can't redeclare the bus width on the same lane. It's=
probably best to just use two lines:=20
> >=20 > > reg [8:0] left;=20 > > reg [8:0] right; > On Monday, November 9, 2020 at 2:11:11 PM UTC-8, Kevin Neilson wrote:=20 > > Sorry; I guess you can't redeclare the bus width on the same lane. It's=
probably best to just use two lines:=20
> >=20 > > reg [8:0] left;=20 > > reg [8:0] right; > Thanks, Kevin Neilson! That did the trick. Now one post prior to that las=
t 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 w= riting 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 a= re 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 pack=
ed and then see if the compiler likes that, but I'm not sure that's the bes= t 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=C5=82ek, 9 listopada 2020 o=C2=A023:11:11 UTC+1 Kevin Neilson nap=
isa=C5=82(a):
> On Monday, November 9, 2020 at 2:39:02 PM UTC-7, Kevin Simonson wrote:=20 > > On Thursday, November 5, 2020 at 12:47:22 PM UTC-8, Kevin Neilson wrote=
:=20
> > > On Thursday, November 5, 2020 at 1:28:26 PM UTC-7, Kevin Simonson wro=
te:=20
> > ...=20 > > > > Can anyone tell me what I'm doing wrong? Do I have the syntax wrong=
for expressing a slice of arguments (left) and (right)?=20
> > > Yes--you have declared 'left' and 'right' with "unpacked" dimensions =
instead of "packed". Try this declaration:=20
> > >=20 > > > reg [8:0] left, [8:0] right;=20 > > >=20 > > > That should work.=20 > > Kevin Neilson, I copied your line of code into my code, giving me:=20 > > [code]=20 > > module neilson ();=20 > > reg [8:0] left, [8:0] right;=20 > > wire result;=20 > >=20 > > lessThan ltc( result, left[ 8:4], right[ 8:4]);=20 > >=20 > > initial=20 > > begin=20 > > left =3D 9'd287;=20 > > right =3D 9'd449;=20 > > #5 $display( "left: %d, right: %d, result: %d.", left, right, result);=
=20
> > #5 $finish;=20 > > end=20 > >=20 > > endmodule=20 > > [/code]=20 > > Then I tried simulating, and got the following error messages:=20 > > [demo]=20 > > D:\Hf\Verilog\Unpacked\Src>\HdlTools\Icarus\bin\iverilog -g2009 -o neil=
son.vvp lessThan.sv neilson.sv=20
> > neilson.sv:3: syntax error=20 > > neilson.sv:3: error: invalid module item.=20 > > D:\Hf\Verilog\Unpacked\Src>=20 > > [/demo]=20 > > Do you have any idea what Icarus means by "syntax error" or "invalid mo=
dule 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 p=
robably best to just use two lines:=20
>=20 > reg [8:0] left;=20 > reg [8:0] right;
reg [8:0] left =3D 0, right =3D 0; You could just make it as above, which creates two 9-bit arrays with proper= data init...