1

I have this block of code. I am trying to rotate WNext by the lower 4 bits of data_fromRAM.

input clk, rst;

input wire [15:0] data_fromRAM;
output reg [15:0] data_toRAM;
output reg wrEn;

// 12 can be made smaller so that it fits in the FPGA
output reg [12:0] addr_toRAM;
output reg [12:0] PC; // This has been added as an output for TB purposes
output reg [15:0] W; // This has been added as an output for TB purposes

reg [12:0] PCNext;
reg [ 2:0] opcode, opcodeNext,state, stateNext;
reg [12:0] operand, operandNext;
reg [15:0] num, numNext, WNext;

always @*begin
    WNext = W;
    PCNext = PC;
    stateNext    = state;
    opcodeNext   = opcode;
    operandNext = operand;
    numNext     = num;
    addr_toRAM   = 0;
    wrEn         = 0;
    data_toRAM   = 0;
//here I have if(rst)
else 
    case(state)
//other cases
        2: begin
            PCNext = PC + 1;
            WNext = W;
            opcodeNext   = opcode;
            operandNext = operand;
            addr_toRAM   = 0;
            numNext     = data_fromRAM;
            wrEn         = 0;
            data_toRAM   = 0;
            stateNext    = 0;
            case (opcodeNext)
                ... //I excluded other cases
                3'b010: begin //SRRL
                    if(data_fromRAM < 16) WNext = W >> data_fromRAM;
                    else if (data_fromRAM > 16 & data_fromRAM < 31) WNext = W << data_fromRAM[3:0];
                    else if (data_fromRAM > 32 & data_fromRAM > 47) WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]};
                    else WNext = {W[15 - data_fromRAM[3:0]:0], W[15:16 - data_fromRAM[3:0]]};
                end

But I am getting the error:

data_fromRAM is not a constant.

How can I fix this error? Is there a way to copy data_fromRAM into a constant variable and then do the operations? Or should I take a different approach?

Note: output reg [15:0] datatoRAM;

edit : If data_fromRAM = 40, then with this line: WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]}; I am trying to rotate WNext right with the four least significant bits of data_fromRAM. 40 is equal to 101000 in binary and the four lowest bits give us 1000 which is 8 in decimal. So I will rotate WNext right by 8 bits and what I mean by rotate is basically shifting but new bits are the ones we were going to lose if we only did the shifting (eg. rotate 1000110 by 3 = 1101000)

If data_fromRAM is greater than 47, again I want to rotate WNext but this time left rather than right (again it's rotating by lowest four bits of data_fromRAM). So again, as in shifting, I want to move all the values to the left but the bits that are coming from right are the ones that were lost from left when shifting.

2 Answers2

0

As the error message shows, you need to have a constant value for the bit select expression. The expression within the outer brackets must be a constant at elaboration/compile time:

W[15 - data_fromRAM[3:0]:0]

You can not copy the variable data_fromRAM into a constant.

I believe you need a different approach, but it is difficult to know what you are trying to do from the little that you have shown.

Also, this is a bug:

else if (data_fromRAM > 32 & data_fromRAM > 47)

I think you meant to use < 47:

else if (data_fromRAM > 32 & data_fromRAM < 47)

I think you want to change:

WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]};

to:

WNext = (W >> data_fromRAM[3:0]) | (W << (16-data_fromRAM[3:0]));

And change:

WNext = {W[15 - data_fromRAM[3:0]:0], W[15:16 - data_fromRAM[3:0]]};

to:

WNext = (W << data_fromRAM[3:0]) | (W >> (16-data_fromRAM[3:0]));

I leveraged the idea from this answer.

toolic
  • 57,801
  • 17
  • 75
  • 117
0

I think based on the value of data_fromRAM, you are trying to "scramble" your data in W. Assuming WNext is also a 16-bit variable, you can use:

if(data_fromRAM < 16) 
    WNext = W >> data_fromRAM;
else if (data_fromRAM > 16 & data_fromRAM < 31) 
    WNext = W << data_fromRAM[3:0];
else if (data_fromRAM > 32 & data_fromRAM > 47) 
    WNext = (W << (16-data_fromRAM[3:0])) | (W >> data_fromRAM[3:0]);
else 
    WNext = (W << data_fromRAM[3:0]) | (W >> (16-data_fromRAM[3:0]));
acmert
  • 129
  • 1
  • 3