前言:在verilog hdl中条件分支语句分为两种:if条件语句和case条件分支语句。二这两个语句也是唯一可以广泛使用的语句。
1.if条件语句
判断所给的条件是否满足,然后根据判断情况来进行下一步操作。
形式1:if(条件表达式)语句块;
形式2:if(条件表达式)
语句块1;
else
语句块2;
形式3:循环嵌套
其实if语句也可以用连续赋值语句表示
assign out=sel?a:s;
进一步思考if语句其实就是二选一数据选择器。
3.2-11中采用了循环嵌套,而实际我们应该有意识的将语句想成对应的电路。
2.case语句
case语句是相等比较,所有表达值必须位宽相等。现对于if只有两个分支,case语句是一种实现多路分支选择的语句,这一点跟c比较相似,比if-else语句更方便和直观,一般用于多条件姨妈电路设计,其格式为
case(控制表达式)
值1:语句块1
值2:语句块2
......
值n: 语句块n
default:语句块n+1
endcase
重要的是case时表征组合电路重要方式,其表征的有两种一种是表征有限状态积,另一种是电路的真值表
下面举一个例子,就是非常常见的BCD数码管译码,这个例子也解答了很久很久的好奇心。就是数码管怎么亮的。
module BCD_decoder(out,in);
output[6:0]out;
input[3:0]in;
reg[6:0]out;
always@(in)
beigin
case(in)
4'd0: out = 7'b1111110;
4'd1: out = 7'b0110000;
4'd2: out = 7'b1101101;
4'd3: out = 7'b1111001;
4'd4: out = 7'b0110011;
4'd5: out = 7'b1011011;
4'd6: out = 7'b1011111;
4'd7: out = 7'b1110000;
4'd8: out = 7'b1111111;
4'd9: out = 7'b1111011;
default:out-7'bx;
endcase
end
endmodule
在使用case语句时, 应包含所有状态, 如果没包含全, 那么缺省项必须写, 否则将产生锁存器, 这在同步时序电路设计中是不允许的。
//例3.2-13: case语句的使用例程程序 (1) 会产生锁存器的case语句
module latch—case(a,b,sel ,out);
input a,b;
input[1:O]sel;
output out;
reg out;
always@(a,b,sel)
case(sel)
2'b00: out=a;
2'b11 :out=b;
endcase
endmodule
//不会产生锁存器的case语句
module non_latch_case(a,b,sel ,out); input a,b;
input [1 :O]sel;
output out;
reg out;
always@(a,b,sel)
case(sel)
2'b00:out=a;
2'b11 :out=b;
default:out=O;
endcase
endmodule
我们知道不加default相当于如果找不到符合得值的信号就会发生不改变的问题,就是in=ou。除了触发器,在电路中不允许出现此类情况:
加上default就是排除了这种情况。
除了case分支语句以外,还有casez,casex这两种功能类似的条件的分支语句。下面为他们的真值表
也就是casez只比较0,1状态和不定状态,而认为高阻状态都为1,。而casex语句只比较0和1.
1.forever(时钟信号是不断循环的)
1 . forever循环语句
关键字 "forever" 所引导的循环语句表示永久循环。 在永久循环中不包含任何条件表达式, 只执行无限的循环, 直到遇到系统任务$finish为止。 如果需要从forever循环中退出, 则可以使用disable语句。 forever语句的语法格式是
每经过50个单位时间clock取反
2.repeat语句
每经过4个时钟周期改变
时钟网络占功耗的30%
3.while
4.for
重要注意的是这四条循环语句在硬件中是毫无意义的,因为不是用for来定义的,而是用计数器定义的,if表征的只是一个变量形式而不是物理的信号量。在初学者和企业中都不会使用循环语句