基于FPGA的数字跑表
更新时间:2023-10-08 07:31:01 阅读量: 综合文库 文档下载
现代电子实验
数字跑表实验报告
一.功能要求 基本功能: 1)、跑表精度为0.01秒 2)、跑表计时范围为:1小时 3)、设置开始计时/停止计时、复位两个按钮 4)、显示工作方式:用六位BCD七段数码管显示读数。显示格式:
分 秒 0.01秒
扩展功能: 1)、按键消抖; 2)、分别存储三组选手时间并分时回放显示;
一.设计要求
1)设计出符合要求的解决方案 2)设计出单元电路
3)利用EDA软件对单元电路及整体电路进行仿真 4)利用EDA软件在实验板上验证
总体设计框图
时钟输入
按键输入
计数器 除法器 按键消抖 功能控制模块 译码模块 数码管扫描模块 数码管 设计说明:
对于按键输入,先对按键进行消抖,然后按键输入信息给功能控制模块,此模块是核心控制中心,它能控制计数模块计数的开始,停止。同时,当相应按键按下时,它还可以对计数结果进行存储和读取,其中用到了一个F I F O。由于计数时候个位和十位并没有分开,所以之后我们采用了一个除法器,把个位和十位分离。之后的数据经过译码以后就可以由数码管显示了。
单元电路划分
1.按键输入模块 (1)按键检测模块 (2)按键消抖模块 2.计数器模块 3.功能控制模块 4.数码管显示译码模块
(1)除法器(实现计数结果十位,个位的分离) (2)译码模块 5.数码管扫描显示模块
各单元电路设计
1.按键输入模块
功能说明:检测按键的输入,并对按键进行消抖,由两个小的模块组成 源码:
module debounce (
CLK, RST, Pin_In, Pin_Out ); input CLK; input RST; input Pin_In; output Pin_Out; /**************************/ wire H2L_Sig; wire L2H_Sig;
detect U1 ( .CLK( CLK ), .RST( RST ), .Pin_In( Pin_In ), // input - from top .H2L_Sig( H2L_Sig ), // output - to U2 .L2H_Sig( L2H_Sig ) // output - to U2 ); /**************************/ delay U2 ( .CLK( CLK ), .RST( RST ), .H2L_Sig( H2L_Sig ), // input - from U1 .L2H_Sig( L2H_Sig ), // input - from U1 .Pin_Out( Pin_Out ) // output - to top ); /*******************************/
endmodule
1)按键检测 功能说明:
本模块实现对按键的检测,当按键被按下时,产生相应的信号 源代码: module detect (
CLK, RST, Pin_In, H2L_Sig, L2H_Sig );
input CLK; input RST; input Pin_In; output H2L_Sig; output L2H_Sig; /**********************************/
parameter T100US = 11'd4_799; /**********************************/ reg [10:0]Count1; reg isEn; always @ ( posedge CLK or negedge RST ) if( !RST ) begin Count1 <= 11'd0; isEn <= 1'b0; end else if( Count1 == T100US ) isEn <= 1'b1; else Count1 <= Count1 + 1'b1;
/********************************************/ reg H2L_F1; reg H2L_F2; reg L2H_F1; reg L2H_F2; always @ ( posedge CLK or negedge RST ) if( !RST ) begin H2L_F1 <= 1'b1; H2L_F2 <= 1'b1; L2H_F1 <= 1'b0; L2H_F2 <= 1'b0; end else begin H2L_F1 <= Pin_In; H2L_F2 <= H2L_F1; L2H_F1 <= Pin_In; L2H_F2 <= L2H_F1; end
/***********************************/
assign H2L_Sig = isEn ? ( H2L_F2 & !H2L_F1 ) : 1'b0; assign L2H_Sig = isEn ? ( !L2H_F2 & L2H_F1 ) : 1'b0; /***********************************/
Endmodule
Testbench Detect.v
`timescale 1 ps/ 1 ps module detect_tb(); reg CLK; reg Pin_In; reg RST;
// wires wire H2L_Sig; wire L2H_Sig;
detect i1 ( .CLK(CLK), .H2L_Sig(H2L_Sig), .L2H_Sig(L2H_Sig), .Pin_In(Pin_In), .RST(RST) );
initial begin CLK=0; RST=0; Pin_In=0; #10 RST=1; #100 Pin_In=1;
end
always begin #1
CLK=~CLK;
end Endmodule
仿真截图:
结果说明:
当电平由0到1跳变时,L2H_Sig做出了正确的反应,此模块功能正确。
2)按键消抖模块
功能说明:
由于机械振动,当按键按下时,如果直接控制功能模块,我们可能会得到错误的信息,因此,我们有必要对按键进行消抖,本模块采用延时的方法,对按键进行消抖。 源代码: module delay (
CLK, RST, H2L_Sig, L2H_Sig, Pin_Out );
input CLK; input RST; input H2L_Sig; input L2H_Sig; output Pin_Out; /****************************************/ parameter T1MS = 16'd47_999; /***************************************/ reg [15:0]Count1; reg isCount; always @ ( posedge CLK or negedge RST ) if( !RST ) Count1 <= 16'd0;
else if( isCount && Count1 == T1MS ) Count1 <= 16'd0; else if( isCount ) Count1 <= Count1 + 1'b1; else if( !isCount ) Count1 <= 16'd0;
/****************************************/
reg [3:0]Count_MS; always @ ( posedge CLK or negedge RST ) if( !RST ) Count_MS <= 4'd0; else if( isCount && Count1 == T1MS ) Count_MS <= Count_MS + 1'b1; else if( !isCount ) Count_MS <= 4'd0; /******************************************/ reg rPin_Out; reg [1:0]i; always @ ( posedge CLK or negedge RST ) if( !RST ) begin isCount <= 1'b0; rPin_Out <= 1'b0; i <= 2'd0; end else case ( i ) 2'd0 : if( H2L_Sig ) i <= 2'd1; else if( L2H_Sig ) i <= 2'd2; 2'd1 : if( Count_MS == 4'd10 ) begin isCount <= 1'b0; rPin_Out <= 1'b1; i <= 2'd0; end else isCount <= 1'b1;
2'd2 : if( Count_MS == 4'd10 ) begin isCount <= 1'b0; rPin_Out <= 1'b0; i <= 2'd0; end else isCount <= 1'b1; endcase
/********************************************/ assign Pin_Out = rPin_Out; /********************************************/
Endmodule
Testbech
`timescale 1 ps/ 1 ps module delay_tb(); reg CLK; reg H2L_Sig; reg L2H_Sig; reg RST;
// wires wire Pin_Out;
delay i1 ( .CLK(CLK), .H2L_Sig(H2L_Sig), .L2H_Sig(L2H_Sig), .Pin_Out(Pin_Out), .RST(RST) );
initial begin CLK=0; RST=0; H2L_Sig=0; H2L_Sig=0; #10 RST=1; #100
H2L_Sig=1; #10
H2L_Sig=0;
#50
H2L_Sig=1; #100
H2L_Sig=0;
end
always begin #1
CLK=~CLK;
end Endmodule
仿真截图
功能说明:
对于短暂的抖动,Pin_Out并无变化,只有当按键按下时间大于一定时间是,Pin_Out才会发生变化。此模块功能正确。
2.计数器模块
功能说明:
由于本实验是为了实现数字跑表,毫无疑问,计数器就成了本实验的关键,本模块主要完成技术功能,实现毫秒,秒,分的计数 源代码:
module count(CLK, RST, Ten_MS, Minute,
isCount, Second);
input CLK; input RST; input isCount;
output [7:0]Minute; output [7:0]Second; output [7:0]Ten_MS;
/**********************************/
parameter T10MS = 19'd479_999;//CLK=48MHz-1
/**********************************/
reg [18:0]Count1; reg [7:0]Count_S; reg [7:0]Count_M;
reg [7:0]Count_10MS;
always @ ( posedge CLK or negedge RST ) if(! RST ) begin Count1 <= 16'd0; Count_S <= 6'd0; Count_M <= 6'd0; Count_10MS<=10'd0; end
else if(isCount) begin if( Count1 == T10MS ) begin Count1 <= 16'd0; if( Count_10MS== 7'd99 ) begin Count_10MS<=10'd0; if( Count_S== 6'd59 ) begin Count_S<=6'd0; if( Count_M== 6'd59 ) begin Count_M<=6'd0;
end else Count_M<=Count_M+1'b1; end else Count_S<=Count_S+1'b1; end else Count_10MS<=Count_10MS+1'b1; end else Count1 <= Count1 + 1'b1; end
else if(!isCount) begin Count1 <= Count1; Count_S <= Count_S; Count_M <= Count_M; Count_10MS<=Count_10MS; end
/******************************************/ assign Minute=Count_M; assign Second=Count_S; assign Ten_MS=Count_10MS;
/******************************************/ Endmodule
Testbench
`timescale 1 ps/ 1 ps module count_tb();
reg CLK; reg RST; reg isCount;
// wires wire [7:0] Minute; wire [7:0] Second; wire [7:0] Ten_MS;
count i1 (
.CLK(CLK), .Minute(Minute), .RST(RST), .Second(Second), .Ten_MS(Ten_MS), .isCount(isCount) );
initial begin CLK=0; RST=0; isCount=1; #10 RST=1;
end always begin #1
CLK=~CLK; end
endmodule 仿真波形
仿真结果说明:
由仿真图可知,当Ten_MS=99是,秒加一,当秒计数到59时,分加一,所以此模块功能正确
3.功能控制模块
功能说明:
此模块接受按键传过来的信息,并根据按键信息对各模块进行控制,包括了计时器的计数使能,存储数据,回放数据,是所有模块中最复杂的部分。 源代码:
module control( CLK, RST, KEY, MS_Data_in, SEC_Data_in, Minu_Data_in, MS_Data_out, SEC_Data_out, Minu_Data_out, Count_EN, LED );
input CLK; input RST; input [2:0]KEY;
input [7:0]MS_Data_in; input [7:0]SEC_Data_in; input [7:0]Minu_Data_in; output [7:0]MS_Data_out; output [7:0]SEC_Data_out; output [7:0]Minu_Data_out; output Count_EN; output [3:0]LED;
/****************************************/ parameter T10MS = 19'd49_9999; /***************************************/ reg [18:0]Count1; reg isCount;
always @ ( posedge CLK or negedge RST ) if( !RST ) Count1 <= 19'd0; else if( isCount && Count1 == T10MS ) Count1 <= 19'd0; else if( isCount ) Count1 <= Count1 + 1'b1; else if( !isCount ) Count1 <= 19'd0;
/****************************************/
reg [9:0]Count_MS; always @ ( posedge CLK or negedge RST ) if( !RST ) Count_MS <= 4'd0; else if( isCount && Count1 == T10MS ) if( Count_MS == 10'd200 ) Count_MS<=10'd0; else Count_MS <= Count_MS + 1'b1; else if( !isCount ) Count_MS <= 4'd0; /******************************************/
reg [7:0]rMS; reg [7:0]rSEC; reg [7:0]rMinu;
reg [7:0]rMS_Data[2:0]; reg [7:0]rSEC_Data[2:0]; reg [7:0]rMinu_Data[2:0];
reg rEN;
reg [2:0]wr_addr; reg [2:0]rd_addr; reg Key_Up;
always @(posedge CLK or negedge RST) if(!RST) begin wr_addr=3'b0;
rd_addr=3'b0; rEN=1'b0; Key_Up=0; rMS<=MS_Data_in; rSEC<=SEC_Data_in; rMinu<=Minu_Data_in; end else
case(Key_Up) 1'b0: case(KEY) 3'b001: begin rEN=~rEN; Key_Up<=1'b1; end 3'b010: begin Key_Up<=1'b1; if(wr_addr==2'b11) wr_addr=2'b0; else begin rMS_Data[wr_addr]<=MS_Data_in; rSEC_Data[wr_addr]<=SEC_Data_in; rMinu_Data[wr_addr]<=Minu_Data_in; wr_addr<=wr_addr+1'b1; end end 3'b100: begin rEN=0; Key_Up<=1'b1; if(rd_addr==2'b11) rd_addr<=3'd0; else begin rMS<=rMS_Data[rd_addr]; rSEC<=rSEC_Data[rd_addr]; rMinu<=rMinu_Data[rd_addr]; rd_addr<=rd_addr+1'b1; end end
default: begin if(rEN) begin rMS<=MS_Data_in; rSEC<=SEC_Data_in; rMinu<=Minu_Data_in; end end endcase 1'b1: if( Count_MS == 10'd200 ) Key_Up <= 1'd0; else isCount <= 1'b1; endcase
assign MS_Data_out=rMS; assign SEC_Data_out=rSEC; assign Minu_Data_out=rMinu; assign Count_EN=rEN; assign LED[3]=rEN; assign LED[2]=Key_Up;
assign LED[1:0]=rd_addr[1:0]; endmodule
数码管译码模块
功能说明:
此模块用来实现对计数结果的显示,包括两个小模块:除法器,译码模块。 源码:
module convert (
CLK, RST, MS_Data, S_Data, M_Data, MS_One_SData, MS_Ten_SData, S_One_SData, S_Ten_SData, M_One_SData, M_Ten_SData
);
input CLK; input RST;
input [7:0]MS_Data; input [7:0]S_Data; input [7:0]M_Data;
output [7:0]MS_One_SData; output [7:0]MS_Ten_SData; output [7:0]S_One_SData; output [7:0]S_Ten_SData; output [7:0]M_One_SData; output [7:0]M_Ten_SData;
wire [3:0]MS_One_Data; wire [3:0]MS_Ten_Data; wire [3:0]S_One_Data; wire [3:0]S_Ten_Data; wire [3:0]M_One_Data; wire [3:0]M_Ten_Data;
encoder6 U1 ( .CLK(CLK), .RST(RST), .MS_One_Data(MS_One_Data), .MS_Ten_Data(MS_Ten_Data), .S_One_Data(S_One_Data), .S_Ten_Data(S_Ten_Data), .M_One_Data(M_One_Data), .M_Ten_Data(M_Ten_Data), .MS_One_SData(MS_One_SData), .MS_Ten_SData(MS_Ten_SData), .S_One_SData(S_One_SData), .S_Ten_SData(S_Ten_SData), .M_One_SData(M_One_SData), .M_Ten_SData(M_Ten_SData) ); div3 U2 (
.CLK(CLK), .RST(RST), .MS_Data(MS_Data), .S_Data(S_Data), .M_Data(M_Data), .MS_One_Data(MS_One_Data), .MS_Ten_Data(MS_Ten_Data), .S_One_Data(S_One_Data), .S_Ten_Data(S_Ten_Data), .M_One_Data(M_One_Data), .M_Ten_Data(M_Ten_Data), );
endmodule
除法器
功能说明:
此模块用来实现把技术结果的个位和十位分离 源代码: module div (
CLK, RST, Number_Data, Ten_Data, One_Data );
input CLK; input RST; input [7:0]Number_Data; output [3:0]Ten_Data; output [3:0]One_Data; /*********************************/ reg [3:0]rTen; reg [3:0]rOne; reg [3:0]cnt; reg [7:0]rem; reg i;
always @ ( posedge CLK or negedge RST )
if( !RST ) begin rTen <= 4'd0; rOne <= 4'd0; i<=1'b0; cnt<=4'd0; rem<=8'd0; end else case(i) 0: begin rem<=Number_Data; i=1'b1; cnt=4'd0; end 1: begin if(rem<4'd10) begin rTen<=cnt; rOne<=rem[3:0]; i=1'b0; end else begin cnt<=cnt+1; rem<=rem-4'd10; end end endcase /***********************************/ assign Ten_Data = rTen; assign One_Data = rOne; /***********************************/
Endmodule Testbench
`timescale 1 ps/ 1 ps module div_tb(); reg CLK;
.M_Ten_SData(M_Ten_SData), .S_One_SData(S_One_SData), .S_Ten_SData(S_Ten_SData), .DIG_Sig(SEL), .SEG_Sig(DIG) ); endmodule 下载验证
1. 管脚分配 NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \NET \
NET \NET \NET \NET \NET \2. 下载过程
点击IMPACT,对FPGA进行编程,程序下载完成后,数码管显示计时时间,按下存储按键,能存储此时的时间,按下回放按键,可以显示存储的时间,达到实验要求。
测试结果与结论
本实验采用Verilog编写源代码,模块划分精细,采用TOP-DOWN的设计流程,对各个模块给予仿真,最终下载验证,达到了预期的效果。
正在阅读:
基于FPGA的数字跑表10-08
国际经济法任务01任务000204-23
普法志愿者发言稿02-25
语文教育《儿童文学》讲义(下)04-05
查字典比赛作文03-12
马边彝族自治县人民医院2010年上半年进一步加强行风建设总结06-18
数学的内涵10-05
六年级读书手抄报图片02-06
中国农业科学院兰州兽医所研究生院导师简介09-12
汽机检修规程12-15
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 跑表
- 基于
- 数字
- FPGA
- 苏教版五年级上册科学全册教案
- wireshark的使用教程 - 图文
- 武汉工程大学勤工助学中心人事管理信息系统
- 2018年民政局城乡统筹发展工作计划范文与2018年民政局局长个人工作计划范文汇编 doc
- 化工建设项目项目建议书内容和深度规定
- 抗滑桩专项施工方案
- %E9%BE%9A%E5%A4%AA%E4%BA%91%E6%8A%80%E6%9C%AF%E6%8A%A5%E5%91%8A%5B1%5D
- 2019-2020年七年级地理上册 第三章第三节 中国的河流和湖泊教案 中图版
- 广东海洋大学软件工程考试试卷
- 2017年仁爱版初中英语八年级英语上册全套全册精品导学案
- 学习全国优秀共产党员事迹心得:学习榜样的力量,做群众的“贴心人”
- 基础化学第三版习题解答 - 图文
- 小学科学课外活动的拓展与实践
- 达茂旗概况
- 第二章 国际结算中的票据练习题
- 空间管治与用地布局
- 智能机器人行为能力的
- 优秀教研组材料
- 《我的成长脚印》填写要求
- 第9部分:邮政电信