Индекс частоты: 0..5 → 0,10,20,30,40,50 Гц english

This commit is contained in:
irobo 2026-05-13 17:32:27 +03:00
parent 8daaf11b02
commit bbd177ba0b

131
blink.v
View File

@ -1,4 +1,5 @@
module blink #( module blink #(
// Input clock frequency in Hz
parameter integer F_CLK = 50_000_000 // 50 MHz parameter integer F_CLK = 50_000_000 // 50 MHz
)( )(
input wire clk, input wire clk,
@ -7,94 +8,96 @@ module blink #(
output wire pin_10 output wire pin_10
); );
//------------------------------------------------------------- //---------------------------------------------------------
// Длительность шага: 0 Гц = 8с, остальные = 4с // Step duration:
//------------------------------------------------------------- // - for 0 Hz : 8 s
localparam integer STEP_4SEC_MAX = (F_CLK * 4) - 1; // - for others : 4 s
localparam integer STEP_8SEC_MAX = (F_CLK * 8) - 1; //---------------------------------------------------------
localparam integer STEP_4SEC_MAX = (F_CLK * 4) - 1;
localparam integer STEP_8SEC_MAX = (F_CLK * 8) - 1;
reg [31:0] sec_cnt = 0; // Step timer counter
reg [31:0] step_cnt = 32'd0;
// Индекс частоты: 0..5 0,10,20,30,40,50 Гц // Frequency index: 0..5 0,10,20,30,40,50 Hz
reg [2:0] freq_idx = 0; reg [2:0] freq_idx = 3'd0;
reg [2:0] freq_idx_prev = 0; // для детекта входа в 0 Гц
// Текущая половина периода в тактах // Half-period counter and current half-period length in clock cycles
reg [31:0] max_count = 32'd0; reg [31:0] blink_cnt = 32'd0;
reg [31:0] max_count = 32'd0;
// Базовый сигнал (до инверсий на выходах) // Base LED signal (before output inversions)
reg led_base = 1'b0; reg led_base = 1'b0;
//------------------------------------------------------------- //---------------------------------------------------------
// Функция пересчёта max_count по freq_idx // Function to calculate half-period in clock cycles
//------------------------------------------------------------- //---------------------------------------------------------
function [31:0] calc_max_count; function [31:0] calc_max_count;
input [2:0] idx; input [2:0] idx;
integer f; integer f;
begin begin
f = idx * 10; // 0,10,20,...,50 Гц // Frequency in Hz: 0, 10, 20, 30, 40, 50
f = idx * 10;
if (f == 0) begin if (f == 0) begin
calc_max_count = 32'd0; // особый случай: 0 Гц // Special case: 0 Hz no blinking
calc_max_count = 32'd0;
end else begin end else begin
// Half-period: F_CLK / (2 * f)
calc_max_count = (F_CLK / (2 * f)) - 1; calc_max_count = (F_CLK / (2 * f)) - 1;
end end
end end
endfunction endfunction
//------------------------------------------------------------- //---------------------------------------------------------
// Счётчик мигания + смена частоты // Main process: step timing, frequency selection,
//------------------------------------------------------------- // blink generation
reg [31:0] cnt = 0; //---------------------------------------------------------
always @(posedge clk) begin
//-----------------------------------------------------
// Step timer: change frequency every 4 or 8 seconds
//-----------------------------------------------------
if (step_cnt >= (freq_idx == 3'd0 ? STEP_8SEC_MAX : STEP_4SEC_MAX)) begin
step_cnt <= 32'd0;
always @(posedge clk) begin // Cycle through 0123450...
// Смена частоты по таймеру
if (sec_cnt >= (freq_idx == 3'd0 ? STEP_8SEC_MAX : STEP_4SEC_MAX)) begin
sec_cnt <= 0;
// сохраняем предыдущий индекс
freq_idx_prev <= freq_idx;
// Цикл по частотам 010203040500...
if (freq_idx == 3'd5) if (freq_idx == 3'd5)
freq_idx <= 0; freq_idx <= 3'd0;
else else
freq_idx <= freq_idx + 1; freq_idx <= freq_idx + 3'd1;
max_count <= calc_max_count(freq_idx == 3'd5 ? 0 : freq_idx + 1);
end else begin end else begin
sec_cnt <= sec_cnt + 1; step_cnt <= step_cnt + 32'd1;
end end
// Одноразовый импульс при входе в режим 0 Гц: //-----------------------------------------------------
// когда freq_idx стало 0, а раньше было не 0 // Recalculate half-period for current frequency
if ((freq_idx == 3'd0) && (freq_idx_prev != 3'd0)) begin //-----------------------------------------------------
// один "щелчок": инвертируем led_base один раз max_count <= calc_max_count(freq_idx);
led_base <= ~led_base;
cnt <= 0; //-----------------------------------------------------
// Blink generation
//-----------------------------------------------------
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 end else begin
// обычное мигание для частот != 0 Гц if (blink_cnt >= max_count) begin
if (max_count == 0) begin blink_cnt <= 32'd0;
// 0 Гц: дальше не мигаем, состояние фиксировано
cnt <= 0;
end else begin
if (cnt >= max_count) begin
cnt <= 0;
led_base <= ~led_base; led_base <= ~led_base;
end else begin end else begin
cnt <= cnt + 1; blink_cnt <= blink_cnt + 32'd1;
end end
end end
end end
end
//------------------------------------------------------------- //---------------------------------------------------------
// Выходы: // Outputs:
// led = инверсия базового, // led = inverted base signal
// pin = как led, // pin = same as led
// pin_10 = инверсия pin // pin_10 = inverted pin
//------------------------------------------------------------- //---------------------------------------------------------
assign led = ~led_base; assign led = ~led_base;
assign pin = led; assign pin = led;
assign pin_10 = pin; assign pin_10 = ~pin;
endmodule endmodule