差别
这里会显示出您选择的修订版和当前版本之间的差别。
— |
endgenerate [2018/09/14 13:55] (当前版本) group001 创建 |
||
---|---|---|---|
行 1: | 行 1: | ||
+ | 一:generate\\ | ||
+ | Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function,continous assignment,initial和always。在generate语句中可以引入if-else和case语句,根据条件不同产生不同的实例化。\\ | ||
+ | 用法:\\ | ||
+ | - generate语法有generate for, genreate if和generate case三种 | ||
+ | - generate for语句必须有genvar关键字定义for的变量 | ||
+ | - for 的内容必须加begin和end | ||
+ | - 必须给for语段起个名字 | ||
+ | 例子:\\ | ||
+ | 1. generate for例子:\\ | ||
+ | <code verilog> | ||
+ | generate | ||
+ | genvar i; //generate 8 samll fifo for in_data[i] 8X72 | ||
+ | for(i=0; i<NUM_QUEUES; i=i+1) begin: in_arb_queues //NUM_QUEUES = 8 | ||
+ | small_fifo | ||
+ | #( .WIDTH(DATA_WIDTH+CTRL_WIDTH), | ||
+ | .MAX_DEPTH_BITS(2)) | ||
+ | in_arb_fifo | ||
+ | (// Outputs | ||
+ | .dout ({fifo_out_ctrl[i], fifo_out_data[i]}), | ||
+ | .full (), | ||
+ | .nearly_full (nearly_full[i]), | ||
+ | .prog_full (), | ||
+ | .empty (empty[i]), | ||
+ | // Inputs | ||
+ | .din ({in_ctrl[i], in_data[i]}), | ||
+ | .wr_en (in_wr[i]), | ||
+ | .rd_en (rd_en[i]), | ||
+ | .reset (reset), | ||
+ | .clk (clk)); | ||
+ | end // block: in_arb_queues | ||
+ | endgenerate | ||
+ | </code> | ||
+ | 2.generate if例子:\\ | ||
+ | <code verilog> | ||
+ | generate | ||
+ | if (REG_WIDTH == WRITE_WIDTH) begin : new_data_a_generation | ||
+ | assign new_data_a = merge_update ? merge_wr_data : held_wr_data_a; | ||
+ | end | ||
+ | else begin | ||
+ | assign new_data_a = merge_update ? | ||
+ | {{(REG_WIDTH - WRITE_WIDTH - 1){merge_wr_data_sign}}, merge_wr_data} : | ||
+ | {{(REG_WIDTH - WRITE_WIDTH){held_wr_data_sign_a}}, held_wr_data_a}; | ||
+ | end | ||
+ | endgenerate | ||
+ | </code> | ||
+ | 3.generate还可以进行多个assign赋值\\ | ||
+ | <code verilog> | ||
+ | module anytest_v( | ||
+ | input clk, | ||
+ | input[7:0] datain, | ||
+ | output[7:0] dataout, | ||
+ | output finish | ||
+ | ); | ||
+ | wire[7:0] mem[31:0]; | ||
+ | wire[32*8-1:0] xxx; | ||
+ | //reg[7:0] i; | ||
+ | generate | ||
+ | genvar i; | ||
+ | for(i=0;i<=31;i=i+1) | ||
+ | begin :wiertech | ||
+ | assign mem[i]= 8'b0; | ||
+ | end | ||
+ | endgenerate | ||
+ | endmodule | ||
+ | </code> | ||
+ | ps: 对于a[8*i+:8]\\ | ||
+ | this is the so-called "Indexed vector part selects"\\ | ||
+ | 在Verilog-1995中,可以选择向量的任一位输出,也可以选择向量的连续几位输出,不过此时连续几位的始末数值的index需要是常量。而在Verilog-2001中,可以用变量作为index,进行part select。\\ | ||
+ | [base_expr +: width_expr] //positive offset | ||
+ | [base_expr -: width_expr] //negative offset | ||
+ | 其中base_expr可以是变量,而width_expr必须是常量。+:表示由base_expr向上增长width_expr位,-:表示由base_expr向上递减width_expr位。例如:\\ | ||
+ | <code verilog> | ||
+ | reg [63:0] word; | ||
+ | reg [3:0] byte_num; //a value from 0 to 7 | ||
+ | wire [7:0] byteN = word[byte_num*8 +: 8]; | ||
+ | </code> | ||
+ | 如果byte_num的值为4,则word[39:32]赋值给byteN\\ | ||
+ | 二、参数传递\\ | ||
+ | 类似VHDL的Generic语句,Verilog也可以在例化时传递参数\\ | ||
+ | 传递的参数是子模块中定义的parameter。\\ | ||
+ | 传递的方法:\\ | ||
+ | - module_name #( parameter1, parameter2) inst_name( port_map); | ||
+ | - module_name #( .parameter_name(para_value), .parameter_name(para_value)) inst_name (port map); | ||
+ | 用#方法和port map的写法差不多\\ | ||
+ | <code verilog> | ||
+ | module multiplier (a, b, product); | ||
+ | parameter a_width = 8, b_width = 8; | ||
+ | localparam product_width = a_width+b_width; | ||
+ | input [a_width-1:0] a; | ||
+ | input [b_width-1:0] b; | ||
+ | output[product_width-1:0]product; | ||
+ | generate | ||
+ | if((a_width < 8) || (b_width < 8)) | ||
+ | CLA_multiplier #(a_width, b_width) u1 (a, b, product); | ||
+ | else | ||
+ | WALLACE_multiplier #(a_width, b_width) u1 (a, b, product); | ||
+ | endgenerate | ||
+ | endmodule | ||
+ | </code> |