设计要求
(1)具有显示24秒计时功能;
(2)系统设置外部操作开关,控制计时器的直接启动(重置为24)和暂停/继续功能;
(3)计时器为24秒递减计时,其计时间隔为1秒;
(4)计时器递减计时到零时,数码显示器不能灭灯,同时发出光电报警信号。
24s倒计时
代码实现
设计模块
module varmodcnt(CP,CLR,EN,PE,D,Q,carry_out);
parameter n=4,MOD=10;
input CP,CLR,EN,PE;
input [n-1:0] D;
output reg[n-1:0] Q;
output carry_out;
/*输入:CP时钟信号,CLR清零信号,EN使能,PE预制信号,D为预置输入
输出:Q为输出4位二进制数,carry_out为借位信号*/
//敏感信号:CP上升沿,CLR下降沿,PE上升沿
always@(posedge CP,negedge CLR)
begin
if(!CLR) Q<='d0; //清零
else if(!EN) Q<=Q; //保持,相当于暂停
else begin
if(Q==4'b0000) Q<=MOD-1; //递减
else Q<=Q-1;
end
end
always@(posedge PE)
begin
Q<=D; //置数
end
assign carry_out=(Q==4'b0000); //借位信号
endmodule
module _24s(CP,EN,PE,Q1,Q0);
input CP,EN,PE;
output [3:0] Q1,Q0;
/*
输入:CP为时钟信号,EN为使能信号,PE为预置信号
输出:Q1为十位输出数,Q0为个位输出数
*/
wire carry_out;
wire carry_out1;
wire CP1;
assign CP1=~carry_out; //个位数减到0时,十位数递减
wire EN1;
assign EN1=EN&~(carry_out&carry_out1); //当减为0时,不在递减
varmodcnt U1(CP1,1'b1,EN1,PE,4'b0010,Q1,carry_out1); //元件实例化
varmodcnt U0(CP,1'b1,EN1,PE,4'b0100,Q0,carry_out); //元件实例化
endmodule
测试模块
`timescale 100ms/10ms
module tb_24s();
reg CP;
reg EN;
reg PE;
wire [3:0] Q1;
wire [3:0] Q0;
_24s U(CP,EN,PE,Q1,Q0); //元件实例化
initial
$monitor($time,"\tQ1=%b,Q0=%b\n",Q1,Q0);
//时钟
initial
CP=1;
always
#5 CP=~CP;
initial
begin
//启动:产生PE上升沿,进行预置
EN=1;PE=0;
#10;
EN=1;PE=1;
#10;
//计数
EN=1;PE=0;
#260;
//启动:产生PE上升沿,进行预置
EN=1;PE=1;
#10;
EN=1;PE=0;
#20;
//暂停
EN=0;PE=0;
#20;
$stop;
end
仿真结果
显示
代码实现
设计模块
//filename:_24show.v
module _24show(
input CP,EN,PE,BL,LT,
output [6:0] L1,L0);
/*
输入:CP时钟信号,EN使能信号,PE预制信号,BL,LT,
*/
wire [3:0]Q1,Q0;
wire BL1;
_24s U(CP,EN,PE,Q1,Q0);
assign BL1=BL&(Q1!=4'b0000);
_74HC4511 U1(1'b0,BL1,LT,Q1,L1);
_74HC4511 U0(1'b0,BL,LT,Q0,L0);
endmodule
module _74HC4511(
input LE,BL,LT,
input [3:0] D,
output reg [6:0] L);
/*
输入输出端口说明。
输入端口: LE,BL,LT为使能信号。D为待显示的四位二进制数字。
输出端口:L为7段显示器各段的工作情况。
*/
wire [2:0] E;
assign E={LE,BL,LT}; //中间变量用于后续的控制端优先级判断
always@(*)
begin
if(LE==0&&BL==1&<==1)
begin
case(D)
//0-9显示。
4'b0000:L=7'b111_1110;
4'b0001:L=7'b011_0000;
4'b0010:L=7'b110_1101;
4'b0011:L=7'b111_1001;
4'b0100:L=7'b011_0011;
4'b0101:L=7'b101_1011;
4'b0110:L=7'b001_1111;
4'b0111:L=7'b111_0000;
4'b1000:L=7'b111_1111;
4'b1001:L=7'b111_1011;
//以下为无效状态
4'b1010:L=7'b000_0000;
4'b1011:L=7'b000_0000;
4'b1100:L=7'b000_0000;
4'b1101:L=7'b000_0000;
4'b1110:L=7'b000_0000;
4'b1111:L=7'b000_0000;
endcase
end
else
begin
casex(E)
3'bxx0:L=7'b111_1111; //灯测试
3'bx01:L=7'b000_0000; //灭灯
3'b111:L<=L; //锁存
endcase
end
end
endmodule
测试模块
//filename:tb_show.v
`timescale 100ms/10ms
module tb_show();
reg CP,EN,PE,BL,LT;
wire [6:0] L1,L0;
_24show U3(CP,EN,PE,BL,LT,L1,L0);
initial
$monitor($time,"\tL1=%b,L0=%b\n,",L1,L0);
initial
CP=1;
always
#5 CP=~CP;
initial
begin
BL=1'b1;LT=1'b1;EN=1;PE=0;
#10;
BL=1'b1;LT=1'b1;EN=1;PE=1;
#10;
BL=1'b1;LT=1'b1;EN=1;PE=0;
#260;
$stop;
end
endmodule