HDLbits 刷题 -- Always if

学习:

An if statement usually creates a 2-to-1 multiplexer, selecting one input if the condition is true, and the other input if the condition is false.

always @(*) begin
    if (condition) begin
        out = x;
    end
    else begin
        out = y;
    end
end

This is equivalent to using a continuous assignment with a conditional operator:

assign out = (condition) ? x : y;

However, the procedural if statement provides a new way to make mistakes. The circuit is combinational only if out is always assigned a value.

译:

 一个 if 语句通常会产生一个2选1的多路选择器(multiplexer),如果条件为真,则选择一个输入;如果条件为假,则选择另一个输入。

这相当于使用带有条件运算符的连续赋值(continuous assignment):

assign out = (condition) ? x : y;

然而,程序化的 if 语句提供了犯新错误的可能。只有当输出 out 总是被赋值时,电路才是组合逻辑的。

练习:

Build a 2-to-1 mux that chooses between a and b. Choose b if both sel_b1 and sel_b2 are true. Otherwise, choose a. Do the same twice, once using assign statements and once using a procedural if statement.

构建一个2选1多路选择器(2-to-1 mux),在 ab 之间进行选择。如果 sel_b1sel_b2 都为真,则选择 b。否则,选择 a。用两种方式完成这个任务,一次使用赋值语句(assign statements),一次使用程序化的 if 语句。

sel_b1sel_b2out_assign
out_always
00a
01a
10a
11b
// synthesis verilog_input_version verilog_2001
module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always   ); 
    assign out_assign = (sel_b1 & sel_b2)?b:a;
    always@(*) begin
        if (sel_b1 & sel_b2) begin
            out_always = b;
        end
        else begin 
            out_always = a;
        end
    end
endmodule

运行结果:

分析:

        主要是两种判断方式的使用,一种是前面提到的三元选择法(三元运算符);另外就是if - else的方法;

        使用if - else的方法要注意使用格式,配合好 begin - end 的调用;另外 if- else 只能在 always中调用,要注意赋值方式;关于赋值方式的选择,参考上一篇;

        

介绍begin - end

在硬件描述语言(HDL)如Verilog和SystemVerilog中,`begin` 和 `end` 是用来定义代码块的关键字。它们通常成对出现,用以标识一段特定的代码区域的开始和结束。这种结构在编写复杂的赋值语句、条件语句、循环语句以及其他控制结构时非常有用。

   组合逻辑中的 `begin` - `end`

在组合逻辑的 `always` 块中,`begin` 和 `end` 用于包含一系列的赋值和操作,这些操作是同时发生的,不涉及时序控制。

 

always @(a or b) begin
  // 组合逻辑操作
  output = a & b; // 逻辑与操作
  // 更多的组合逻辑操作...
end

在这个例子中,`begin` 和 `end` 之间的代码块定义了输出信号 `output` 是如何根据输入信号 `a` 和 `b` 的逻辑与结果来计算的。

### 时序逻辑中的 `begin` - `end`

在时序逻辑的 `always` 块中,`begin` 和 `end` 也用于定义代码块,但这里的操作是按照它们在代码中出现的顺序依次执行的,并且通常与时钟信号的边沿同步。

 

always @(posedge clk) begin
  // 时序逻辑操作
  if (reset) begin
    reg_value = 0; // 异步复位
  end else begin
    reg_value = input; // 时钟边沿触发的赋值
  end
end

在这个例子中,`begin` 和 `end` 之间的代码块定义了一个寄存器 `reg_value` 的行为。当复位信号激活时,`reg_value` 被异步清零;否则,在时钟的上升沿,`reg_value` 会被 `input` 的值更新。

### 条件语句中的 `begin` - `end`

在 `if`、`else if`、`else` 条件语句中,`begin` 和 `end` 用于定义每个条件分支的代码块。

if (condition1) begin
  // 条件1为真时执行的代码
end else if (condition2) begin
  // 条件2为真时执行的代码
end else begin
  // 所有条件都不为真时执行的代码
end

### 循环语句中的 `begin` - `end`

在 `for`、`while` 循环语句中,`begin` 和 `end` 定义了循环体中的操作。

 

for (i = 0; i < N; i = i + 1) begin
  // 循环体内的代码
end

在这个例子中,`begin` 和 `end` 之间的代码块定义了 `for` 循环的执行体。

### 总结

`begin` 和 `end` 是Verilog和SystemVerilog中定义代码块的重要结构。它们使得代码更加结构化和模块化,提高了代码的可读性和可维护性。无论是在组合逻辑还是时序逻辑中,正确地使用这些关键字对于设计正确的硬件电路至关重要。

  • 64
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刚及格的陆拾伍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值