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

一、 软件平台与硬件平台

  软件平台:

  1、操作系统:Windows-8.1

  2、开发套件:ISE14.7

  3、仿真工具:ModelSim-10.4-SE

  硬件平台:

  1、FPGA型号:XC6SLX45-2CSG324

二、 原理介绍

  我的开发板上有4个LED灯,原理图如下:

  

  

  由原理图可知仅当FPGA的对应管脚输入低电平时LED才会亮,流水灯的效果可以轮流让四个对应管脚输出低电平来产生。

三、 目标任务

  编写四个LED流水的Verilog代码并用ModelSim进行仿真,仿真通过以后下载到开发板进行测试,要求开发板上每个LED亮的时间为1s。

四、 设计思路与Verilog代码编写

  由于每个LED亮的时间为1s,所以首先很自然想到产生一个1s的时钟用来驱动后续逻辑,有了这个1s的时钟以后,就可以在这个1s时钟的节拍下对LED的输出进行以移位操作来产生流水灯的效果。

   1、1s时钟的分频逻辑

   由于主时钟是50MHz,周期为20ns,所以可以利用50MHz主时钟驱动一个计数器,当计数器的值每次到达24999999时,消耗的时间为25000000*20ns=0.5s,这时把分频器的输出反转,并把计数值清0,这样分频器的输出就会每隔0.5s翻转一次,产生了一个1s的时钟。

  Verilog代码如下:

//
// 功能:产生1s的时钟
//
always @(posedge I_clk or negedge I_rst_n)
beginif(!I_rst_n)beginR_cnt_ls        <= 32'd0 ; R_clk_ls_reg    <= 1'b1  ;end else if(R_cnt_ls == 32'd24_999_999)beginR_cnt_ls        <= 32'd0          ;R_clk_ls_reg    <= ~R_clk_ls_reg  ;  endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;          
endassign W_clk_ls = R_clk_ls_reg ;

 

  2、移位逻辑

  有了1s的时钟信号以后,就在这个1s时钟信号的驱动下对输出的LED寄存器进行移位操作产生流水效果。

  Verilog代码如下:

//
// 功能:对输出寄存器进行移位产生流水效果
//
always @(posedge W_clk_ls or negedge I_rst_n)
beginif(!I_rst_n) R_led_out_reg <= 4'b0001 ; else if(R_led_out_reg == 4'b1000)R_led_out_reg <= 4'b0001 ;else    R_led_out_reg <= R_led_out_reg << 1 ;             
endassign O_led_out = ~R_led_out_reg ;

五、 ModelSim仿真

  写好逻辑以后,为了确定时序是正确的,最好写一个测试文件对功能进行仿真,为了加快仿真速度,修改分频逻辑计数器的计数值为24,然后编写测试文件,测试文件中激励产生的Verilog代码如下:

initial begin// Initialize InputsI_clk = 0;I_rst_n = 0;// Wait 100 ns for global reset to finish#100;I_rst_n = 1;// Add stimulus hereendalways #10 I_clk = ~I_clk ;

 

  仿真的时序图如下图所示:

 

可以看到时序完全正确,接下来就是绑定管脚,生成bit文件下载到开发板测试了。

六、 进一步思考——C语言流水灯与Verilog流水灯区别

  看完网上《Verilog那些事》系列博文以后,作者提出了一种“仿顺序操作”方法,其实以前自己写代码的时候无形之中一直在用这种思想,但是一直没有提炼出来,看完作者的介绍以后才发现确实是有那个“仿顺序”的味道。详细的博文请参考博客园博主akuei2的系列博文。这里我在总结一遍,给以后留个印象。

  C语言实现流水灯的大致代码框架如下:

    while(1)

    {

      1、让第1个LED亮,其他的灭;

      2、延时1s

      3、让第2个LED亮,其他的灭

      4、延时1s

      5、让第3个LED亮,其他的灭;

      6、延时1s

      7、让第4个LED亮,其他的灭

      8、延时1s

      }

  在while(1)里面代码是一行一行的执行,最后一行执行完毕以后在回到第一行重新开始新一轮的执行。就这样产生了流水的效果。

  看到这里,有人应该突然明白了吧,这不正好就是Verilog中的一个状态机么。对应的Verilog代码也可以写出来了 

  always @(posedge I_clk)

  begin

         case(R_state)

                第1个状态:让第1个LED亮,其他的灭,下一状态是第2个状态;

                第2个状态:延时1s,下一状态是第3个状态;

                第3个状态:让第2个LED亮,其他的灭,下一状态是第4个状态;

                第4个状态:延时1s,下一状态是第5个状态;

                第5个状态:让第3个LED亮,其他的灭,下一状态是第6个状态;

                第6个状态:延时1s,下一状态是第7个状态;

                第7个状态:让第4个LED亮,其他的灭,下一状态是第8个状态;

                第8个状态:延时1s,下一状态是第1个状态;

                default          : ;

         endcase

  end

  具体的代码如下:

