当前位置: 首页 > web >正文

Verilog基础语法(13)之case语句

目录

    • 语法
    • 实例
    • case语句与if_else_if语句的区别
    • 锁存器问题

case语句检查给定的表达式是否与列表中的其他表达式之一相匹配,并据此进行分支。它通常用于实现一个多路复用器。

如果要检查的条件很多,if-else结构可能不合适,因为它会综合成一个优先编码器而不是多路复用器。

语法

一个Verilog case语句以case关键字开始,以endcase关键字结束。在括弧内的表达式将被精确地评估一次,并按其编写顺序与备选方案列表进行比较,与给定表达式匹配的备选方案的语句将被执行。一块多条语句必须分组,并在 begin 和 end 范围内。

case (<expression>)case_item1 : 	<single statement>case_item2,case_item3 : 	<single statement>case_item4 : 	begin<multiple statements>enddefault 	 : <statement>
endcase

如果所有的case项都不符合给定的表达式,则执行缺省项内的语句,缺省语句是可选的,在case语句中只能有一条缺省语句。case语句可以嵌套。

如果没有符合表达式的项目,也没有给出缺省语句,执行将不做任何事情就退出case块。Verilog HDL中的case语句有两种变种,casex和casez:

case(表达式)  <case分支项> endcase
casez(表达式) <case分支项> endcase
casex(表达式) <case分支项> endcase
缺省项:default:语句

case、casez、casex真实表:
在这里插入图片描述

实例

设计一个2位选择信号,用于将其他三个3位输入中的一个信号连接到被调用的输出信号。根据sel的值,用case语句将正确的输入分配到输出。由于sel是一个2位信号,它可以有2^2种组合,从0到3。如果sel为3,默认语句有助于将输出设置为0。

module my_mux (input       [2:0] 	a, b, c, 		[1:0]	sel, 			  output reg  [2:0] 	out); 			always @ (a, b, c, sel) begincase(sel)2'b00    : out = a; 		// If sel=0, output is a2'b01    : out = b; 		// If sel=1, output is b2'b10    : out = c; 		// If sel=2, output is cdefault  : out = 0; 		// If sel is anything else, out is always 0endcaseend
endmodule

综合后的RTL原理图;
在这里插入图片描述

case语句与if_else_if语句的区别

主要区别:

  • 与case语句中的控制表达式和多分支表达式这种比较结构相比,if_else_if结构中的条 件表达式更为直观一些。

  • 对于那些分支表达式中存在不定值x和高阻值z位时,case语句提供了处理这种情况的手 段。下面的两个例子介绍了处理x,z值位的case语句。

Verilog HDL针对电路的特性提供了case语句的其它两种形式用来处理case语句比较过程中的不必考虑的情况( don’t care condition )。
其中casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻值z和不定值都视为不必关心的情况。
所谓不必关心的情况,即在表达式进行比较时,不将该位的状态考虑在内。这样在case语句表达式进行比较时,就可以灵活地设置以对信号的某些位进行比较。见下面的两个例子:

 reg[7:0] ir; 
casez(ir) 8'b1???????: instruction1(ir); 8'b01??????: instruction2(ir); 8'b00010???: instruction3(ir); 8'b000001??: instruction4(ir); 
endcase
reg[7:0] r, mask; 
mask = 8'bx0x0x0x0; 
casex(r^mask) 8'b001100xx: stat1; 8'b1100xx00: stat2; 8'b00xx0011: stat3; 8'bxx001100: stat4; 
endcase 

锁存器问题

Verilog HDL设计中容易犯的一个通病是由于不正确使用语言,生成了并不想要的锁存器。下面我们
给出了一个在“always"块中不正确使用if语句,造成这种错误的例子。
有锁存器:

always @(al or d)beginif(al)q<=d;
end

检查一下左边的"always"块,if语句保证了只有当al=1时,q才取d的值。这段程序没有写出 al = 0 时的结果, 那么当al=0时会怎么样呢? 在"always"块内,如果在给定的条件下变量没有赋值,这个变量将保持原值,也就是说会生成一个锁存器!

无锁存器:

always @(al or d)beginif(al) q<=d;else q<=0
end

Verilog HDL程序另一种偶然生成锁存器是在使用case语句时缺少default项的情况下发生的。
case语句的功能是:在某个信号(本例中的sel)取不同的值时,给另一个信号(本例中的q)赋不同的值。注意看下图左边的例子,如果sel=0,q取a值,而sel=11,q取b的值。这个例子中不清楚的是:如果sel取00和11以外的值时q将被赋予什么值?在下面左边的这个例子中,程序是用Verilog HDL写的,即默认为q保持原值,这就会自动生成锁存器。

有锁存器:

always @(sel[1:0] or a or b)begincase(sel[1:0])2'b00: q<=a;2'b11: q<=b;endcase
end

无锁存器:

always @(sel[1:0] or a or b)begincase(sel[1:0])2'b00: q<=a;2'b11: q<=b;default:q<='b0;endcase
end

`以上就是怎样来避免偶然生成锁存器的错误。如果用到if语句,最好写上else项。如果用case语句,最好写上default项。

http://www.xdnf.cn/news/11632.html

相关文章:

  • Element-UI介绍:主题定制、自定义组件和插件扩展
  • OpenCV快速入门:初探
  • Fiddlerd的工作原理与配置
  • JDK安装太麻烦?一篇文章搞定
  • Maven详解(入门到精通)学习maven有这个就够了
  • 传奇GEE引擎版本如何封挂?GEE引擎设置简单的封挂脚本教程
  • 窄带高清技术之百万级并发下的演唱会直播细节修复
  • C#从入门到精通(史上最全,爆肝十万字)
  • 独家:经开区受理京东涉嫌卖假货投诉案,刘强东在日本难掌控业务
  • 程序员福利各大平台免费接口,非常适用!
  • KVM虚拟化
  • 2021年美容师(初级)考试及美容师(初级)考试报名
  • 2019年最新web前端学习大纲及视频链接免费分享
  • 【云计算】6_云数据库产品介绍
  • 2018年第九届C/C++ A组蓝桥杯省赛真题
  • linux 学习
  • 活动预告 | GDG 社区 - Android 11 Meetup 讲师抢先看
  • 机械类岗位面试专业知识54题
  • zsh安装及配置
  • 科大讯飞副总裁刘鹏:人机交互的未来是人人交互?
  • Python能用来做什么?以下是Python的三大主要用途
  • do...while循环概要
  • 【网络安全】sick0s 靶场实践之getshell
  • postgreSQL 操作 教程
  • Android | 广播( Broadcast )
  • 智慧养老照护:科技赋能,让老年人享受更美好的晚年生活
  • c++ make_pairpair
  • 10个常用的软件测试工具,你不容错过
  • CSS基础知识点
  • 工作流引擎Activiti系列(一)——初识