赞
踩
一、实现功能
1. 能正常完成时钟的时、分、秒走时;
2. 使用LED闪烁或者改变颜色等方式实现秒的指示,要求闪烁频率或者颜色切换频率为1Hz;
3. 使用两位七段数码管显示时和分,其切换方式为:默认显示“分钟”,按住K4键显示“小时”,按下K3显示秒针;
4. 关上开关sw2,使用K1和K2键调整时间,分别为“+”和“-”,则K1和K2调整“分钟”,当K4按下,则K1和K2调整“小时”,当K3按下,则K1和K2调整“秒针”;
5. 整点报时:当时间到达每个整点,则全彩LED以某种固定颜色按1Hz频率闪烁相应次数(按24小时制);
6. 闹钟设置,将sw3开关设置为1,开始设置固定时钟和分钟,当时间计时到达时,八个led灯闪烁一分钟;
二、实验
1.整体结构
2.主函数
- // Module Function:时钟设计
-
- module time_clock (clk,rst,seg_led_1,seg_led_2,led,key,sw2,sw3,led_rgb1,led_rgb2);
-
- input clk,rst;
- input [3:0]key;
- input sw2,sw3;
- output reg [8:0] seg_led_1;
- output reg [8:0] seg_led_2;
-
- output reg [7:0] led;
- output reg [2:0] led_rgb1=3'b 111;
- output reg [2:0] led_rgb2=3'b 111;
-
-
- reg [3:0] cnt1 ; //定义了一个4位的计数器
- reg [3:0] count1;
- reg [3:0] count_set_1;
- reg [3:0] cnt2 ;
- reg [3:0] count2;
- reg [3:0] count_set_2;
- reg [3:0] cnt3 ; //定义了一个4位的计数器
- reg [3:0] count3;
- reg [3:0] count_set_3;
- reg [3:0] cnt4 ;
- reg [3:0] count4;
- reg [3:0] count_set_4;
- reg [3:0] cnt5 ; //定义了一个4位的计数器
- reg [3:0] count5;
- reg [3:0] count_set_5;
- reg [3:0] cnt6 ;
- reg [3:0] count6;
- reg [3:0] count_set_6;
- reg [30:0]count_1s;
- reg [30:0]count_05s;
- reg [15 : 0] count;
- reg [15 : 0] count0;
- reg [8:0] seg [9:0];
-
-
- wire clk1s; //定义一个中间变量,表示分频得到的时钟,用作计数器的触发
-
-
- //间隔脉冲模块,产生一个 秒针 时钟信号
- parameter N1 = 12000000;
- always@(posedge clk) begin
- if(!rst)
- count_1s <= 0;
- else if(count_1s == N1-1)
- count_1s<=0;
- else
- count_1s<= count_1s + 1;
- end
- //间隔脉冲模块,产生一个调整 间隔 信号时钟信号
- parameter N2 = 1500000;
- always@(posedge clk) begin
- if(!rst)
- count_05s <= 0;
- else if(count_05s == N2-1)
- count_05s<= 0;
- else
- count_05s<= count_05s + 1;
- end
-
-
-
- divide #(.WIDTH(32),.N(12000000)) u2 ( //传递参数
- .clk(clk),
- .rst_n(rst), //例化的端口信号都连接到定义好的信号
- .clkout(clk1s)
- );
-
-
-
- always @(posedge clk or negedge rst)
- begin
-
- if (!rst) //---------------------------------------------异步清零
- begin
- cnt1 <= 0;
- cnt2<=0;
- cnt3 <= 0;
- cnt4<=0;
- cnt5 <= 0;
- cnt6<=0;
- end
- //----------------------------------------开始计时
- else
- begin
- if(sw2==1)//sw2调整时间的开关 1:开始计时 0:调整时间 sw3为闹钟设置开关 设置闹钟模式sw3:1 退出设置闹钟模式sw3:0
- begin
- if(count_1s==N1-1 )
- begin
- //秒
- if((cnt2==5)&&(cnt1==9))
- begin
- cnt1<=0;
- cnt2<=0;
- //分钟
- if((cnt4==5)&&(cnt3==9))
- begin
- cnt3<=0;
- cnt4<=0;
- //小时
- if((cnt6==2)&&(cnt5==3))
- begin
- cnt5<=0;
- cnt6<=0;
- end
- else if(cnt5==9)
- begin
- cnt5<=0;
- cnt6<=cnt6+1;
- end
- else
- begin
- cnt5<=cnt5+1;
- end
- //小时
- end
- else if(cnt3==9)
- begin
- cnt3<=0;
- cnt4<=cnt4+1;
- end
- else
- begin
- cnt3<=cnt3+1;
- end
- end
- //分钟
- else if(cnt1==9)
- begin
- cnt1<=0;
- cnt2<=cnt2+1;
- end
- else
- begin
- cnt1<=cnt1+1;
- end
-
- //秒
- end
-
-
-
- end
- //-------------------------------------------------------------------暂停调整时间
- if(sw2==0 && sw3==0)
- begin
- if(key[2]==1 && key[3]==1)//-----------------------------------------------调整分针
- begin
- if( key[0]==0 )
- begin
- if(count_05s==N2-1)
- begin
- if((cnt4==5)&&(cnt3==9))
- begin
- cnt3<=0;
- cnt4<=0;
- end
- else if(cnt3==9 )
- begin
- cnt3<=0;
- cnt4<=cnt4+1;
- end
- else
- begin
- cnt3<=cnt3+1;
- end
- end
-
-
- end
- else if(key[1]==0)
-
- begin
- if(count_05s==N2-1)
- begin
- if(cnt3==0 && cnt4==0)
- begin
- cnt3<=9;
- cnt4<=5;
- end
- else if(cnt3==0)
- begin
- cnt3<=9;
- cnt4<=cnt4-1;
- end
- else
- cnt3<=cnt3-1;
- end
-
- end
- else
- begin
- cnt3<=cnt3;
- cnt4<=cnt4;
- end
- end
-
- else if(key[2]==1 && key[3]==0)//-----------------------------------------------调整时针
- begin
- if( key[0]==0 )
- begin
- if(count_05s==N2-1)
- begin
- if((cnt6==2)&&(cnt5==3))
- begin
- cnt5<=0;
- cnt6<=0;
- end
- else if(cnt5==9)
- begin
- cnt5<=0;
- cnt6<=cnt6+1;
- end
- else
- begin
- cnt5<=cnt5+1;
- end
- end
- end
- else if(key[1]==0)
-
- begin
- if(count_05s==N2-1)
- begin
- if(cnt5==0 && cnt6==0)
- begin
- cnt5<=3;
- cnt6<=2;
- end
- else if(cnt5==0)
- begin
- cnt5<=9;
- cnt6<=cnt6-1;
- end
- else
- cnt5<=cnt5-1;
- end
-
- end
- else
- begin
- cnt5<=cnt5;
- cnt6<=cnt6;
- end
- end
- else if(key[2]==0 && key[3]==1)//-----------------------------------------------调整秒针
- begin
- if( key[0]==0 )
- begin
- if(count_05s==N2-1)
- begin
- if((cnt2==5)&&(cnt1==9))
- begin
- cnt1<=0;
- cnt2<=0;
- end
- else if(cnt1==9)
- begin
- cnt1<=0;
- cnt2<=cnt2+1;
- end
- else
- begin
- cnt1<=cnt1+1;
- end
- end
- end
- else if(key[1]==0)
-
- begin
- if(count_05s==N2-1)
- begin
- if(cnt1==0 && cnt2==0)
- begin
- cnt1<=9;
- cnt2<=5;
- end
- else if(cnt1==0)
- begin
- cnt1<=9;
- cnt2<=cnt2-1;
- end
- else
- cnt1<=cnt1-1;
- end
-
- end
- else
- begin
- cnt1<=cnt1;
- cnt2<=cnt2;
- end
- end
-
-
-
- end
- //-----------------------------------------------设置闹钟
-
- if(sw3==1 )
- begin
- if(key[2]==1 && key[3]==1)//-----------------------------------------------调整分针
- begin
- if( key[0]==0 )
- begin
- if(count_05s==N2-1)
- begin
- if((count_set_4==5)&&(count_set_3==9))
- begin
- count_set_3<=0;
- count_set_4<=0;
- end
- else if(count_set_3==9 )
- begin
- count_set_3<=0;
- count_set_4<=count_set_4+1;
- end
- else
- begin
- count_set_3<=count_set_3+1;
- end
- end
-
-
- end
- else if(key[1]==0)
-
- begin
- if(count_05s==N2-1)
- begin
- if(count_set_3==0 && count_set_4==0)
- begin
- count_set_3<=9;
- count_set_4<=5;
- end
- else if(count_set_3==0)
- begin
- count_set_3<=9;
- count_set_4<=count_set_4-1;
- end
- else
- count_set_3<=count_set_3-1;
- end
-
- end
- else
- begin
- count_set_3<=count_set_3;
- count_set_4<=count_set_4;
- end
- end
-
- else if(key[2]==1 && key[3]==0)//-----------------------------------------------调整时针
- begin
- if( key[0]==0 )
- begin
- if(count_05s==N2-1)
- begin
- if((count_set_6==2)&&(count_set_5==3))
- begin
- count_set_5<=0;
- count_set_6<=0;
- end
- else if(count_set_5==9)
- begin
- count_set_5<=0;
- count_set_6<=count_set_6+1;
- end
- else
- begin
- count_set_5<=count_set_5+1;
- end
- end
- end
- else if(key[1]==0)
-
- begin
- if(count_05s==N2-1)
- begin
- if(count_set_5==0 && count_set_6==0)
- begin
- count_set_5<=3;
- count_set_6<=2;
- end
- else if(count_set_5==0)
- begin
- count_set_5<=9;
- count_set_6<=count_set_6-1;
- end
- else
- count_set_5<=count_set_5-1;
- end
-
- end
- else
- begin
- count_set_5<=count_set_5;
- count_set_6<=count_set_6;
- end
-
- end
-
-
- end
-
- end
- end
- //--------------------------------------------------------------------数码管显示
-
- //在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial
- initial //initial和always不同,其中语句只执行一次
- begin
- seg[0] = 9'h3f; //对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字 0
- seg[1] = 9'h06; //7段显示数字 1
- seg[2] = 9'h5b; //7段显示数字 2
- seg[3] = 9'h4f; //7段显示数字 3
- seg[4] = 9'h66; //7段显示数字 4
- seg[5] = 9'h6d; //7段显示数字 5
- seg[6] = 9'h7d; //7段显示数字 6
- seg[7] = 9'h07; //7段显示数字 7
- seg[8] = 9'h7f; //7段显示数字 8
- seg[9] = 9'h6f; //7段显示数字 9
- end
- always @(posedge clk)
- begin
- if(sw3==0)
- begin
- if(key[2]==1 && key[3]==0)
- begin
- count5<=cnt5;
- count6<=cnt6;
- seg_led_1<=seg[count6];
- seg_led_2<=seg[count5];
-
- end
- else if(key[2]==0 && key[3]==1)
- begin
- count1<=cnt1;
- count2<=cnt2;
- seg_led_1<=seg[count2];
- seg_led_2<=seg[count1];
- end
- else
- begin
- count4<=cnt4;
- count3<=cnt3;
- seg_led_1<=seg[count4];
- seg_led_2<=seg[count3];
- end
- end
- else
- begin
- if(key[2]==1 && key[3]==0)
- begin
- count5<=count_set_5;
- count6<=count_set_6;
- seg_led_1<=seg[count6];
- seg_led_2<=seg[count5];
-
- end
- else if(key[2]==0 && key[3]==1)
- begin
- count1<=count_set_1;
- count2<=count_set_2;
- seg_led_1<=seg[count2];
- seg_led_2<=seg[count1];
- end
- else
- begin
- count4<=count_set_4;
- count3<=count_set_3;
- seg_led_1<=seg[count4];
- seg_led_2<=seg[count3];
- end
- end
-
- end
-
- //--------------------------------------------整点--三色灯闪烁
- always @(posedge clk1s)
- begin
- led_rgb2[0]<=~led_rgb2[0];//--------------------------------------------三色灯秒钟闪烁
- if(cnt3==0 && cnt4==0)
- begin
- led_rgb1[0]<=~led_rgb1[0];
- end
- else
- begin
- led_rgb1[0]<=1;
-
- end
-
-
- end
- //-------------------------------------------闹钟闪烁
- always @(posedge clk1s)
- begin
- if(count_set_3 == cnt3 && count_set_4 == cnt4 && count_set_5 == cnt5 && count_set_6 == cnt6)
- begin
-
- led<=~led;
- end
- else
- begin
- led<=8'b 11111111;
- end
- end
-
-
- endmodule

