Verilog:信号不支持变量索引
Verilog : Variable index is not supported in signal
我收到一条错误消息 'Index is not supported in signal'。据我所见,错误出现在非阻塞分配的左侧。为什么下面的代码会出错,是否有解决方法?
...
parameter width = 32;
parameter size = 3;
input clk, reset;
input [width*size-1:0] A;
input [width*size-1:0] B;
output [width*size-1:0] result;
reg signed [width*size-1:0] partials;
reg signed [width-1:0] temp;
reg signed [width-1:0] currenta;
reg signed [width-1:0] currentb;
wire signed [width-1:0] temp1wire;
...
integer k = 0;
always @ (posedge clk)
begin
currenta[width-1:0] <= A[width*k +: width];
k = k+1
currentb[width-1:0] <= B[width*k +: width];
partials[width*k +: width] <= temp1wire;
end
Add Add1(clk, temp1wire, currenta, currentb);
...
此代码是执行向量加法并将结果保存在 partials[width*k +: width]
的顺序块的一部分。
k
到达size-1
后需要夹紧或缠绕。
可以使用 mod 运算符 (%
) 进行回绕;示例:k = (k+1)%size
。 %
可能无法以最佳方式合成(检查你的合成器),因此 if 语句是一种功能替代方案 if(k==SIZE-1) k = 0; else k=k+1;
建议:
通常建议将参数保留为大写,这样您可以轻松地从信号名称中识别参数。将阻塞赋值放在顺序块中是合法的,但大多数设计规则建议将组合逻辑与顺序赋值分开。我更喜欢像下面这样编写您的代码:
// $clog is IEEE1364-2005 § 17.11, some synthesizers support it, others don't
reg [$clog2(SIZE):0] k=0, next_k;
always @* begin
if (k==SIZE-1) begin
next_k = 0; // wrap around
// next_k = k; // clamp
end
else begin
next_k = k+1;
end
end
always @ (posedge clk)
begin
currenta[WIDTH-1:0] <= A[WIDTH*k +: WIDTH];
currentb[WIDTH-1:0] <= A[WIDTH*next_k +: WIDTH];
partials[WIDTH*next_k +: WIDTH] <= temp1wire;
k <= next_k;
end
我在 Xilinx 论坛上找到 this:
"XST works fine with the indexed part-select operator "+:" if it is on the right-hand side (RHS) of the assignment. It also works fine when it is on the left-hand side (LHS) AND the starting index is a constant. Your case uses a variable as the starting index on the LHS and that what XST doesn't like although it's legal."
我收到一条错误消息 'Index is not supported in signal'。据我所见,错误出现在非阻塞分配的左侧。为什么下面的代码会出错,是否有解决方法?
...
parameter width = 32;
parameter size = 3;
input clk, reset;
input [width*size-1:0] A;
input [width*size-1:0] B;
output [width*size-1:0] result;
reg signed [width*size-1:0] partials;
reg signed [width-1:0] temp;
reg signed [width-1:0] currenta;
reg signed [width-1:0] currentb;
wire signed [width-1:0] temp1wire;
...
integer k = 0;
always @ (posedge clk)
begin
currenta[width-1:0] <= A[width*k +: width];
k = k+1
currentb[width-1:0] <= B[width*k +: width];
partials[width*k +: width] <= temp1wire;
end
Add Add1(clk, temp1wire, currenta, currentb);
...
此代码是执行向量加法并将结果保存在 partials[width*k +: width]
的顺序块的一部分。
k
到达size-1
后需要夹紧或缠绕。
可以使用 mod 运算符 (%
) 进行回绕;示例:k = (k+1)%size
。 %
可能无法以最佳方式合成(检查你的合成器),因此 if 语句是一种功能替代方案 if(k==SIZE-1) k = 0; else k=k+1;
建议:
通常建议将参数保留为大写,这样您可以轻松地从信号名称中识别参数。将阻塞赋值放在顺序块中是合法的,但大多数设计规则建议将组合逻辑与顺序赋值分开。我更喜欢像下面这样编写您的代码:
// $clog is IEEE1364-2005 § 17.11, some synthesizers support it, others don't
reg [$clog2(SIZE):0] k=0, next_k;
always @* begin
if (k==SIZE-1) begin
next_k = 0; // wrap around
// next_k = k; // clamp
end
else begin
next_k = k+1;
end
end
always @ (posedge clk)
begin
currenta[WIDTH-1:0] <= A[WIDTH*k +: WIDTH];
currentb[WIDTH-1:0] <= A[WIDTH*next_k +: WIDTH];
partials[WIDTH*next_k +: WIDTH] <= temp1wire;
k <= next_k;
end
我在 Xilinx 论坛上找到 this:
"XST works fine with the indexed part-select operator "+:" if it is on the right-hand side (RHS) of the assignment. It also works fine when it is on the left-hand side (LHS) AND the starting index is a constant. Your case uses a variable as the starting index on the LHS and that what XST doesn't like although it's legal."