Индекс частоты: 0..5 → 0,10,20,30,40,50 Гц
This commit is contained in:
parent
87983abfcf
commit
8daaf11b02
121
blink.v
121
blink.v
@ -1,55 +1,100 @@
|
|||||||
module blink #(
|
module blink #(
|
||||||
// Выбор частоты мигания (F_BLINK), Гц:
|
parameter integer F_CLK = 50_000_000 // 50 MHz
|
||||||
// 1 -> 1
|
|
||||||
// 2.5 -> 25 (см. ниже, делим на 10)
|
|
||||||
// 5 -> 5
|
|
||||||
// 10 -> 10
|
|
||||||
parameter integer MODE = 4 // по умолчанию 1 Гц
|
|
||||||
)(
|
)(
|
||||||
input wire clk, // 50 MHz
|
input wire clk,
|
||||||
output reg led,
|
output wire led,
|
||||||
output reg pin,
|
output wire pin,
|
||||||
output reg pin_10
|
output wire pin_10
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam integer F_CLK = 50_000_000;
|
//-------------------------------------------------------------
|
||||||
|
// Длительность шага: 0 Гц = 8с, остальные = 4с
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
localparam integer STEP_4SEC_MAX = (F_CLK * 4) - 1;
|
||||||
|
localparam integer STEP_8SEC_MAX = (F_CLK * 8) - 1;
|
||||||
|
|
||||||
// Предрасчитанные MAX_COUNT для половины периода:
|
reg [31:0] sec_cnt = 0;
|
||||||
//
|
|
||||||
// 1 Гц: T=1 c → T/2=0.5 c → 25_000_000
|
|
||||||
// 2.5 Гц: T=0.4 c → T/2=0.2 c → 10_000_000
|
|
||||||
// 5 Гц: T=0.2 c → T/2=0.1 c → 5_000_000
|
|
||||||
// 10 Гц: T=0.1 c → T/2=0.05 c → 2_500_000
|
|
||||||
|
|
||||||
localparam integer MAX_1HZ = 25_000_000 - 1;
|
// Индекс частоты: 0..5 → 0,10,20,30,40,50 Гц
|
||||||
localparam integer MAX_2_5HZ = 10_000_000 - 1;
|
reg [2:0] freq_idx = 0;
|
||||||
localparam integer MAX_5HZ = 5_000_000 - 1;
|
reg [2:0] freq_idx_prev = 0; // для детекта входа в 0 Гц
|
||||||
localparam integer MAX_10HZ = 2_500_000 - 1;
|
|
||||||
|
|
||||||
// Выбор MAX_COUNT по MODE
|
// Текущая половина периода в тактах
|
||||||
// MODE:
|
reg [31:0] max_count = 32'd0;
|
||||||
// 1 -> 1 Гц
|
|
||||||
// 2 -> 2.5 Гц
|
|
||||||
// 3 -> 5 Гц
|
|
||||||
// 4 -> 10 Гц
|
|
||||||
localparam integer MAX_COUNT =
|
|
||||||
(MODE == 1) ? MAX_1HZ :
|
|
||||||
(MODE == 2) ? MAX_2_5HZ :
|
|
||||||
(MODE == 3) ? MAX_5HZ :
|
|
||||||
(MODE == 4) ? MAX_10HZ :
|
|
||||||
MAX_1HZ; // по умолчанию 1 Гц
|
|
||||||
|
|
||||||
reg [25:0] cnt; // хватает до > 33 млн (2^25 = 33_554_432)
|
// Базовый сигнал (до инверсий на выходах)
|
||||||
|
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
|
always @(posedge clk) begin
|
||||||
if (cnt >= MAX_COUNT) 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;
|
cnt <= 0;
|
||||||
led <= ~led;
|
end else begin
|
||||||
pin <= led;
|
// обычное мигание для частот != 0 Гц
|
||||||
pin_10 <= led;
|
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
|
end else begin
|
||||||
cnt <= cnt + 1;
|
cnt <= cnt + 1;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// Выходы:
|
||||||
|
// led = инверсия базового,
|
||||||
|
// pin = как led,
|
||||||
|
// pin_10 = инверсия pin
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
assign led = ~led_base;
|
||||||
|
assign pin = led;
|
||||||
|
assign pin_10 = pin;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
Loading…
Reference in New Issue
Block a user