块语句
概念:将两条或多条语句组合在一起,使其在格式上看更像一条语句
顺序块:标识顺序执行的语句
- 块内的语句按顺序执行,上一条语句执行完后下面语句才能执行
- 每条语句的延迟时间相对于前一条语句的仿真时间
-
直到最后一条语句执行完,程序流程才跳出该语句块
-
块内声明语句可以是参数声明语句、reg型变量声明语句、integer型变量声明语句和real型变量声明语句
并行块:标识并行执行的语句
- 块内语句同时执行
- 块内每条语句的延迟时间相对于程序流程控制进入到块内的仿真时间
- 延迟时间用来给赋值语句提供时序
-
当按时间时序排在最后的语句执行完后或一个disable语句执行时,程序流程控制跳出块
-
块内声明语句可以是参数声明语句、reg型变量声明语句、integer型变量声明语句、real型变量声明语句、time型变量声明语句和event声明语句
并行块需避免竞争:不能存在两条语句同时对一个变量产生影响
特点:
-
嵌套块:顺序块并行块混合使用
-
命名块:块可以具有自己的名字
- 块名:在任何仿真时刻确认变量值的方法
- 可在块内定义局部变量(只能在块内使用的变量)
- 可以允许块被其他语句调用(如disable)
- 所有变量是静态的,跳入或跳出块不影响存储在变量内的值
- 块名:在任何仿真时刻确认变量值的方法
-
命名块禁用
- disable关键字:类似于break,可禁用任意一个命名块
生成块¶
概念:动态地生成Verilog代码,能控制变量的声明、任务或函数的调用,还能对实例引用进行全面的控制
可生成实例类型:
- 模块
- 用户定义原语
- 门级原语
- 连续赋值语句
initial
和always
块 可声明数据类型:- net, reg
- integer, real, time, realtime
- event
循环生成:对模块或模块项进行多次实例引用 例:两条N位总线变量按位异或
module bitwise_xor(out, i0, i1);
parameter N = 32;
output [N-1: 0] out;
input [N-1: 0] i0, i1;
genvar j; // 临时循环变量, 设计时不存在
generate
for (j = 0; j < N; j = j + 1) begin: xor_loop
xor g1 (out[j], i1[j], i1[j]);
end
endgenerate
// xor可用always块替代
reg [N-1: 0] out;
generate
for (j = 0; j < N; j = j + 1) begin: bit
always @ (i0[j] or i1[j]) out[j] = i0[j] ^ i1[j];
end
endgenerate
endmodule
- 在仿真开始前,仿真器会对生成块中的代码进行确定(展平),将生成块转换为展开时的代码,然后对展开后的代码进行仿真;本质时使用循环内的一条语句替代多条重复的Verilog语句
- 关键字genvar用于声明生成变量,只能用在生成块之中;确立后的仿真代码不含生成变量;生成变量的值只能在循环生成语句中改变
- 循环生成语句可以嵌套使用(使用同一个生成变量作为索引的生成语句不能相互嵌套)
xor_loop
是循环生成语句名,对异或门的引用:xor_loop[0].g1
重点在于想象循环生成语句被展平后的形式
例:脉动加法器
module ripple_adder(co, sum, a0, a1, ei);
parameter N = 4;
output [N-1:0] sum;
output co;
input [N-1:0] a0, a1;
input ci;
wire [N-1:0] carry;
assign carry[0] = ci;
genvar i;
generate
for (int i = 0; i < N; i = i + 1) begin: r_loop
wire t1, t2, t3;
xor g1 (t1, a0[i], a1[i]);
xor g2 (sum[i], t1, carry[i]);
and g3 (t2, a0[i], a1[i]);
and g4 (t3, t1, carry[i]);
or g5 (carry[i + 1], t2, t3);
end
endgenerate
assign co = carry[N];
endmodule
条件生成语句:用条件地调用Verilog结构
例:参数化乘法器
module multiplier (product, a0, a1);
parameter a0_width = 8;
parameter a1_width = 8;
// 本地参数不能使用defparam修改, 也不能在实例引用时通过传递参数语句修改
localparam product_width = a0_width + a1_width;
output [product_width - 1: 0] product;
input [a0_width - 1: 0] a0;
input [a1_width - 1: 0] a1;
generate
if (a0_width < 8 || a1_width < 8)
cal_multiplier # (a0_width, a1_width) m0 (product, a0, a1);
else
tree_multiplier # (a0_width, a1_width) m0 (product, a0, a1);
endgenerate
endmodule
case生成语句:多选一case构造,有条件调用Verilog结构
例:N位加法器
module adder(co, sum, a0, a1, ci);
parameter N = 4;
output [N-1: 0] sum;
output co;
input [N-1: 0] a0, a1;
input ci;
generate
case (N)
1: adder_1bit adder1 (co, sum, a0, a1, ci);
2: adder_2bit adder2 (co, sum, a0, a1, ci);
default: adder_cla # (N) adder3 (co, sum, a0, a1, ci);
endcase
endgenerate
endmodule