Verilog“如果”使用变量的语句

发布于 2024-10-31 21:21:58 字数 355 浏览 5 评论 0原文

我在 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

I have the following verilog code within a genvar, although the variable 'j' is not a genvar variable. When I check the syntax (using Xilinx) I receive the error "Illegal condition expression in generate if statement" on the line with the 'if' statement. Changing 'j' to a genvar variable doesn't fix the issue, how can I make read 'j' properly? Thanks for any help.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自由如风 2024-11-07 21:21:58

当详细设计时(仿真开始之前),生成块需要解析为标准 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 块中。当详细设计时,该工具将用两个always块替换generate块,一个带有i=0,一个带有i=1

风格注释:虽然从多个always块更新变量是合法的verilog,但它不被认为是好的做法。它可能会合成为多驱动信号,并可能在模拟中引入竞争条件。在我的第二个示例中,如果分配为 ​​j = j + 1(没有 [i]),则 j 将始终以多个方式分配块。

The generate block needs to be resolved to standard verilog module items when the design is elaborated (before simulation starts). In your example, the tool is trying to evaluate if (j==0) as a constant, and can't do it.

It's not clear from your example what you're trying to do. Here are a couple examples that work for me:

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

This code iterates over the bits of a bus and assigns a different value depending on the bit. The output is 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

This code creates identical logic for j[0] and j[1] to increment them if they are zero. The output is:

0: j[0]:          x, j[1]:          x
3: j[0]:          0, j[1]:          0
5: j[0]:          1, j[1]:          1

The difference between my second case and your example is that the if statement and assignment are placed within an always block. When the design is elaborated, the tool will replace the generate block with two always blocks, one with i=0 and one with i=1.

A style note: although it is legal verilog to update a variable from multiple always blocks, it is not considered good practice. It will likely synthesize as a multiply-driven signal and may introduce race conditions in simulation. In my second example, if the assignment were j = j + 1 (without [i]), then j would be assigned in multiple always blocks.

太阳男子 2024-11-07 21:21:58

从上面的代码片段中,我无法弄清楚您正在尝试建模的硬件类型。

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 的生成循环:

生成循环允许一个或多个变量声明、模块、用户定义的原语、
门原语、连续赋值、初始块和要实例化的always块
使用for循环多次。生成 for 循环中使用的索引循环变量
应被声明为 genvar。 for 循环中的两个 genvar 分配应分配给相同的
genvar,这是循环索引变量。 for 循环中的第一个 genvar 赋值不应
引用右侧的循环索引变量。

在您的代码中,j 的用途是什么?在 Verilog 中,分配变量然后将其用作同一程序块中的控制逻辑是一种不好的形式。最有可能的是,您需要在生成循环之外为 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;

From your code snippet above, I could not figure out what type of hardware you are trying to model.

For-loops: In Verilog for-loops are used primarily for

- iterating over a set of bits for an operation (XORing, demux, et cetera)
- creating multiple instances of a structure using generate statements

Straight from the Verilog LRM for generate-loops:

A generate-loop permits one or more variable declarations, modules, user defined primitives,
gate primitives, continuous assignments, initial blocks and always blocks to be instantiated
multiple times using a for-loop. The index loop variable used in a generate for-loop
shall be declared as a genvar. Both genvar assignments in the for-loop shall assign to the same
genvar, which is the loop index variable. The first genvar assignment in the for-loop shall not
reference the loop index variable on the right-hand side.

In your code, what is the purpose of j? In Verilog it is bad form to assign a variable and then use it as control logic in the same procedural block. Most likely you need another procedural block for j outside of the generate-loop. I don't know the purpose of j in your code, but perhaps something like the following?

 // continuously increment counter each clock cycle
 //  asynchronous reset capability 
 integer j;
 always @(posedge clock, posedge reset)
    if (reset) j <= 0;
    else j <= j + 1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文