module blink #( parameter integer F_CLK = 50_000_000 // 50 MHz )( input wire clk, output wire led, output wire pin, output wire pin_10 ); //------------------------------------------------------------- // Длительность шага: 0 Гц = 8с, остальные = 4с //------------------------------------------------------------- localparam integer STEP_4SEC_MAX = (F_CLK * 4) - 1; localparam integer STEP_8SEC_MAX = (F_CLK * 8) - 1; reg [31:0] sec_cnt = 0; // Индекс частоты: 0..5 → 0,10,20,30,40,50 Гц reg [2:0] freq_idx = 0; reg [2:0] freq_idx_prev = 0; // для детекта входа в 0 Гц // Текущая половина периода в тактах reg [31:0] max_count = 32'd0; // Базовый сигнал (до инверсий на выходах) reg led_base = 1'b0; //------------------------------------------------------------- // Функция пересчёта max_count по freq_idx //------------------------------------------------------------- function [31:0] calc_max_count; input [2:0] idx; integer f; begin f = idx * 10; // 0,10,20,...,50 Гц if (f == 0) begin calc_max_count = 32'd0; // особый случай: 0 Гц end else begin calc_max_count = (F_CLK / (2 * f)) - 1; end end endfunction //------------------------------------------------------------- // Счётчик мигания + смена частоты //------------------------------------------------------------- reg [31:0] cnt = 0; always @(posedge clk) begin // Смена частоты по таймеру if (sec_cnt >= (freq_idx == 3'd0 ? STEP_8SEC_MAX : STEP_4SEC_MAX)) begin sec_cnt <= 0; // сохраняем предыдущий индекс freq_idx_prev <= freq_idx; // Цикл по частотам 0→10→20→30→40→50→0... if (freq_idx == 3'd5) freq_idx <= 0; else freq_idx <= freq_idx + 1; max_count <= calc_max_count(freq_idx == 3'd5 ? 0 : freq_idx + 1); end else begin sec_cnt <= sec_cnt + 1; end // Одноразовый импульс при входе в режим 0 Гц: // когда freq_idx стало 0, а раньше было не 0 if ((freq_idx == 3'd0) && (freq_idx_prev != 3'd0)) begin // один "щелчок": инвертируем led_base один раз led_base <= ~led_base; cnt <= 0; end else begin // обычное мигание для частот != 0 Гц if (max_count == 0) begin // 0 Гц: дальше не мигаем, состояние фиксировано cnt <= 0; end else begin if (cnt >= max_count) begin cnt <= 0; led_base <= ~led_base; end else begin cnt <= cnt + 1; end end end end //------------------------------------------------------------- // Выходы: // led = инверсия базового, // pin = как led, // pin_10 = инверсия pin //------------------------------------------------------------- assign led = ~led_base; assign pin = led; assign pin_10 = pin; endmodule