Search code examples
verilogcounterquartus8-bitcyclone

Why is my 8-bit counter stuck at 0 or 255?


I am trying to write some simple Verilog code for practice reasons. I am using the FPGA Cyclone 4. My 8-bit counter works fine with the on-board clock (50MHz), but it's way too fast to see the LEDs at that speed, so I tried first to slow the clock with this:

module enableCounter(
    input clock_5,
    input reset,
    output reg enable_out);

    reg [3:0] counter;

    always @(posedge clock_5) begin
        if (reset) begin
            counter <= 4'b0000;
        end 
        else begin
            counter <= counter + 1;
            if (counter == 4'b0000)
                enable_out <= 1;
            else
                enable_out <= 0;
        end
    end

endmodule

Technically this would set the enable_out output to 1 only 8th of clock_5 time. To count Up and Down I wrote also this function:

module updown_counter(
    input up_down,
    input clk,
    input enable,
    input reset,

    output reg [7:0] count_out);
    
    always @ (posedge clk) begin
        if (up_down == 0) begin                 // Count UP
            if (reset)
                count_out <= 8'b0000_0000;
            else if (enable && count_out == 8'b1111_1111)
                count_out <= 8'b0000_0000;
            else if (enable && count_out != 8'b1111_1111)
                count_out <= count_out + 8'b0000_0001;
            else
                count_out <= count_out;
        end
        
        else if (up_down == 1) begin            // Count DOWN
            if (reset)
                count_out <= 8'b1111_1111;
            else if (enable && count_out == 8'b0000_0000)
                count_out <= 8'b1111_1111;
            else if (enable && count_out != 8'b0000_0000)
                count_out <= count_out - 8'b0000_0001;
            else
                count_out <= count_out;
        end
    end            
endmodule

There is no compilation error. The 8 LEDs (connected to count_out) are off and turn all on, when I press the button for reset. I also tried changing some value like the up_down direction, just to check if its a button fault, but it did the opposite, which indicates, that there's a bug in my program (I guess?)

Edited: Using .bdf in Quartus, the connection from on-board clock to pll-block and then to the modules is shown here: enter image description here


Solution

  • from personal experience: everytime I try to skip the testbench/sim part I pay dearly. Just happend so last week.

    Anyhow, even 50/16 = 3.125 MHz is still pretty fast. If you have a 8 bit counter it would result in 50 MHz/16/256 ≈ 12 kHz for the slowest bit, if I am not mistaken. At least my sight is limited to several Hz changes at best. Btw, your resulting clock will be highly unbalanced (20 ns to 300 ns on-off-time), which is often not really desired.

    TL;DR: check the resulting frequencies. You most likely have to divide the clock even further down to see changes. Right now the current update rates will result only in dimming of the LEDs.

    EDIT:

    here a scrambled sim and the result - the LEDs should be toggling but way too fast to see it except for a dimming effect.

    `timescale 1 ns / 1 ns
    
    // Define Module for Test Fixture
    module main_tf();
    
    reg         clock_in;
    reg         nrst;
    wire        clock_en;
                        
    // Instantiate the UUT - normally the main
    updown_counter updown_counter_inst0(    
        .reset(~nrst),
        .clk(clock_in),
        .up_down(1'b1),
        .enable(clock_en)
        );
    
    enableCounter enableCounter_inst1(
        .reset(~nrst),
        .clock_5(clock_in),
        .enable_out(clock_en)
        );
    
    
    // Initialize Inputs
    initial begin 
        clock_in = 0;
        nrst = 1;
        #5 nrst = 0;  
        #20 nrst = 1;  
    end
        
    always begin                            
        #20 clock_in = ~clock_in;      //magic happens here
    end
    
    endmodule // main_tf
    

    enter image description here