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.

[SOLVED] Verilog counter not counting

Status
Not open for further replies.

DocJava

Newbie level 4
Joined
Mar 14, 2017
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
181
Hello, I have a deceptively simple problem with my Verilog code. I've simulated the first module and it appears to work when using blocking assignments in the initial block but not when using non-blocking assignments. When I synthesize the code for a DE2i-150 board I cannot seem to replicate the blinking LED example (Terasic's code doesn't even work within my project, but it works if I use their Quartus project file).

This is the code I'm working with.

heartbeat_driver.v

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
module heartbeat_driver (
    //Inputs
    input clk,
    input reset,
 
    //Outputs
    output wire hb_out
);
    parameter CLOCK_RATE = 50_000_000;
    parameter HB_RATE = 2;
    parameter COUNTER_BITS = 32;
 
    reg [COUNTER_BITS-1:0] counter;
    reg r_out;
 
    initial
        begin
            counter <= 0;
            r_out <= 0;
        end
 
    always @(posedge clk or posedge reset)
        begin
            if (reset)
                begin
                    counter <= 0;
                    r_out <= 0;
                end
            else
                begin
                    counter <= counter + 1;
 
                    //Only flip r_out if the clock delay has been achieved
                    if (counter == (CLOCK_RATE / HB_RATE)) 
                        begin
                            r_out <= ~r_out;
                            counter <= 0;
                        end                
                end
        end
 
    assign hb_out = r_out;
endmodule



Testbench for the first module:

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
`timescale 1ns/1ns
 
module hb_driver_sim;
    reg test_clk;
    reg test_reset;
    wire test_hb;
 
    initial
        begin: CLOCK_INITIALIZATION
            test_clk = 0;
        end
 
    always
        begin: CLOCK_GENERATOR
            #5 test_clk = !test_clk;
        end
        
    initial
        begin        
            test_reset = 0;
            #5
            test_reset = 1;            
            #10
            test_reset = 0;
 
            #10000
            test_reset = 1;
        end
        
    heartbeat_driver dut (
        .clk        (test_clk),
        .reset      (test_reset),
        .hb_out     (test_hb)
    );
    defparam dut.CLOCK_RATE = 10;
    defparam dut.HB_RATE = 1;
 
endmodule



This is the heartbeat code that Terasic provides (which also doesn't work with my project, but it works with their project file):

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
module heart_beat(
    //Inputs
    input clk,
 
    //Outputs
    output led
);
    parameter DUR_BITS = 26;
 
    reg [(DUR_BITS-1):0] cnt;
 
    initial
        begin
            cnt = 0;
        end
    
    always @ (posedge clk)
        begin
            cnt <= cnt + 1;
        end
 
    assign led = cnt[DUR_BITS-1];
endmodule



It's instantiated using this code in the top module file.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
wire hb_50_a;
heartbeat_driver u2 (
    .clk    (CLOCK50),
    .reset  (hex_reset),
    .hb_out (hb_50_a)
);
defparam u2.CLOCK_RATE = 50_000_000;
defparam u2.HB_RATE = 5;
defparam u2.COUNTER_BITS = 32;
 
assign LEDG[0] = hb_50_a;
assign LEDR[0] = hb_50_a;
 
wire hb_50_b;
heart_beat u3 (
    .clk (CLOCK50),
    .led (hb_50_b)
);
assign LEDG[1] = hb_50_b;
assign LEDR[1] = hb_50_b;



Any thoughts on how to fix this and get the LED to blink?

I've verified my project files using the PCI-e connection between the FPGA and Atom chipset on the DE2i. I can write LED values and read the value of switches using a custom kernel driver without too much of a problem (lots of reboots of the HPS involved, somewhat problematic). Therefore I think the clock is working properly, so whatever is broken has to be subtle. Unfortunately I just haven't seen the solution to the issue during my debugging.

I also looked at the counters for both modules in SystemTap and noticed that all the counters are zero even over multiple timesteps.

Respectfully,
DocJava

- - - Updated - - -

After checking the Quartus build logs the LEDs that are supposed to be driven by the counters/heartbeats are stuck at GND with the error message "Output pins are stuck at VCC or GND."
 
Last edited:

Firstly initial statements should not be in synthesizable RTL. They aren't synthesizable in most tools and are ignored. Initial values given on the declaration are synthesized in FPGAs as the default PoR value. The issue you are seeing with the simulation being different with blocking vs. nonblocking in the initial statement should not be the case, I can't reproduce it.

There is an issue with using 50_000_000 for your clock rate, that is interpreted as 50 so your counter is rolling over every 11 clock cycles. If you want to use _'s then write this correctly as 32'd_50_000_000 (a 32-bit decimal value). This makes me wonder if you really tried simulating this (and analyzing the waveforms) or did you just run it and see signals toggling so it must work! :thinker:

You should also place your parameters (at least the ones that need to be changed) in your module port declaration instead of in your code, you are using Verilog 2001 port declarations so why are you using the antiquated and bad defparam. Read the following paper, which gives good reasoning behind not using defparam.

Besides these issues if your counter value is fixed your counter will only toggle at 0.1 seconds (actually slightly more as you will count from 0-to-10,000,000 = 10,000,001 counts), a rate at which I really doubt you'll be able to see it blinking.

- - - Updated - - -

The Terasic code probably uses a divided down clock in the supplied by another file, which you aren't using in your project, so of course you are probably getting a dim flickering ~0.6 second toggling LED.
 
Thanks for pointing this stuff out. I'll take a look at the paper. I did run ModelSim on the code and it produced output that seemed reasonable (see screenshot).

modelsim.png

I swapped over to developing out of the PCIE-Fundamental design example for the DE2i and am seeing inconsistent results when adding essentially an identical heartbeat module to the top module lighting up a different LED. As odd as this may sound, even using essentially the same code as what already works doesn't result in a working module: the LEDs assigned as outputs are "stuck at GND" as per the warning message. Copying Terasic's heartbeat module verbatim into a separate Verilog file and instantiating that did result in positive results in their project (just not when I do that same verbatim copy in my other project).
 

That is not a reasonable toggle rate for an LED 11 10 ns clock periods for each toggle? I think you need to reconsider what you think is reasonable. :-?

About your project problems, you probably have something wrong with your projects selection of pins and or top-level file (if these counters are not the top level file)

You would have to supply more of the project files to get any help with that issue.
 
After looking more carefully at the differences between projects I did find a discrepancy with the input clock name between the two projects. The correct name was CLOCK_50 instead of CLOCK50. Before fixing the name everything still synthesized without any errors (I'm surprised at this). So I think I've fixed the main problem that I was having.

Thanks for the help!
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top