0

Want to use inputs to be passed in range of another vector to extract corresponding value

Say for example see the Verilog code below.

But the problem is: I cant pass a variable(input) into the range of another variable. But this has to be done like that. Is there any other was to execute code with similar functionality? Actually my question pertains to the syntax correction of this code, and options available to execute similar functionality.

module foo(input1, input2, output1)
input [3:0] input1;
input [3:0] input2;
output reg [3:0] output1;
always@(*) begin
output1 <= input2[3:3-input1[1:0]];
end
endmodule

1
  • Can input1 be a verilog paramter? In other words, is it a known constant at instantiation of 'foo'? Commented May 7, 2019 at 15:24

1 Answer 1

2

If you want to take a slice out of the vector you have to work around the unequal size on the RHS and LHS. This is such a solution:

always @( * )  
case (input1)
2'b00 : output1 = input2[3];
2'b01 : output1 = input2[3:2];
2'b10 : output1 = input2[3:1]; 
2'b11 : output1 = input2[3:0]; 
endcase

I find that somewhat sloppy. The following is the same but the vectors are equal size on the RHS and LHS:

always @( * )  
case (input1)
2'b00 : output1 = {3'b000,input2[3]  };
2'b01 : output1 = { 2'b00,input2[3:2]};
2'b10 : output1 = {  1'b0,input2[3:1]};
2'b11 : output1 =         input2[3:0];
endcase

You suddenly mention an 8-bit input. I assume you mean that input2 is 8 bits wide. But that requires only a maximum length of input1 of 3 bits. So the solution above would be a twice as big but still feasible.

Just for your sake here is a version for a 8 bit index which requires 256 bit vectors. :-) It is a bit more difficult to understand but also works for your specific case where you always need only the MS X bits.

module foo( 
   input  [  7:0] input1,
   input  [255:0] input2,
   output [255:0] output1
);
wire [7:0] shift_right = 255-input;

   assign output1 = input2 >> shift_right ;

endmodule
Sign up to request clarification or add additional context in comments.

8 Comments

would not it be possible to write it as: output1 = {(3-input1){1'b0}, input2[3-:input1+1'b1]}? Explanation: one can "repeat" a part by n_repetitions{part_to_repeat} and "dynamic" slicing can be done using offset and width with bus[offset-:width]. But be aware that the amount of required ressources increases quickly as many muxes are required.
This method will yield a very long code, as the intended input has 8 bits.
@ChristianB no, it will not b possible for the same reason: you need compile-time constants for 'repeat' and for 'indexing'.
ah you are right. The offset is allowed to be a variable but not the width. So one has to do a little workaround: wire [7:0] bus = {4'b0, input2}; always@(*) begin output1 <= bus[input1-:3]; end
@ChristianB. yes, bit it will not work in your case. Your scheme requires variable width. Therefore Oldfart's solution is the best one, unless 'input1' can be a real verilog parameter.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.