//
// 功能:“仿顺序操作”
//
always @(posedge I_clk or negedge I_rst_n)
beginif(!I_rst_n)beginR_state  <= 3'b000 ; R_cnt_ls <= 32'd0  ;endelsebegin    case(R_state)C_S0:beginR_led_out_reg <= 4'b0001 ;R_state       <= C_S1    ;  endC_S1:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S2  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S2:beginR_led_out_reg <= 4'b0010 ;R_state       <= C_S3    ;  endC_S3:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S4  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S4:beginR_led_out_reg <= 4'b0100 ;R_state       <= C_S5    ;  endC_S5:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S6  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S6:beginR_led_out_reg <= 4'b1000 ;R_state <= C_S7 ;  endC_S7:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S0  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                end default: R_state <= 3'b000 ;                                                                               endcase end                  
endassign O_led_out = ~R_led_out_reg ;

  时序图如下图:

  时序图仍然正确,实现了流水灯的效果

七、 总结

  1、所谓的“仿顺序操作”实际上就是一个状态机,通过状态的跳变实现“顺序执行”的效果。这种思想在后面写接口时序的时候还是挺管用的,今后可以多多琢磨琢磨。

  2、 C语言的while(1)和Verilog语言的always @(posedge I_clk)有类似的地方,只要CPU的时钟存在,它们就一直执行下去。书上都说C语言是一种串行语言,Verilog是一种并行语言,实际上这里也能有体会:C语言里只能有1个while(1)语句,进入while(1)以后CPU就出不来了,而Verilog中可以有多个always @(posedge I_clk)语句,并且每个always @(posedge I_clk)同时运行的,这就是两种语言最大的区别吧。

 

八、 附录

  1、分频1s产生流水灯的完整代码

module led_work_top
(input           I_clk       ,input           I_rst_n     ,output  [3:0]   O_led_out
);reg  [31:0]  R_cnt_ls      ;
wire         W_clk_ls      ;
reg          R_clk_ls_reg  ;
reg  [3:0]   R_led_out_reg ;//
// 功能:产生1s的时钟
//
always @(posedge I_clk or negedge I_rst_n)
beginif(!I_rst_n)beginR_cnt_ls        <= 32'd0 ; R_clk_ls_reg    <= 1'b1  ;end else if(R_cnt_ls == 32'd24_999_999)beginR_cnt_ls        <= 32'd0          ;R_clk_ls_reg    <= ~R_clk_ls_reg  ;  endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;          
endassign W_clk_ls = R_clk_ls_reg ;//
// 功能:对输出寄存器进行移位产生流水效果
//
always @(posedge W_clk_ls or negedge I_rst_n)
beginif(!I_rst_n) R_led_out_reg <= 4'b0001 ; else if(R_led_out_reg == 4'b1000)R_led_out_reg <= 4'b0001 ;else    R_led_out_reg <= R_led_out_reg << 1 ;             
endassign O_led_out = ~R_led_out_reg ;endmodule

 

  2、 “仿顺序操作”产生流水灯完整代码

module led_work_top
(input           I_clk         ,input           I_rst_n       ,output  [3:0]   O_led_out     
);                                reg  [31:0]  R_cnt_ls             ;
reg  [3:0]   R_led_out_reg        ;
reg  [2:0]   R_state              ;parameter    C_CNT_1S =   32'd49_999_999  ;          parameter    C_S0     =   3'b000  ,C_S1     =   3'b001  ,C_S2     =   3'b010  ,C_S3     =   3'b011  ,C_S4     =   3'b100  ,C_S5     =   3'b101  ,C_S6     =   3'b110  ,C_S7     =   3'b111  ;//
// 功能:仿顺序操作
//
always @(posedge I_clk or negedge I_rst_n)
beginif(!I_rst_n)beginR_state  <= 3'b000 ; R_cnt_ls <= 32'd0  ;endelsebegin    case(R_state)C_S0:beginR_led_out_reg <= 4'b0001 ;R_state       <= C_S1    ;  endC_S1:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S2  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S2:beginR_led_out_reg <= 4'b0010 ;R_state       <= C_S3    ;  endC_S3:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S4  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S4:beginR_led_out_reg <= 4'b0100 ;R_state       <= C_S5    ;  endC_S5:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S6  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S6:beginR_led_out_reg <= 4'b1000 ;R_state <= C_S7 ;  endC_S7:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S0  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                end default: R_state <= 3'b000 ;                                                                               endcase end                  
endassign O_led_out = ~R_led_out_reg ;endmodule

  3、测试记录文件完整代码

