+ Post New Thread
Results 1 to 5 of 5
  1. #1
    Newbie level 4
    Points: 51, Level: 1

    Join Date
    Mar 2017
    Posts
    7
    Helped
    0 / 0
    Points
    51
    Level
    1

    Verilog counter not counting

    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 by DocJava; 14th March 2017 at 13:45.

    •   Alt14th March 2017, 14:32

      advertising

        
       

  2. #2
    Super Moderator
    Points: 27,402, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,242
    Helped
    1524 / 1524
    Points
    27,402
    Level
    40

    Re: Verilog counter not counting

    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!

    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.


    1 members found this post helpful.

    •   Alt14th March 2017, 16:01

      advertising

        
       

  3. #3
    Newbie level 4
    Points: 51, Level: 1

    Join Date
    Mar 2017
    Posts
    7
    Helped
    0 / 0
    Points
    51
    Level
    1

    Re: Verilog counter not counting

    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).

    Click image for larger version. 

Name:	modelsim.png 
Views:	2 
Size:	69.6 KB 
ID:	136931

    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).



    •   Alt14th March 2017, 16:08

      advertising

        
       

  4. #4
    Super Moderator
    Points: 27,402, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,242
    Helped
    1524 / 1524
    Points
    27,402
    Level
    40

    Re: Verilog counter not counting

    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.


    1 members found this post helpful.

  5. #5
    Newbie level 4
    Points: 51, Level: 1

    Join Date
    Mar 2017
    Posts
    7
    Helped
    0 / 0
    Points
    51
    Level
    1

    Re: Verilog counter not counting

    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!



--[[ ]]--