【发布时间】:2020-06-02 15:09:45
【问题描述】:
很简单的问题。给定以下代码:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
generate
genvar k;
for(k=0; k<2; k=k+1) begin: m
always @(posedge clk) begin
if(wren[k])
ram[addr[k]] <= dIn[k];
dOut[k] <= ram[addr[k]];
end
end
endgenerate
endmodule
quarus 13.0sp1 给出了这个错误(以及它的其他 20 个不正当的兄弟姐妹):
错误 (10028):无法在 main.v(42) 处解析网络“ram[63][14]”的多个常量驱动程序
但如果我手动展开生成循环:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
always @(posedge clk) begin
if(wren[0])
ram[addr[0]] <= dIn[0];
dOut[0] <= ram[addr[0]];
end
always @(posedge clk) begin
if(wren[1])
ram[addr[1]] <= dIn[1];
dOut[1] <= ram[addr[1]];
end
endmodule
分析和合成步骤一切顺利。
有什么办法可以让生成循环运行?
【问题讨论】:
-
绝对正确。您生成多个驱动
ram[addr[whatever]]的always语句;addr是一个 var 数组,无法在编译时解析。所以,它是多重驱动的。 -
@Serge 我无法理解您的评论。
-
我所说的“ram”在您的两种情况下都是多重驱动的。在任何情况下,综合都应该给出一些警告/错误,除非它可以将 'addr' 解析为常量。
-
Serge 和工具谢谢。我懂了。但是为什么展开的版本有效。此外,模板使用非常相似的代码来推断 Quartus 的真正双端口 RAM。那里看不到同一个地址写冲突吗?
-
@toolic,如果我强制更新条件为
addr[0]!=addr[1] && wren[k],则没有雪茄
标签: verilog fpga hdl quartus intel-fpga