Vivado程序设计-仿真流程

目录

一、基本流程

二、新建工程

三、文件输入

3.1、文件创建

3.2、端口设定补充

3.3、RTL程序输入

3.4、XDC约束文件建立

3.5、快捷定义

四、仿真

4.1、文件创建

4.2、激励文件编写

4.3、开始仿真

五、下载 

六、仿真文件要点补充

1、端口变量

2、文件关系

3、简单案例

七、代码写入


 

一、基本流程

  1. 编写RTL文件
  2. 建立仿真文件
  3. 通过I/O Planing添加管脚约束
  4. 编写约束文件添加管脚约束
  5. 添加时序约束
  6. 生产Bitstream文件并下载

二、新建工程

  1. Create New Project;
  2. 输入工程名称、选择工程存储路径,并勾选 Create project subdirectory 选项,为工程在指定存储路径下建立独立的文件夹;Next;
  3. 选择 RTL Project 一项,并勾选 Do not specify sources at this time,勾选该选项是为了跳过在新建工程的过程中添加设计源文件;Next;
  4. 根据使用的 FPGA 开发平台,选择对应的 FPGA 目标器件;Next;

  5. Finish.Vivado程序设计-仿真流程_第1张图片

        新建工程如图

三、文件输入

3.1、文件创建

        如下图所示,点击 Flow Navigator 下的 Project Manager->Add Sources 或中间 Sources 中的对话框打开设计文件导入添加对话框。

Vivado程序设计-仿真流程_第2张图片

         选择第二项 Add or Create Design Sources,用来添加或新建 Verilog 或 VHDL 源文件,点击Next。Vivado程序设计-仿真流程_第3张图片

         如果有现有的 V/VHD 文件,可以通过 Add Files 一项添加。在这里,我们要新建文件,所以选择 Create File 一项。Vivado程序设计-仿真流程_第4张图片

         在 Create Source File 中输入 File Name,点击 OK。

Vivado程序设计-仿真流程_第5张图片

         点击OK。Vivado程序设计-仿真流程_第6张图片

         在弹出的 Define Module 中的 I/O Port Definition,输入设计模块所需的端口,并设置端口方向,如果端口为总线型,勾选 Bus 选项,并通过 MSB 和 LSB 确定总线宽度。

        在弹出的 Define Module 中的 I/O Port Definition,输入设计模块所需的端口,并设置端口方向,完成后点 OK。Vivado程序设计-仿真流程_第7张图片

        新建的设计文件(此处为 flowing_light.v)即存在于 Sources 中的 Design Sources 中。双击打开该文件,输入相应的设计代码。Vivado程序设计-仿真流程_第8张图片

3.2、端口设定补充

        Vivado中Bus用于创建、编辑和配置总线(Bus)的工具,总线即计算机系统中用于多设备之间传输的通信系统。

        Bus选项有四种功能:

  • 创建新总线;
  • 编辑已有总线的名称、信号及位宽等属性;
  • 添加新的总线接口,以将IP核或子系统连接如总线;
  • 总线属性配置,如clk和rst信号。

        MSB(Most Significant Bit)和 LSB(Least Significant Bit)分别为数据最高有效位(左侧位)与最低有效位(右侧位)。

3.3、RTL程序输入

'timescale 1ns / 1ps

