Verilog中的If语句和case语句

 
 
 
 
关注、星标公众号,精彩内容每日送达

来源:网络素材

在这篇文章中,我们讨论了verilog中最常用的两个结构-if语句和case语句。

我们在上一篇文章中已经看到了如何使用程序块(例如 always 块来编写按顺序执行的 verilog 代码。

我们还可以在程序块中使用许多语句来控制在我们的verilog设计中信号赋值的方式。这些语句统称为顺序语句。case 语句和 if 语句都是 verilog 中顺序语句的示例。在这篇文章的其余部分,我们将讨论如何在verilog中使用这两个语句。然后,我们考虑这两个结构的简短示例,以说明我们如何在实践中使用它们。

Verilog If 语句

if 语句是一个条件语句,它使用布尔条件来确定要执行哪些verilog代码块。只要条件的计算结果为 true,就会执行与该条件关联的代码分支。此语句类似于其他编程语言(如 C)中使用的 if 语句。

下面的 verilog 代码片段显示了 if 语句的基本语法。

1if (<expression1>) begin
2  // Code to execute
3end
4else if (<expression2>) begin
5  // Code to execute
6end
7else begin
8  // Code to execute
9end

如果我们不需要 else 和 else 分支,我们可以从语句中删除它们。事实上,我们已经在关于always块的帖子中看到了这一点,我们在其中使用 posedge 宏来检测时钟信号的上升沿。如果需要,我们可以包含尽可能多的其他分支,以正确建模底层电路。

if 语句使用布尔条件来确定要执行的代码行。在上面的代码段中,这些表达式由 <expression1> 和 <expression2> 给出。这些表达式按顺序计算,如果表达式的计算结果为 true,则执行与表达式关联的代码。

if 语句只有一个分支将执行。这通常是计算结果为 true 的第一个表达式。唯一的例外情况是,当所有表达式都不为 true 时。在这种情况下,将执行 else 分支中的代码。当我们在 if 语句代码中省略 else 分支时,在这种情况下不会执行任何分支。

与每个分支关联的代码可以包含任何有效的 verilog 代码,包括进一步的 if 语句。此方法称为嵌套 if 语句。

在 verilog 中使用这种类型的代码时,我们应该注意限制嵌套语句的数量,因为它可能会导致满足时间的困难。

If 语句示例

我们已经看到了 if 语句的实际示例,当在 verilog always块的帖子中对触发器进行建模时。为了更彻底地演示此结构,让我们考虑一个时钟多路复用器的示例。

在本例中,我们将使用异步复位的 D 类型触发器来保存多路复用器的输出。下面的电路图显示了我们将在本例中使用的电路。

031b14a448a2c1be175fb825437f9f6b.png

下面的代码片段显示了我们如何使用单个 always 块和 if 语句来实现这一点。

1always @(posedge clock, posedge reset) begin
2  if (reset) begin
3    Q <= 1'b0;
4  end
5  else begin
6    if (addr) begin
7      Q <= b;
8    end
9    else begin
10      Q <= a;
11    end
12  end
13end

在此示例中,我们使用第一个if语句在复位时触发,输出0。当复位无效时,always块已由时钟的上升沿触发。我们使用第一个 if 语句的 else 分支来被触发,我们使用第二个if语句来模拟多路复用电路的行为。这是 verilog 中嵌套 if 语句的示例。

当 addr 信号为 0b时,我们使用嵌套 if 语句的第一个分支被触发,将输入a赋值给输出。然后,我们使用嵌套 if 语句的 else 分支来捕获 addr信号为1b 时的情况。

我们也可以在这里使用 else-if 类型语句,但 else 语句更简洁。这两种情况下的行为是相同的,因为信号在实际电路中只能是0b或1b。

Verilog case语句

我们使用 verilog case 语句根据设计中给定信号的值选择要执行的代码块。当我们在verilog中编写语句时,我们指定了一个要监视和评估的输入信号。然后将该信号的值与case语句的每个分支中指定的值进行比较。找到输入信号值的匹配项后,将执行与该值关联的分支。

verilog case语句执行的功能 C语言中的switch语句相同。下面的代码片段显示了 verilog 中case语句的一般语法。

1case (<variable>)
2  <value1> : begin
3    // This branch executes when <variable> = <value1>
4  end
5  <value2> : begin
6    // This branch executes when <variable> = <value2>
7  end
8  default begin
9    // This branch executes in all other cases
10  end
11endcase

可以删除语句的默认分支,尽管这是不可取的。如果删除默认分支,则<变量>的所有有效值都必须具有自己的分支。与 if 语句一样,与每个分支关联的代码可以包含任何有效的 verilog 代码。这包括进一步嵌套顺序语句,例如if或case语句。同样,我们应该尝试限制嵌套语句的数量,因为它可以更轻松地满足我们的计时要求。

case语句示例

为了更好地演示erilog中使用case语句的使用方式,让我们考虑一个基本示例。在本例中,我们将介绍一个简单的四比一多路复用电路。

我们经常使用 case 语句在 verilog 中对大型多路复用器进行建模,因为它生成的代码比基于连续赋值的实现更具可读性。下面的电路图显示了我们将在本例中使用的电路。

下面的代码片段显示了我们将如何使用 case 语句实现此电路。

3dda393c16e761c13914f690a92a0280.png

1always @(*) begin
2  case (addr)
3    2'b00 begin
4      q = a;
5    end
6    2'b01 begin
7      q = b;
8    end
9    2'b10 begin
10      q = c;
11    end
12    default begin
13      q = d;
14    end
15  endcase
16end

此示例显示了使用 verilog中的case语句对多路复用器进行建模是多么简单。事实上,case语句提供了在 verilog 中对多路复用器进行建模的最直观方法。

虽然这个例子很简单,但有几个要点我们应该更详细地考虑。在这个例子中首先要注意的是,我们使用阻塞赋值。这样做的原因是我们正在对组合逻辑进行建模,而非阻塞分配通常会导致在我们的设计中放置触发器。

这里要注意的另一件事是,我们可以从此示例中删除默认关键字。然后,我们将显式列出输出d 值所需的 addr 值。但是,我们在此示例中包含了默认关键字,以演示应如何使用它。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值