0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog代码:if-else和case的电路结构和区别

要长高 来源:eetop 作者:曜曜曜切克闹 2023-11-29 15:10 次阅读

本文是针对在写项目中遇到的Verilog代码写法错误,多对一和一对多赋值问题,从逻辑赋值的角度理解为何会编译出错。并在后续讨论了if-else和case的电路结构和区别。在此处列出来供大家一起交流学习。

2.对Verilog代码的理解

2.1 一对多赋值、多对一赋值行为的区别

2.1.1多对一赋值的Verilog代码:

always @(posedge clk or negedge rstn)begin

if(!rstn)begin

REG1 <= 'd0;

REG2 <= 'd0;

end

else begin

if(write) begin

case(paddr)

'h54321 : REG1 <=  pwdata;   //在32'h54321写入pwdata

'h12345 : REG2 <=  pwdata;   //在32'h12345写入pwdata

default begin

REG1 <= REG1 ;

REG2 <= REG2 ;

end

endcase

//另一种写法

//REG1 <= (paddr == 'h54321) ? pwdata : REG1; //在32'h54321写入pwdata

//REG2 <= (paddr == 'h12345) ? pwdata : REG2;  //在32'h12345写入pwdata

end

else begin

REG1 <= REG1;

REG2 <= REG2;

end

end

end

·如果将一个信号(如pwdata)对多个信号进行赋值(如REG1、REG2),应该使用译码器形式的电路结构。也就是pwdata根据paddr进行译码,从而将值赋给REG1/REG2。如下图所示

#FormatImgID_0#

·译码器一般用多个输入信号,根据padder判断取值的不同,将输入信号pwdata赋值给相应的输出信号。代码中给出了两种写法都可以。

2.1.2一对多赋值的Verilog代码:

always @(posedge clk or negedge rstn)begin

if(!rstn)begin

prdata <= 'd0;

end

else begin

if(read) begin

case(paddr)

'h54321 : prdata <= REG1; //在32'h54321读出prdata = REG1  

'h12345 : prdata <= REG2; //在32'h12345读出prdata = REG2

default : prdata <= prdata;

endcase

//注意下面这种写法是错误的(2.1.3中会分析)

//prdata <= (paddr == 'h54321) ? REG1 : prdata;

//prdata <= (paddr == 'h54321) ? REG2 : prdata;

end

else begin

prdata <= prdata;

end

end

end

·如果将多个信号(如REG1、REG2)对一个信号进行赋值(如prdata),应该使用多路选择器形式的电路结构。也就是REG1/REG2根据paddr进行判断,从而将值赋给prdata。如下图所示

#FormatImgID_1#

·多路选择器的写法一般是利用case语句进行实现,根据case的条件不同,选择不同的输入信号对输出信号进行赋值。

2.1.3 为什么多对一赋值不能用三目运算符呢?

即写成:

always @(posedge clk or negedge rstn)begin

if(!rstn)begin

prdata <= 'd0;

end

else begin

if(read) begin

//注意多对一中,下面这种写法是错误的

