Verilog "not a constant" 位旋转错误
Verilog "not a constant" error on bit-rotation
我有这段代码。我正在尝试将 WNext
旋转 data_fromRAM
.
的低 4 位
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
但我收到错误消息:
data_fromRAM is not a constant.
我该如何解决这个错误?有没有办法将 data_fromRAM
复制到一个常量变量中,然后进行操作?或者我应该采取不同的方法?
注:output reg [15:0] datatoRAM;
编辑:如果 data_fromRAM = 40,则使用此行:WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]};我试图用 data_fromRAM 的四个最低有效位向右旋转 WNext。 40 等于二进制的 101000,最低四位给我们 1000,即十进制的 8。所以我将 WNext 向右旋转 8 位,我所说的旋转基本上是移位,但如果我们只进行移位,我们将丢失新的位(例如,将 1000110 旋转 3 = 1101000)
如果 data_fromRAM 大于 47,我想再次旋转 WNext,但这次是向左而不是向右旋转(再次按 data_fromRAM 的最低四位旋转)。因此,再次,就像在移位中一样,我想将所有值移到左侧,但是来自右侧的位是移位时从左侧丢失的位。
如错误消息所示,您需要为位 select 表达式设置一个常量值。外括号内的表达式在elaboration/compile时必须是常量:
W[15 - data_fromRAM[3:0]:0]
您不能将变量 data_fromRAM
复制到常量中。
我相信您需要一种不同的方法,但是很难从您展示的内容中了解您想要做什么。
此外,这是一个错误:
else if (data_fromRAM > 32 & data_fromRAM > 47)
我认为你打算使用 < 47
:
else if (data_fromRAM > 32 & data_fromRAM < 47)
我想你想改变:
WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]};
至:
WNext = (W >> data_fromRAM[3:0]) | (W << (16-data_fromRAM[3:0]));
并更改:
WNext = {W[15 - data_fromRAM[3:0]:0], W[15:16 - data_fromRAM[3:0]]};
至:
WNext = (W << data_fromRAM[3:0]) | (W >> (16-data_fromRAM[3:0]));
我借鉴了 this answer 的想法。
我认为基于 data_fromRAM
的值,您正试图 "scramble" 您的数据在 W
中。假设WNext
也是16位变量,可以使用:
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]));
我有这段代码。我正在尝试将 WNext
旋转 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
但我收到错误消息:
data_fromRAM is not a constant.
我该如何解决这个错误?有没有办法将 data_fromRAM
复制到一个常量变量中,然后进行操作?或者我应该采取不同的方法?
注:output reg [15:0] datatoRAM;
编辑:如果 data_fromRAM = 40,则使用此行:WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]};我试图用 data_fromRAM 的四个最低有效位向右旋转 WNext。 40 等于二进制的 101000,最低四位给我们 1000,即十进制的 8。所以我将 WNext 向右旋转 8 位,我所说的旋转基本上是移位,但如果我们只进行移位,我们将丢失新的位(例如,将 1000110 旋转 3 = 1101000)
如果 data_fromRAM 大于 47,我想再次旋转 WNext,但这次是向左而不是向右旋转(再次按 data_fromRAM 的最低四位旋转)。因此,再次,就像在移位中一样,我想将所有值移到左侧,但是来自右侧的位是移位时从左侧丢失的位。
如错误消息所示,您需要为位 select 表达式设置一个常量值。外括号内的表达式在elaboration/compile时必须是常量:
W[15 - data_fromRAM[3:0]:0]
您不能将变量 data_fromRAM
复制到常量中。
我相信您需要一种不同的方法,但是很难从您展示的内容中了解您想要做什么。
此外,这是一个错误:
else if (data_fromRAM > 32 & data_fromRAM > 47)
我认为你打算使用 < 47
:
else if (data_fromRAM > 32 & data_fromRAM < 47)
我想你想改变:
WNext = {W[data_fromRAM[3:0] - 1:0], W[15:data_fromRAM[3:0]]};
至:
WNext = (W >> data_fromRAM[3:0]) | (W << (16-data_fromRAM[3:0]));
并更改:
WNext = {W[15 - data_fromRAM[3:0]:0], W[15:16 - data_fromRAM[3:0]]};
至:
WNext = (W << data_fromRAM[3:0]) | (W >> (16-data_fromRAM[3:0]));
我借鉴了 this answer 的想法。
我认为基于 data_fromRAM
的值,您正试图 "scramble" 您的数据在 W
中。假设WNext
也是16位变量,可以使用:
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]));