Logic2_to_FPGA/pattern_player.v
2026-06-01 06:19:27 +03:00

82 lines
2.6 KiB
Verilog

// pattern_player.v
// Проигрывает один раз последовательность сегментов из pattern_rom.
module pattern_player #(
parameter TICKS_WIDTH = 32,
parameter DEPTH = 128
)(
input wire clk,
input wire rst,
input wire start, // 1 → начать воспроизведение
output reg out, // выход на пин
output reg busy // 1, пока идёт воспроизведение
);
// Адрес в ROM
reg [$clog2(DEPTH)-1:0] addr;
// Текущие {level, ticks}
reg [TICKS_WIDTH:0] cur_data;
reg [TICKS_WIDTH-1:0] ticks_cnt;
wire [TICKS_WIDTH:0] rom_data;
// Экземпляр ROM (Автогенерированный pattern_rom.v от Python-скрипта)
pattern_rom #(
.TICKS_WIDTH(TICKS_WIDTH),
.DEPTH(DEPTH)
) rom_inst (
.addr(addr),
.data(rom_data)
);
// Простая машина состояний
localparam IDLE = 2'd0;
localparam LOAD = 2'd1;
localparam RUN = 2'd2;
reg [1:0] state;
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE;
addr <= 0;
ticks_cnt <= 0;
out <= 0;
busy <= 0;
end else begin
case (state)
IDLE: begin
busy <= 0;
if (start) begin
addr <= 0;
state <= LOAD;
busy <= 1;
end
end
LOAD: begin
cur_data <= rom_data;
out <= rom_data[TICKS_WIDTH]; // уровень
ticks_cnt <= rom_data[TICKS_WIDTH-1:0]; // длительность
state <= RUN;
end
RUN: begin
if (ticks_cnt == 0) begin
if (addr == DEPTH - 1) begin
// Проиграли все сегменты один раз → назад в IDLE
state <= IDLE;
end else begin
addr <= addr + 1;
state <= LOAD;
end
end else begin
ticks_cnt <= ticks_cnt - 1;
end
end
endcase
end
end
endmodule