Project: timer

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.

Contents

Verilog Files

timer_main.v
decimal_counter.v
divide_by_10.v
divide_by_50.v
hex_7seg.v
one_pulse.v
clock_divider.v

Quartus Files

fit.summary
tan.summary

Verilog Files

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

Quartus Compilation Summary

fit.summary

Fitter 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