pong-verilog/beep.v
2025-11-04 22:47:49 +01:00

104 lines
1.4 KiB
Verilog

module beep #(
parameter HIT_PERIOD = 1,
parameter HIT_LEN = 150,
parameter MISS_PERIOD = 3,
parameter MISS_LEN = 1400,
parameter HALF_MS_DIV = 500
)(
input wire clk,
input wire rst,
input wire hit,
input wire miss,
output reg beep
);
reg [8:0] cntr;
always @(posedge clk)
begin
if (rst)
begin
cntr <= 9'd0;
end
else
begin
if (cntr != (HALF_MS_DIV - 1))
begin
cntr <= cntr + 9'd1;
end
else
begin
cntr <= 9'd0;
end
end
end
wire tc = (cntr == (HALF_MS_DIV - 1));
reg [3:0] period;
reg [3:0] subperiod_cntr;
always @(posedge clk)
begin
if (rst || (!sound_playing))
begin
beep <= 1'b0;
subperiod_cntr <= 4'd0;
end
else if (sound_playing && tc)
begin
if (subperiod_cntr != period)
begin
subperiod_cntr <= subperiod_cntr + 4'd1;
end
else
begin
subperiod_cntr <= 4'd0;
beep <= ~beep;
end
end
end
reg sound_playing;
reg [10:0] len;
always @(posedge clk)
begin
if (rst)
begin
sound_playing <= 1'b0;
len <= 11'd0;
period <= 4'd0;
end
else if ((!sound_playing) && (hit || miss))
begin
if (hit)
begin
period <= HIT_PERIOD;
len <= HIT_LEN;
end
else if (miss)
begin
period <= MISS_PERIOD;
len <= MISS_LEN;
end
sound_playing <= 1'b1;
end
else if (sound_playing && tc)
begin
if (len != 10'd0)
begin
len <= len - 10'd1;
end
else
begin
sound_playing <= 1'b0;
end
end
end
endmodule