begin fen=0; shi=shi+1'b1; if(shi==24) shi=0; end end end else if(!moshi&&key1_low)//时间模式下 按加键 begin fen=fen+1'b1; if(fen==60) begin fen=0; shi=shi+1'b1; if(shi==24) shi=0; end end else if(!moshi&&key2_low)//时间模式下 按减键 begin
fen=fen-1'b1; if(fen==0) begin shi=shi-1'b1; fen=59; end end else if(moshi&&key1_low)//时间模式下 按加键 begin nao_fen=nao_fen+1'b1; if(nao_fen==60) begin nao_fen=0; nao_shi=nao_shi+1'b1; if(shi==24) shi=0; end end else if(moshi&&key2_low)//闹钟模式下 按减键 begin
nao_fen=nao_fen-1'b1; if(nao_fen==0)
12
begin nao_shi=nao_shi-1'b1; nao_fen=59; end end else begin shi<=shi; fen<=fen; miao<=miao; nao_shi<=nao_shi; nao_fen<=nao_fen; nao_miao<=nao_miao; end end
endmodule
3.3.2 时间模块仿真
时间模块的RTL视图如图8所示,可以看出输出端shi、fen、miao、nao_shi、nao_fen、mao_miao与输入端Key1_low和Key2_low、Key3_low、en_1s、rst_n的逻辑关系。
图8 时间模块的RTL视图
仿真了时钟,仿真波形图如图9、图10所示,仿真图满足设计的要求。分计数和时计数模块的设计原理与秒模块的类似。
13
图9 秒时钟仿真波形
图10 计时模块仿真
3.4 显示模块
显示模块的作用是:在8位数码管上显示时间模块输出的时间和闹钟信号,通过按键可以切换显示时间和闹钟。
具体原理是采用动态扫描的方法,动态扫描电路将计数器输出的8421BCD码转换为数码管需要的逻辑状态,并且输出数码管的片选信号和位选信号。所谓动态扫描显示方式是在显示某一位LED显示块的数据的时候,让其它位不显示,然后在显示下一位的数据,同时关闭其他显示块。这样做可以使每一个显示块显示与自己相对应的数据。只要保证每一位显示的时间间隔不要太大,利用人眼的视觉暂留的现象,就可以造成各位数据同时显示的假象。一般每一位的显示时间为1~10ms。
3.4.1 显示模块源代码
显示模块的部分源代码如下:(以显示秒为例)
module
xianshi(clk,rst_n,en_1ms,shi,fen,miao,led_bit,dataout,moshi,nao_shi,nao_fen,nao_miao);
input clk; input rst_n; input en_1ms; input[5:0] shi; input[5:0] fen; input[5:0] miao;
14
input[5:0] nao_shi; input[5:0] nao_fen; input[5:0] nao_miao; input[1:0] moshi;
output[2:0] led_bit; //位选 output[7:0] dataout; //段选 //数码管显示 0~9 对应段选输出
parameter num0 = 8'b11000000, num1 = 8'b11111001, num2 = 8'b10100100, num3 = 8'b10110000, num4 = 8'b10011001, num5 = 8'b10010010, num6 = 8'b10000010, num7 = 8'b11111000, num8 = 8'b10000000, num9 = 8'b10010000; reg[3:0] shi1,shi2,fen1,fen2,miao1,miao2;
reg[3:0] nao_shi1,nao_shi2,nao_fen1,nao_fen2,nao_miao1,nao_miao2; reg[2:0] led_bit; //位选 reg[7:0] dataout; //段选
reg[2:0] state; //状态寄存器
always@(posedge clk or negedge rst_n) if(!rst_n) begin state<=3'b0; end
else if(en_1ms) begin state<=state+1'b1;
shi1=shi/10; shi2=shi; fen1=fen/10; fen2=fen; miao1=miao/10; miao2=miao; nao_shi1=nao_shi/10; nao_shi2=nao_shi; nao_fen1=nao_fen/10; nao_fen2=nao_fen; nao_miao1=nao_miao/10;
15
nao_miao2=nao_miao; if(state==3'b000) begin led_bit=3'b101; if(!moshi) begin case(miao2) 0: dataout<=num0; 1: dataout<=num1; 2: dataout<=num2; 3: dataout<=num3; 4: dataout<=num4; 5: dataout<=num5; 6: dataout<=num6; 7: dataout<=num7; 8: dataout<=num8; 9: dataout<=num9; default :dataout<=num0; endcase end else if(moshi) begin case(nao_miao2) 0: dataout<=num0; 1: dataout<=num1; 2: dataout<=num2; 3: dataout<=num3; 4: dataout<=num4; 5: dataout<=num5; 6: dataout<=num6; 7: dataout<=num7; 8: dataout<=num8; 9: dataout<=num9; default :dataout<=num0; endcase end end
else if(state==3'b001) begin led_bit=3'b100; if(!moshi) begin case(miao1)
16

