Quartus_blink/blink.v

122 lines
4.1 KiB
Verilog

module blink #(
// Input clock frequency in Hz
parameter integer F_CLK = 50_000_000 // 50 MHz
)(
input wire clk,
output wire led,
output wire pin,
output wire pin_10
);
//---------------------------------------------------------
// Step duration:
// - for 0.5 Hz : 2 s
// - for others : 4 s
//---------------------------------------------------------
localparam integer STEP_2SEC_MAX = (F_CLK * 2) - 1;
localparam integer STEP_4SEC_MAX = (F_CLK * 4) - 1;
// Step timer counter
reg [31:0] step_cnt = 32'd0;
// Frequency index: 0..5 → 0, 10, 20, 30, 40, 50 Hz
reg [2:0] freq_idx = 3'd0;
// Half-period counter and current half-period length in clock cycles
reg [31:0] blink_cnt = 32'd0;
reg [31:0] max_count = 32'd0;
// Base LED signal (before output inversion)
reg led_base = 1'b0;
//---------------------------------------------------------
// 1 Hz generator for pin: divider from F_CLK
// Period 1 Hz = 1 s, half-period = 0.5 s
//---------------------------------------------------------
localparam integer PIN_1HZ_HALF_MAX = (F_CLK / 2) - 1;
reg [31:0] pin_cnt = 32'd0;
reg pin_base = 1'b0;
//---------------------------------------------------------
// Function to calculate half-period in clock cycles
//---------------------------------------------------------
function [31:0] calc_max_count;
input [2:0] idx;
integer f;
begin
// Frequency in Hz: 0, 10, 20, 30, 40, 50
f = idx * 10;
if (f == 0) begin
// Special case: 0 Hz → no blinking
calc_max_count = 32'd0;
end else begin
// Half-period: F_CLK / (2 * f)
calc_max_count = (F_CLK / (2 * f)) - 1;
end
end
endfunction
//---------------------------------------------------------
// Main process: step timing, frequency selection,
// blink generation
//---------------------------------------------------------
always @(posedge clk) begin
//-----------------------------------------------------
// Step timer: change frequency every 2 or 4 seconds
//-----------------------------------------------------
if (step_cnt >= (freq_idx == 3'd1 ? STEP_2SEC_MAX : STEP_4SEC_MAX)) begin
step_cnt <= 32'd0;
// Cycle through 0→1→2→3→4→5→0...
if (freq_idx == 3'd5)
freq_idx <= 3'd0;
else
freq_idx <= freq_idx + 3'd1;
end else begin
step_cnt <= step_cnt + 32'd1;
end
//-----------------------------------------------------
// Recalculate half-period for current frequency
//-----------------------------------------------------
max_count <= calc_max_count(freq_idx);
//-----------------------------------------------------
// Blink generation for led
//-----------------------------------------------------
if (max_count == 32'd0) begin
// 0 Hz: hold current state, no blinking
blink_cnt <= 32'd0;
// led_base keeps its last value
end else begin
if (blink_cnt >= max_count) begin
blink_cnt <= 32'd0;
led_base <= ~led_base;
end else begin
blink_cnt <= blink_cnt + 32'd1;
end
end
//-----------------------------------------------------
// 1 Hz generation for pin (independent of freq_idx)
//-----------------------------------------------------
if (pin_cnt >= PIN_1HZ_HALF_MAX) begin
pin_cnt <= 32'd0;
pin_base <= ~pin_base;
end else begin
pin_cnt <= pin_cnt + 32'd1;
end
end
//---------------------------------------------------------
// Outputs:
// led = inverted base signal (variable frequency)
// pin = 1 Hz
// pin_10 = inverted pin
//---------------------------------------------------------
assign led = ~led_base;
assign pin = pin_base;
assign pin_10 = led;
endmodule