0

I am trying to control the width of data bus using part select.

But, the following error occurs:

r_count is not a constant.

Is there a way in which I can use the wired r_count bit values as a constant decimal for defining the range of the vector being taken?

This is the part of the code:

module shiftdata (data, r_count, out_data);
input [32:0] data;

input [4:0] r_count;

output [20:0] out_data;

assign out_data = data[r_count-1:r_count+5];

endmodule

toolic
  • 8,262
  • 7
  • 24
  • 35
Rezef
  • 93
  • 6

3 Answers3

1

Use this format:

vect[base_expr +: width_expr]

or

vect[base_expr -: width_expr]

See "5.2.1 Vector bit-select and part-select addressing" in IEEE.1364-2005 LRM.

Light
  • 351
  • 1
  • 2
  • 12
  • What if I want to have a variable length as in I want the length to be variable, instead of a constant? – Rezef Sep 11 '23 at 08:31
  • This does not answer the question about variable signal width. – toolic Sep 11 '23 at 11:25
  • @TahmidMahbub170021040 in the example code you provide in the question, you are not changing the width of the selected signal - your code (if it were valid) would always result in a 7-bit wide slice at varying offset, in whichc ase this answer would do the same legally (data[r_count-1+:7]). If you want a variable width, you'd have to more accurately describe what you want with a matching example (even invalid). In any case, variable width is not possible (think about the hardware, a data bus couldn't suddenly become wider - where would the hardware come from). – Tom Carpenter Sep 11 '23 at 12:59
1

There are a few problems with the Verilog code you are attempting to use.

As the error demonstrates, the code has a syntax error. It is illegal in Verilog to use variable signals for vector part selects. The width of the part-select must be a constant.

Even if that syntax were legal, you would have another problem because the part-select would have bits that are out of range. For example, when r_count=0, (r_count-1)=-1, which is out of range of data, whose lower index is 0.

Another potential problem is that you might also be inferring unintended latches if you are not assigning to all 21 bits of out_data.

Since you can't use the compact syntax that you would like to use, you must find another approach. For example, you could consider using a case statement with 32 case items (one for each of the 32 values of r_count).

toolic
  • 8,262
  • 7
  • 24
  • 35
1

It's not clear from your question what you are trying to acheive - you say in the comments that you are looking to select a variable width, but your code example (even if it compiled) would always be trying to access a 7-bit amount from data. In that case @Light's answer would be the way forward.

However based on the name of your module, and signal names, I'm going to hazard a guess that what you are actually trying to accomplish is a simple bit-shift, setting the out_data to a specific part of the data bus. In this case, you can simply use the bit-shift operator:

assign out_data = data >> r_count;

I've assumed right shift there (based on the name r_count), but you could equally use left shift (<<) or arithmetic right shift (>>> - sign extending shift for 2's complement).

You may get warnings about truncation, in which case you can either ignore the warning, or add an intermediate step:

wire [31:0] data_rshift;
assign data_rshift = data >> r_count;
assign out_data = data_rshift[20:0];
Tom Carpenter
  • 65,995
  • 3
  • 145
  • 204
  • Yes I forsake part select and did this with shifting one time at the right and one time at the left depending on the variable width – Rezef Sep 13 '23 at 06:05