blob: c8d8afa847efd7b2de744acec6ea1f6dfb413f29 [file] [log] [blame]
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: Wenting Zhang
//
// Create Date: 15:06:53 04/09/2018
// Module Name: sound_wave
// Project Name: VerilogBoy
// Description:
// Sound wave player for channel 3
// Dependencies:
// clk_div, sound_length_ctr
// Additional Comments:
// If Ch3 bugs are to be implemented, they should be probably implemented
// outside of this file. This file does not handle of RW to wave RAM
//////////////////////////////////////////////////////////////////////////////////
module sound_wave(
input rst, // Async reset
input clk, // Main CPU clock
input clk_length_ctr, // Length control clock
input [7:0] length, // Length = (256-t1)*(1/256) second, used iff single is set
input [1:0] volume,
input on,
input single,
input start,
input [10:0] frequency,
output [3:0] wave_a,
input [7:0] wave_d,
output [3:0] level,
output enable
);
wire start_posedge;
edgedet start_edgedet (
.clk(clk),
.i(start),
.o(start_posedge)
);
// Freq = 64kHz / (2048 - frequency)
wire [3:0] current_sample;
reg [4:0] current_pointer = 5'b0;
assign wave_a[3:0] = current_pointer[4:1];
assign current_sample[3:0] = (current_pointer[0]) ?
(wave_d[3:0]) : (wave_d[7:4]);
reg [11:0] divider = 12'b0;
always @(posedge clk)
begin
if (start_posedge) begin
divider <= frequency * 2;
current_pointer <= 5'd0;
end
else begin
if (divider == 12'd4095) begin
if (on) begin
current_pointer <= current_pointer + 1'b1;
end
divider <= frequency * 2;
end
else begin
divider <= divider + 1'b1;
end
end
end
sound_length_ctr #(8) sound_length_ctr(
.clk(clk),
.rst(rst),
.clk_length_ctr(clk_length_ctr),
.start(start),
.single(single),
.length(length),
.enable(enable)
);
assign level = (on) ? (
(volume == 2'b00) ? (4'b0000) : (
(volume == 2'b01) ? (current_sample[3:0]) : (
(volume == 2'b10) ? ({1'b0, current_sample[3:1]}) : (
({2'b0, current_sample[3:2]}))))) : 4'b0000;
endmodule