出处https://blog.csdn.net/m0_66307842/article/details/128909623?spm=1001.2014.3001.5501
作者:流继承

前言:本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载

示例:数码管的使用

  • 功能特性: 采用 Xilinx Artix-7 XC7A35T芯片
  • 配置方式:USB-JTAG/SPI Flash
  • 高达100MHz 的内部时钟速度
  • 存储器:2Mbit SRAM N25Q064A SPI Flash(样图旧款为N25Q032A)
  • 通用IO:Switch :x8LED:x16Button:x5DIP:x8 通用扩展IO:32pin
  • 音视频/显示: 7段数码管:x8 VGA视频输出接口 Audio音频接口
  • 通信接口:UART:USB转UART Bluetooth:蓝牙模块
  • 模拟接口: DAC:8-bit分辨率 XADC:2路12bit 1Msps ADC

目录

[TOC]

Ⅰ. 前置知识

0x01 七段数码管工作原理

共阴极七段数码管内部结构如图。七个线形LED灯a~g构成七段,其位置序号如图:

一端并接称为位码;一端分别接收电平信号以控制灯的亮灭,称为段码。

点亮要求为:共阴型数码管位码接低电平,需点亮的段码接高电平。若数码管类型为共阳极,其点亮要求的电平正好相反。

BCD码转七段数码管的电路作用是将BCD码表示的十进制数转换成七段LED数码管的7个驱动段码端。

如输入DB(A3、A2、A1、A0),输出g-a。如输入数据为0000,则控制数码管显示“0”形,即f~a灯亮,g灯灭,若设计的译码器用于控制共阴极数码管,则输出的g~a的信号为0111111。

以8421BCD码转七段数码管段码为例,说明电路原理:

8421BCD码转七段数码管段码是将BCD码表示的十进制数转换成七段LED数码管的7个驱动段码,真值表如下

数字

输入

输出

B8

B4

B2

B1

a

b

c

d

e

f

g

0

0

0

0

0

1

1

1

1

1

1

0

1

0

0

0

1

0

1

1

0

0

0

0

2

0

0

1

0

1

1

0

1

1

0

1

3

0

0

1

1

1

1

1

1

0

0

1

4

0

1

0

0

0

1

1

0

0

1

1

5

0

1

0

1

1

0

1

1

0

1

1

6

0

1

1

0

1

0

1

1

1

1

1

7

0

1

1

1

1

1

1

0

0

0

0

8

1

0

0

0

1

1

1

1

1

1

1

9

1

0

0

1

1

1

1

1

0

1

1

10

1

0

1

0

d

d

d

d

d

d

d

15

1

1

1

1

d

d

d

d

d

d

d

下面以a为例介绍原理与过程。首先绘制输出a的卡诺图如下表:

B2B1

B8B4

00

01

11

10

00

1

0

1

1

01

0

1

1

1

10

1

1

d

d

11

d

d

d

d

然后考虑无关项的必要质蕴含项,如图:

接着就可以得到最简与或式了。

同样方法,根据真值表画出每个输出项的卡诺图,化简得到b-g的逻辑表达式。a-g的逻辑表达式如下:

根据上述逻辑表达式,可用Verilog语言编写设计源代码

或用IP包搭建电路如图:

0x01 多位数码管工作原理

下图示意了四个数码管组合的结构:

由于实验板内部采用驱动电路控制数码管,其内部结构和控制方法采用以下规则:四个数码管的段码引脚按序号分别并接,用位码控制某一个数码管的亮灭。

如:要让图中第1、3个数码管显示“0”,其他2、4数码管全灭,可以给a~g送段码8’b11111100,给1~4送位码4’b1010。

这里我们以 EG01 实验板卡为 FPGA 板级验证平台:

Ⅱ. Verilog实现

0x00 实现内容

采用Verilog设计一个编码转换电路,将输入的8421BCD编码转换七段数码管段码,并利用EGO1实验板上的数码管上显示与输入数据对应的十进制值。

0x01 设计代码文件

Veriog HDL 共有三种建模方式。

其描述风格分为结构描述、数据流描述、行为描述以及混合描述。

为了方便读者,本篇博客使用行为描述和数据流描述两种建模方法进行建模

行为描述建模:

module hex7seg(input wire [3:0] x,output reg [6:0] a_to_g);
always @ (x)
    case(x)
        0:a_to_g=7'b1111110;
        1:a_to_g=7'b0110000;
        2:a_to_g=7'b1101101;
        3:a_to_g=7'b1111001;
        4:a_to_g=7'b0110011;
        5:a_to_g=7'b1011011;
        6:a_to_g=7'b1011111;
        7:a_to_g=7'b1110000;
        8:a_to_g=7'b1111111;
        9:a_to_g=7'b1111011;
        default:a_to_g=7'b0000001;
    endcase
endmodule
module hex7seg_top(sw,a_to_g,an,dp);
    input wire [3:0] sw;
    output wire [6:0] a_to_g;
    output wire [3:0] an;
    output wire dp;
        assign an=4'b1111;
        assign dp=0;
    hex7seg D4(.x(sw),.a_to_g(a_to_g));
endmodule

数据流描述建模:

module Nixielight(input[3:0] B,output [7:0]SEG,output [3:0]bC);
 assign SEG[0]=B[3]|((~B[2])&(~B[0]))|B[1]|(B[2]&B[0]);
 assign SEG[1]=(~B[2])|(B[1]&B[0])|((~B[1]&(~B[0])));
 assign SEG[2]=B[2]|(~B[1])|B[0];
 assign SEG[3]=B[3]|((~B[2])&(~B[0]))|((~B[2])&B[1])|(B[1]&(~B[0]))|(B[2]&(~B[1])&B[0]);
 assign SEG[4]=((~B[2])&(~B[0]))|(B[1]&(~B[0]));
 assign SEG[5]=B[3]|((~B[1])&(~B[0]))|(B[2]&(~B[1]))|(B[2]&(~B[0]));
 assign SEG[6]=B[3]|(B[1]&(~B[0]))|((~B[2])&B[1])|(B[2]&(~B[1])); 
 assign SEG[7]=0;
 assign bC=15;