prdata <= (paddr == 'h54321) ? REG1 : prdata;

prdata <= (paddr == 'h54321) ? REG2 : prdata;

end

else begin

prdata <= prdata;

end

end

end

分析:这时候编译就会报错,prdata同时被两个常量赋值。假如说paddr选中了'h54321,此时 prdata<= REG1成立;但是请注意在第二条语句中,由于paddr≠'h54321,prdata <= prdata。

由此我们可以知道三目运算符和case并不等价,如果改写成if-else多层嵌套语句,编译没有出错误。

always @(posedge clk or negedge rstn)begin

if(!rstn)begin

prdata <= 'd0;

end

else begin

if(read) begin

if(paddr == 'h54321)begin

prdata <= REG1;

end

else begin

if(paddr == 'h54321)begin

prdata <= REG2;

end

else begin

prdata <= prdata;    

end

end

end

else begin

prdata <= prdata;

end

end

end

下面进一步分析if-else和case语句的区别来分析。

2.2 if—else语句与case语句的区别

2.2.1 if-else语句的电路结构

每个if-else就是一个2选1mux器。当信号有明显优先级时,首先要考虑if-else,但是if嵌套过多也会导致速度变慢;if语句结构较慢,但占用面积小。

嵌套的if语句如果使用不当,就会导致设计的更大延时,为了避免较大的路径延迟,最好不要使用特别长的嵌套if结构。如想利用if语句来实现那些对延时要求苛刻的路径时,应将最高优先级给最迟到达的关键信号。

2.2.2 case语句的电路结构

case语句综合为 n选1的mux电路。适用于无明显优先级的逻辑判断,即这些逻辑条件都处于同一个优先级且互斥;case结构电路速度较快,但占用面积较大。

2.2.3 if语句和case语句中的latch问题

if-else:组合逻辑和时序逻辑中的always语句块中实现是不同的。

组合逻辑中:if缺少else 时,会有latch;

时序逻辑中:尽管缺少else,依旧是D触发器,不存在latch。

case语句:case列举不全并且还没写default语句,则会综合出锁存器。所以一定写default,无论是组合还是时序逻辑。

总结:保证if-else对应齐全;case必写default。

2.2.4 if-else语句和case语句的区别

对于这个的讨论,本人认为是以前由于综合工具落后,导致有区别,但是随着综合工具的更新,他们之间的区别越来越小,甚至有人可以用if-else综合出无优先级的多路选择器,用case综合出有优先级的多路选择器。

“if-else的逻辑判别是有优先级的,而case的逻辑判断条件是并列的。

举个例子,如果你用IF实现译码器,综合出的是有优先级的译码器。如果用CASE,综合出的就是一个无优先级的译码器。也就是说IF是有优先级的,执行的次序有先后。而CASE执行的时候是没有先后顺序的。”

“随着综合工具的进步,已经不需要讨论if-else 和case的区别了,两者可以等同 ”

“Verilog 2001标准(IEEE 1364-2001)第132页:

The case item expressions shall be evaluated and compared in the exact order in which they are given.

指出了case是串行有优先级。又:

Apart from syntax, the case statement differs from the multiway if-else-if construct in two important ways:

a) The conditional expressions in the if-else-if construct are more general than comparing one expression with several others, as in the case statement.

b) The case statement provides a definitive result when there are x and z values in an expression.

a)是废话。b)指出了case是四态对比。除此之外和if-else没有差别。”

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Verilog
    +关注

    关注

    28

    文章

    1343

    浏览量

    109973
  • D触发器
    +关注

    关注

    3

    文章

    164

    浏览量

    47859
  • 代码
    +关注

    关注

    30

    文章

    4741

    浏览量

    68325
  • Case
    +关注

    关注

    0

    文章

    27

    浏览量

    13356
  • 多路选择器
    +关注

    关注

    1

    文章

    22

    浏览量

    6517
