URL
https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk
Subversion Repositories xulalx25soc
Compare Revisions
- This comparison shows the changes necessary to convert path
/xulalx25soc
- from Rev 7 to Rev 8
- ↔ Reverse comparison
Rev 7 → Rev 8
/trunk/rtl/wbpwmaudio.v
4,10 → 4,52
// |
// Project: A Wishbone Controlled PWM (audio) controller |
// |
// Purpose: |
// |
// Purpose: This PWM controller was designed with audio in mind, although |
// it should be sufficient for many other purposes. Specifically, |
// it creates a pulse-width modulated output, where the amount of time |
// the output is 'high' is determined by the pulse width data given to |
// it. Further, the 'high' time is spread out in bit reversed order. |
// In this fashion, a halfway point will alternate between high and low, |
// rather than the normal fashion of being high for half the time and then |
// low. This approach was chosen to move the PWM artifacts to higher, |
// inaudible frequencies and hence improve the sound quality. |
// |
// The interface supports two addresses: |
// |
// Addr[0] is the data register. Writes to this register will set |
// a 16-bit sample value to be produced by the PWM logic. |
// Reads will also produce, in the 17th bit, whether the interrupt |
// is set or not. (If set, it's time to write a new data value |
// ...) |
// |
// Addr[1] is a timer reload value, used to determine how often the |
// PWM logic needs its next value. This number should be set |
// to the number of clock cycles between reload values. So, |
// for example, an 80 MHz clock can generate a 44.1 kHz audio |
// stream by reading in a new sample every (80e6/44.1e3 = 1814) |
// samples. After loading a sample, the device is immediately |
// ready to load a second. Once the first sample completes, |
// the second sample will start going to the output, and an |
// interrupt will be generated indicating that the device is |
// now ready for the third sample. (The one sample buffer |
// allows some flexibility in getting the new sample there fast |
// enough ...) |
// |
// |
// If you read through the code below, you'll notice that you can also |
// set the timer reload value to an immutable constant by changing the |
// VARIABLE_RATE parameter to 0. When VARIABLE_RATE is set to zero, |
// both addresses become the same, Addr[0] or the data register, and the |
// reload value can no longer be changed--forcing the sample rate to |
// stay constant. |
// |
// |
// Of course, if you don't want to deal with the interrupts or sample |
// rates, you can still get a pseudo analog output by just setting the |
// value to the analog output you would like and then not updating |
// it. In this case, you could also shut the interrupt down at the |
// controller, to keep that from bothering you as well. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
40,7 → 82,7
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 |
parameter DEFAULT_RELOAD = 32'd1814, // about 44.1 kHz @ 80MHz |
//DEFAULT_RELOAD = 32'd2268,//about 44.1 kHz @ 100MHz |
VARIABLE_RATE=0; |
input i_clk; |