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

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

Started by ●November 5, 2020

Reply by ●November 5, 20202020-11-05

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))

Reply by ●November 5, 20202020-11-05

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)?

Reply by ●November 5, 20202020-11-05

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.

Reply by ●November 9, 20202020-11-09

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.

Reply by ●November 9, 20202020-11-09

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;

Reply by ●November 10, 20202020-11-10

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?

Reply by ●November 10, 20202020-11-10

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.

Reply by ●November 11, 20202020-11-11

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.

Reply by ●November 17, 20202020-11-17

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...