草庐IT

Verilog中case,casez,casex语句的用法

孤独的单刀 2023-04-21 原文

文章目录

        1、case的用法

        2、casez/casex的用法

        3、case语句的常数表达式


1、case的用法

        case语句是一种多路选择结构语句,根据表达式(expression)中的值,对选项(case_item)从上到下一一进行匹配。若有选项与表达式对应,则执行该选项的表达语句(statement),并从case语句退出。若所有选项均无法匹配表达式,则执行default语句中的语句;若无default语句且所有选项均不匹配表达式,则什么也不执行。

        case语句的一般结构如下:

        需要注意的是:default语句虽然是可选选项(非强制性),但是在一般的开发过程中,为了避免产生锁存器LATCH,通常都会要求加上default语句。 

       

        下面是一个使用case语句的典型例子: 

        举例:电路会根据寄存器rega的值对下列选项进行匹配。

  1. 如果rega = 16'd0,则执行改选项后的执行语句----result = 10'b0111111111;然后退出case语句。
  2. 如果rega 不等于 16'd0,则继续搜寻下一条选项是否匹配,直到某个选项匹配表达式,然后执行该选项的执行语句后,退出case语句。
  3. 如果rega的值不等于这些选项中的任意一个,则执行default语句中的执行语句----result = 'bx;

        虽然case语句是从第一句开始匹配直到default语句,但通常由于所有选项的互异性,所以造成了case语句成了事实上的并行语句,而不存在优先级。

        

        此外,我们知道Verilog HDL 有四种基本的值来表示硬件电路中的电平逻辑:

  • 0:逻辑 0 或 "假"
  • 1:逻辑 1 或 "真"
  • x 或 X:未知
  • z 或 Z:高阻

        那么case语句对x/z的支持如何?答案是,在case语句中x就是x,而z就是z(听起来很奇怪,需要结合后面casex/casez来理解)。

        下面是一个在选项中有x、z的例子:

        选项2'b0x、2'b0z、2'bx0和2'bz0均需要完全匹配才会执行对应的执行语句。比如select[1:2] = 2'b0x且flaga = 0,则result = 0。


2、casez/casex的用法

        casez语句和case语句的用法非常相似,其唯一的区别在于,状态z在casez语句中不会被视为正常的z状态,而是将表达式中,标记为z的那个(或那些)bit视为不在乎(dont care)。

        比如下面的例子:

         选项8'b1??????? 意味着 后面7bit均不用在乎,随便是什么值都可以,只要最高位是1即可完成匹配,从而执行后面的执行语句----instruction1(ir);

        casex语句和casez语句的用法非常相似,其唯一的区别在于,casex可以同时将状态x和状态z均视为不在乎(dont care)。


3、case语句的常数表达式

        case表达式中的值除了是某个变量或其组合外,也可以是一个常数。

        比如下面这种写法:

        把表达式的值固定为了常数1即真,所以只需判断encode[2]是否为真,为真则执行$display("Select Line 2") ;为假则判断 encode[1],直到default。

        写个简单的testbench验证一下,顺便看看再表达选项不为互异的情况下,case语句如何进行判断。

