跳转至

实验四 点亮数码管实验

实验目的

  1. 通过数码管点亮程序,熟悉可编程器件的实验环境以及实验流程,掌握 EDA 软件(vivado)的使用方法和工作流程
  2. 初步了解 SystemVerilog 语言的一些基本框架,了解掌握硬件程序的编写规范。
  3. 进一步理解可编程芯片的工作原理。

实验内容

根据数码管的译码要求,用硬件描述语言设计数码管输出显示电路,输入端为四位开关表示的 8421BCD 码。

  1. 点亮一个带译码的数码管,数码管根据输入显示从 0 到 9;
  2. 点亮一个不带译码的数码管数码管,根据输入显示从 0 到 f。

设计需求

  1. 带译码的七段数码管本身已经带译码电路,可以直接开关模块的 4 位开关连接到带译码的七段数码管模块的一个数码管的四个输入即可,不使用 FPGA;
  2. 不带译码的七段数码管需要使用 FPGA 将 4 位开关 sw 译码成七段数码管的各段控制信号 seg, 从而在不带译码的七段数码管上显示成相应的数字。

设计框图

flowchart LR

  sw[拨动开关]:::periph -- sw ---> decoder;

  decoder -- seg --> seg[SEG]:::periph;

  subgraph FPGA
    direction BT
    decoder[译码器 Decoder]:::comb;
  end

  classDef comb fill:#e8f5e9,stroke:#43a047;   %% green
  classDef seq fill:#ffecb3,stroke:#ffa000;    %% orange
  classDef periph fill:#e3f2fd,stroke:#2196f3; %% blue
  linkStyle default opacity:1.0

原理图

七段数码管显示原理

七段数码管由七个横条发光二极管(a,b,c,d,e,f,g)和一个圆点发光二极管(h)构成,每一个发光二极管由一位输入控制,共有 8 个信号控制(包括小数点),如图所示:

当输入为高时,相应位置的发光二极管数码管点亮,点亮不同的发光二极管可以组成不同的图形,因此一个七段数码管可以用来显示 0~9、A~F 十六进制数和一个小数点。

译码器 Decoder

译码器的功能是将 4 位的 8421BCD 码开关输入信号 sw[3:0] 转换为对应的七段数码管的 7 个发光二极管的控制信号 seg[6:0] ,使得这个 7 个发光二极管组成不同的数字。

Tips

本实验不考虑小数点,不带译码的七段数码管模块上的小数点位也直接接低,不会点亮。

译码器的真值表如下所示:

代码模板

下面给出的代码仅供参考

module decoder (
    input wire [3:0] sw,    //拨动开关输入
    output reg [6:0] seg    //七段数码管输出
    );

    always_comb begin
        case (sw)
            4'h0: seg = 7'b1111110;
            // ... 补全其他情况 (4'h1~4'hF)
            default: seg = 7'b0; 
        endcase
    end
endmodule

管脚绑定

使用可编程模块上的接插孔连接开关和七段数码管,其中 IO1 ~ IO4 作为输入 sw[3:0],连接到开关模块;IO14 ~ IO20 作为输出 seg[6:0],分别连接七段数码管的a ~ f。约束文件如下:

# sw input
set_property -dict {PACKAGE_PIN M21 IOSTANDARD LVCMOS33} [get_ports sw[3]];
set_property -dict {PACKAGE_PIN N20 IOSTANDARD LVCMOS33} [get_ports sw[2]];
set_property -dict {PACKAGE_PIN N22 IOSTANDARD LVCMOS33} [get_ports sw[1]];
set_property -dict {PACKAGE_PIN P21 IOSTANDARD LVCMOS33} [get_ports sw[0]];

# seg output
set_property -dict {PACKAGE_PIN Y21 IOSTANDARD LVCMOS33} [get_ports seg[6]];
set_property -dict {PACKAGE_PIN AB22 IOSTANDARD LVCMOS33} [get_ports seg[5]];
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD LVCMOS33} [get_ports seg[4]];
set_property -dict {PACKAGE_PIN AB18 IOSTANDARD LVCMOS33} [get_ports seg[3]];
set_property -dict {PACKAGE_PIN AA20 IOSTANDARD LVCMOS33} [get_ports seg[2]];
set_property -dict {PACKAGE_PIN AB21 IOSTANDARD LVCMOS33} [get_ports seg[1]];
set_property -dict {PACKAGE_PIN AA21 IOSTANDARD LVCMOS33} [get_ports seg[0]];

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]

关于约束和引脚绑定

FPGA 的对应端口已经与板子上对应的 IO 口用导线连接。具体关系参见:可编程模块(XC7A35) 一小节中的管脚连接表。

因此我们只需要将设计中顶层模块的信号接到对应 FPGA 管脚上,就可以将我们的设计与 FPGA 模块上的 IO 口连接起来了。

在后续课程中我们还会用到时钟,时钟信号只能够接在特定的引脚上,同时还需要添加额外的约束指令。我们在后面使用时钟时会进行更详细的介绍。

具体来说,这些管脚约束命令用于在FPGA或其他可编程逻辑设备的配置文件中指定特定端口(或管脚)的属性。每个命令基本上都在做两件事:指定一个具体的物理管脚和设置该管脚的电气标准。下面是对这些命令的详细解释:

端口(sw[3] 至 sw[0]) 和 端口(seg[6] 至 seg[0]) 管脚约束

对于每个 set_property -dict 命令:

PACKAGE_PIN: 指定FPGA芯片上的物理管脚位置,例如 M21, N20, N22 等 。 IOSTANDARD: 设置该管脚的电气标准,这里使用的是 LVCMOS33,代表低压CMOS 3.3V 逻辑电平。

[get_ports ]: 指定这些属性应用于哪个逻辑端口(顶层模块的输入输出),sw[3] 到 sw[0] 和 seg[6] 到 seg[0] 是端口名称,通常这些端口连接到FPGA外部的开关或是其他输入/输出设备。

设计属性

set_property CFGBVS VCCO [current_design]: 设置当前设计的板载电压。CFGBVS 是配置电压选择,VCCO 指代一个电压区域。

set_property CONFIG_VOLTAGE 3.3 [current_design]: 设置FPGA配置阶段使用的电压,这里设定为3.3V。

这些设置对于确保FPGA与外部硬件正确接口并按预期工作至关重要,因为它们确保了电气信号的兼容性和物理连接的正确性。

实验步骤

  1. 使用 vivado2019.2 新建一个工程,编写 system verilog 代码,并进行综合;
  2. 设置管脚约束,生成 bitsteam 文件;
  3. 使用开关模块,可编程模块和带译码的七段数码管模块,进行电路连接;
  4. 配置 FPGA,测试电路功能是否满足要求,完成实验。

具体实验步骤请参见vivado 使用入门

实验报告

  1. 整理出完整、清晰的代码,并详细添加注释说明电路的工作原理。
  2. 总结编写和调试中所遇到的问题及解决方法。

最后更新: 2024年5月30日
作者:cuibst (8.78%), 李山山 (67.57%), Jiajie Chen (9.46%), liuh22 (14.19%)