1 Getting Started


Step One

欢迎来到 HDLBits!

HDLBits 提供了一个非常有用的平台,帮助初学者练习数字逻辑设计。对于刚开始接触数字逻辑设计的人来说,通常会感到信息量庞大,因为你不仅要学习新的概念,还要掌握一种新的硬件描述语言(如 Verilog),使用多个软件工具包,并可能要熟悉 FPGA 开发板的使用。HDLBits 平台通过简单的“仿真”按钮,简化了这些操作,让用户可以专注于练习电路设计和调试。

在设计数字电路的过程中,一般包括几个主要步骤。首先,你需要编写 Verilog 代码来描述电路的行为。接着,通过编译器(如 Altera Quartus)将代码转换为硬件电路。最后,你可以仿真电路,测试其功能并修复错误。通过这样的过程,逐步掌握设计数字电路的技能。

数字逻辑设计的流程

设计一个电路通常需要经过几个步骤:

  1. 编写 HDL 代码:使用 Verilog 语言描述电路的功能。
  2. 编译代码(逻辑综合):将 Verilog 代码转换为可以实际运行的电路。
  3. 仿真电路:通过仿真测试电路是否正常工作,并根据结果修复问题。
  4. 查看最终状态:检查电路是否达到了预期的功能。

这些步骤为数字电路设计提供了系统性的工作流程,帮助你逐步构建、验证并优化电路。

1. 编写代码 (Writing Code)

编写代码是设计电路的第一步。HDLBits 提供的代码编辑器让你可以直接编写 Verilog 代码。对于简单的练习,平台已经为你预先填充了大部分代码,你只需要完成剩下的部分。

在编写代码时,以下是几个关键点:

  • 使用代码编辑框,完成电路描述。
  • 代码完成后,点击“仿真”(Simulate)按钮,进行编译和仿真。

这一过程可以帮助你了解 Verilog 代码的基本结构,以及如何通过代码描述简单的电路。在 HDLBits 中,所有操作都是可视化的,这让你能够快速看到自己的设计结果,并从中学习改进。

2. 编译代码 (Compiling/Logic Synthesis)

当你点击“仿真”按钮时,HDLBits 使用 Altera Quartus 工具来编译你的 Verilog 代码,将其转换为可以在硬件上运行的电路。编译过程中,Quartus 会生成大量的消息和警告。这些消息有助于你了解代码的质量和潜在问题。

编译的几个要点:

  • 尽量减少警告,虽然不可能完全避免所有警告,但减少它们有助于优化代码。
  • 点击“Show Quartus messages”按钮,可以查看或隐藏 Quartus 生成的编译信息。

通过编译过程,你可以逐步熟悉如何从 HDL 代码生成硬件电路。编译不仅是验证代码正确性的一个步骤,还能提供关于电路优化的提示和反馈。

3. 仿真电路 (Simulation)

编译完成后,接下来就是仿真阶段。仿真用于验证你的电路是否按照预期工作。HDLBits 使用 ModelSim 进行仿真,它会将你的电路与参考电路进行对比,确保其输出与参考设计一致。

仿真报告包含以下内容:

  • 仿真结果会告诉你电路是否完全匹配参考电路(即“无不匹配”)或存在多少个不匹配。
  • 仿真过程还可能生成波形图,显示电路在运行测试向量时的输出情况。波形图的三个部分分别为“Inputs”(输入)、“Yours”(你的输出)和“Ref”(参考输出),通过对比你的输出和参考输出,你可以看到电路是否正常工作。
  • 如果出现“Mismatch”信号,意味着电路的某些部分没有正确匹配,这时你需要检查问题并修复代码。

为了确保仿真顺利进行,HDLBits 强调了电路中最顶层模块的名称和端口名称不得更改,否则会出现仿真错误。这一限制是为了确保仿真工具能够正确识别电路结构。

4. 最终状态 (Final Status)

在完成仿真后,你可以检查电路的最终状态。如果一切正常,你将会看到“Status: Success!” 的提示。但如果出现问题,可能会看到以下几种结果:

  • Compile Error:电路没有成功编译,这通常是由于代码中存在语法错误。
  • Simulation Error:代码成功编译了,但仿真未能完成。
  • Incorrect:电路编译和仿真成功,但输出结果与参考电路不匹配。
  • Success!:电路完全正确,输出匹配参考电路。

你可以在“我的统计(My Stats)”页面上追踪或分享你的学习进展。这不仅可以帮助你了解自己已经完成的任务,还可以激励你不断提高电路设计的能力。

5. 问题描述 (Problem Statement)

在这一步的练习中,目标是熟悉 HDLBits 的界面和操作。你将从编写一小段 HDL 代码开始,完成一个非常简单的电路任务:

任务描述:
设计一个没有输入、只有一个输出的电路。该输出始终为逻辑高电平(即输出1)。

预期的解决方案长度: 大约 1 行代码。

你需要在代码框中填写以下模块声明,并补全代码。

模块声明:

module top_module( output one );

Write your solution here

module top_module( output one );

// Insert your code here
    assign one = [fixme];

endmodule
module top_module( output one );
  
// 在此处插入代码
	assign one = 1'b1; // 输出逻辑高电平
endmodule

这个简单的任务是为了让你熟悉 HDLBits 的工作流程,同时理解 Verilog 中如何实现一个固定输出的电路。


Zero

在之前的练习中,你已经实现了一个简单的电路,该电路的输出总是逻辑高电平(1)。现在,我们将尝试一个类似的任务,但这次输出将始终为逻辑低电平(0)。这不仅有助于巩固你对 Verilog 代码的理解,还能进一步熟悉数字电路中的简单逻辑设计。

任务描述

设计一个没有输入且只有一个输出的电路,该输出始终为逻辑低电平,即输出 0。这是一个基本的恒定输出电路,任务十分简单,代码长度约为一行。

在 Verilog 中,通过 assign 语句可以直接为输出分配常量值。我们将使用 assign 来使输出始终为 0。

Verilog 代码语法

HDLBits 使用 Verilog-2001 的 ANSI 风格端口声明语法。这种语法简化了代码的可读性,减少了书写错误。在 Verilog-2001 中,端口声明和定义可以在模块的参数列表中完成,省去额外的声明语句。尽管你也可以使用 Verilog-1995 的语法,但在大多数情况下,Verilog-2001 更为简洁和实用。

以下是两种语法的模块声明形式,均是合法的:

  1. Verilog-1995 风格:
    module top_module ( zero );
        output zero;
        // 在模块体中为输出赋值
    endmodule
    
  2. Verilog-2001 风格:
    module top_module ( output zero );
        // 在模块体中为输出赋值
    endmodule
    

模块实现

对于这个任务,我们需要编写一个模块 top_module,它的输出 zero 始终为逻辑低电平。你只需要使用 assign 语句将 zero 赋值为 1'b0,其中 1'b0 表示一个1位宽度的二进制数,值为 0。

完整的代码示例:

module top_module(
    output zero
);
    assign zero = 1'b0;  // 将输出恒定为0
endmodule

代码讲解

  • 模块声明: 使用 Verilog-2001 风格,在模块参数中直接声明 output zero,省去了单独的 output 声明。
  • assign 语句: assign 是 Verilog 中用于连续赋值的语句。在这里,我们将 zero 始终赋值为逻辑 0 (1'b0),确保输出固定为低电平。
  • 缩进: Verilog 代码的缩进有助于代码的可读性,模块体和 assign 语句都保持一致的缩进格式,便于理解代码结构。

这一练习的目标是让你在没有提示的情况下,独立编写出最基本的 Verilog 代码,进一步增强对数字电路设计的信心和理解。