Download: timer.zip.
This project measures the time KEY3 is depressed, that is from the time the button is pressesd until it is released. Two different timing methods are used, and there is often a count or so difference between them.
The project is a good candidate for SignalTap II debugging.
timer_main.v
module timer_main(
// Clock Input (50 MHz)
input CLOCK_50,
// Push Buttons
input [3:0] KEY,
// DPDT Switches
input [17:0] SW,
// 7-SEG Displays
output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7,
// LEDs
output [8:0] LEDG, // LED Green[8:0]
output [17:0] LEDR, // LED Red[17:0]
// GPIO Connections
inout [35:0] GPIO_0, GPIO_1
);
// set all inout ports to tri-state
assign GPIO_0 = 36'hzzzzzzzzz;
//assign GPIO_1 = 36'hzzzzzzzzz;
assign GPIO_1[35:32] = 4'hz;
assign GPIO_1[31:0] = final_count;
wire [6:0] myclock;
wire RST;
assign RST = KEY[0];
// Setup clock divider
clock_divider cdiv(CLOCK_50,RST,myclock);
assign GPIO_0[6:0] = myclock;
// Connect interesting signals to green LEDs
assign LEDG[0] = timer_clock;
assign LEDG[1] = trigger;
// Connect dip switches to red LEDS
assign LEDR[17:0] = SW[17:0];
// set up counters
wire [3:0] digit7, digit6, digit5, digit4, digit3, digit2, digit1, digit0;
wire ovr0, ovr1, ovr2, ovr3, ovr4, ovr5, ovr6, ovr7;
wire reset = ~postrig & KEY[0];
decimal_counter count0(digit0,ovr0,counter_clock,reset);
decimal_counter count1(digit1,ovr1,ovr0,reset);
decimal_counter count2(digit2,ovr2,ovr1,reset);
decimal_counter count3(digit3,ovr3,ovr2,reset);
decimal_counter count4(digit4,ovr4,ovr3,reset);
decimal_counter count5(digit5,ovr5,ovr4,reset);
decimal_counter count6(digit6,ovr6,ovr5,reset);
decimal_counter count7(digit7,ovr7,ovr6,reset);
// map to 7-segment displays
hex_7seg dsp0(digit0,HEX0);
hex_7seg dsp1(digit1,HEX1);
hex_7seg dsp2(digit2,HEX2);
hex_7seg dsp3(digit3,HEX3);
hex_7seg dsp4(digit4,HEX4);
hex_7seg dsp5(digit5,HEX5);
hex_7seg dsp6(digit6,HEX6);
hex_7seg dsp7(digit7,HEX7);
reg [31:0] count;
reg [31:0] final_count;
reg state;
parameter
HOLD = 1'b0,
COUNT = 1'b1;
wire timer_clock = myclock[2];
wire counter_clock;
assign counter_clock = (state==COUNT? timer_clock: 1'b0);
wire trigger = ~KEY[3];
reg oldtrig;
wire postrig = (trigger & ~oldtrig);
wire negtrig = (~trigger & oldtrig);
always @ (posedge timer_clock or negedge RST)
begin
if (!RST) state <= HOLD;
else
begin
oldtrig <= trigger;
case (state)
HOLD : if (postrig)
begin
state <= COUNT;
count <= 1;
end
COUNT: if (negtrig)
begin
state <= HOLD;
final_count <= count;
end
else count <= count + 1'b1;
endcase
end
end
endmodule
decimal_counter.v
module decimal_counter(A,OVERFLOW,CLK,RST);
input CLK, RST;
output OVERFLOW;
output [3:0] A;
reg OVERFLOW;
reg [3:0] A;
always @ (posedge CLK or negedge RST)
if (~RST) begin
OVERFLOW <= 1'b0;
A <= 4'b0000;
end
else if (A<9) begin
A <= A + 1'b1;
OVERFLOW <= 1'b0;
end
else begin
A <= 4'b0000;
OVERFLOW <= 1'b1;
end
endmodule
divide_by_10.v
module divide_by_10(Q,CLK,RST);
input CLK, RST;
output Q;
reg Q;
reg [2:0] count;
always @ (posedge CLK or negedge RST)
begin
if (~RST)
begin
Q <= 1'b0;
count <= 3'b000;
end
else if (count < 4)
begin
count <= count+1'b1;
end
else
begin
count <= 3'b000;
Q <= ~Q;
end
end
endmodule
divide_by_50.v
module divide_by_50(Q,CLK,RST);
input CLK, RST;
output Q;
reg Q;
reg [4:0] count;
always @ (posedge CLK or negedge RST)
begin
if (~RST)
begin
Q <= 1'b0;
count <= 5'b00000;
end
else if (count < 24)
begin
count <= count+1'b1;
end
else
begin
count <= 5'b00000;
Q <= ~Q;
end
end
endmodule
hex_7seg.v
module hex_7seg(hex_digit,seg);
input [3:0] hex_digit;
output [6:0] seg;
reg [6:0] seg;
// seg = {g,f,e,d,c,b,a};
// 0 is on and 1 is off
always @ (hex_digit)
case (hex_digit)
4'h0: seg = 7'b1000000;
4'h1: seg = 7'b1111001; // ---a----
4'h2: seg = 7'b0100100; // | |
4'h3: seg = 7'b0110000; // f b
4'h4: seg = 7'b0011001; // | |
4'h5: seg = 7'b0010010; // ---g----
4'h6: seg = 7'b0000010; // | |
4'h7: seg = 7'b1111000; // e c
4'h8: seg = 7'b0000000; // | |
4'h9: seg = 7'b0011000; // ---d----
4'ha: seg = 7'b0001000;
4'hb: seg = 7'b0000011;
4'hc: seg = 7'b1000110;
4'hd: seg = 7'b0100001;
4'he: seg = 7'b0000110;
4'hf: seg = 7'b0001110;
endcase
endmodule
one_pulse.v
module one_pulse(pulse_out,trigger_in, clk);
input trigger_in,clk;
output pulse_out;
reg pulse_out, delay;
always @ (posedge clk)
begin
if (trigger_in && !delay) pulse_out <= 1'b1;
else pulse_out <= 1'b0;
delay <= trigger_in;
end
endmodule
clock_divider.v
module clock_divider(CLK,RST,clock);
input CLK,RST;
output [6:0] clock;
wire clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz;
assign clock = {clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz};
divide_by_50 d6(clk_1Mhz,CLK,RST);
divide_by_10 d5(clk_100Khz,clk_1Mhz,RST);
divide_by_10 d4(clk_10Khz,clk_100Khz,RST);
divide_by_10 d3(clk_1Khz,clk_10Khz,RST);
divide_by_10 d2(clk_100hz,clk_1Khz,RST);
divide_by_10 d1(clk_10hz,clk_100hz,RST);
divide_by_10 d0(clk_1hz,clk_10hz,RST);
endmodule
fit.summaryFitter Status : Successful - Wed Jun 13 14:20:26 2007 Quartus II Version : 6.0 Build 178 04/27/2006 SJ Full Version Revision Name : timer Top-level Entity Name : timer_main Family : Cyclone II Device : EP2C35F672C6 Timing Models : Final Total logic elements : 768 / 33,216 ( 2 % ) Total registers : 624 Total pins : 182 / 475 ( 38 % ) Total virtual pins : 0 Total memory bits : 5,120 / 483,840 ( 1 % ) Embedded Multiplier 9-bit elements : 0 / 70 ( 0 % ) Total PLLs : 0 / 4 ( 0 % )
tan.summary-------------------------------------------------------------------------------------- Timing Analyzer Summary -------------------------------------------------------------------------------------- Type : Worst-case tsu Slack : N/A Required Time : None Actual Time : 0.393 ns From : altera_internal_jtag~TMSUTAP To : sld_hub:sld_hub_inst|sld_dffex:IRF_ENA_0|Q[0] From Clock : -- To Clock : altera_internal_jtag~TCKUTAP Failed Paths : 0 Type : Worst-case tco Slack : N/A Required Time : None Actual Time : 48.491 ns From : decimal_counter:count7|A[3] To : HEX7[6] From Clock : CLOCK_50 To Clock : -- Failed Paths : 0 Type : Worst-case tpd Slack : N/A Required Time : None Actual Time : 9.804 ns From : SW[16] To : LEDR[16] From Clock : -- To Clock : -- Failed Paths : 0 Type : Worst-case th Slack : N/A Required Time : None Actual Time : 9.142 ns From : KEY[3] To : sld_signaltap:auto_signaltap_0|acq_trigger_in_reg[38] From Clock : -- To Clock : CLOCK_50 Failed Paths : 0 Type : Clock Setup: 'altera_internal_jtag~TCKUTAP' Slack : N/A Required Time : None Actual Time : 191.20 MHz ( period = 5.230 ns ) From : sld_hub:sld_hub_inst|sld_dffex:\GEN_IRF:1:IRF|Q[3] To : sld_hub:sld_hub_inst|hub_tdo From Clock : altera_internal_jtag~TCKUTAP To Clock : altera_internal_jtag~TCKUTAP Failed Paths : 0 Type : Clock Setup: 'CLOCK_50' Slack : N/A Required Time : None Actual Time : 194.10 MHz ( period = 5.152 ns ) From : decimal_counter:count0|A[3] To : sld_signaltap:auto_signaltap_0|acq_trigger_in_reg[36] From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 0 Type : Clock Hold: 'CLOCK_50' Slack : Not operational: Clock Skew > Data Delay Required Time : None Actual Time : N/A From : decimal_counter:count0|A[0] To : decimal_counter:count0|A[0] From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 148 Type : Total number of failed paths Slack : Required Time : Actual Time : From : To : From Clock : To Clock : Failed Paths : 148 --------------------------------------------------------------------------------------
Maintained by John Loomis, last updated Wed Jun 13 14:28:00 2007