82 lines
2.6 KiB
Verilog
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 |