Search code examples
verilogfpgavivado

Verilog - Register being removed at synthesis


I have a short piece of Verilog that I've written which displays a count on LEDs. I'm getting a warning from Vivado:

[Synth 8-3332] Sequential element (led_reg[3]) is unused and will be removed from module top.

Here is my code:

module top(
input   wire            reset,       //  ACTIVE LOW
input   wire            system_clk_p,//  200MHz DIFFERENTIAL CLOCK
input   wire            system_clk_n,//

//LED
output  reg    [3:0]   led
);

reg counter;
wire reset_p;

assign reset_p = ~reset;

clk_wiz_0 clocks
(
    .clock_200MHz_p(system_clk_p),    // Input Clock 200MHz p
    .clock_200MHz_n(system_clk_n),    // Input Clock 200MHz n
    .clock_125MHz(clock_125MHz),      // Output Clock 125MHz
    .reset(reset_p)
);

always @(posedge clock_125MHz or negedge reset)
begin
    if (!reset)
    begin
        counter <= 0;
        led <= 0;
    end
    else
    begin
        counter <= counter + 1;
        if (counter == 125000000)
        begin
            counter <= 0;
            led <= led + 1;
        end
    end
end

endmodule

I think the register for the LEDs is absolutely required as I'm incrementing the LEDs' value.


Solution

  • Thought I'd post this, as it took me a little while to realise what the issue was, and oftentimes it can be hard to see the wood for the trees:

    The warning was telling me that the LED register had been synthesised out as it was unused; my mistake was thinking that that meant that the led_reg was the issue, it wasn't.

    The issue was that counter was declared as reg counter; which is a single bit wide. Because it's a single bit wide, the biggest number it can count to is 1 before it overflows, meaning it could never reach the intended 125000000 which is where the led output would be needed. As a result, the synthesiser optimised led_reg out as that piece of code was unreachable.

    In order to fix this I declared counter as integer counter; which is wide enough to count up to 125000000.