Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Verilog - FPGA - Need help creating a minute and second counter

Status
Not open for further replies.

d_rose_davidson

Newbie level 4
Joined
Nov 22, 2015
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
113
Hey there, I'm doing a Verilog project where I need to use a 7 segment display to display the seconds and minutes of a timer. I'm using the Digilent NEXYS4DDR Artix 7 FPGA board.
My code (shown below) gives me the minutes and seconds appropriately, but I dont quite know how to implement them on the FGPA board. Also, I dont really know to get binary into BCD.

My project is supposed to work as follows: Theres 5 buttons on the board, I press one (S) and it starts the count, 1 second per, and then I press the second button (R) and it resets. Yet it may be better to have R be a button that holds the value, and then S will start and reset the timer.

Here is my code. I commented the beginning of the 7 segment display because it affected my synthesis. Any help is appreciated


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
module Timer(
     );
    reg Q,clock,S,R;
    integer Cnansec = 0;
    integer Csec = 0;
    integer Cmin = 0;
    initial begin
    S = 0;
    R = 0;
    clock = 0;
    Q = 0;
    end
    
    always @(*)
        #1 clock <= ~clock;
        
    always@(S, R, clock) begin 
    if (clock) begin
        if (S == 1 && R == 0) begin
        Q = 1;
        end
        else if (S == 0 && R == 1) begin
        Q = 1'b0;
        end
     end
    end
    
    
    always @(clock)begin
    Cnansec = Cnansec + 1;
    
        if(R != 1)begin
            if(Csec == 59 && Cnansec == 1000000000)begin
                Cmin = Cmin + 1;
                Csec = 0;
                Cnansec = 0; 
            end
            else if (Cnansec == 1000000000) begin
                Csec = Csec + 1; 
                Cnansec = 0;   
            end
            
       
        end
    
    if (S)begin
    Cnansec = 0;
    Cmin = 0;
    Csec = 0;    
    end   
    end
    
    
    always @(clock) begin
    #1 S = 1; R = 0;
    #10 S=0; R=0;
    #100000 S = 0; R = 1;
    
    
    
    end
    
    
//    output reg [0:6] seg;
//    output [0:7] an;
        
//        assign an = 8'b0111_1111;
//        always @(*) 
           
//           begin
//           case(seg)
//             0:seg = 7'b0000001; 
//             1:seg = 7'b1001111;
//             2:seg = 7'b0010010;
//             3:seg = 7'b0000110;
//             4:seg = 7'b1001100;
//             5:seg = 7'b0100100;
//             6:seg = 7'b0100000;
//             7:seg = 7'b0001111;
//             8:seg = 7'b0000000;
//             9:seg = 7'b0000100;
//             10:seg = 7'b0001000;
//             11:seg = 7'b1100000;
//             12:seg = 7'b0110001;
//             13:seg = 7'b1000010;
//             14:seg = 7'b0110000;
//             15:seg = 7'b0111000;
//             endcase
//             end
    
    
    
    
endmodule

 
Last edited by a moderator:

There are two main problems here:

1. Your code is not synthesisable. You have used delay # statements to generate signals, which are only used in simulation.
2. Your design has no inputs or outputs. How do you expect it to work on an FPGA?

Your clock should be an input to your timer module. If you need to generate a clock - it will come in from an external source (a crystal or a DCM)
 

Internal clock generation and external signals constitute the code as a test bench, useful simulation only, as stated.

The bad point is that also the internal counter code isn't written in a synthesizable style which would require clock edge sensitive always statements.
 

Hi,

While it makes no difference with the FPGA, I wonder why you write the "minutes" before the "seconds".
As well as in the title as in the code.

If you want seconds and minutes in BCD, from a 1GHz clock (at least your code makes me assume this) then try this:
You have secondsUnit, secondsTens, minutesUnit and minutesTens.
Count pulses then increment secondsUnit 0..9
When secondsUnit= 10, then set it to zero and increment secondsTens 0..5
When secondTens = 6 then set it zero and increment minutesUnit 0..9
When minutesUnit= 10, then set it zero and increment minutesTens 0..5
And so on

Klaus
 

Hi,

While it makes no difference with the FPGA, I wonder why you write the "minutes" before the "seconds".
As well as in the title as in the code.

If you want seconds and minutes in BCD, from a 1GHz clock (at least your code makes me assume this) then try this:
You have secondsUnit, secondsTens, minutesUnit and minutesTens.
Count pulses then increment secondsUnit 0..9
When secondsUnit= 10, then set it to zero and increment secondsTens 0..5
When secondTens = 6 then set it zero and increment minutesUnit 0..9
When minutesUnit= 10, then set it zero and increment minutesTens 0..5
And so on

Klaus

