差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

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>​