// hello.v -- the smallest useful synthesizable design: blink one LED. // // The LED toggles once every CLK_HZ/(2*BLINK_HZ) clocks, so the observed blink rate is BLINK_HZ. // Plain counter, no PLL, no vendor primitive, no initial block: this drops into any flow. `default_nettype none `timescale 1ns/1ps module hello #( parameter integer CLK_HZ = 50_000_000, // input clock in Hz parameter integer BLINK_HZ = 1 // wanted blink rate in Hz ) ( input wire clk, input wire rst_n, output reg led ); // clocks in one half period; the counter counts down to 0 and reloads localparam integer HALF = CLK_HZ / (2 * BLINK_HZ); // bits needed to hold HALF-1 localparam integer CW = (HALF <= 2) ? 1 : $clog2(HALF); // reload value: take HALF in the counter's own width so nothing is truncated // verilog_lint: waive explicit-parameter-storage-type localparam [CW-1:0] RELOAD = HALF[CW-1:0] - 1'b1; reg [CW-1:0] cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin cnt <= RELOAD; led <= 1'b0; end else if (cnt == {CW{1'b0}}) begin cnt <= RELOAD; led <= ~led; end else begin cnt <= cnt - 1'b1; end end endmodule `default_nettype wire