`timescale 1ns/1ns module tone_generator ( input clk, input rst, input output_enable, input [23:0] tone_switch_period, input volume, output square_wave_out ); wire duty; reg [23:0] clk_counter; reg wave; // Assigning volume = 0 to be even quieter. 25% duty cycle was still loud... assign duty = (volume) ? (clk_counter[0] == 0) : (clk_counter[6:0] == 0); assign square_wave_out = (output_enable && duty && (tone_switch_period != 24'd0)) ? wave : 1'b0; always @(posedge clk) begin if (rst) begin clk_counter <= 0; wave <= 0; end else if (clk_counter == tone_switch_period) begin clk_counter <= 0; wave <= ~wave; end else clk_counter <= clk_counter + 1; end endmodule