300|0

182

帖子

0

资源

一粒金砂(中级)

【Perf-V评测】流水灯&Verilog基本语法 [复制链接]

本帖最后由 donatello1996 于 2021-2-19 20:21 编辑

       春节放假在家有空的时候学习了一下VIVADO开发环境的基本使用和Verilog语言基本语法,用着学到的知识写了个简单的流水灯,颇有收获。先说下VIVADO环境,要在这个环境下写流水灯代码,需要做、


-源码编写
-run synthesis(综合) 
-run implementation(执行/落实)
-implementation design指定硬件管脚
-生成bit文件
-烧录bit文件到DDR中或FLASH中


五步,其中run implementation依赖run synthesis步骤,生成bit文件依赖run implementation步骤,还有就是将FPGA芯片的硬件管脚和源码做绑定在run implementation步骤的implementation design功能中完成,因为源码里面所有的输入输出变量都没有绑定任何管脚。如果源码中的输入输出变量发生变化(变量名/变量个数发生变化),则需要重新运行上述所有步骤;如果只是想重新指定若干硬件管脚而输入输出变量没变的话,则不需要重新运行run synthesis步骤。先来看看源码编写部分:

module led(
    input sw1,
    input sw2,
    input sw3,
    input sw4,
    input clk,
    output D0,
    output D1,
    output D2,
    output D3,
    output reg[8:0] D456
    );
    assign D0 = sw1;
    assign D1 = sw2;
    assign D2 = sw3;
    assign D3 = sw4;
    parameter T = 10000000;
    reg [31:0] cnt;
    reg [31:0] state;
    reg [8:0] led_bits [8:0];
    integer flag = 1;

    always @ (posedge clk)
    begin
        if(flag == 1)
        begin
            flag <= 0;
            state <= 0;
            led_bits[0] <= 9'b111111110;
            led_bits[1] <= 9'b111111101;
            led_bits[2] <= 9'b111111011;
            led_bits[3] <= 9'b111110111;
            led_bits[4] <= 9'b111101111;
            led_bits[5] <= 9'b111011111;
            led_bits[6] <= 9'b110111111;
            led_bits[7] <= 9'b101111111;
            led_bits[8] <= 9'b011111111;
        end
        cnt <= cnt + 1;
        if(cnt == T)
        begin
            cnt <= 0;
            D456 <= led_bits[state];
            state <= state + 1;
            if(state == 10)
            begin
                state <= 0;
            end
        end
    end
endmodule

一行一行进行解读,生怕忽略掉细节:

 

-begin/end类似C语言的大括号{},为一段包含性代码;

 

-module led(...);写法类似C语言的main函数,是Verilog语言的主体执行部分,小括号内是对于输入输出变量的声明,小括号后要加分号,module写完之后要用endmodule结尾,类似C语言函数结束的}右大括号
module里面一般写input输入变量和output输出变量,如果没有reg或者中括号[8:0]关键字,则默认为bool类型变量,变量值为1或0,比如input sw1就是一位宽输入变量sw1,output D0就是一位宽输出变量D0,output reg[8:0] D456就是9位宽输出变量D456;

-assign D0 = sw1;这行语句充分说明了Verilog语言是描述性语言而不是过程性语言,这行语句说明了输出变量D0的值完全要与输入变量sw1的值相等,只要FPGA开始上电运行代码,D0的状态就必须跟随sw1状态,与执行时间无关,不受其它过程性因素和其它变量的影响;

 

-parameter T = 10000000; T是一个值为10000000的常量,不能在源码的其它地方被修改,类似C语言const;

 

-reg [31:0] cnt;cnt是一个位宽为32位的变量,类似C语言的int cnt,reg变量位宽可自由指定;

 

-reg [8:0] led_bits [8:0];led_bits是一个成员个数为9,成员位宽为9的一维数组,reg关键字后是成员个数,变量名后是位宽,reg数组位宽可自由指定;

 

