Verilog中generate的使用(转载)

  常用generate语句做三件事情转载学习

  • 一个是用来构造循环结构,generate-for,用来多次实例,其中生成的实例可以是多个类型
    (1)模块;
    (2)用户定义原语;
    (3)门级语句;
    (4)连续赋值语句;
    (5)initial和always。
      

  • 一个是构造条件generate结构,用来在多个块之间最多选择一个代码块,条件generate结构包含if–generate结构和case–generate形式。

  • 断言
      其中关键字generate-endgenerate用来指定范围。

1.generate for 循环结构

  使用时必须先在genvar声明中声明循环中使用的索引变量名,然后才能使用它。genvar声明可以是generate结构的内部或外部区域,并且相同的循环索引变量可以在多个generate循环中,只要这些环不嵌套。genvar只有在建模的时候才会出现,在仿真时就已经消失了。
  Verilog中generate循环中的generate块可以命名也可以不命名。如果已命名,则会创建一个generate块实例数组。如果未命名,则有些仿真工具会出现警告,因此,最好始终对它们进行命名。
  generate语法上的用法

generate-for语句(通常用于重复例化模块)
(1) 必须有genvar关键字定义for语句的变量。
(2)for语句的内容必须加begin和end(即使就一句)。
(3)for语句必须有个名字。

  详细的示例程以及注意事项

//通过循环结构来例化多个模块,一般的语法结构就是:
genvar j;
generate
    for(i=0; i<3; i=i+1)begin: inst_rtl 
    //generate for begin后面的名字是必须要有的,之后仿真器会通过这个标识来生成结构:
        flow_proc U_PROC(clk, rst_n, data_vld, in_data);
    end
endgenerate
//把若干[DATA_WD -1:0]的数据拼成总线数据PPORT_NUM
bit [DATA_WD -1:0]  data_arr [PORT_NUM];
bit [PORT_NUM*DATA_WD -1:0] data_in;
 
genvar i;
generate
    for(i=0; i<PORT_NUM; i=i+1)begin:gen_data
        assign data_in[i*DATA_WD +:DATA_WD] = data_arr[i];  //起始位位i*data_wd,位宽为data_wd
    end
endgenerate
//generate for里的参数必须直接调用,例如for(i=0; i<DEPTH; i=i+1),不能够出现运算例如for(i=0; i<DEPTH*5; i=i+1)

  generate循环的语法与for循环语句的语法很相似,区别主要是:

通常,generate for循环和普通 for循环之间的主要区别在于generate for循环正在为每次迭代生成一个实例。但博主通过观察电路图的方式认为两者再综合电路后没有不同。Verilog中关于for与generate for用法和区别的一点愚见

1.1 Verilog 可变的向量域选择

Verilog 支持可变的向量域选择,例如:

  • [bit+: width] : 从起始 bit 位开始递增,位宽为 width。
  • [bit-: width] : 从起始 bit 位开始递减,位宽为 width。

2.条件generate构造

详细的示例程序条件语句从很多的备选块中选择最多一个generate块,请注意,在这我说的是最多,因为有可能是一个也不选择的。条件必须为常量表达式

2.1 条件if-generate构造

generate
    if(FLOP_FLAG)begin
        always @(posedge clk)begin: FLOP_OUT
            if(~rst_n)begin
                out_vld  <= 0;
                out_data <= 0;
                out_cnt  <= 0;
            end
            else begin
                out_vld <= vld;
                out_data <= data;
                out_cnt <= cnt;
            end
        end
    end
    else begin
        always @(*) begin: NO_FLOP_OUT
            out_vld = vld;
            out_data = data;
            out_cnt = cnt;
        end
    end
endgenerate

&empt;&empt;由于最多选择一个代码块,因此在单个的if-generate中以相同的名称命名所有的备用代码块是合法的.

2.2.case_generate构造

&empt;&empt;generate_case其实跟generate_if一样的,都是根据模块的参数(必须是常量)作为条件判断,来生成满足条件的电路,不同的地方仅仅是改成使用case 的语法而已。
示例

//如果generate它内部含always块,那么根据所含是组合或者时序逻辑选择不同赋值方式
module generate_case #(
parameter SEL = 1
	)(
	output [3:0] out
    );
    generate
    	case(SEL)
    	1: begin
    		assign out = 4'b0001;
    	end
    	2: begin
    		assign out = 4'b0010;
    	end
    	3: begin
    		assign out = 4'b0100;
    	end
    	default: begin
    		assign out = 4'b0000;
    	end
    	endcase    	
    endgenerate
endmodule

3.断言和形式验证

verilog断言(SVA)语法
SV_Assertions断言(推荐阅读)

  断言assertion被放在verilog设计中,方便在仿真时查看异常情况。当异常出现时,断言会报警。一般在数字电路设计中都要加入断言,断言占整个设计的比例应不少于30%。

在这里插入图片描述

  • 2
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值