Thank you, that makes a lot of sense, minutesTens would go on the 1st 7 segment, then minutesUnit, secondsTens, and lastly secondsUnit. I'm still not clear on how to put these values into the 7 segment display. Do I need to convert binary to BCD? And any idea how?
 

Fixed the code to include the 10s place for minutes and seconds, thank you for that.

As of now, I'm just trying to get the 7 segment to display seconds 0-9 with 1 second in between, but it keeps giving me the error that my clock is not defined, and it being non-net which I'm unclear of. In addition to that, I don't know how to make the counter go up 1 every second, I believe its called a delay but I haven't found a good site online that explains it well or what to do well enough for me to implement it correctly.
After I do this correctly, I believe I can do the rest. Thanks in advance if you can help me out



Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
//////////////////////////////////////////////////////////////////////////////////
 
 
module timer(
     );
    input clock;
    input S,R;
    integer Cnansec = 0;
    integer Csec = 0;
    integer Csec10s = 0;
    integer Cmin = 0;    
    integer Cmin10s = 0;
    reg clock;
    reg S, R;
   
 
    always @(*) begin
       #1 clock <= ~clock;
       end
        
 
    
    
    always @(clock, R, S)begin
    Cnansec = Cnansec + 1;
    
        if(R != 1 && S == 1)begin
            if (Cnansec == 1000000000) begin
                Csec = Csec + 1; 
                Cnansec = 0;
                if (Csec == 9) begin
                    Csec10s = Csec10s + 1;
                    Csec = 0;
                        if (Csec10s == 6) begin
                            Cmin = Cmin + 1;
                            Csec10s = 0;
                                if (Cmin == 9) begin
                                    Cmin10s = Cmin10s + 1;
                                    Cmin = 0;
                                end
                        end
                 end
          end
          else begin
          Csec = 0;
          Cmin = 0;
          Csec10s = 0;
          Cmin10s = 0;
          end
       end
         
         
    if (R)begin
    Cnansec = 0;
    Cmin = 0;
    Csec = 0;    
    end   
    end
   
    
    
 
     output reg [0:6] seg;
       output [0:7] an;
      
       
           assign an = 8'b0111_1111;
          
       always @(*) 
          
          begin
          case(Csec)
            0:seg = 7'b0000001; 
            1:seg = 7'b1001111;
            2:seg = 7'b0010010;
            3:seg = 7'b0000110;
            4:seg = 7'b1001100;
            5:seg = 7'b0100100;
            6:seg = 7'b0100000;
            7:seg = 7'b0001111;
            8:seg = 7'b0000000;
            9:seg = 7'b0000100;
            10:seg = 7'b0001000;
            11:seg = 7'b1100000;
            12:seg = 7'b0110001;
            13:seg = 7'b1000010;
            14:seg = 7'b0110000;
            15:seg = 7'b0111000;
            endcase
            end
    
    
 
    
    
    
    
endmodule

 
Last edited by a moderator:

Hi,

What is your external clock source frequency?
Do you generate internally a new clock? What frequency, how?

Klaus
 

You need to learn the Verilog language structure before writing any code.

You have numerous problems and I'm not a Verilog instructor. You need to read online tutorials on how to write code. As you are going to implement this in a device using a vendors tools you need to understand how to write synthesizable Verilog.

1. Put your inputs and outputs between the "()", i.e.: module timer (put inputs and outputs here);
2. don't define things as integers unless they are really just integers for indexing something. Integers are 32-bit and will result in 32-bit wide logic. Instead use reg [the_msb:the_lsb] some_bus;.
3. A FF is described using always @(posedge clock) ... Go read a tutorial!
4. Why are you generating a HEX display of the number when you are trying to make a decimal output display it a waste of resources, that will never get used.\
5. Trying to implement both a Set and a Reset on a FF will result in a non optimal design that will have extra logic inserted to implement both the Set and reset. Use either a Set OR a Reset NOT both.
6. Using separate if statements for the functional output vs the reset output may result in multiple drivers errors for the signal assignment depending on how smart/good the synthesis tool is. Cnansec, Cmin, and Csec all suffer from this problem where you have a separate if for the reset. Use an if-else if-else type structure (have you ever programmed in C etc?).
7. You can't use # in synthesizable code, it doesn't do anything except possibly cause simulation gotchas due to changing the scheduling of events. You don't generate a clock in your module you generate it outside the module in a testbench (do you even know what a testbench is?)
8. The intention is to have FFs in the always @(clock, R, S) block, therefore coding with = (blocking) assignments is incorrect. Use <= (non-blocking) assignments to model FFs.
9. You should have a drawing of what you are trying to design, so you don't write random spaghetti code that has not been designed. Hacking is for people who like to spend gobs of time in the lab debugging obvious mistakes that would have been caught if the system was designed up front. Keep in mind Verilog is a hardware description language, so you should know what hardware you want before you write any code!
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top