HDLbits 刷题 -- Alwaysblock1

本文探讨了在Verilog和SystemVerilog中如何使用always块描述数字电路,重点介绍了组合逻辑与时序逻辑的区别,以及assign和alwaysblocks在表达电路中的角色。同时强调了正确处理线网(wire)和寄存器(reg)以及always(*)的使用在硬件设计中的重要性。
摘要由CSDN通过智能技术生成

学习:

Since digital circuits are composed of logic gates connected with wires, any circuit can be expressed as some combination of modules and assign statements. However, sometimes this is not the most convenient way to describe the circuit. Procedures (of which always blocks are one example) provide an alternative syntax for describing circuits.

For synthesizing hardware, two types of always blocks are relevant:

  • Combinational: always @(*)
  • Clocked: always @(posedge clk)

Combinational always blocks are equivalent to assign statements, thus there is always a way to express a combinational circuit both ways. The choice between which to use is mainly an issue of which syntax is more convenient. The syntax for code inside a procedural block is different from code that is outside. Procedural blocks have a richer set of statements (e.g., if-then, case), cannot contain continuous assignments*, but also introduces many new non-intuitive ways of making errors. (*Procedural continuous assignments do exist, but are somewhat different from continuous assignments, and are not synthesizable.)

For example, the assign and combinational always block describe the same circuit. Both create the same blob of combinational logic. Both will recompute the output whenever any of the inputs (right side) changes value.

译:

由于数字电路是由用导线连接的逻辑门组成的,因此任何电路都可以表示为模块和赋值语句的某种组合。然而,有时这不是最方便的方式来描述电路。Procedures(以 always blocks为例)为描述电路提供了另一种语法。

对于合成硬件,有两种类型的always块是相关的:

组合: always @(*)
时钟: always @(posedge clk)


组合always块相当于赋值语句,因此总有一种方法可以用两种方式表示组合电路。选择使用哪一种主要是哪种语法更方便的问题。过程块内部代码的语法与外部代码不同。过程块具有更丰富的语句集(例如,if-then, case),不能包含连续赋值*,但也引入了许多新的非直观的出错方式。(*程序连续分配确实存在,但与连续分配有些不同,并且不可综合。)

例如,赋值和组合总是块描述相同的电路。两者都创建了相同的组合逻辑。每当任何输入(右侧)改变值时,两者都将重新计算输出。

        assign out1 = a & b | c ^ d;

        always @(*) out2 = a & b | c ^ d;

组合逻辑的always块应该总是使用一个敏感性列表()。明确地列出信号是容易出错的(如果你漏掉了一个信号),并且对于硬件综合来说这是被忽略的。如果你明确指定了敏感性列表并漏掉了一个信号,综合出的硬件仍然会表现得像是指定了()一样,但是仿真不会,并且不会与硬件的行为匹配。(在SystemVerilog中,使用always_comb。)

关于线网(wire)与寄存器(reg)的说明:assign语句的左侧必须是网类型(例如,wire),而always块中的程序化赋值的左侧必须是变量类型(例如,reg)。这些类型(线网对比寄存器)与综合出的硬件无关,只是Verilog作为硬件仿真语言时留下的语法。

练习:

Build an AND gate using both an assign statement and a combinational always block. (Since assign statements and combinational always blocks function identically, there is no way to enforce that you're using both methods. But you're here for practice, right?...)

使用赋值语句和组合always块构建AND门。(因为赋值语句和组合语句总是相同地阻塞函数,所以没有办法强制使用这两种方法。但你是来练习的,对吧?)

// synthesis verilog_input_version verilog_2001
module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);
	assign out_assign = a&b;
    always@(*) out_alwaysblock = a&b;
endmodule

运行结果:

注释:

 关于always@(*)的使用

always 块是硬件描述语言(如Verilog和SystemVerilog)中用于描述硬件电路行为的一种结构。它主要用于模拟和综合时序逻辑和组合逻辑的行为。以下是 always 块的基本用法和注意事项:

时序逻辑(Sequential Logic)

时序逻辑 always 块用于描述那些依赖于时钟信号或其他寄存器值的状态变化。这些 always 块通常包含一个敏感性列表,用于指定哪些信号的变化会触发块内的代码执行。

解释

 

always @(posedge clk or negedge rst_n) begin
  if (!rst_n) begin
    reg_value <= initial_value;
  end else begin
    reg_value <= next_value;
  end
en

在这个例子中,always 块对时钟信号 clk 的上升沿(posedge)和复位信号 rst_n 的下降沿(negedge)敏感。当这些信号变化时,块内的代码会执行。如果复位信号被激活,寄存器 reg_value 将被设置为初始值。否则,它会根据下一个值 next_value 更新。

组合逻辑(Combinational Logic)

组合逻辑 always 块用于描述那些仅依赖于当前输入值的逻辑行为。在这种情况下,敏感性列表包含了所有影响输出的输入信号。在SystemVerilog中,可以使用 always_comb 关键字来明确指出这是一个组合逻辑块。

always @(*) begin
  output = input_A & input_B;
end

在这个例子中,always 块对所有列出的信号(input_Ainput_B)敏感。这意味着,只要这些信号中的任何一个发生变化,块内的代码就会执行。这里没有明确列出敏感性列表,而是使用了 (*) 表示对所有可能影响输出的信号都敏感。

注意事项

  • 敏感性列表:在时序逻辑中,敏感性列表是必须的,用于指定触发 always 块执行的信号。在组合逻辑中,可以使用 (*) 来表示对所有信号敏感。
  • 阻塞赋值:always 块内部通常使用阻塞赋值(例如 reg_value <= value;),这样可以在单个时钟周期内完成赋值。
  • 非阻塞赋值:在某些情况下,特别是在时钟边沿触发的 always 块中,使用非阻塞赋值(例如 reg_value = value;)来避免数据冒险和竞争条件。
  • 仿真与综合:always 块的行为在仿真和综合时可能有所不同。在仿真时,明确列出敏感性列表有助于提高仿真的准确性。然而,在综合时,硬件综合工具通常会忽略显式列出的信号,而是依赖于它们内部的分析来确定敏感性。因此,对于组合逻辑,使用 (*) 是推荐的做法。

总之,always 块是描述数字电路行为的重要工具,它在Verilog和SystemVerilog中被广泛使用。正确理解和使用 always 块对于设计正确和高效的硬件电路至关重要。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刚及格的陆拾伍

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

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

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

打赏作者

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

抵扣说明:

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

余额充值