• 牛客刷题<八>使用generate...for语句简化语句


    题目:使用generate…for语句简化代码_牛客题霸_牛客网

    收获:首先解决一个常见的报错问题,

    (97111238)编译错误:您提交的代码无法完成编译

    main.v:11: error: data_out[i] is not a valid l-value in gen_for_module.

    main.v:5: : data_out[i] is declared here as wire.

    Elaboration failed

    此问题的原因在于变量 data_out被定义为wire型,但是却被在always块中使用,所以报错。解决办法是:要么在最初定义变量的时候直接定义为reg型,要么在module块外再定义一个reg型变量,此变量只是变量名和类型不同,其它位数是和其相同,用新定义的变量代替原变量用在always块中,最后在always块外使用assign赋值语句把新定义的变量赋值给原变量即可。

    1. `timescale 1ns/1ns
    2. module gen_for_module
    3. (
    4. input [7:0] data_in,
    5. output [7:0] data_out
    6. );
    7. integer i;
    8. //reg [7:0] dout_reg;
    9. always@(*)begin
    10. for(i=0;i<8;i=i+1) begin
    11. data_out[i] = data_in[7-i];
    12. end
    13. end
    14. //assign data_out = dout_reg;
    15. endmodule

    上面是报错的代码

    1. `timescale 1ns/1ns
    2. module gen_for_module
    3. (
    4. input [7:0] data_in,
    5. output reg [7:0] data_out
    6. );
    7. integer i;
    8. //reg [7:0] dout_reg;
    9. always@(*)begin
    10. for(i=0;i<8;i=i+1) begin
    11. data_out[i] = data_in[7-i];
    12. end
    13. end
    14. //assign data_out = dout_reg;
    15. endmodule

    上面是加reg后的

    1. `timescale 1ns/1ns
    2. module gen_for_module
    3. (
    4. input [7:0] data_in,
    5. output [7:0] data_out
    6. );
    7. integer i;
    8. reg [7:0] dout_reg;
    9. always@(*)begin
    10. for(i=0;i<8;i=i+1) begin
    11. dout_reg[i] = data_in[7-i];
    12. end
    13. end
    14. assign data_out = dout_reg;
    15. endmodule

    上面是使用新变量的

    generate语句

    generate语句是verilog-2001添加的新语法,也被叫做生成语句,包括generate-for(循环生成语句)、generate-case(条件生成语句)和generate-if(条件生成语句)三种语句
    generate语句可以方便地重复实例化模块或者条件性实例化模块,这也是该语句的核心用法,

    2. 解析

    2.1 for循环

    for循环,必须在always块里使用。对应的,always块内的变量要声明成reg类型。

    for(表达式1;表达式2;表达式3),执行时对表达式1、2、3和C语言中一样:

    (1)执行表达式1,一般是循环变量赋初值;

    (2)执行表达式2,若结果为真则执行for里面的内容,否则结束for语句;

    (3)执行完for里面的语句,执行表达式3,一般是循环变量自增、自减、移位等操作,回到(2);

    verilog的for和C语言的for的不同点;

    C语言的for里面的语句是串行顺序执行,而verilog的for内的语句实际是并行的,只是为了写代码方便才用for对多个同样的结构赋值。

    当相同结构的赋值语句较多时,使用for语句能够简化代码,并不会影响实际综合后的电路结构。

    2.2 generate...for

    1

    2

    3

    4

    5

    6

    genvar i;

    generate for(i=0;表达式2;表达式3)

    begin :起个名字

        ...;

    end

    endgenerate

    作用上:和for是一样的;

    区别:

    (1)generate for的循环变量必须用genvar声明,for的变量可以用reg、integer整数等多种类型声明;

    (2)for只能用在always块里面,generate for可以做assign赋值,用always块话always写在generate for里;

    (3)generate for后面必须给这个循环起一个名字,for不需要;

    (4)generate for还可以用于例化模块;

    上面的for如果用generate...for写:

    1. always @ (posedge clk)
    2. begin
    3. data_reg[0] <= data_in;
    4. end
    5. genvar i;
    6. generate for(i = 0; i < 4; i = i+1) begin : shift_reg
    7. always @ (posedge clk) begin
    8. data_reg[i+1] <= data_reg[i];
    9. end
    10. end
    11. endgenerate

  • 相关阅读:
    maven学习笔记
    英特尔旗下Mobileye纳斯达克上市:上涨38% 市值231亿美元
    聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(完结篇)
    Android 指定有线网或Wifi进行网络请求
    网络安全(黑客)自学
    CNN,RNN,LSTM,GRU的前后向传播算法(梯度是怎么更新的)
    qtdesigner界面美化
    Es集群部署
    新手小白教程之 圈X-QuantumultX i茅台自动预约教程
    第六十三天 p1192
  • 原文地址:https://blog.csdn.net/mxh3600/article/details/126419268