我尝试使用生成语句(Verilog HDL)重写此代码:
integer j;
always@(posedge cpu_clk) begin
// ACCU_RST
if(RAM[3][7]) begin
RAM[3][7] <= 1'b0;
for(j = 10; j <= 15; j = j + 1)
RAM[j] <= 8'b0;
end
// CPU write
RAM[addr + 0] <= in_valid && cmd && (addr + 0 <= 9 || addr + 0 >= 16) ? data_in[8 * 0 + 7:8 * 0] : RAM[addr + 0];
RAM[addr + 1] <= in_valid && cmd && (addr + 1 <= 9 || addr + 1 >= 16) ? data_in[8 * 1 + 7:8 * 1] : RAM[addr + 1];
RAM[addr + 2] <= in_valid && cmd && (addr + 2 <= 9 || addr + 2 >= 16) ? data_in[8 * 2 + 7:8 * 2] : RAM[addr + 2];
RAM[addr + 3] <= in_valid && cmd && (addr + 3 <= 9 || addr + 3 >= 16) ? data_in[8 * 3 + 7:8 * 3] : RAM[addr + 3];
//CPU read
out_valid <= !cmd && in_valid;
out_data[8 * 0 + 7:8 * 0] <= !cmd && in_valid ? RAM[addr + 0] : out_data[8 * 0 + 7:8 * 0];
out_data[8 * 1 + 7:8 * 1] <= !cmd && in_valid ? RAM[addr + 1] : out_data[8 * 1 + 7:8 * 1];
out_data[8 * 2 + 7:8 * 2] <= !cmd && in_valid ? RAM[addr + 2] : out_data[8 * 2 + 7:8 * 2];
out_data[8 * 3 + 7:8 * 3] <= !cmd && in_valid ? RAM[addr + 3] : out_data[8 * 3 + 7:8 * 3];
end
但是,如果我尝试这个,我会收到以下错误:
// CPU write
for(i = 0; i <= 3; i = i + 1) begin
if(in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[8 * i + 7:8 * i];
end
//CPU read
out_valid <= !cmd && in_valid;
for(i = 0; i <= 3; i = i + 1) begin
if(in_valid && !cmd)
out_data[8 * i + 7:8 * i] <= RAM[addr + i];
end
错误:我不是一个恒定的价值。 (错误指向data_in [8 * i + 7:8 * i]和out_data [8 * i + 7:8 * i])
另一次尝试,使用两个始终块,一个用于生成,一个用于ACCU_RST,为RAM生成多个驱动程序(duh)。
上次尝试:
genvar i;
always@(posedge cpu_clk) begin
if(ACCU_RST) begin
RAM[3][7] <= 1'b0;
for(j = 10; j <= 15; j = j + 1)
RAM[j] <= 8'b0;
end
// CPU write cmd
for(i = 0; i <= 3; i = i + 1) begin :CPU_W
if(in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[8 * i + 7:8 * i];
end
//CPU read cmd
out_valid <= !cmd && in_valid;
for(i = 0; i <= 3; i = i + 1) begin :CPU_R
if(in_valid && !cmd)
out_data[8 * i + 7:8 * i] <= RAM[addr + i];
end
end
产量: 错误:不允许对非寄存器i进行程序分配,左侧应为reg / integer / time / genvar(并指向i = 0和i = i + 1)。
请停下来。答案 0 :(得分:1)
为此你不应该使用生成块。 generate for循环必须存在于always块之外。并且值必须仅在一个始终块中分配以便可合成。以下面的示例为例,RAM[2]
可以在第三个循环addr==0
上i==2
时分配,addr==1
在第二个循环(i==1
上)时分配,{}在第一个循环addr==2
上i==0
时。三个独立的始终块,这是一个可综合的错误。
genvar i;
generate
for(i=0; i<4; i++) begin
always @(posedge clk)
if (in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[8*i + 7 : 8*i];
end
endgenerate
跳过生成并在always块内使用标准for循环。使用索引部分选择(引用here和here):
integer i; // <-- not genvar
always @(posedge cpu_clk) begin
/* ... your other code ... */
// CPU write cmd
for (i = 0; i < 4; i = i + 1) begin :CPU_W
if (in_valid && cmd && (addr + i <= 9 || addr + i >= 16))
RAM[addr + i] <= data_in[ 8*i +: 8];
end
//CPU read cmd
out_valid <= !cmd && in_valid;
for (i = 0; i < 4; i = i + 1) begin :CPU_R
if (in_valid && !cmd)
out_data[ 8*i +: 8] <= RAM[addr + i];
end
end