設計要求
(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