首页 > 分享 > 从零开始学习vivado——day 3 时序逻辑设计之计数器

从零开始学习vivado——day 3 时序逻辑设计之计数器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录 前言一、一、vivado是什么?二、计数器的设计1.创建新的工程文件并编译代码2.创建激励文件3.仿真结果展示 总结

前言

研一从零开始学习verilog!!!此时不学何时学!
第一次写博客,以此激励自己努力学习!
我跟的视频教程是b站的一个up主,小梅哥爱漂流。

一、一、vivado是什么?

vivado是一个编译平台,可运行verilog代码,并且进行模拟仿真。

二、计数器的设计

1.创建新的工程文件并编译代码

(1)定义端口

module led_flash( Clk, Reset_n, Led ); input Clk;//时钟 input Reset_n;//复位端 output reg Led;//灯 reg [24:0]counter;//计数变量 12345678910

(2)计数与Led的变化

always@(posedge Clk or negedge Reset_n)//posedge Clk代表时钟的上升沿,negedge Reset_n代表复位端下降沿 if(!Reset_n) //!代表取非,即如果Reset_n为低电平,则counter归零 counter <=0;//<=为非阻塞赋值,此处可以理解为等于 else if(counter == 25000000-1)//要计数25000000次,则需要减1,因为清零也算一次 counter <=0 ;//清零,计数从头开始 else counter <= counter + 1'd1 ; always@(posedge Clk or negedge Reset_n)//posedge Clk代表时钟的上升沿,negedge Reset_n代表复位端下降沿 if(!Reset_n) //!代表取非,Reset_n为低电平时,Led也为低电平 Led <=0; else if(counter == 25000000-1) Led <= !Led; 12345678910111213

首先,解读一下代码。
其实注释的都很清楚了,计数器是利用D触发器进行设计的,即在时钟上升沿的时候触发,or negedge Reset_n这段代码其实不加也可以,因为代码里面并没有让Reset_n变为高电平之后再变为低电平。对于counter变量,需要用到if ,else if,else,因为它有三种情况,复位端为低电平时肯定是清零的,因为计数器没有工作,还有当计数器计满的时候也要清零,否则counter会加1.
而Led可以直接利用取反符号达到亮灯和灭灯的目的,因为要设计在1s内,有500ms是亮灯状态,500ms是熄灯状态,即从Led亮的一瞬间开始计时,到下一次灯亮的时间,应该刚好是1s。
时钟的周期为20ns,所以500ms/20ns=25000000次,也就是说counter需要计数25000000之后,Led灯的状态才会翻转。而25000000换算成二进制,有25位,所以定义的时候需要加个[24:0]。
再一点,计数的时候,当counter达到25000000-1的时候,就需要清零和翻转了,因为从25000000-1到0也算一次运行过程,即总共也是计数了25000000次。
因为Led和counter的变化条件都一样,嫌麻烦的话可以利用begin end语句将Led和counter的变化括起来即可。

(3)代码整合

module led_flash( Clk, Reset_n, Led ); input Clk; input Reset_n; output reg Led; reg [24:0]counter; always@(posedge Clk or negedge Reset_n)//posedge Clk代表时钟的上升沿,negedge Reset_n代表复位端下降沿 if(!Reset_n) //!代表取非,即如果Reset_n为低电平,则counter归零 counter <=0;//<=为非阻塞赋值,此处可以理解为等于 else if(counter == 25000000-1)//要计数25000000次,则需要减1,因为清零也算一次 counter <=0 ;//清零,计数从头开始 else counter <= counter + 1'd1 ; always@(posedge Clk or negedge Reset_n)//posedge Clk代表时钟的上升沿,negedge Reset_n代表复位端下降沿 if(!Reset_n) //!代表取非,Reset_n为低电平时,Led也为低电平 Led <=0; else if(counter == 25000000-1) Led <= !Led; //led和counter两个变量分开进行会好一点,如果要合在一起写的话,需要用begin end括起来 // endmodule

1234567891011121314151617181920212223242526

2.创建激励文件

(1)时间尺度

`timescale 1ns/1ns 12

依旧默认1ns
(2)例化

module led_flash_tb; reg Clk; reg Reset_n; wire Led;//输出为wire型 led_flash led_flash( .Clk(Clk), .Reset_n(Reset_n), .Led(Led) ); 1234567891011

(3)时钟信号编写

initial Clk =1; always#10 Clk=!Clk;//!是逻辑取反,`是按位取反,对于单信号来说是等价的 整句话就是延时10ns之后,Clk总是取反 12

10ns让时钟翻转一次即可,因为要设计的计数器是1s的间隔,所以也可以把是时钟的周期延长一点,这个都可以自己修改。
(4)复位端信号编写

initial begin Reset_n=0;//初始复位端为低电平 #101;//避开时钟上升沿 Reset_n=1;//101ns之后复位端变高电平 #1000000000; $stop;//1s之后停止 end 1234567

复位端初始为低电平,Led处于清零状态,错开时钟上升沿之后,将复位端变为高电平,为防止一直运行下去,可以使用stop停止。
(4)代码整合

`timescale 1ns/1ns module led_flash_tb; reg Clk; reg Reset_n; wire Led;//输出为wire型 led_flash led_flash( .Clk(Clk), .Reset_n(Reset_n), .Led(Led) ); initial Clk =1; always#10 Clk=!Clk;//!是逻辑取反,`是按位取反,对于单信号来说是等价的 整句话就是延时10ns之后,Clk总是取反 initial begin Reset_n=0;//初始复位端为低电平 #101;//避开时钟上升沿 Reset_n=1;//101ns之后复位端变高电平 #1000000000; $stop;//1s之后停止 end endmodule

123456789101112131415161718192021222324252627

3.仿真结果展示

在这里插入图片描述

可以看出,Led第一次翻转到第二次翻转的间隔为500ms,成功完成设计。

总结

今天学习的是基于D触发器设计的计数器。
新学的语法有:

①上升沿,下降沿

always@(posedge Clk or negedge Reset_n) 1

poseedge是沿上升沿触发,negedge是沿下降沿触发;
②时钟信号的产生

initial Clk =1; always#10 Clk=!Clk; 12

③if else内嵌一个if else

if(!Reset_n) counter <=0; else if(counter == 25000000-1) counter <=0 ; else counter <= counter + 1'd1 ; 123456

④<=为非阻塞赋值,目前还没搞清楚啥意思,后面再说。。。

相关知识

vivado(zynq)使用ILA分析的常见问题,并将ILA数据导入matlab分析
Valentine's Day《情人节》精讲之六
从零开始学养花音频,养花技巧视频大全
Day
从零开始学养花攻略,养花教程
东北地区植被物候时序变化
从零开始学习花草种植:技术、注意事项和常见问题解答
HAPPY VALENTINE'S DAY!
从零开始学种花
用功能指令改变计数器C0的设定值,当X1、X0=00时设定值为10,当X1、X0

网址: 从零开始学习vivado——day 3 时序逻辑设计之计数器 https://m.huajiangbk.com/newsview893374.html

所属分类:花卉
上一篇: Vmware中虚拟化Intel
下一篇: 集成计数器