module tb_led_work_top;// Inputsreg I_clk;reg I_rst_n;// Outputswire [3:0] O_led_out;// Instantiate the Unit Under Test (UUT)
    led_work_top U_led_work_top (.I_clk(I_clk), .I_rst_n(I_rst_n), .O_led_out(O_led_out));initial begin// Initialize InputsI_clk = 0;I_rst_n = 0;// Wait 100 ns for global reset to finish#100;I_rst_n = 1;// Add stimulus hereendalways #5 I_clk = ~I_clk ;endmodule

 

欢迎关注我的公众号:FPGA之禅

转载于:https://www.cnblogs.com/liujinggang/p/9463589.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows下安装mysql服务

1.下载 首先上MySql的官网下载 https://dev.mysql.com/downloads/mysql/ &#xff0c;本人下载的是 mysql-5.7.24-winx64.zip版。 2.解压存放目录 下载完解压到你想要存放的位置 我的是解压到D:\Program Files\MySQL 。 3.配置环境变量 在环境变量path中追加一句&#xff1a;;D…

web.xml 配置文件 超详细说明!!!

一、web.xml是什么&#xff1f; 首先 web.xml 是java web 项目的一个重要的配置文件&#xff0c;但是web.xml文件并不是Java web工程必须的。 web.xml文件是用来配置&#xff1a;欢迎页、servlet、filter等的。当你的web工程没用到这些时&#xff0c;你可以不用web.xml文件来配…

window上安装mysql服务核心版(亲测可用)

上次安装服务启动后&#xff0c;这次又准备重新安装&#xff0c;出现了了很多问题 1首先我们还是去官网下载对应的window安装包 2放置在D:\Program Files\mysql下面&#xff0c;没有则新建一个Program Files 3在同路径下E:\Program Files\mysql建立一个my.ini文件 [mysql] 设置…

windows安装apache

1打开apache官网http://httpd.apache.org/ 下载win版本 2解压放入D盘D:\Apache24 3修改http.conf,安装路径 端口改成8080&#xff0c;避免占用&#xff0c;原先是80 4http -t检查配置文件合法 5httpd -k install -n apache安装主服务 6net start apache

公司网络故障那些事(路由器变交换机)

首先这次网络故障是断电引起的 我给大家画个模型 三层的为八口交换机 一层的为五口打印机 笔记本代表两台无线打印机 首先八口的连接了公司采购电脑一台&#xff0c;业务电脑一台&#xff0c;其他电脑三台 第二个五口交换的连接财务电脑两台 最后一个五口交换机连接两台无线打印…

java 文件上传 配置_SpringMVCMultipartFilefile文件上传及参数接收

一、form表单属性中加上enctype"multipart/form-data"form表单的二、配置文件中配置MultipartResolver文件超出限制会在进入controller前抛出异常&#xff0c;在允许范围内这个配置无影响三、MultipartFile接受文件并通过IO二进制流(MultipartFile.getInputStream())…

list foreach方法_Java集合三兄弟List,Set,Map你分的清楚吗?

前言集合作为Java基础知识的核心部分&#xff0c;不论是在面试还是平时工作中都是经常遇见的。当然面对熟悉的List、Set、Map&#xff0c;面试管的提问一般也都不会从简单的问题出发了&#xff0c;今天就来聊下集合中的高级部分&#xff0c;让你对它们的理解更加清楚。一、List…

SpringBoot使用Jsp

本文是简单总结一下SpringBoot使用Jsp的Demo。 前言 在早期做项目的时候&#xff0c;JSP是我们经常使用的java服务器页面&#xff0c;其实就是一个简化servlet的设计&#xff0c;在本文开始之前&#xff0c;回顾一下jsp的几大对象&#xff0c;如图。 而在现在SpringBoot框架流行…

cacti 监控安装失败

1首先这是基于lnmp模式进行的 2yum安装 yum -y install httpd mysql mysql-server php php-mysql php-json php-pdo 3lib库 yum -y install cairo-devel libxml2-devel pango pango-devel 4 解压rrdtool-1.3.1.tar.gz Cd rrdtool-1.3.1 ./configure --prefix/usr/local/rrdtoo…