module flowing_light(
    input clk,        //时钟
    input rst,        //复位
    output [3:0] led    //管脚设定
);

    reg [23 : 0] cnt_reg;    //计数
    reg [3 : 0] light_reg;    //亮灯控制
    
    always @ (posedge clk)    //高电平触发
        begin
            if (!rst)        //若rst为低电平
                cnt_reg <= 0;        //计数器复位
            else
                cnt_reg <= cnt_reg + 1;        
                //rst为高电平时计数器累加,达到最大值后越界变回0
        end
    //计数器,作用于分频相同,控制输出信号的变化频率
    
    always @ (posedge clk)    //高电平触发
        begin
            if (!rst)        //rst为低电平
                light_reg <= 4'h1;    //复位,0001
            else if (cnt_reg == 24'hffffff)        //计数器达到最大值
                begin
                    if (light_reg == 4'h8)    //若为'b1000
                        light_reg <= 4'h1;    //变为'b0001
                        //数位为二进制是的位数
                    else
                        light_reg <= light_reg << 1;    //左移一位,下一位LED亮
                end
        end
    //输出信号生成器

    assign led = light_reg;    //赋值输出信号
    //连个always并行执行
endmodule

3.4、XDC约束文件建立

        点击 Add Sources,选择第一项 Add or Create Constraints 一项,点击 Next。   Vivado程序设计-仿真流程_第9张图片

         点击 Create File,新建一个 XDC 文件,输入 XDC 文件名,点击 OK。点击 Finish。   

Vivado程序设计-仿真流程_第10张图片

        点击 Create File,新建一个 XDC 文件,输入 XDC 文件名,点击 OK,点击 Finish。   

        双击打开新建好的 XDC 文件,并按照如下规则,输入相应的 FPGA 管脚约束信息和电平标准。

## Clock signal 125 MHz
//时间信号为125MHz

set_property -dict { PACKAGE_PIN H16   IOSTANDARD LVCMOS33 } [get_ports { clk }];
create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { clk }];

##LEDs

set_property -dict { PACKAGE_PIN R14   IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; 
set_property -dict { PACKAGE_PIN P14   IOSTANDARD LVCMOS33 } [get_ports { led[1] }];
set_property -dict { PACKAGE_PIN N16   IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; 
set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; 

##Buttons

set_property -dict { PACKAGE_PIN D19   IOSTANDARD LVCMOS33 } [get_ports { rst }]; 

        其中"PACKAGE_PIN"为引脚代号,"IOSTANDARD LVCMOS33"表示标准电平为3.3V的低压差分CMOS,即逻辑高电平为3.3V,逻辑低电平为0V。标准电平为电路正常工作下单电压,通常在数字电路中标准电平用于描述逻辑高、低电平。

3.5、快捷定义

        在PROJECT MANAGER中点击RTL ANALYSIS,在点击Open Elaborated Design,再在Schematic界面选择 I/O Ports,即可在屏幕下方弹出的Find Results 中快速设定端口管脚。

        其中管脚名与IO直接由主程序定义,用户只需要对Package Pin(管脚) 以及 I/O Std 标准电平进行选择即可。但需要注意由此生成的xdc文件在格式上会与手动输入有所不同。Vivado程序设计-仿真流程_第11张图片

 

四、仿真

4.1、文件创建

        创建激励文件,在 Add Source 界面中选择第三项 Add or Create Simulation Source,点击 Next。选择 Create File 创建一个仿真激励文件。Vivado程序设计-仿真流程_第12张图片

         确认添加完成之后点击 Finish,因为是激励文件不需要对外端口,所以直接 Port 部分直接空着,点击 ok。

Vivado程序设计-仿真流程_第13张图片

4.2、激励文件编写

`timescale 1ns / 1ps

module tb(    );
    reg clk;
    reg rst;
    wire [3 : 0] led;
    flowing_light u0(
        .clk(clk),
        .rst(rst),
        .led(led) );
    
    parameter PERIOD = 10;

    always    //持续执行 
        begin
            clk = 1'b0;
            #(PERIOD/2)
            clk = 1'b1;
            #(PERIOD/2);
        end
    //时钟设置,周期为10个时间单位,占空比50%

    initial    //仅执行一次
        begin
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;
            #100;
            rst = 1'b0; 
            #100; 
            rst = 1'b1;
        end
    //初始化复位状态
endmodule

        initial 块,表示在模块被实例化时只执行一次。

        initial块的作用是对时钟和复位信号进行初始化,以确保模块在开始工作之前处于正确的状态。具体来说,该代码段将时钟信号 clk 初始化为低电平,并将复位信号 rst 初始化为高电平。然后,等待一段时间,将复位信号 rst 置为低电平。等待一段时间后,再次将复位信号 rst 置为高电平。这样做的目的是确保模块在开始工作时具有稳定的时钟信号和正确的复位状态。

4.3、开始仿真

        下图所示为仿真界面。Vivado程序设计-仿真流程_第14张图片

           可通过左侧 Scope 一栏中的目录结构定位到设计者想要查看的 module 内部寄存器,在 Objects对应的信号名称上右击选择 Add To Wave Window,将信号加入波形图中。 因为窗口已有信号,此操作不需要进行。     Vivado程序设计-仿真流程_第15张图片        可通过选择工具栏中的如下选项来进行波形的仿真时间控制。如下工具条,分别是复位波形(即清空现有波形)、运行仿真、运行特定时长的仿真、仿真时长设置、仿真时长单位、单步运行、暂停……

 49fb3811bbd64f25aa6547cc6416a2a3.png

五、下载 

        在 Flow Navigator 中点击 Program and Debug 下的 Generate Bitstream 选项,工程会自动完成综合、实现、 Bit 文件生成过程。

        点击 Flow Navigator 中 Open Hardware Manager 一项,进入硬件编程管理界面。

        在提示的信息中,选择 Open Hardware Manager(或在 Flow Navigator 中展开 HardwareManager,点击 Open Target)。 选择Auto Connect连接到板卡。Vivado程序设计-仿真流程_第16张图片

         连接成功后, 在目标芯片上右击,选择 “Program Device”。在弹出的对话框中 “Bitstream File” 一栏已经自动加载本工程生成的比特流文件,点击 “Program” 对 FPGA 芯片进行编程。下载完成后, 在板子上观察实验结果。Vivado程序设计-仿真流程_第17张图片

六、仿真文件要点补充

1、端口变量

  1. 在主程序内,仅可对端口输出变量进行赋值无法对端口变量类型进行定义,否则会出现警告:(图中outout为一个端口输出变量)(即主程序内不需要对端口变量进行定义,在物理上一个模块也无法定义上一模块产生的数据)(应当在端口设定时定义)739a2c6d0d77471d9e23d844a52bac26.png
  2.  在tb文件输出中需要注意复位rst&时钟clk为reg型变量,而其他输出为wire型变量
  3. 仿真中的变量以tb文件为标准,若tb文件中向量A超过主程序中A两个维度,则在仿真结果中向量A的最高两维将会是高阻态Z;
  4. 所有变量在均为2进制储存。

2、文件关系

  1. 主程序文件与tb文件通过程序开头变量声明来连系;
  2. tb文件依靠对主程序文件IO端口的“调用”来与主程序文件连系。

3、简单案例

        主程序:

`timescale 1ns / 1ps
module test1(
    input rst,
    input clk,
    output [5:0] outout
    );
    reg [5:0] outout1 = 6'b0;
    //应当尽量保持计算变量与输出变量的长度一致
    always@(posedge clk)
        outout1 = outout1 + 1;
    assign outout = outout1;
endmodule

        tb:

`timescale 1ns / 1ps
module tb(
    );
    reg clk;
    reg rst;
    wire [5:0] outout;
    //wire [7:0] outout ;//此时最高位为Z,可以发现仿真输出由tb决定
    test1 test1(//后面的名字随便写
        .rst(rst),
        .clk(clk),
        .outout(outout)
        );//主程序通过此函数与tb文件相连接,与ip核的调用相同,I或O控制有主程序来定义
    initial
        begin 
            clk =1'b0;
            rst = 1'b1;
            #20
            rst = 1'b0;
            #20 
            rst = 1'b1;
        end
    always 
        begin
            #10
            //仿真仅到1k nm 若需要后续仿真数据,可以通过改主频率来实现,反正是仿真,时钟是程序给的,超过主板的主频也行
            clk = ~clk;
        end
endmodule

        其中调用主程序IO端口为:

    test1 test1(
        .rst(rst),
        .clk(clk),
        .outout(outout));

        代码中后一个test1可以写任意合法字符串,而端口变量按以上形式写即可,可以看到这段代码与ip核的调用十分相似。

4、实际端口

        在vivado中完成仿真后,就是烧录步骤。在此步骤需要注意,程序中定义的所以IO口均需要进行定义

七、代码写入

  1. 在Flow Navigator中点击Generate Bitstream选项;
  2. 点击Flow Navigator中的Open Hardware Manager选项,进入硬件变成管理界面;
  3. 在屏幕上方的提示界面(绿色)中点击Open target,并选择Auto Connet,随后连接到板卡;
  4. 连接后在目标芯片(绿色)中选择Program Device选项,在弹出的对话框中Bitstream File一栏中已经自动加载好比特流文件,点击Program对FPGA进行编程。

        切忌生产bitstream后不录入文件(本人没发现之后和程序斗智斗勇三天结果发现是没写进去)

 

你可能感兴趣的:(FPGA-Vivado学习,fpga开发)