// 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