实验时间:2008-10-14
设计一个电子时钟,使用左边两个数码管显示分钟、右边两个数码管显示秒。
FPGA的开发环境为Xilinx公司的Foundation ISE 8.1i,使用DP-FPGA实验仪,目标FPGA芯片为XC2S100-PQ208。
module b(SL, PWM1, LED, KEY_RUN, KEY_PAUSE, KEY_RESET, CLK);
output [12:1] SL;
output PWM1;
output [5:4] LED;
input KEY_RUN;
input KEY_PAUSE;
input KEY_RESET;
input CLK;
// 1Hz 50% clock
wire CLK_2Hz; div_2Hz u1(CLK_2Hz, CLK);
reg CLK_1Hz = 1'b0;
always @(posedge CLK_2Hz) CLK_1Hz = ~CLK_1Hz;
// key input
wire K_RUN; wire K_PAUSE; wire K_RESET;
wire CLK_100Hz; div_100Hz u2(CLK_100Hz, CLK);
debounce u3_1(K_RUN, KEY_RUN, CLK_100Hz);
debounce u3_2(K_PAUSE, KEY_PAUSE, CLK_100Hz);
debounce u3_3(K_RESET, KEY_RESET, CLK_100Hz);
// controller
reg [4:0] warmup = 5'd0;
always @(posedge CLK_100Hz) begin
if (warmup < 5'd30) warmup<=warmup+5'd1;
end//state would go directly into 2'h3 without warmup
reg [1:0] state = 2'h0;//0=initial,1=reset,2=paused,3=running
always @(K_RUN,K_PAUSE,K_RESET) begin
if (warmup>5'd29 && ~K_RUN) state<=2'h3;
else if (state==2'h3 && ~K_PAUSE) state<=2'h2;
else if (state==2'h2 && ~K_RESET) state<=2'h1;
end
// counters
wire counter_enable; assign counter_enable=(state==2'h3);
wire counter_reset; assign counter_reset=(state==2'h1);
wire [15:0] numbers;
wire CLK_low; assign CLK_low = counter_enable && CLK_1Hz;
wire CLK_high; wire Cout_high;//assign CLK_high = (numbers[7:4]==4'd0) && (numbers[3:0]==4'd0);
counter60_inc u4(numbers[7:4], numbers[3:0], CLK_low, counter_reset, CLK_high);
counter60_inc u5(numbers[15:12], numbers[11:8], CLK_high, counter_reset, Cout_high);
// display
wire indi_minute; assign indi_minute=(state==2'h3)&&(numbers[7:4]==4'd5)&&(numbers[3:0]==4'd9);
assign PWM1=~indi_minute;
wire indi_second; assign indi_second=(state==2'h3);
assign LED=~{2{indi_second&&CLK_1Hz}};
wire [3:0] blanks; assign blanks={4{state==2'h0}};
wire dot;
assign dot=(state==2'h0)?1'b0:(
(state==2'h3)?CLK_1Hz:1'b1);
wire [3:0] dots; assign dots={1'b0,dot,2'b0};
digits u6(SL, numbers, blanks, dots, CLK);
endmodule
module counter60_inc(N2, N1, CLK, reset, Cout);
output reg [3:0] N2 = 4'd0;
output reg [3:0] N1 = 4'd0;
input CLK;
input reset;
output reg Cout = 1'b0;
always @(posedge CLK, posedge reset) begin
if (reset) N1<=4'd0;
else if (N1==4'd9) N1<=4'd0;
else N1<=N1+4'd1;
end
wire Cout1; assign Cout1=N1==4'd0;
always @(posedge Cout1, posedge reset) begin
if (reset) N2<=4'd0;
else if (N2==4'd5) begin N2<=4'd0; Cout<=1'b1; end
else begin N2<=N2+4'd1; Cout<=1'b0; end
end
endmodule
module div_2Hz(CLK_2Hz, CLK_32M);
output CLK_2Hz;
input CLK_32M;
reg [23:0] counter;
always @(posedge CLK_32M)
if (counter < 25'd16000000) counter <= counter+1;
else counter <= 24'b0;
assign CLK_2Hz = counter[23];
endmodule
本设计中还使用了消除回跳振荡debounce.v、100Hz分频div_100Hz.v、四位数码管显示digits.v组件,与实验06完全相同,代码不再列出。