case语句,是包含在case和endcase之间的代码,逻辑上等价于if-else语句,使用方法如下:
case (case_expression)
case_item1 : case_item_statement1;
case_item2 : case_item_statement2;
case_item3 : case_item_statement3;
case_item4 : case_item_statement4;
default : case_item_statement5;
endcase
casez语句,允许"z" 和 "?"值在比较时被当作不关心,"z" 和 "?"时等价的。
注意:当编写可综合代码时,要小心使用casez;使用casez时,最好使用"?" 表示不关心,不能使用"z" 表示不关心。
casex语句,允许"x" "z" 和 "?"值在比较时被当作不关心.
注意:当编写可综合代码时,不要使用casez
case语句执行过程:
1. 每次执行case语句时,括号内case expression 只计算一次,然后按照从上到下的顺序与每个case item比较。
2. 如果有case default ,那么在这个从上到下的比较过程中忽略它。
3. 如果有一个case item 与 case expression 匹配上,那么就执行此case item语句,然后终止case语句。
· 4. 如果所有比较都失败,而且有case default,那么就执行case default语句,然后终止case语句。
5.如果所有比较都失败,而且没有case default,那么就终止case语句。
注意:1 排在前面的case item 具有更高的优先级。
2 所有的case expression 和 case item的位长都将调整到最长的位长。
3 如果有一个时unsigned,那么所有都按照unsigned调整。
case应用
case可以检查x和z
case (sig)
1'bz : $display ("signal is floating");
1'bx : $display ("signal is unknown");
default : $display ("signal is %b" ,sig);
endcase
case item中有x和z时,这段代码时不可综合的
可使用反向case语句,而且是优先级编码器。
reg [2:0] encode;
case (1)
encode[2] :$display ("Select Line 2");
encode[1] :$display ("Select Line 1");
encode[0] :$display ("Select Line 0");
default :$display ("Error: Only one of the bits is expected ON");
endcase
case 语句可以时full 和parallel :若是full,就不会产生latch ; 若是parallel ,就不会产生优先级编码器。综合工具一般可以自由推导出是否是full 或parallel。
// 这段代码就是full 又是 parallel ,因此既不会生产Latch 也不会生成优先级编码器
always @ (*)
begin
case (sel)
2'b00: outc = a;
2'b01: outc = b;
2'b10: outc = c;
2'b11: outc = d;
endcase
// 若使用if ,就会生成优先级编码器。
always @ (*)
begin
if(sel == 2'b00) outi = a;
else if (sel == 2'b01) outi = b;
else if (sel == 2'b10) outi = c;
else outi = d;
casez应用
在case item中,0 1 z x都要进行比较,z和?对应的bit在比较时忽略,x不会被忽略。常用于实现优先编码器。
//实现指令译码,优先级编码器
reg [7:0] ir;
casez (ir)
8'b1??????? : instruction1(ir);
8'b01?????? : instruction2(ir);
8'b00010??? : instruction3(ir);
8'b000001?? : instruction4(ir);
endcase
casex 会导致设计出现问题, 把x当作不关心,前后防结果不一致。复位前的高阻值在复位后将初始化错误隐藏。
// 在case语句前给输出赋一个默认值,综合会当成full的case语句,不会产生Latch
// 在case前给出输出信号默认值,不会出现前后仿真不一致的情况。
module mux3c (y, a, b, c, sel);
output y;
input [1:0] sel;
input a, b, c;
reg y;
always @ ( a or b or c or sel )
y = 1'b0 ; //<====== default value
case (sel)
2'b00 : y = a;
2'b01 : y = b;
2'b10 :y = c;
endcase
endmodule
//使用full_case综合指令
//仿真时,sel = 2'b11 ,y 表现为Latch;综合时,工具把sel == 2'b11时y输出当做不关心,从而导致前后防真不一致。
module mux3c (y, a, b, c, sel);
output y;
input [1:0] sel;
input a, b, c;
reg y;
always @ ( a or b or c or sel )
case (sel) // synopsys full_case
2'b00 : y = a;
2'b01 : y = b;
2'b10 :y = c;
endcase
endmodule
full_case会优化设计,导致设计结果出错。
full_case还是有可能生成Latch(case中对多个输出进行赋值)
消除Latch最简单的方法:在always块的敏感表下面,在执行case语句之前为每个输出都赋一个默认值。
parallel_case是指case expression只能匹配一个case item的语句。如果发现case expression能够匹配超过一个的case item,那么这些匹配的case item被称为overlapping case item,这个case语句就不是parallel
// Synopsys dc_shell 在读入Verilog文件时,如果full_case语句用在不是full的case语句上会报告warning
// Non_full case statement with "full_case" directive
// parallel_case同样会出现警告。
//该警告会使设计崩溃。
case语句的编码原则
1 对于编写表达式并行的设计,case语句是不错的选择,可使代码更加整洁
2 在设计可综合代码时,要小心使用casez语句,不要是要casex语句
3 要小心使用反向case语句,最好只针对时parallel的case语句使用
4 要小心使用casez设计优先级编码器,可以用if-else-if语句实现优先级编码器,这样意图更明显
5 在使用casez语句时,用?表示不关心的位。
6 最好为case语句添加case default,而且不要把输出值赋值未x
case语句,是包含在case和endcase之间的代码,逻辑上等价于if-else语句,使用方法如下:case (case_expression) case_item1 : case_item_statement1; case_item2 : case_item_statement2; case_item3 : case_item_statement3; case_item4 : case_item_statement4; default : case
1,在casez()语句中,如果分支表达式某些位为高阻态z时,对这个位的比较就不予考虑。
2,在casex()语句中,如果分支表达式某些位为z或x时,那么这些位的比较就不予考虑。
示例如下:
case(a)
2'b1x: out = 1; //只有a=1x时,out才为1
casez(a)
2'b1x: out = 1; //若a=1x或1Z时,out=1
casex(a)
2'b1x: out = 1; //若a=10,11,1x,1z时out=1
//考虑分支表达式含"?"的情况
casez
1、 if
-else if
-else 单if
语句
单if
语句(if
-elseif
-…elseif
-else)综合出来的电路没有优先级,从电路的角度来说,单if
语句综合出来的电路类似于数据选择器,else路选通的条件是前面所有的if条件都不满足。
always@(*) begin
z = 0;
if(sel1)
z = a;
else if(sel2)
z = b;
else if(sel3)
z = c;
default语句的对case语句综合的影响
之前看书都说case语句不加default会产生不必要的latch,浪费资源,有时候还会产生错误的时序。然后我写了点简单的程序测试一下,加不加default到底会对电路产生怎样的影响。
时序电路不加default
input clk;
input [2:0] sel;
output [3:0] out;
reg [3:0] out;
always@(posedge clk) begin
case(sel)
3'b000: out &
转自:https://blog.csdn.net/CLL_caicai/article/details/104395480
实际问题中常常需要用到多分支选择,使用if
语句导致内容繁琐;更明智的做法是使用
case语句,
case语句是一种多分支选择
语句,可以方便的处理多分支选择。本文通过实际例子,讲解
case语句的使用,以及
case语句的变体
casez和
casex的使用:
一、
case的用法
二、
casez与
casex的用法
三、参考文献
7.3 过程赋值语句Verilog HDL 中提供两种过程赋值语句 initial 和 always 语句,用这两种语句来实现行为的建模。这两种语句之间的执行是并行的,即语句的执行与位置顺序无关。这两种语句通常与语句块(begin ....end)相结合,则语句块中的执行是按顺序执行的。 1. initial 语句initial 语句只执行一次,即在设计被开始模拟执行时开始(0时刻)。通常只用在对设计进行仿真的测试文件中,用于对一些信号进行初始化和产生特定的信号波形。语法如下:(大家只要先有个概念就可以) initial [timing_control] procedural_statemen