`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Universität des Saarlandes
// Engineer: Erik Endres
// 
// Create Date:    10:46:08 09/19/2007 
// Design Name: 	 
// Module Name:    Buzzer 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: A 1000 Hz Buzzer. Enabled by a write access for <data_i> cycles.
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

`include "defines.v"

module Buzzer(clk_i, reset_i, Breq_i, WR_i, addr_i, data_i, reqp_o, Brdy_o, buzzer_o);

	input clk_i, reset_i;
	input Breq_i, WR_i;
	input [31:0] addr_i;
	input [31:0] data_i;
	
	output reqp_o, Brdy_o;
	output buzzer_o;
	
	reg [1:0] bstate;
	reg [31:0] buz_en = 0;
	reg buz_sig = 0;
	reg [12:0] clk_cnt = 0;
	
	wire myreq;

	parameter ba= `BUZ_BASE_ADDR;
	parameter freq2_dv = 8192;

	parameter bs_idle = 3'd0;
	parameter bs_wait = 3'd1;
	parameter bs_ack	= 3'd2;
	parameter bs_next = 3'd3;


	assign myreq=Breq_i && WR_i && (addr_i == ba);
	assign reqp_o=(myreq || bstate==bs_wait)?1:bstate==bs_ack?0:1'bz;
	assign Brdy_o=(myreq || bstate==bs_wait)?0:bstate==bs_ack?1:1'bz;
	assign buzzer_o = (buz_en != 32'h0)?buz_sig:1'hz;

	always @(posedge clk_i or posedge reset_i) begin
		if (reset_i) begin
			bstate<=bs_idle;
			clk_cnt <= 0;
			buz_en <= 32'h0;
		end
		else begin
			case (bstate)
				bs_idle: begin
					if (buz_en != 32'h0) buz_en <= buz_en -1;
					if (myreq)
						bstate<=bs_wait;
				end
				bs_wait: begin
					buz_en <= data_i;
					bstate<=bs_ack;
				end
				bs_ack:
					bstate<=bs_next;
				bs_next:
					bstate<=bs_idle;
			endcase
			if (clk_cnt == 0)
				buz_sig <= !buz_sig;
			clk_cnt <= clk_cnt - 1;
		end
	end

endmodule