3.分频器
-
- // Module Function:任意整数时钟分频
-
- module divide ( clk,rst_n,clkout);
-
- input clk,rst_n; //输入信号,其中clk连接到FPGA的C1脚,频率为12MHz
- output clkout; //输出信号,可以连接到LED观察分频的时钟
-
- //parameter是verilog里常数语句
- parameter WIDTH = 24; //计数器的位数,计数的最大值为 2**WIDTH-1
- parameter N = 12_000_000; //分频系数,请确保 N < 2**WIDTH-1,否则计数会溢出
-
- reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p为上升沿触发时的计数器,cnt_n为下降沿触发时的计数器
- reg clk_p,clk_n; //clk_p为上升沿触发时分频时钟,clk_n为下降沿触发时分频时钟
-
- //上升沿触发时计数器的控制
- always @ (posedge clk or negedge rst_n ) //posedge和negedge是verilog表示信号上升沿和下降沿
- //当clk上升沿来临或者rst_n变低的时候执行一次always里的语句
- begin
- if(!rst_n)
- cnt_p<=0;
- else if (cnt_p==(N-1))
- cnt_p<=0;
- else cnt_p<=cnt_p+1; //计数器一直计数,当计数到N-1的时候清零,这是一个模N的计数器
- end
-
- //上升沿触发的分频时钟输出,如果N为奇数得到的时钟占空比不是50%;如果N为偶数得到的时钟占空比为50%
- always @ (posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- clk_p<=0;
- else if (cnt_p<(N>>1)) //N>>1表示右移一位,相当于除以2去掉余数
- clk_p<=0;
- else
- clk_p<=1; //得到的分频时钟正周期比负周期多一个clk时钟
- end
-
- //下降沿触发时计数器的控制
- always @ (negedge clk or negedge rst_n)
- begin
- if(!rst_n)
- cnt_n<=0;
- else if (cnt_n==(N-1))
- cnt_n<=0;
- else cnt_n<=cnt_n+1;
- end
-
- //下降沿触发的分频时钟输出,和clk_p相差半个时钟
- always @ (negedge clk)
- begin
- if(!rst_n)
- clk_n<=0;
- else if (cnt_n<(N>>1))
- clk_n<=0;
- else
- clk_n<=1; //得到的分频时钟正周期比负周期多一个clk时钟
- end
-
- assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p; //条件判断表达式
- //当N=1时,直接输出clk
- //当N为偶数也就是N的最低位为0,N(0)=0,输出clk_p
- //当N为奇数也就是N最低位为1,N(0)=1,输出clk_p&clk_n。正周期多所以是相与
- endmodule

4.广角分配
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。