当前位置:   article > 正文

模六十计数器_模为60减法计数器

模为60减法计数器


前言

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

一、开发环境

Verilog 语言

1、数据类型

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

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

过程语句(@敏感表)
begin(:块名)
……
end
  • 1
  • 2
  • 3
  • 4

(2)case语句:

case(变量)1:块12:块2
   ……
   default:块3
endcase
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(3)if语句:

if(条件1)1
else if(条件2)
    块2
else3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(4)for语句

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

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

四、测试文件

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

五、波形仿真

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;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

总结

没学过Verilog
绝望~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/776748
推荐阅读
相关标签
  

闽ICP备14008679号