问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Verilog:generate、for、always 语句用法与电路结构对比

创作时间:
作者:
@小白创作中心

Verilog:generate、for、always 语句用法与电路结构对比

引用
CSDN
1.
https://blog.csdn.net/weixin_44544687/article/details/109720389

本文通过实际代码对比了Verilog中generate、for、always等语句的不同用法及其对应的电路结构。文章内容详实,包含了具体的代码示例、仿真结果和电路结构图,对于学习和使用Verilog的工程师具有较高的参考价值。

1. always-for

代码:

reg [data_width-1:0] in1_reg [0:depth-1];
integer i;
always @(posedge clk or negedge rst_n)
begin
    if (!rst_n)
    begin
        for (i = 0; i < depth; i = i + 1)
            in1_reg[i] <= 0;
    end
    else
    begin
        for (i = 0; i < depth; i = i + 1)
            in1_reg[i] <= in1 + i;
    end
end

仿真结果说明:in1_reg 在第一个有效时钟沿后,数据均变为目标值

ANALYSIS得到的结构图

综合后的电路图:

2. for-always

代码:

//integer j;							// Error:j is not a genvar;j is not a constant
genvar j;
reg [data_width-1:0] in2_reg [0:depth-1];
for (j = 0; j < depth; j = j + 1)
begin: in2_loop
    always @(posedge clk or negedge rst_n)
    begin
        if (!rst_n)
            in2_reg[j] <= 0;
        else
            in2_reg[j] <= in2 + j;
    end
end

仿真结果说明:in2_reg 在第一个有效时钟沿后,数据均变为目标值

ANALYSIS得到的结构图

综合后的电路图:

3. generate_for_always

代码:

reg [data_width-1:0] in3_reg [0:depth-1];
genvar k;
generate
    for (k = 0; k < depth; k = k + 1)
    begin: generate_case
        always @(posedge clk or negedge rst_n)
        begin
            if (!rst_n)
                in3_reg[k] <= 0;
            else
                in3_reg[k] <= in3 + k;
        end
    end
endgenerate

仿真结果说明:in3_reg 在第一个有效时钟沿后,数据均变为目标值

ANALYSIS得到的结构图

综合后的电路图:

3.1. generate-always-for

代码:

reg [data_width-1:0] in31_reg [0:depth-1];
//genvar k1;		// Error:procedural assignment to a non-register k1 is not permitted, left-hand side should be reg/integer/time/genvar 
integer k1;
generate
    always @(posedge clk or negedge rst_n)
    begin
        if (!rst_n)
        begin
            for (k1 = 0; k1 < depth; k1 = k1 + 1)
            begin: for_rst
                in31_reg[k1] <= 0;
            end
        end
        else
        begin
            for (k1 = 0; k1 < depth; k1 = k1 + 1)
            begin: generate_always_for
                in31_reg[k1] <= in31 + k1;
            end
        end
    end
endgenerate

仿真结果说明:in31_reg 在第一个有效时钟沿后,数据均变为目标值

ANALYSIS得到的结构图

综合后的电路图:

4. for-assign

代码:

wire [data_width-1:0] in4_wire [0:depth-1];
//integer n;			// Error: n is not a genvar;n is not a constant
genvar n;
for (n = 0; n < depth; n = n + 1)
begin: for_assign
    assign in4_wire[n] = in4 + n;
end

仿真结果说明:wire型,仿真开始即有值,随输入信号变化而变化

ANALYSIS得到的结构图

综合后的电路图:

5. generate-for-assign

代码:

wire [data_width-1:0] in5_wire [0:depth-1];
genvar m;
generate
    for (m = 0; m < depth; m = m + 1)
    begin: generate_for_assign
        assign in5_wire[m] = in5 + m;
    end
endgenerate

仿真结果说明:wire型,仿真开始即有值,随输入信号变化而变化

ANALYSIS得到的结构图

综合后的电路图:

6. always@(*)-for

代码:

reg [data_width-1:0] in6_reg [0:depth-1];
always @(*)
begin
    for (i = 0; i < depth; i = i + 1)
        in6_reg[i] = in6 + i;
end

仿真结果说明:wire型,仿真开始即有值,随输入信号变化而变化

ANALYSIS得到的结构图

综合后的电路图:

7. for-always@(*)

可以用 for-assign 替换

8. generate_for_always@(*)

可以用generate-assign 替换

仿真结果

可以看到,时序信号in1_reg,in2_reg,in3_reg,in31_reg 都在第一个有效时钟边沿后变为目标值;组合逻辑信号in4_wire, in5_wire, in6_reg 在电路开始仿真时即被赋值进行运算,输入数据变化后随之发生变化

  1. 根据电路结构,generate-for 和 for 循环对于always 和 assig 语句的作用相同,但书写方法不同

generate-for / for循环在alway块外面时,循环变量要定义为 genvar 型

for 循环在always 块内时,循环遍历要定义为 integer 类型

  1. 结论:

若要在循环/条件/分支语句中调用模块,须使用 generate-for语句,注意要用genvar 定义循环变量,并在for循环的 begin: 后跟上 循环名称;

其他情况可根据自身情况而定

generate-for和for循环使用说明可见 Verilog:generate-for 语句(用法,及与for语句区别)

文中的代码等可见https://download.csdn.net/download/weixin_44544687/13117406

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号