ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模六十计数器

2022-02-27 16:01:23  阅读:204  来源: 互联网

标签:reset LOC 六十 clock 计数器 num NET reg


文章目录


前言

Verilog、Xilinx ISE 13.4、BASYS2、模六十计数器

一、开发环境

Verilog 语言

1、数据类型

常量:parameter IN_width = 4;可用来定义变量宽度
变量:wire型:用assign赋值;输入输出信号默认
      reg型:在always内赋值;表示触发器输出信号
间隔符:空格,TAB
注释符:单行//,多行/*……*/
逻辑值:0,1,X,Z
关键词:module, endmodule, input, output, wire, reg, and
assign语句:数据流方式
always语句:行为方式
元件例化:结构化

2、程序语句
(1)过程块:

过程语句(@敏感表)
begin(:块名)
……
end

(2)case语句:

case(变量) 
   值1:块1
   值2:块2
   ……
   default:块3
endcase

(3)if语句:

if(条件1) 
    块1
else if(条件2)
    块2
else
    块3

(4)for语句

for(表达式1;表达式2;表达式3)
	块语句

Xilinx ISE 13.4

1、组成及功能:
项目管理工具Project Navigator
综合工具(电路原理图,技术原理图)XST
仿真工具Isim
约束编辑工具(文本编辑器,图形用户界面编辑器,时序约束编辑器)PlanAhead与Constraint Editor
实现工具Implement
下载编程工具Impact
在线逻辑分析仪Chipscope

BASYS2实验板

1、可用资源
4个七段数码管、8个LED指示灯、4个按键开关、8个滑动开关、1个PS/2接口、1个8位VGA显示接口、4个6针PMOD用户扩展接口、可配置晶振、USB 2.0接口。
2、管脚定义:

二、设计思路

创建一个34位二进制的计数器,截取25到28位作为个位数字,29到32位作为十位数字,个位数字满10进1,十位数字满6清零,通过扫描、取数、译码,在数码管上显示数字,从而实现模六十计数器的功能。

计数间隔与扫描频率的确定:
计算公式:t为变化一次的时间,n为所截取的最低位数

取计数间隔1s,可得所需位数i约为26位
取i=25,可得计数间隔约为0.67s

取扫描频率100Hz可得所需位数j约为19位

三、Verilog源文件

module mo60(
    input clock,
    input reset,
    output [3:0] loc,//数码管位置
    output [7:0] num//数码管引脚
    );
	
	parameter i = 25;//控制计数速率,仿真时取0;下载时取25(每0.7s计数一次)
	parameter j = 19;//控制扫描速率,仿真时取0;下载时取19(扫描频率100Hz)
	reg [33:0] counter = 0;//计数
	reg [33:0] counter0 = 0;//reset时计数,用于控制扫描速率
	reg [3:0] scan;//位置
	reg [4:0] temp;//数字
	reg [7:0] pin;//引脚
	reg [3:0] q1 = 0;//十位
	reg [3:0] q0 = 0;//个位
	
	//计数器
	always @(posedge clock)//上升沿触发
	begin
		//计数
		if (reset)//高电平有效
			begin
				counter <= 0;
				counter0 <= counter0+1;
			end
		else
			begin
				counter0 <= 0;
				counter <= counter+1;
			end
		//进位
		if (counter[3+i:0+i] >= 10)
			begin
				counter[7+i:4+i] <= counter[7+i:4+i]+1;
				counter[3+i:0+i] <= 0;
			end
		if (counter[7+i:0+i] >= 8'b01100000)//60
			counter[7+i:0+i] <= 0;
		q1 = counter[7+i:4+i];
		q0 = counter[3+i:0+i];
	end

	//扫描@取数
	always @(counter[j] or counter0[j])
	begin
		if (reset)
			begin
				temp <= 0;
				if (counter0[j])
					scan <= 4'b1101;
				else
					scan <= 4'b1110;
			end
		else
			if (counter[j])
				begin
					scan <= 4'b1101;
					temp <= q1;
				end
			else
				begin	
					scan <= 4'b1110;
					temp <= q0;
				end
	end	
	
	//显示
	always @(temp)
	begin
			case(temp)
				0: pin = 8'b00000011;//最后一位表示小数点
				1: pin = 8'b10011111;
				2: pin = 8'b00100101;
				3: pin = 8'b00001101;
				4: pin = 8'b10011001;
				5: pin = 8'b01001001;
				6: pin = 8'b01000001;
				7: pin = 8'b00011111;
				8: pin = 8'b00000001;
				9: pin = 8'b00001001;
				default: pin = 8'b01100001;//其他状态显示E
			endcase
	end
	
	assign loc = scan;
	assign num = pin;
	
endmodule

四、测试文件

module test1;
	//Inputs
	reg clock;
	reg reset;
	//Outputs
   wire [3:0] loc;
   wire [7:0] num;
	//时钟周期20ns
	parameter PERIOD = 20;
	//实例化
	mo60 uut (
		.clock(clock), 
		.reset(reset), 
		.loc(loc),
		.num(num)
	);
	//时钟信号
	always begin
		clock = 1'b0;
		#(PERIOD/2) clock = 1'b1;
		#(PERIOD/2);
	end
	//初始状态
	initial begin
		clock = 1'b0;
		reset = 1;
		//复位信号持续500ns
		#500;
      	reset = 0; 
	end
endmodule

五、波形仿真

1、i=0(计数间隔为1个cp),j=0(扫描间隔为1个cp)时的整体波形

clock:时钟,reset:清零,q1:计数器十位上显示的数字,q2:计数器个位上显示的数字,loc:4个数码管上的电平,num:数码管8个引脚上的电平。
2、i=0(计数间隔为1个cp),j=0(扫描间隔为1个cp)时的局部波形

以黄线时刻的波形为例,解释各变量的含义。q1=5,q0=8,表示数码管上显示的数字为58,loc=1101,表示十位上的数码管被点亮,num=01001001,表示除小数点外的各段均被点亮,即显示数字5。
由于非阻塞赋值,在进位处产生了长度为1个脉冲周期错误的状态(红色箭头所示)。
3、i=5(计数间隔为0.6us),j=3(扫描频率为6MHz)时的局部波形

当i增大到5时,正常状态所持续的时间远大于1个脉冲周期,错误状态的影响可以忽略不计。
由此可推知,当i=25(计数间隔为0.7s),j=19(扫描频率为100Hz)时,进位时产生的错误状态可以忽略不计,不影响计数器的功能。

六、创建时序约束和管脚约束

#Created by Constraints Editor (xc3s100e-cp132-4) - 2021/11/17
NET "clock" TNM_NET = "clock";
TIMESPEC TS_clock = PERIOD "clock" 20 ns HIGH 50 %;
# PlanAhead Generated physical constraints 
NET "clock" LOC = B8;
NET "reset" LOC = P11;
NET "loc[3]" LOC = K14;
NET "loc[2]" LOC = M13;
NET "loc[1]" LOC = J12;
NET "loc[0]" LOC = F12;
NET "num[7]" LOC = L14;
NET "num[6]" LOC = H12;
NET "num[5]" LOC = N14;
NET "num[4]" LOC = N11;
NET "num[3]" LOC = P12;
NET "num[2]" LOC = L13;
NET "num[1]" LOC = M12;
NET "num[0]" LOC = N13;

七、生成.bit文件,下载到开发板

总结

没学过Verilog
绝望~

标签:reset,LOC,六十,clock,计数器,num,NET,reg
来源: https://blog.csdn.net/qq_53715621/article/details/123164595

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有