模六十计数器

文章目录

  • 前言
  • 一、开发环境
    • Verilog 语言
    • Xilinx ISE 13.4
    • BASYS2实验板
  • 二、设计思路
  • 三、Verilog源文件
  • 四、测试文件
  • 五、波形仿真
  • 六、创建时序约束和管脚约束
  • 七、生成.bit文件,下载到开发板
  • 总结


前言

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语句:行为方式
元件例化:结构化

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

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

(2)case语句:

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

(3)if语句:

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

(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、管脚定义:
模六十计数器_第1张图片

二、设计思路

创建一个34位二进制的计数器,截取25到28位作为个位数字,29到32位作为十位数字,个位数字满10进1,十位数字满6清零,通过扫描、取数、译码,在数码管上显示数字,从而实现模六十计数器的功能。
模六十计数器_第2张图片
计数间隔与扫描频率的确定:
计算公式:t为变化一次的时间,n为所截取的最低位数

取计数间隔1s,可得所需位数i约为26位
取i=25,可得计数间隔约为0.67s
模六十计数器_第3张图片

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

模六十计数器_第4张图片

三、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)时的整体波形
模六十计数器_第5张图片

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

模六十计数器_第6张图片

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

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

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

模六十计数器_第8张图片

#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
绝望~

你可能感兴趣的:(Verilog,verilog,fpga)