我正在使用Xilinx使用XST来合成我的设计。当我写someReg[offest*index+:constant] <= someOtherReg;
之类的东西时,我遇到了麻烦。给出的错误是“信号中不支持变量索引”。我在网上搜索后收集到的是XST综合工具不支持索引左侧信号的索引。
我想知道的是如何在不使用该语法的情况下实现索引信号的逻辑。在下面的示例中,我创建了一个矩阵乘法器,它重用了'rowByColumn'乘数。
基本上在每个上升时钟边沿,我将新值加载到'rowByColumn'乘法器的输入端,并且在下一个上升时钟边沿,我将结果保存在新寄存器中。将结果保存在新的寄存器中是我遇到的主要问题。
以下是给出错误的代码。您能否就如何解决或解决问题提出建议。
module MatrixSeq(clk,A,B,C);
// param
parameter WIDTH = 32;
parameter ROW_A = 2;
parameter COL_A = 2;
parameter ROW_B = 2;
parameter COL_B = 2;
//ports
input clk;
input [WIDTH*COL_A*ROW_A-1:0] A;
input [WIDTH*COL_B*ROW_B-1:0] B;
output [WIDTH*ROW_A*COL_B-1:0] C;
// inputs to rowBycol
reg signed [WIDTH*COL_A-1:0] currentRowA;
reg signed [WIDTH*ROW_B-1:0] currentColB;
reg signed [WIDTH-1:0] rowByColOut;
wire signed [WIDTH-1:0] rowByColOutWire; // wire to connet to rowByColOut
// A,B matrix holders
reg signed [WIDTH*COL_A*ROW_A-1:0] AsigHolder;
reg signed [WIDTH*COL_B*ROW_B-1:0] BsigHolder;
reg signed [WIDTH*ROW_A*ROW_B-1:0] CsigHolder; // C = A*B
// reg signed [WIDTH-1:0] count;
integer idxA = 0; // iterates through the rows of A
integer idxB = 0; // iterates through the 'rows' of B
// Indexing Syntax:
// signalAdd[some_expression +: some_range];
// Resolves to
// signalAdd[some_expression + (some_range - 1) : some_expression];
always @(posedge clk) begin // assume we have the transpose of matrix B
currentRowA <= AsigHolder[WIDTH*COL_A*idxA+:WIDTH*COL_A];
currentColB <= BsigHolder[WIDTH*COL_B+idxB+:WIDTH*COL_B];
CsigHolder[WIDTH*(idxA*ROW_A+idxB)+:WIDTH] <= rowByColOut; // Error: 'Variable index is not supported in signal.'
idxB <= idxB +1;
if(idxB == ROW_B) begin // multiply each row of A with every 'row' B
idxA <= idxA + 1;
idxB <= 0;
end else if(idxA == ROW_A) begin
idxA <= 0;
idxB <= 0;
end
end
assign rowByColOutWire = rowByColOut;
rowBycol rowMultColumn (.CLK(clk), .a(currentRowA), .b(currentColB), .y(rowByColOutWire)); // row by column multiplier
assign C = CsigHolder;
endmodule
要清楚问题是always块内的第三行给出了错误'信号中不支持变量索引。'
答案 0 :(得分:0)
如果XST不支持部分选择(+:
/ -:
)并且您无法升级到IEEE Std 1364-2001的投诉,那么您将需要在1995年完成方法;位分配:
for(bit_idx = 0; bit_idx < WIDTH*COL_A; bit_idx=bit_idx+1) begin
currentRowA[idx] <= AsigHolder[WIDTH*COL_A*idxA + bit_idx];
end
或二维数组:
reg signed [WIDTH*COL_A-1:0] AsigHolder [0:ROW_A-1];
...
always @(posedge clk) begin // assume we have the transpose of matrix B
currentRowA <= AsigHolder[idxA];
我注意到您的idxA
和idxB
可能会超出范围。分配有非阻塞(<=
)的所有寄存器在评估后都会更新。这意味着idxB==ROW_B
将在更新idxB <= idxB +1
之前进行评估
你应该有更多类似的东西:
if (idxB < ROW_B-1) begin
idxB <= idxB + 1;
end
else begin
idxB <= 0;
if (idxA < ROW_A-1) begin
idxA <= idxA + 1;
end
else begin
idxA <= 0;
end
end
注意 :通过修复索引分配,部分选择(+:
/ -:
)可能会起作用,因为设计无法覆盖一个出界的指数。