-integer flag = 1;用法与C语言int flag = 1;完全相同;

 

-always @ (posedge clk)是循环语法,类似while(),其中变量posedge clk的意思是clk输入变量/输入信号的上升沿,整句语句的意思是clk输入信号每产生一个上升沿,则always内部语句执行一次,从这里可以看出来,Verilg的循环语法完全可以由硬件信号进行控制,而C语言中while(1)/while(i++)等语句由CPU机器周期进行控制,虽然机器周期和硬件信号有特定代数关系,但是还是有本质区别的。这里还说明一点,FPGA芯片可以接入一个或多个时钟源,至少接入一个,不同的always语句可以由不同频率时钟源进行控制,在always语句内部通过计数器溢出方式对接入时钟源进行分频,代码非常简单粗暴,看到这我想起了STM32单片机自带的TIMER定时器,但Verilog语句明显比TIMER直接多了;

 

-        if(flag == 1)
        begin
            flag <= 0;
            ...
        end
这个是上电之后执行一次的语句,因为Verilg语法规定所有变量赋值语句必须在实体模块中执行,always语句就是最常用的实体模块;

 

-上电后对led_bits数组的每一个成员进行赋值,从111111110依次到011111111按序赋值,也就是流水灯的效果;

 

-D456 <= led_bits[state];将数组的值赋给D456输出变量,D456刚好就是一个9位的变量,对应板子上的三个RGBLED灯。

 

代码写好,检查无语法错误,开始进行run synthesis和run implementation,快捷键F11:

15.jpg 16.jpg

 

然后指定硬件管脚,这里指定D456输出变量的管脚为开发板实际RGBLED灯管脚,一共九个管脚,依次配置,除此之外还有D0~D3,sw1~sw4对应的四盏红色LED灯和四个开关:

17.jpg

18.jpg

19.jpg

 

配置完毕之后生成bit文件,点击上方工具栏按钮即可,注意生成bit文件的时候有几率会报错,提示Error(s) found during DRC. Bitgen not run,解决方法参考:
https://blog.csdn.net/weixin_43065256/article/details/86557378即写一个name.tcl脚本文件,内容为:

set_property SEVERITY {Warning} [get_drc_checks NSTD-1]

set_property SEVERITY {Warning} [get_drc_checks RTSTAT-1]

set_property SEVERITY {Warning} [get_drc_checks UCIO-1]

21.jpg

将脚本指定到Generate Bitstram功能的右键菜单Settings设置中,在tcl.pre一栏填写刚刚指定的name.tcl文件:

然后重新生成bit文件不会有任何问题。

20.jpg

这个应该算XILINX官方的bug,后来官方论坛也对此做出反应:
https://forums.xilinx.com/t5/Vivado-TCL-Community/Error-during-Bitgen-Vivado-12-1345-Error-s-found-during-DRC/td-p/333171

 

bit文件生成完毕就是下载文件到板子的DDR上面了,直接用Hardware Manager功能即可。

22.jpg

下到板子上,板子的RGBLED会有流水灯效果:

1.gif

拨动开关会有对应红灯亮灭:

2.gif

 

如果要下载到SPI FLASH上,则还会遇到第二个问题:ERROR: [Writecfgmem 68-20] SPI_BUSWIDTH property is set to "1" on bitfile

这个方法也好解决,在下方终端中输入

set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]

指令,重新生成bit文件并烧录MCS文件即可。
23.jpg

 

除此之外,VIVADO环境还有一个RTL功能可以让开发者参考,以验证代码书写,器件搭建是否有误:

24.jpg

26.jpg


最后,VIVADO2020运行过程中有可能会出现与2018版本驱动不兼容的情况,可以用VIVADO路径下data\xicom\cable_drivers\nt64\digilent的路径下的驱动:
25.jpg


回复
您需要登录后才可以回帖 登录 | 注册

最新文章 更多>>
    关闭
    站长推荐上一条 1/8 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表