手把手教你学veriolg(十一)--Verilog 过程赋值

目录

Verilog 过程赋值

1. 过程赋值的基本语法

2. 过程赋值的应用场景

3. 过程赋值的示例

示例 1:简单的时序逻辑

示例 2:使用流程控制语句的过程赋值

示例 3:使用 if 语句的过程赋值

示例 4:使用 repeat 和 forever 循环的过程赋值

4. 过程赋值与连续赋值的区别

5. 最佳实践

总结


 

Verilog 过程赋值

在 Verilog 中,过程赋值(procedural assignment)是指在 always 块、initial 块或 final 块中定义的赋值语句。这些赋值语句通常用于描述时序逻辑和控制流,因为它们是在特定的事件或条件下执行的。与连续赋值不同,过程赋值可以在程序的不同阶段进行多次修改。

1. 过程赋值的基本语法

过程赋值的基本语法如下:

 

verilog

深色版本

always @(sensitivity_list) begin
    statement;
    statement;
    // ...
end

其中:

  • sensitivity_list 定义了触发 always 块中语句执行的信号或事件。
  • statement 是具体的赋值或其他操作语句。

2. 过程赋值的应用场景

过程赋值主要用于以下场景:

  • 时序逻辑:在时钟或其他同步信号的上升沿或下降沿触发的逻辑。
  • 组合逻辑:尽管 always 块也可以用于组合逻辑,但通常建议使用 assign 语句来表示组合逻辑。
  • 状态机:使用 always 块来实现有限状态机(FSM)。
  • 初始化和清理:使用 initial 和 final 块来执行初始化和清理任务。

3. 过程赋值的示例

下面通过几个示例来展示过程赋值的使用方法。

示例 1:简单的时序逻辑

 

verilog

深色版本

module simple_sequential_logic;
    input clk, reset;
    output reg q;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 1'b0; // 重置
        end else begin
            q <= ~q; // 反相
        end
    end
endmodule

在这个例子中,q 的值在 clk 的上升沿或 reset 的上升沿改变。如果没有 reset 的上升沿,q 的值将在每次 clk 上升沿时翻转。

示例 2:使用流程控制语句的过程赋值

 

verilog

深色版本

module process_assignment_with_control;
    input [1:0] sel;
    output reg [3:0] out;

    always @(sel) begin
        case (sel)
            2'b00: out <= 4'd0;
            2'b01: out <= 4'd1;
            2'b10: out <= 4'd2;
            2'b11: out <= 4'd3;
            default: out <= 4'd0;
        endcase
    end
endmodule

在这个例子中,根据选择信号 sel 的值,out 的值被设置为不同的常数值。

示例 3:使用 if 语句的过程赋值

 

verilog

深色版本

module process_assignment_if;
    input clk, reset;
    output reg q;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 1'b0; // 重置
        end else if (q) begin
            q <= 1'b0; // 清零
        end else begin
            q <= 1'b1; // 置位
        end
    end
endmodule

在这个例子中,q 的值在 clk 的上升沿或 reset 的上升沿改变。如果没有 reset 的上升沿,如果 q 当前为高电平,则将其清零;否则将其置位。

示例 4:使用 repeat 和 forever 循环的过程赋值

 

verilog

深色版本

module process_assignment_loop;
    output reg clk;
    parameter CLK_PERIOD = 10;

    initial begin
        clk = 0;
        forever begin
            #CLK_PERIOD/2 clk = ~clk; // 产生时钟信号
            #CLK_PERIOD/2;
        end
    end
endmodule

在这个例子中,clk 信号每 CLK_PERIOD 时间单位翻转一次,产生了一个周期性的时钟信号。

4. 过程赋值与连续赋值的区别

  • 执行时机:连续赋值是立即执行的,一旦其输入发生变化,赋值就会立刻发生。过程赋值则是在特定条件下或事件发生时执行。
  • 适用场景:连续赋值通常用于描述组合逻辑,而过程赋值用于描述时序逻辑。
  • 存储类型:连续赋值通常用于 wire 或 logic 类型的信号,而过程赋值通常用于 reg 类型的信号。

5. 最佳实践

  • 明确敏感列表:确保 always 块的敏感列表完整,避免遗漏导致的不可预测行为。
  • 避免竞争条件:确保在 always 块中处理所有可能的情况,避免竞争条件。
  • 使用清晰的流程控制:使用适当的流程控制语句(如 ifcase)来组织代码,使其逻辑清晰易懂。
  • 合理使用时延:在必要时使用时延来模拟实际电路中的延迟,但应避免过度使用,以免影响仿真性能。

总结

过程赋值是 Verilog 中用于描述时序逻辑的关键工具之一。通过合理使用 always 块、initial 块、final 块以及流程控制语句,可以精确地控制硬件的行为。希望本节的内容能够帮助你更好地理解和使用 Verilog 的过程赋值,并在实际的设计中发挥重要作用。继续深入学习 Verilog 的其他特性和高级功能,将有助于你更好地掌握这门语言,并应用于实际的硬件设计中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值