OpenCores
URL https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [wbpwmaudio.v] - Rev 2

Go to most recent revision | Compare with Previous | Blame | View Log

///////////////////////////////////////////////////////////////////////////
//
// Filename: 	wbpwmaudio.v
//		
// Project:	A Wishbone Controlled PWM (audio) controller
//
// Purpose:	
//		
//
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
///////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
module	wbpwmaudio(i_clk, 
		// Wishbone interface
		i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
			o_wb_ack, o_wb_stall, o_wb_data,
		o_pwm, o_int);
	parameter	DEFAULT_RELOAD = 32'd2268, // about 44.1 kHz @  80MHz
			//DEFAULT_RELOAD = 32'd2268,//about 44.1 kHz @ 100MHz
			VARIABLE_RATE=0;
	input	i_clk;
	input	i_wb_cyc, i_wb_stb, i_wb_we;
	input		i_wb_addr;
	input	[31:0]	i_wb_data;
	output	reg		o_wb_ack;
	output	wire		o_wb_stall;
	output	wire	[31:0]	o_wb_data;
	output	reg		o_pwm;
	output	reg		o_int;
 
 
	// How often shall we create an interrupt?  Every reload_value clocks!
	// If VARIABLE_RATE==0, this value will never change and will be kept
	// at the default reload rate (44.1 kHz, for a 100 MHz clock)
	generate
	if (VARIABLE_RATE != 0)
	begin
		reg	[31:0]	r_reload_value;
		initial	r_reload_value = DEFAULT_RELOAD;
		always @(posedge i_clk) // Data write
			if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr))
				reload_value <= i_wb_data;
		wire	[31:0]	w_reload_value;
		assign	w_reload_value = r_reload_value;
	end else begin
		wire	[31:0]	w_reload_value;
		assign	w_reload_value = DEFAULT_RELOAD;
	end endgenerate
 
	reg	[31:0]	reload_value, timer;
	initial	reload_value = DEFAULT_RELOAD;
	always @(posedge i_clk)
		if (timer == 0)
			timer <= reload_value;
		else
			timer <= timer - 1;
 
	reg	[15:0]	sample_out;
	always @(posedge i_clk)
		if (timer == 0)
			sample_out <= next_sample;
 
 
	reg	[15:0]	next_sample;
	reg		next_valid;
	initial	next_valid = 1'b1;
	initial	next_sample = 16'h8000;
	always @(posedge i_clk) // Data write
		if ((i_wb_cyc)&&(i_wb_stb)&&((~i_wb_addr)||(VARIABLE_RATE==0)))
		begin
			// Write with two's complement data, convert it
			// internally to binary offset
			next_sample <= { ~i_wb_data[15], i_wb_data[14:0] };
			next_valid <= 1'b1;
		end else if (timer == 0)
			next_valid <= 1'b0;
 
	initial	o_int = 1'b0;
	always @(posedge i_clk)
		o_int <= (~next_valid);
 
	reg	[15:0]	pwm_counter;
	initial	pwm_counter = 16'h00;
	always @(posedge i_clk)
		pwm_counter <= pwm_counter + 1;
 
	wire	[15:0]	br_counter;
	genvar	k;
	generate for(k=0; k<16; k=k+1)
	begin
		assign br_counter[k] = pwm_counter[15-k];
	end endgenerate
 
	always @(posedge i_clk)
		o_pwm <= (sample_out < br_counter);
 
	generate
	if (VARIABLE_RATE == 0)
	begin
		assign o_wb_data = { 15'h00, o_int, sample_out };
	end else begin
		reg	[31:0]	r_wb_data;
		always @(posedge i_clk)
			if (i_wb_addr)
				r_wb_data <= reload_value;
			else
				r_wb_data <= { 15'h00, o_int, sample_out };
		assign	o_wb_data = r_wb_data;
	end endgenerate
 
	initial	o_wb_ack = 1'b0;
	always @(posedge i_clk)
		o_wb_ack <= (i_wb_cyc)&&(i_wb_stb);
	assign	o_wb_stall = 1'b0;
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.