endmodule

0x02 仿真代码文件

行为描述建模:

module sim1();
reg [3:0] sw;
wire [6:0] a_to_g;
wire [3:0] an;
wire dp;
hex7seg_top uu1(sw,a_to_g,an,dp);
initial sw=4'b0000;
always #100 sw=sw+1;
endmodule


数据流描述建模:

module sim_Nixielight();
 reg [3:0]B;
 wire [7:0]SEG;
 wire [3:0]bC;
 Nixielight test(.B(B),.SEG(SEG),.bC(bC));
 always begin
 B[3]=0;B[2]=0;B[1]=0;B[0]=0;#100;
 B[3]=0;B[2]=0;B[1]=0;B[0]=1;#100;
 B[3]=0;B[2]=0;B[1]=1;B[0]=0;#100;
 B[3]=0;B[2]=0;B[1]=1;B[0]=1;#100;
 B[3]=0;B[2]=1;B[1]=0;B[0]=0;#100;
 B[3]=0;B[2]=1;B[1]=0;B[0]=1;#100;
 B[3]=0;B[2]=1;B[1]=1;B[0]=0;#100;
 B[3]=0;B[2]=1;B[1]=1;B[0]=1;#100; 
 B[3]=1;B[2]=0;B[1]=0;B[0]=0;#100;
 B[3]=1;B[2]=0;B[1]=0;B[0]=1;#100; 
 end
endmodule

0x03 观察记录仿真波形

分析仿真波形,记录输出结果,对所设计的电路功能是否满足设计要求给出结论。

0x04 添加引脚约束

按照 EG01 硬件手册提供的资料,选择输入和输出设备,设置引脚约束。

设置完毕,保存管脚约束文件。

本次实验利用 SW7-SW4 作为数据输入,DK5-8 及对应的八个段码作为显示电路输出.

引脚约束关系如下:

引脚约束设置完成后,综合,点击“PROGRAM AND DEBUG”选项中的“Generate Bitstream”在经过综合、实现两个阶段后,可生成 bit 文件。

下载 bit 文件到 FPGA

正确得到 bit 文件后,将 EG01 板与电脑用板卡包里提供 USB 数据线进行连接。

连接完毕,打开 EG01 电源开关,可看到电源指示灯点亮。

随后,点击“Open Hardware Manager”选择 “Auto Connect”,连接 EG01。

连接成功后,点击“Program Device”将 bit 文件下载至 EG01 的 FPGA。

下载完毕,利用设计时选择的开关输入不同的值,对电路进行测试

Ⅳ 知识扩展

0x00 扩展实验

结合前期实验内容,实现能完成下列功能的电路,

要求在Vivado中完成设计与仿真,并下载至EGO1实验板进行验证与分析。

用1个数码管显示开关的编号,电路功能如下:

开关1按下,在第一个数码管显示1;开关2按下,在第二个数码管显示2;开关3按下,在第三个数码管显示3;开关4按下,在第四个数码管显示4。参考真值表如下:

输入

输出

SW1

SW2

SW3

SW4

a

b

c

d

e

f

g

h

1

0

0

0

0

1

1

0

0

0

0

0

0

1

0

0

1

1

0

1

1

0

1

0

0

0

1

0

1

1

1

1

0

0

1

0

0

0

0

1

0

1

1

0

0

1

1

0

x

x

x

x

d

d

d

d

d

d

d

d

根据真值表,写出设计代码如下:

module SY3_KZ(input [3:0]b,output [7:0]seg,output [3:0]bc);
assign seg[0]=(~b[0])&(~b[3]);
assign seg[1]=1;
assign seg[2]=(~b[1])&(~b[3])|((~b[0])&(~b[1])&(~b[2]));
assign seg[3]=(~b[0])&(~b[3]);
assign seg[4]=b[1];
assign seg[5]=b[3];
assign seg[6]=((~b[0])&(~b[3]))|((~b[0])&(~b[1])&(~b[2]));
assign seg[7]=0;
assign bc=b;
endmodule

仿真代码:

module sim_SY3_KZ();
 reg [3:0]b;
 wire [7:0]seg;
 SY3_KZ test(.b(b),.seg(seg));
 always begin
 b[0]=1;b[1]=0;b[2]=0;b[3]=0;#100;
 b[0]=0;b[1]=1;b[2]=0;b[3]=0;#100;
 b[0]=0;b[1]=0;b[2]=1;b[3]=0;#100;
 b[0]=0;b[1]=0;b[2]=0;b[3]=1;#100;
 end
endmodule

引脚约束:

波形图:

引脚约束设置完成后,综合,点击“PROGRAM AND DEBUG”选项中的“Generate Bitstream”在经过综合、实现两个阶段后,可生成 bit 文件。

下载 bit 文件到 FPGA

正确得到 bit 文件后,将 EG01 实验板与电脑用板卡包里提供 USB 数据线进行连接。

连接完毕,打开 EG01 电源开关,可看到电源指示灯点亮。

随后,点击“Open Hardware Manager”选择 “Auto Connect”,连接 EG01。连接成功后,点击“Program Device”将 bit 文件下载至 EG01 的 FPGA。

下载完毕,利用设计时选择的开关输入不同的值,对电路进行测试