case语句是包含在case和endcase之间的代码,逻辑上等效于if-else语句,用于:
case(case_expression ) case _ item1: case _ item _ statement 1; case _ item2: case _ item _ statement 2; case _ item3: case _ item _ statement 3; case _ item4: case _ item _ statement 4; efault : case _ item _ statement 5; endcase casez语句、' z '和'? 值在比较时被认为冷漠,' z '和'? 时间是等价的。
注意:在编写可集成代码时,请小心使用casez; 如果使用casez,则为“?” 表示不希望使用的兴趣,不能使用“z”表示不感兴趣。
casex语句,' x' 'z '和'? 数值在比较时被认为是冷漠的。
注:在编写可集成代码时,请不要使用casez
执行case语句的步骤:
1 .括号中的case expression每次执行case语句时只计算一次,并从顶部开始按顺序与每个case item进行比较。
如果存在case default,则在从上到下的比较过程中忽略。
如果存在与case expression匹配的case item,请执行此case item语句并退出case语句。
4 .如果所有比较都失败,并且存在case default,则执行case default语句并退出case语句。
5 .如果所有比较都失败,并且没有case default,则退出case语句。
注意:第一列中的case item具有较高的优先级。
2所有case expression和case item的位长均调整为最长的位长。
3一个时间有无符号,均按无符号调整。
case APP应用
case可以检查x和z
case(SIG )1(BZ:$display ) (signalisfloating ); 1 ' bx : $ display (signalisunknown ); efault : $ display (' signal is % b ',sig ); 如果endcase case item具有x和z,则无法集成此代码
可以使用反向case语句,是优先级编码器。
reg [2:0] encode; case(1) encode) :$display () selectline2); encode [1] : $ display ('选择线1 ); encode [0] : $ display ('选择线0 ); 默认: $ display (error : onlyoneofthebitsisexpectedon ); 如果endcase case语句可用,则full和parallel:full不生成latch。 对于parallel,不生成优先级编码器。 综合工具一般可以自由导出是full还是parallel。
//由于此代码既是full也是parallel,因此Latch和优先级编码器always@((* ) begincase ) sel )2'b00: outc=a; 2'b01: outc=b; 2'b10: outc=c; 2'b11: outc=d; 结束案例结束
使用//if时生成优先级编码器。 Always@(* ) Beginif ) sel==2'b00 ) outi=a; elseif(sel==2'b01 ) outi=b; elseif(sel==2'B10 ) outi=c; else outi=d; 结束
casez APP应用程序
在case item中,0 1 z x必须全部进行比较,与z? 对应的bit在比较时被忽略,x不被忽略。 常用于实现优先编码器。
//实现指令解码,优先级编码器reg [7:0] ir; Casez(IR )8) B1? instruction1(IR; 8'b
01?????? : instruction2(ir); 8'b00010??? : instruction3(ir); 8'b000001?? : instruction4(ir);endcasecasex 会导致设计出现问题, 把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; endcaseendmodule//使用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; endcaseendmodulefull_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