Verilog_Day3
内容为书中第5章
条件语句
- 条件语句必须在过程块语句中使用。所谓过程块语句是指由 initial 和 always 语句引导的执行语句集合。除这两种块语句引导的begin_end块中可以编写条件语句外,模块中的其他地方都不能编写。
- if 后面的表达式的结果若为0 ,x ,z 则按“假”处理;只有当为“1”时,按“真”处理。
case语句
- case语句通常用于微处理器的指令译码。
- 一般表示形式: 1. case(表达式) <case分支项> endcase
2. casez(表达式) <case分支项> endcase
3. casex(表达式) <case分支项> endcase
- 书中的一个case例子:
reg [15:0] rega; reg [9:0] result; case(rega) 16'd0:result=10'b01_1111_1111; //注意冒号 16'd1:result=10'b10_1111_1111; 16'd2:result=10'b11_0111_1111; 16'd3:result=10'b11_1011_1111; 16'd4:result=10'b10_1101_1111; 16'd5:result=10'b10_1110_1111; 16'd6:result=10'b10_1111_0111; 16'd7:result=10'b10_1111_1011; 16'd8:result=10'b10_1111_1101; 16'd9:result=10'b10_1111_1110; default:result=10'bx; // 注意不能写成 result='bx; endcase
- default项可有可无,一个case语句中只准有一个default项。
- case,casez,casex的真值
| case | 0 | 1 | x | z | casez | 0 | 1 | x | z | casex | 0 | 1 | x | z | ||
| 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | ||
| 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | ||
| x | 0 | 0 | 1 | 0 | x | 0 | 0 | 1 | 1 | x | 1 | 1 | 1 | 1 | ||
| z | 0 | 0 | 0 | 1 | z | 1 | 1 | 1 | 1 | z | 1 | 1 | 1 | 1 |
case 执行严格的对比,类似于=== ;casez将高阻态(z)当万能牌 ; casex将高阻和不定(x,z)都当做万能牌。
-
casex和casez是case的特殊情况,用来处理过程中不必考虑的情况(don't care condition)。casez用来处理不用考虑高阻值,casex表示不用考虑高阻值和不定值。
上述表格说明casez中,可以将z任意匹配,casex中可以将x任意匹配。在case的分支语句中,从上到下开始匹配,输出第一个匹配成功的值。http://www.cnblogs.com/poiu-elab/archive/2012/11/02/2751323.html
循环语句
- 类型共有4种:1.forever ; 2.repeat ; 3.while ; 4.for 。
- forever begin 多条语句 end 必须写在initial块中。
- repeat(表达式)begin 多条语句 end 。其表达式多为常量表达式,表示循环次数。
- while(表达式) begin 多条语句 end 。
- for的用法与C类似。
顺序快与并行块
- 顺序块:begin...end。下面是一个简单的例子
// 1.无延时块 reg x,y; reg [1:0] z,w; initial begin x=1'b0; y=1'b1; z={x,y}; w={y,x}; end // 2. 有延时块 reg x,y; reg [1:0] z,w; initial begin x=1'b0; #5 y=1'b1; #10 z={x,y}; #20 w={y,x}; end
在上面的例子中,说明1,在仿真时刻0时刻x,y,z,w的最终值分别为0,1,1,2。执行这4个赋值语句有顺序,但不需要执行时间。在说明2中,这4个变量的最终值同1一样。但最终的仿真时间为35.
- 并行块:fork-join。目前所使用的仿真器无法正确的处理竞争。
- 命名块:
module top; initial begin:block1 integer i; end initial fork:block2 reg i; join
像上面的代码,可以通过top.block1.i访问block1块中的整型变量i;也可以通过top.block2.i访问block2块中的寄存器型变量i。
- Verilog通过关键字disable提供了一种终止命名块执行的方法。disable可以用来从循环中退出,处理错误条件以及根据控制信号来控制某些代码段是否执行。类似于C中的break。但是break只可以退出当前所在的循环,而disable可以禁用设计中任意一块命名块。使用方法:disable 块名;
生成块
以下内容转载来自:https://www.cnblogs.com/SYoong/p/5858996.html
生成块可以动态的生成Verilog代码。可以用于对矢量中的多个位进行重复操作、多个模块的实例引用的重复操作、根据参数确定程序中是否包含某段代码。生成语句可以控制变量的声明、任务和函数的调用、还能对实例引用进行全面的控制。在编程时,应用关键字generate_endgenerate来说明生成的实例范围。
生成实例可以是一下的以下一种或多种类型:
1)模块 ; 2)用户定语原语 ; 3)门级原语 ; 4)连续赋值语句; 5)initial 和 always 块。
生成实例中语序的数据类型:
1)wire型 reg型;
2)integer型,real型,time型,realtime型;
3)event型。
生成的数据、实例、任务、函数都具有唯一的标识名,可以被层次引用。(任务和函数的声明可以出现在生成范围之中,但是不能出现在循环过程当中)
不允许出现在生成范围之中的模块项声明:
1)参数、局部参数;
2)输入、输出、输入/输出声明;
3)指定块。
在Verilog中有三种常见生成语句的方法:
1)循环生成; 2)条件生成; 4)case生成。
A)循环生成语句
循环生成语句允许使用者对下面的模块或模块项进行多次的实例引用;
1)变量声明; 2)模块; 3)用户定义原语、门级原语; 4)连续赋值语句; 5)initial 和 always 块。
例:用循环生成语句描述的脉动加法器
//本地生成一个门级脉动加法器
module ripple_adder(co,sum,a0,a1,ci);
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; //指定进位变量的第0位等于进位的输入
genvar i ; //声明临时变量,该变量只用于生成块的循环中,在确定的仿真代码中是不存在的。
generate
for( 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
//根据上面的循环生成,Verilog编译器会自动生成以下相对层次实例名
//xor: r_loop[0].g1, r_loop[1].g1, r_loop[2].g1, r_loop[3].g1;
// r_loop[0].g2, r_loop[1].g2, r_loop[2].g2, r_loop[3].g2;
//and:r_loop[0].g3, r_loop[1].g3, r_loop[2].g3, r_loop[3].g3;
// r_loop[0].g4, r_loop[1].g4, r_loop[2].g4, r_loop[3].g4;
//or : r_loop[0].g5, r_loop[1].g5, r_loop[2].g5, r_loop[3].g5;
//根据上面的生成实例用下面这些线网连接起来
//Nets:r_loop[0].t1, r_loop[0].t2, r_loop[0].t3;
// r_loop[1].t1, r_loop[1].t2, r_loop[1].t3;
// r_loop[2].t1, r_loop[2].t2, r_loop[2].t3;
// r_loop[3].t1, r_loop[3].t2, r_loop[3].t3;
assign co=carry[N];
endmodule
B)条件生成语句
条件生成语句类似于 if_else_if 的生成构造,该结构可以在设计模块中根据经过仔细推敲并确定表达式,有条件的调用以下结构:
1)模块; 2)用于定义的原语,门级原语; 3)连续赋值语句; 4)initial 或always 块。
C)case生成语句
case生成语句可以调用以下的结构:
1)模块; 2)用于定义的原语,门级原语; 3)连续赋值语句; 4)initial 或 always块。
由定义来看,在if 和 case的生成语句中,不能够声明变量。
生成块补充:使用循环生成语句会生成n个相应循环次数的块。使用块名[m]进行具体块的访问和操作。
浙公网安备 33010602011771号