project 模板_施工进度横道图不会做?18份计划模板收藏好,输入参数迅速成图...

施工进度横道图不会做&#xff1f;18份计划模板收藏好&#xff0c;输入参数迅速成图作为施工组织设计的关键内容&#xff0c;施工进度计划控制了工程施工进度、工程施工期限等各项施工活动。进度计划是否合理&#xff0c;直接影响施工速度、成本和质量。因此施工中的其他工作必…

JavaScript学习系列3 -- JavaScript arguments对象学习

在实际项目开发中&#xff0c;目前还是很少使用到JavaScript 中的arguments对象&#xff0c;那么它到底是干什么用的呢 arguments是JavaScript中的一个类数组对象&#xff0c;它代表传给一个正在执行的函数function的参数列表。 看完这个定义&#xff0c;需要明白&#xff0c…

面向对象的四大特征

面向对象的四大特征 面向对象的程序设计方法要求语言必须具备抽象、封装、继承和多态性这几个关键要素。 面向对象程序设计&#xff0c;是通过为数据和代码建立分块的内存区域&#xff0c;以便提供对程序进行模块化的一种程序设计方法。对象是计算机内存中的一块区域&#xff0…

centos7 安装cacti

1 cacti运行环境准备   cacti需要phpapachemysqlsnmpRRDTool&#xff0c;以及cacti本身。cacti本体是用php开发的网站&#xff0c;通过snmp对远端设备信息进行采集。apachemysqlphp在以前已经做过了      这里只对剩余的部分进行安装。 2 安装snmp    yum install -y n…

linux下zabbix安装

1本人用的是apachemysqlphp 2下载zabbix软件包&#xff0c;官网下载 https://sourceforge.net/projects/zabbix/files/ZABBIX Latest Stable/2.2.23/zabbix-2.2.23.tar.gz/download 上传到 var/www/html下 3cd /var/www/html #进入软件包下载目录 tar zxvf zabbix-2.2.23.tar.g…

定时器取数据时实时进来的数据_Redis-数据淘汰策略amp;持久化方式(RDB/AOF)amp;Redis与Memcached区别...

Redis与Memcached区别&#xff1a; 两者都是非关系型数据库。主要有以下不同&#xff1a; 数据类型&#xff1a; Memcached仅支持字符串类型。 redis支持&#xff1a;String,List,set,zset,hash 可以灵活的解决问题。 数据持久化&#xff1a; Memcached不支持持久化。 Redis采…

linux 下建立多个tomcat

第一步&#xff1a;复制&#xff0c;解压 将准备好的tomcat压缩包复制到你准备安装的目录&#xff0c;我的tomcat压缩包名字是tomcat.tar.gz,我的安 装目录是 /usr/java/tomcat 第二步&#xff1a;解压tomcat [rootaliServer tomcat]# tar -xvf tomcat.tar.gz 第三步&#xff…

linux iptables配置

1 iptables默认系统自带 setup 2重启防火墙 /etc/init.d/iptables restart 3接受端口 Vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT 4 #配置&#xff0c;禁止进&#xff0c;允许出&#xff0c;允许回环网卡 iptables -P I…

memcpy函数_[PART][BUG][MSVCRT][C][CCF NOI1097] 关于memcpy的坑

[Incompleted]CCF NOI1097 试题&#xff0c;本人的源码&#xff1a;Ubuntu Pastebin​paste.ubuntu.comUbuntu PastebinUbuntu Pastebin: SourceCodebyJulianDroid​paste.ubuntu.com满分代码&#xff1a;https://blog.csdn.net/tigerisland45/article/details/71038551​blog.…

Bugku杂项-convert

一进去就发现一堆二进制数&#xff0c;然后考虑怎么才能把这个和隐写扯上关系。首先&#xff0c;二进制我们肉眼就是看不懂再说什么的&#xff0c;这里就想到了转换&#xff0c;再联想上hex将原始数据转化为16进制。我们可以先把2进制转化为16进制&#xff0c;然后再放到hex上看…

图解cacti简单使用

1登录 admin admin 2点击devices localhost 3进入配置保存 4保存 http服务要启动哦 5一步步做 6graph tree 7执行/usr/bin/php /var/www/html/cacti/poller.php 8如果时间设置错误去php.ini里面修改时间 YSTEM STATS: Time:0.4759 Method:cmd.php Processes:1 Threads:N/…