我在genvar中有以下verilog代码,尽管变量'j'不是genvar变量。当我检查语法(使用Xilinx)时,我在带有'if'语句的行上收到错误“生成if语句中的非法条件表达式”。将'j'更改为genvar变量并不能解决问题,如何正确读取'j'?谢谢你的帮助。
genvar i;
generate
integer j=0;
for(i=0; (i<10); i=i+1) begin: gen_columns
if (j==0) begin
//some code
end
assign j=j+1;
end
endgenerate
答案 0 :(得分:1)
在详细设计(模拟开始之前)时,需要将生成块解析为标准的verilog模块项。在您的示例中,该工具正在尝试将if (j==0)
评估为常量,但无法执行此操作。
从你的例子中不清楚你要做什么。以下是一些适用于我的示例:
wire [9:0] w;
genvar i;
generate
for(i=0; (i<10); i=i+1) begin: gen_columns
if (i==0) begin
assign w[i] = 1'b0;
end else begin
assign w[i] = 1'b1;
end
end
endgenerate
initial begin
$display ("%x", w);
$finish;
end
此代码迭代总线的位,并根据位分配不同的值。输出为3fe
。
reg clk;
integer j [0:1];
genvar i;
generate
for(i=0; (i<2); i=i+1) begin: gen_columns
always @(posedge clk) begin
if (j[i]==0) begin
j[i] <= j[i] + 1;
end
end
end
endgenerate
initial clk = 1'b0;
always #1 clk = ~clk;
initial begin
$monitor ("%d: j[0]: %d, j[1]: %d", $time, j[0], j[1]);
repeat (2) @(posedge clk);
j[0] = 0;
j[1] = 0;
repeat (2) @(posedge clk);
$finish;
end
此代码为j[0]
和j[1]
创建相同的逻辑,以便在它们为零时递增它们。输出是:
0: j[0]: x, j[1]: x
3: j[0]: 0, j[1]: 0
5: j[0]: 1, j[1]: 1
我的第二个案例与您的示例之间的区别在于if语句和赋值放在always块中。在详细说明设计时,该工具将使用两个始终块替换生成块,一个块使用i=0
,另一个使用i=1
。
样式注释:虽然从多个always块更新变量是合法的verilog,但这不是一个好习惯。它很可能合成为乘法驱动的信号,并可能在模拟中引入竞争条件。在我的第二个示例中,如果作业是j = j + 1
(没有[i]
),那么j
将在多个始终块中分配。
答案 1 :(得分:1)
从上面的代码片段中,我无法确定您尝试建模的硬件类型。
For循环:在Verilog for循环中主要用于
- iterating over a set of bits for an operation (XORing, demux, et cetera)
- creating multiple instances of a structure using generate statements
直接从Verilog LRM获取生成循环:
生成循环允许一个或多个变量声明,模块,用户定义的基元, 门原语,连续分配,初始块和总是要实例化的块 多次使用for循环。生成for循环中使用的索引循环变量
应宣布为genvar。 for循环中的两个genvar赋值都应分配给它们 genvar,它是循环索引变量。 for循环中的第一个genvar赋值不应该 引用右侧的循环索引变量。
在你的代码中,j的目的是什么?在Verilog中,分配变量然后在同一程序块中将其用作控制逻辑是不好的形式。很可能你需要在generate-loop之外的另一个j程序块。我不知道你的代码中j的用途,但也许类似于以下内容?
// continuously increment counter each clock cycle
// asynchronous reset capability
integer j;
always @(posedge clock, posedge reset)
if (reset) j <= 0;
else j <= j + 1;