收藏 人收藏

    评论

    相关推荐

    C语言中if语句、if-else语句和switch语句详解

    在C语言中,有三种条件判断结构:if语句、if-else语句和switch语句。
    发表于 08-18 16:36 1.2w次阅读
    C语言中if语句、<b class='flag-5'>if-else</b>语句和switch语句详解

    炼狱传奇-if_elsecase之战

    Verilog HDL语言中存在两种分支语言:● if-else 条件分支语句● case 分支控制语句1. if-else条件分支语句if-els
    发表于 03-31 09:51

    Proteus之if-else语句的应用

    Proteus之if-else语句的应用,很好的Proteus资料,快来学习吧。
    发表于 04-18 14:49 0次下载

    verilog中if与case语句不完整产生锁存器的原因分析

      在很多地方都能看到,verilog中if与case语句必须完整,即if要加上elsecase后要加上default语句,以防止锁存器的发生,下载内容中就谈到了其中原因。
    发表于 09-16 09:29 24次下载

    FPGA学习系列:if-elsecase

    设计背景:不管是在什么软件和硬件语言,我们在我们的代码中都或多或少的用到这两条语句,if..elsecase语句,今天我们将学习verilog中的这两条语句,其实不管在什么语言中这两
    的头像 发表于 06-01 16:59 1.2w次阅读
    FPGA学习系列:<b class='flag-5'>if-else</b>与<b class='flag-5'>case</b>

    C语言的switch case多分支选择语句的详细资料说明

    1、switch-case开关语句是一种多分支选择语句,用来实现多方向条件分支。虽然采用if-else条件判断语句也可以实现多方向条件分支,但是当分支较多时,使用if-else条件语句的嵌套层次会
    发表于 07-12 17:39 1次下载
    C语言的switch <b class='flag-5'>case</b>多分支选择语句的详细资料说明

    30多个verilog实用例子代码合集免费下载

    本文档的主要内容详细介绍的是30多个verilog实用例子代码合集免费下载包括了:奇偶校验位产生器,用case语句描述的4选1数据选择器,用casez描述的数据选择器,持续赋值方式定义的2选1多路
    发表于 09-09 08:00 35次下载
    30多个<b class='flag-5'>verilog</b>实用例子<b class='flag-5'>代码</b>合集免费下载

    FPGA代码经验 case,casez,casex语句

    使用case语句代替嵌套的if-else将会产生更易读的代码,更好的逻辑利用率和更高的性能。
    的头像 发表于 12-11 10:42 6193次阅读

    从入门到高级替换If-Else的5种方法示例

    ,它导致设计复杂,代码可读性差,并且可能导致重构困难。 但是,If-Else 已成为事实上的代码分支解决方案,这确实是有道理的。这是向所有有抱负的开发人员讲授的第一件事。 不幸的是,许多开发人员从来没有前进到更合适的分支策略。有
    的头像 发表于 02-20 16:27 6765次阅读
    从入门到高级替换<b class='flag-5'>If-Else</b>的5种方法示例

    不会有人不知道怎么优雅的替换if-else语句吧

    来自:love1024.blog.csdn.net/article/details/104955363 场景日常开发,if-else语句写的不少吧??当逻辑分支非常多的时候,if-else套了一层
    的头像 发表于 07-28 15:46 1404次阅读
    不会有人不知道怎么优雅的替换<b class='flag-5'>if-else</b>语句吧

    数字芯片设计流程之verilog设计

    综合开始拿给后端,确保每一个阶段没有问题。后仿真,证明加入延迟后功能是否正确。一、verilog设计可综合语句四大关键字:always、if-else、assign、case1、if-else
    发表于 11-05 15:51 29次下载
    数字芯片设计流程之<b class='flag-5'>verilog</b>设计

    解锁新姿势:干掉过多的if-else

    这点非常容易理解,就是说在业务逻辑里面,先把不符合条件的给先过滤掉,而不是层层嵌套if-else判断
    的头像 发表于 11-12 10:01 635次阅读

    什么是SystemVerilog-决策语句-if-else语句?

    决策语句(Decision statements)允许程序块的执行流程根据设计中信号的当前值分支到特定语句。SystemVerilog有两个主要的决策语句:if…else语句和case语句,使用关键字case
    的头像 发表于 02-09 14:15 1096次阅读
    什么是SystemVerilog-决策语句-<b class='flag-5'>if-else</b>语句?

    Verilog中的If语句和case语句介绍

    。这些语句统称为顺序语句。case 语句和 if 语句都是 verilog 中顺序语句的示例。在这篇文章的其余部分,我们将讨论如何在verilog中使用这两个语句。然后,我们考虑这两个结构
    的头像 发表于 05-11 15:37 4294次阅读
    <b class='flag-5'>Verilog</b>中的If语句和<b class='flag-5'>case</b>语句介绍

    如何通过策略模式简化if-else

    相信大家日常开发中会经常写各种分支判断语句,比如 if-else ,当分支较多时,代码看着会比较臃肿,那么如何优化呢? 1、什么是策略模式? Define a family
    的头像 发表于 10-08 16:08 727次阅读
    如何通过策略模式简化<b class='flag-5'>if-else</b>