对于FPGA的结构原理,先不进行全面的了解,先能根据教程程序看得懂,写得出来跑起来。慢慢的了解程序运行的原理,各种语法的使用。

  今天对流水的程序有一个认识,熟悉软件的使用,语法规则,原理。以正点原子的例程为例,代码如下

 // Created by:          正点原子

 module flow_led(
input sys_clk , //系统时钟
input sys_rst_n, //系统复位,低电平有效 output reg [:] led //4个LED灯
); //reg define
reg [:] counter; // main code
//计数器对系统时钟计数,计时0.2秒
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter <= 'd0;
else if (counter < 'd1000_0000)
counter <= counter + 'b1;
else
counter <= 'd0;
end //通过移位寄存器控制IO口的高低电平,从而改变LED的显示状态
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led <= 'b0001;
else if(counter == 'd1000_0000)
led[:] <= {led[:],led[]};
else
led <= led;
end endmodule

  这个代码的功能是点亮流水灯。代码的内容是:用一个定时器计时,到了0.2s就自动清零,否则自动+1计数。另一方面,判断是否到了0.2s,到了就换另一个led亮。程序写好后,烧写在芯片里,会形成这样的电路,功能是并行的。不像是stm32需要用C语言写代码,生成指令,cpu取指执行。FPGA会快一些。

  代码的整体结构,头和尾有 module 和 endmodule 这是模块的开始和结束。如果工程中有其他的功能代码,写在一个.v文件,也会有这个 module 。就是一个功能或者一个模块卸载一个.v 文件,这样便于管理。

  input                  sys_clk ,   可以理解为定义一个输入类型的变量。

  output   reg [3:0]     led, 可以理解为,定义一个输出类型的变量,他占据了4个bit。

  always @(posedge sys_clk or negedge sys_rst_n) begin   可理解为,复位了或者有新的始终进来就做下面的代码。

  led <= 4'b0001;    这个是赋值,和C语言有些不一样。

   4'b0001   是一个数,b:二进制表示,0001。 4' 是指这个数是4位的。

补充一下流水灯的形成  led[3:0] <= {led[2:0],led[3]};  意思是:4位循环右移。即,3位放到0位,210位放到321位。led初始化0001,用形象的描述如下:

位          3210

初始值   0001

第一次  0010

第二次  0100

第三次 1000

....................

高电平点亮。形成流水灯。

然后这个程序实现了点灯。但是有一点,他是怎么控制的引脚呢,led是接在引脚少了,这里面也没涉及到引脚啊。在下面这里:

通过这个图可以看到,我们在工程里面的变量,需要“绑定”引脚。使使之一一对应,举个例子led变量是4个bit的,把0 1 2 3 分别对应板子上led连接的引脚上,操作led就相当于操作引脚了。

  几天重新研究了一下这个流水灯的例程,觉得主要部分代码还要再仔细的分析一下,时序代码部分:

 always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter <= 'd0;
else if (counter < 'd1000_0000)
counter <= counter + 'b1;
else
counter <= 'd0;
end

  其中关键字 always 是时序逻辑电路,在这个语句的下面,赋值的话用非阻塞赋值 “ <= ” ,非阻塞可以理解为:相互不干扰、不堵塞,是并行的。而阻塞赋值是串行的,相互之间有顺序干扰的,一个一个的。

  第一行解释:如果有  sys_clk 时钟信号上升沿或者 sys_rst_n 下降沿的话,就开始执行下面的代码一直到 end 结束。

  这是一个或的关系,两个条件满足一个即可。第一条 if 判断是时钟信号上升沿还是复位重启,如果是复位重启的话,就给 counter 计数器赋初值 0 。如果不是复位那就是时钟洗好上升沿,此时,是一个脉冲过来了,执行下一个(类似单片机的下一条指令),那么就看计数器是否达到最大,没达到的话,就 继续 +1 ,达到了最大的话,就置为0。以便于重新计数。

  流水灯部分:

 always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led <= 'b0001;
else if(counter == 'd1000_0000)
led[:] <= {led[:],led[]};
else
led <= led;
end

  这段代码看着和上一段时序部分非常像。主要功能是,实现流水灯,根据上面的时序部分“定时器”,克制外部晶振50MHz,周期是 20ns。0.2s流动一次的话,计数器就要计数到 10^7 个,从0 到10^7-1,就是 24'd1000_0000。在流水灯部分,判断计数器是否为24'd1000_0000 是的话就是到了0.2s。流动一次。

总结:

1.  掌握verilog的语法:

  1.1 always 和 assign的区别

  1.2 阻塞赋值和非阻塞赋值的区别

  1.3 数据格式

  1.4 程序代码的框架

FPGA——流水灯(一)的更多相关文章

  1. FPGA 流水灯

    VerilogHDL那些事儿_建模篇(黑金FPGA开发板配套教程) 作者:akuei2 说明:参照该书将部分程序验证学习一遍 学习时间:2014年5月2号 主要收获: 1. 对FPGA有初步了解: 2 ...

  2. 第一个FPGA工程—LED流水灯

    这一章我们来实现第一个FPGA工程-LED流水灯.我们将通过流水灯例程向大家介绍一次完整的FPGA开发流程,从新建工程,代码设计,综合实现,管脚约束,下载FPGA程序.掌握本章内容,大家就算正式的开始 ...

  3. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】【实验一】流水灯模块

    实验一:流水灯模块 对于发展商而言,动土仪式无疑是最重要的任务.为此,流水灯实验作为低级建模II的动土仪式再适合不过了.废话少说,我们还是开始实验吧. 图1.1 实验一建模图. 如图1.1 所示,实验 ...

  4. NIOS ii 流水灯

    为了做项目的前期验证工作,实验室购买了某开发板,下面是基于该板子的实现过程.作为笔记记录,供入门者参考. 1:创建一个Quartus II的工程 next选择器件,然后finish.我的器件是cycl ...

  5. Xilinx Vivado的使用详细介绍(4):Zedboard+vivado之流水灯(加SDK)

    Vivado+zedboard之初学流水灯 Author:zhangxianhe 环境:vivado 2016.3(已验证适用于2015.4) 开发板:Zedboard version xc7z020 ...

  6. 【接口时序】2、Verilog实现流水灯及与C语言的对比

    一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE 硬件平台: 1.FPGA型号:XC6SLX45 ...

  7. Zedboard学习(三):PL下流水灯实验 标签: fpgazynqPL 2017-07-05 11:09 21人阅读 评论(0)

    zynq系列FPGA分为PS部分和PL部分. PL: 可编程逻辑 (Progarmmable Logic), 就是FPGA部分. PS: 处理系统 (Processing System) , 就是与F ...

  8. S5PV210_流水灯

    1.整体思路:把相应的配置数据写入相应的寄存器,控制GPIO电平(Led.s)——运用工程管理Makefile编译.链接文件(由Led.s编译得到led.bin,该文件用于USB启动方式点亮LED,若 ...

  9. (一)GPIO 编程实验 LED 流水灯控制

    7个寄存器 是R1-R16.(当然,里面有很多是分几个模式的,所以总共有37个)类似于单片机的R0-R7. GPXCON,GPXDAT等等是另外的寄存器,应该叫,特殊功能寄存器,类似于单片机的P0,P ...

随机推荐

  1. Dotnetty 的心跳

    只要你不按照实例中使用libuv,就不会有问题了. 主要区别在于 WorkerEventLoopGroup 和 MultithreadEventLoopGroup 之间.

  2. cordova原生页面切换效果插件的使用:com.telerik.plugins.nativepagetransitions

    1. 添加插件:cordova plugin add com.telerik.plugins.nativepagetransitions2. 使用方法: 在index.html中添加: <met ...

  3. Nginx failing to load CSS and JS files (MIME type error)

    Nginx failing to load CSS and JS files (MIME type error) Nginx加载静态文件失败的解决方法(MIME type错误) 上线新的页面,需要在n ...

  4. git编译安装

    因yum安装的git版本过低,所以尝试使用编译安装git 以下为编译安装时执行的命令 tar xf git-2.9.5.tar.gz cd git-2.9.5yum install curl-deve ...

  5. Asteroids 爆破彗星

    发售年份 1979 平台 街机 开发商 雅达利(Atari) 类型 射击 https://www.youtube.com/watch?v=WYSupJ5r2zo

  6. mysql的事务和数据库锁的关系

    数据库加事务并不是数据就安全来了,事务和锁要分析清楚和配合使用 问题背景处于对高并发的秒杀环节的理解整理如下: 秒杀的时候高并发主要注意1.在秒杀的情况下,肯定不能如此高频率的去读写数据库,会严重造成 ...

  7. js正則匹配经纬度(经纬度逗号隔开)

    谷歌坐標:31.2807691689,112.5382624525 高德坐標:31.2807691689,112.5382624525 regexp: {//正则验证 regexp: /^([0-9] ...

  8. redis 批量删除 keys

    #!/bin/bash redis_list=("192.168.252.174:7000" "192.168.252.174:7001" "192. ...

  9. KindEditor自动过滤首行缩进和全角空格的解决方法

    KindEditor 4.1.11:kindeditor-all.js 文件中大致第752行: /(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?: ...

  10. var entsMapLocation = {……}函数

    var entsMapLocation = { global: { $popupCityBox: $(".ents-map-location-popup-box"), isPosi ...