含有en端和load端的25min倒计时器
程序员文章站
2022-06-09 20:33:26
`timescale 1ns / 1ps//16进制module second(input wire clk,output reg sec);reg [27:0]q1;always @(posedge clk) begin if(q1==50000000) begin q1<=0; sec<=~sec; end else...
`timescale 1ns / 1ps
//16进制
module second(
input wire clk,
output reg sec);
reg [27:0]q1;
always @(posedge clk)
begin
if(q1==50000000)
begin
q1<=0;
sec<=~sec;
end
else
q1<=q1+1;
end
endmodule
module cnt24(
input wire clk,//秒脉冲信号
input clk2,//标准时钟信号
input clear,
input stop,
output reg [3:0] cnt60_L,
output reg [3:0] cnt60_H,
output reg [3:0] cnt25_mL,
output reg [3:0] cnt25_mH,
output reg carry
);
initial begin
cnt60_L=0;
cnt60_H=0;
cnt25_mL=5;
cnt25_mH=2;
end
//状态编码
parameter
[1:0]work=2'b00;
parameter
[1:0]pause=2'b10;
parameter
[1:0]reset=2'b01;
reg [1:0]cstate;
reg [1:0]nstate;
reg en,load;
/*
reg [26:0]counter;
wire clk2Hz=0;
//counter 分频计数器
parameter CNT=50000000;
initial counter=0;
always @(posedge clk )
if (counter==CNT-1)
counter<=0;
else counter<=counter+1;
assign clk2Hz=(counter==CNT)?1:0;
*/
//状态转移
always @(posedge clk2 )
cstate<=nstate;
//次态判断
always @*
//if(jinwei)
case(cstate)
work:
begin
if(stop==1)
nstate=pause;
else
nstate=work;
end
pause:
begin
if(clear==1)nstate=reset;
else if(stop==1)
nstate=work;
else nstate=pause;
end
reset:
begin
if(stop==1)
nstate=work;
else
nstate=reset;
end
default: nstate=reset;
endcase
// else
// nstate=cstate;
//次态输出
always @(posedge clk2 )//or posedge rst)
begin
//else
case(cstate)
reset:begin en<=0;load<=1;end
work:begin en<=1;load<=0;end
pause:begin en<=0;load<=0;end
default:begin en<=0;load<=1;end
endcase
end
//clk为秒脉冲信号 clk2为标准时钟信号
always @(posedge clk)
begin
if(en==0&&load==1)
begin
cnt60_L<=0;
cnt60_H<=0;
cnt25_mL<=5;
cnt25_mH<=2;
end
if(en==1&&load==0)
begin
carry<=0;
cnt60_L<=cnt60_L-1;
if(cnt60_L==0)
begin
cnt60_L<=9;
cnt60_H<=cnt60_H-1;
end
if(cnt60_H==0 && cnt60_L==0 )
begin
cnt60_L<=9;
cnt60_H<=5;
cnt25_mL<=cnt25_mL-1;
end
if(cnt60_H==0 && cnt60_L==0 && cnt25_mL==0)
begin
cnt60_L<=9;
cnt60_H<=5;
cnt25_mL<=9;
cnt25_mH<=cnt25_mH-1;
end
if(cnt60_H==0 && cnt60_L==0 && cnt25_mL==0 && cnt25_mH==0)
begin
cnt60_L<=0;
cnt60_H<=0;
cnt25_mL<=5;
cnt25_mH<=2;
carry<=1;
end
end
if(en==0&&load==0)
begin
cnt60_L<=cnt60_L;
cnt60_H<=cnt60_H;
cnt25_mL<=cnt25_mL;
cnt25_mH<=cnt25_mH;
end
end
endmodule
module shumaguan(
input clk,
input rst_n,
input [3:0]sL,
input [3:0]sH,
input [3:0]mL,
input [3:0]mH,
//input [7:0] x, //等待显示的BCD码
output reg [6:0] a_to_g, //段信号
output reg [3:0] an //位选信号
);
wire [15:0]x={mH,mL,sH,sL};
//x={H,L};
//时钟分频 计数器
reg [20:0] clkdiv;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
clkdiv<=21'd0;
else
clkdiv<=clkdiv+1;
end
/*利用计数器自动溢出时间,即就是clkdiv从0~11111111111111111111循环计数,
则clk[19]会在0~1之间以5.24ms为时间间隔变化 2^19=524288
(即后19位全0到全1的计数时间)
*/
//bitcnt: 位扫描信号 0~1循环变化 扫描周期 5.24ms 控制总扫描时间不超过10ms,单个数码管显示时间约为5ms
wire [1:0]bitcnt;
assign bitcnt=clkdiv[20:19];
//an:位选信号产生,高有效
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
an=4'd0;
else
case(bitcnt)
2'd0:an=4'b0001;
2'd1:an=4'b0010;
2'd2:an=4'b0100;
2'd3:an=4'b1000;
endcase
end
//digit 当前带显示的数字
reg [3:0]digit;
always @(posedge clk or negedge rst_n)
begin
if (!rst_n)
digit=4'd0;
else
case(bitcnt)
2'd0:digit=x[3:0];
2'd1:digit=x[7:4];
2'd2:digit=x[11:8];
2'd3:digit=x[15:12];
default:digit=4'd0;
endcase
end
//a_to_g: 段码信号,共阴极数码管,段码高有效。 7段译码表
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
a_to_g=7'b1111111;
else
case(digit)
0:a_to_g=7'b1111110;//段码位序由高到低为a-g
1:a_to_g=7'b0110000;
2:a_to_g=7'b1101101;
3:a_to_g=7'b1111001;
4:a_to_g=7'b0110011;
5:a_to_g=7'b1011011;
6:a_to_g=7'b1011111;
7:a_to_g=7'b1110000;
8:a_to_g=7'b1111111;
9:a_to_g=7'b1111011;
default:a_to_g=7'b1111110;
endcase
end
endmodule
module edgecheck(
input key1,key2,
input clk,
output Yup1,Yup2
);
reg a1,b1;
always @(posedge clk)
begin
a1<=key1;
b1<=a1;
end
assign Yup1=a1&(~b1);
reg a2,b2;
always @(posedge clk)
begin
a2<=key2;
b2<=a2;
end
assign Yup2=a2&(~b2);
endmodule
module top(
input wire clk,
input rst_n,//数码管的显示开关
input wire clear0,
input wire stop,
output wire [6:0]a_to_g,
output wire [3:0]an
);
wire jinwei;
wire [3:0]sL;
wire [3:0]sH;
wire [3:0]mL;
wire [3:0]mH;
wire stop1;//使能端 暂停或继续
wire clear01; //清零端
second U0(
.clk(clk),
.sec(jinwei)
);
cnt24 U1(
.clk(jinwei),
.clk2(clk),
.clear(clear01),
.stop(stop1),
.cnt60_L(sL),
.cnt60_H(sH),
.cnt25_mL(mL),
.cnt25_mH(mH)
);
shumaguan U2
(
.clk(clk),
.rst_n(rst_n),
.sL(sL),
.sH(sH),
.mL(mL),
.mH(mH),
.a_to_g(a_to_g), //段信号
.an(an)
);
// 开关消除抖动
edgecheck u3(
.key1(clear0),
.key2(stop),
.clk(clk),
//.jinwei(jinwei),
.Yup1(clear01),
.Yup2(stop1)
);
endmodule
备注:本代码由西安交通大学电气工程及其自动化专业教学使用,如有侵权,联系作者删除。 本代码为西安交通大学学生备忘而用。
如果有共同爱好者,可以一起学习
qq:2685783428
如果代码有用,请尽情的点赞和打赏即可
白嫖虽然爽,但是违背公序良俗,不可取哦,亲(づ ̄3 ̄)づ╭❤~
本文地址:https://blog.csdn.net/shenqingdi/article/details/110112941
上一篇: C语言实现三子棋源代码
下一篇: R语言逻辑回归深入讲解