`timescale 1ns / 1ps			//时间单位/精度

module tb_test();
 
reg [2:0] encode ;

initial begin
	encode = 3'b0;
	$display("sim start!");		//仿真开始
	#100
	#10 encode = 3'b100;
	#10 encode = 3'b010;
	#10 encode = 3'b001;
	
	#10 encode = 3'b111;		//此时三个选项均满足,观察如何执行
	#10 encode = 3'b011;		//此时后两个选项均满足,观察如何执行
	#20	$display("sim finish!");//仿真结束
	$finish;
end

always@(*)begin
	case (1)
		encode[2] : $display("Select Line 2") ;
		encode[1] : $display("Select Line 1") ;
		encode[0] : $display("Select Line 0") ;
		default $display("Error: One of the bits expected ON");
	endcase
end 

endmodule

        Vivado终端窗口打印的结果如下:

  1. 此时对encode赋值初值encode = 3'b0; 不满足任何一条选项,执行default语句中的执行语句,显示Error: One of the bits expected ON
  2. 此时对encode赋值    encode = 3'b100; 满足encode[2],执行打印语句Select Line 2
  3. 此时对encode赋值    encode = 3'b010; 满足encode[1],执行打印语句Select Line 1
  4. 此时对encode赋值    encode = 3'b001; 满足encode[0],执行打印语句Select Line 0
  5. 此时对encode赋值    encode = 3'b111;  满足encode[2]、encode[1]和encode[0],但由于encode[2]在最上面,所以会被先匹配到,然后执行打印语句Select Line 2(说明case还是有优先级的
  6. 此时对encode赋值    encode = 3'b011;  满足encode[1]和encode[0],但由于encode[1]在encode[0]上面,所以会被先匹配到,然后执行打印语句Select Line 1(同样说明case是有优先级的

有关Verilog中case,casez,casex语句的用法的更多相关文章

  1. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  2. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  3. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  4. ruby - 在 Ruby 的 if 语句中检查 bash 命令 - 2

    如何在Ruby的if语句中检查bash命令的返回值(true/false)。我想要这样的东西,if("/usr/bin/fswscell>/dev/null2>&1")has_afs="true"elsehas_afs="false"end它会提示以下错误含义,它总是返回true。(irb):5:warning:stringliteralincondition正确的语法是什么?更新:/usr/bin/fswscell寻找afs安装和运行状态。它会抛出这样的字符串,Thisworkstationbelongstocell如果afs没有运行,命令以状态1退出 最

  5. ruby-on-rails - ruby 范围 : operators in case statement - 2

    我想检查my_number是否在某个范围内,包括较高的值。在IF语句中我会简单地使用“x>100&&x但是我应该在Ruby案例中做什么(开关)?使用:casemy_numberwhenmy_number不起作用。备注:标准范围不包括my_number恰好为500的情况,并且我不想添加第二个“when”,因为我必须编写双重内容casemy_number#between100and500when100..500puts"Correct,dosomething"when500puts"Correct,dosomethingagain"end 最佳答案

  6. ruby - 变量赋值后的 if 语句 - 有多常见? - 2

    我最近与一位同事讨论了以下Ruby语法:value=ifa==0"foo"elsifa>42"bar"else"fizz"end我个人并没有看到太多这种逻辑,但我的同事指出,这实际上是一种相当普遍的Rubyism。我试着用谷歌搜索这个主题,但没有找到任何文章、页面或SO问题来讨论它,这让我相信这可能是一种非常实际的技术。然而,另一位同事发现语法令人困惑,而是将上面的逻辑写成这样:ifa==0value="foo"elsifa>42value="bar"elsevalue="fizz"end缺点是value=的重复声明和隐式elsenil的丢失,如果我们想使用它的话。这也感觉它与Ruby

  7. ruby - 当你有一个没有参数的 case 语句并且 when 子句是 lambda 时会发生什么? - 2

    这段代码没有像我预期的那样执行:casewhen->{false}then"why?"else"ThisiswhatIexpect"end#=>"why?"这也不是casewhen->(x){false}then"why?"else"ThisiswhatIexpect"end#=>"why?"第一个then子句在两种情况下都被执行,这意味着我提供给when子句的lambda没有被调用。我知道无论when子句的主题是什么,都应该调用大小写相等运算符===。我想知道当没有为case提供参数时,===的另一边会发生什么。我在想它可能是nil,但它不可能是:->{false}===nil#=>

  8. ruby - 有人可以解释一下在 Ruby 中注入(inject)的真实、通俗易懂的用法吗? - 2

    我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有

  9. ruby - 使用法拉第上传文件 - 2

    我在尝试使用Faraday将文件上传到网络服务时遇到问题。我的代码:conn=Faraday.new('http://myapi')do|f|f.request:multipartendpayload={:file=>Faraday::UploadIO.new('...','image/jpeg')}conn.post('/',payload)尝试发布后似乎没有任何反应。当我检查响应时this是我所看到的:#:post,:body=>#,#,@opts={}>,#],@index=0>>,#>],@ios=[#,#,@opts={}>,#],@index=0>,#],@index=0>

  10. ruby - rspec: raise_error 用法来匹配错误信息 - 2

    我使用raise(ConfigurationError.new(msg))引发错误我试着用rspec测试一下:expect{Base.configuration.username}.toraise_error(ConfigurationError,message)但这行不通。我该如何测试呢?目标是匹配message。 最佳答案 您可以使用正则表达式匹配错误消息:it{expect{Foo.bar}.toraise_error(NoMethodError,/private/)}这将检查NoMethodError是否由privateme

随机推荐