Code: [Select]sample_pulse <= ( I2S_counter == 0 ) ; // Pulse the output reference sample clock.
Just a quick question about the quoted line of code above. Would the following also be a valid method of testing for a zero value?Code: [Select]sample_pulse <= ( !I2S_counter ) ;
And if so, which would be best and why?
if ( I2S_counter == 0 ) begin
DAC_right_buffer <= DAC_Right ; // Keep a copy of the Right channel data to be transmitted during the second half.
// This was done to make sure both left and right channel data are captured in parallel on the same clock.
DAC_serial_buffer <= DAC_Left ; // Transfer the left channel for immediate transmission.
end else if ( I2S_counter == 32 ) begin
DAC_serial_buffer <= DAC_right_buffer ; // Transfer the right channel's sample for immediate transmission.
end else begin
DAC_serial_buffer <= DAC_serial_buffer << 1 ; // Left shift the serial out data.
end
sample_pulse <= ( I2S_counter == 63 ) ; // Pulse the output reference sample clock.
Now, say we want 3 dacs in our system, a cheap 16 bit one with a headphone output and a 20 bit line level one and 24 bit for the HDMI, all with the same sound. Notice how the MSB is at the beginning. What would happen if we feed all 3 digital sources the same signal, all expecting 32 clocks per channel, but each outputting the most bits they can?
localparam bit QUICK_SIM = 0 ; // When running long simulations, turning this on will multiply the sim speed.
localparam CLK_PSG_HZ = 1789000 ; // PSG of simulated clock
localparam CLK_I2S_HZ = 3072000 ; // I2S bit clock rate of simulated clock
localparam CLK_IN_HZ = QUICK_SIM ? CLK_PSG_HZ : 100000000 ; // Select operating frequency of simulation.
localparam CLK_PERIOD = 1000000000/CLK_IN_HZ ; // Period of simulated clock.
localparam CMD_COUNT = 8 ; // Number of commands to send to PSG.
localparam ENDTIME = (1000 * 1000 * 10) + 20 ; // Number of ns to stop simulation at.
wire sample_stb ; // A new strobe for when the sample is ready.
// Instantiate PSG
BHG_jt49 #(
.DAC_BITS ( DAC_BITS ),
.VOL_ATT_DB ( VOL_ATT_DB )
) PSG (
.rst_n ( reset ),
.clk ( clk ),
.clk_en ( p_stb ),
.addr ( addr[step] ),
.cs_n ( 1'b0 ),
.wr_n ( wr_n ),
.din ( data[step] ),
.sel ( 1'b1 ),
.dout ( dout ),
.sound ( sound_mix ),
.A ( ),
.B ( ),
.C ( ),
.sample ( sample_stb ),
.IOA_in ( ),
.IOA_out ( ),
.IOB_in ( ),
.IOB_out ( )
);
jt49_dcrm2 #(
.sw ( DAC_BITS+2 )
) PSG_DCFILT (
.clk ( clk ),
.cen ( sample_stb ),
.rst ( ~reset ),
.din ( sound_mix ),
.dout ( sound )
);
So I need to wire the sine table to the HDMI serialiser to make sure that's working okay? In simulation or actual HDL? Or wire the sine table through the new filters in place of the PSG output and test that in simulation?
Sorry for the confusion, I've only got small pockets of time to work on this this week so I probably need a little more basic instruction than usual.
I'm marvelling at what you've done with the filters, the simulation output and trying to get my head around all these audio-related terms, and failing miserably. Then I realised I need to be doing something...
You don't need to sim, just wire the sine table to the i2s transmitter in a test hdmi out project to see if you get the clean tone.
Dont forget to get rid of the audio pll and use the fp_div, and, the sine's input .clk_ena() needs to be the (fp_strobe && i2s_sample_pulse) so it only increments once every 48khz sample.
fp_div #(
.INPUT_CLK_HZ ( 100000000 ),
.OUTPUT_CLK_HZ ( 3072000 ),
.USE_FLOATING_DIVIDE ( 1 )
) fp_div_i2s (
.clk_in ( CLK_IN ),
.clk_out ( i2s_3072k ),
.strobe_out ( i2s_stb )
);
// ***************************************************************************************************************
// Test Sine Wave Table Generator
// ***************************************************************************************************************
wire [15:0] aud_test ;
Sine_1KHz_16b_48ksps test_audio(
.clk ( CLK_IN ),
.clk_ena ( (i2s_stb && i2s_sample_pulse) ),
.audio ( aud_test )
);
// ***************************************************************************************************************
// HDMI Audio I2S interface
// ***************************************************************************************************************
audio_i2s u_AVG(
//.clk ( pll_1536k ),
.clk ( i2s_3072k ),
.reset_n ( !RST_IN ),
//.audio_i ( aud_16_o ),
.audio_i ( aud_test ),
.sclk ( HDMI_SCLK ),
.lrclk ( HDMI_LRCLK ),
.i2s ( HDMI_I2S )
);
You don't need to sim, just wire the sine table to the i2s transmitter in a test hdmi out project to see if you get the clean tone.
Dont forget to get rid of the audio pll and use the fp_div, and, the sine's input .clk_ena() needs to be the (fp_strobe && i2s_sample_pulse) so it only increments once every 48khz sample.
Uh, still lost on this. Instead of messing about creating a new project, I'm just using the existing GPU_DECA project and tweaking the GPU_DECA_DDR3_top file to get this sine wave table set up.
I've gotten rid of u_sys_pll which produced the pll_1536k signal and replaced it with an fp_div instance. Does this need to output the 1536k clock signal or a 3072k one? Will I need to change the HDMI transmitter's mode at all if I switch to a double-speed clock for the audio_i2s module?
I'm guessing I need another fp_div to create a 48k clock signal to feed a strobe to the clk_ena input of the sine table module?
I'm probably going to give up on this today - I might have some time tomorrow, but I clearly can't put the time into this right now to understand what I need to be doing.
// ------------------------------------------------------------------------------------------------------------
// -------- This little bit is a give-me, I did not expect you to work this out nor is it needed to test ------
// ------------------------------------------------------------------------------------------------------------
localparam DDR3_CLK_HZ = (CLK_KHZ_IN*CLK_IN_MULT/CLK_IN_DIV*1000); // Calculate the DDR3 hz speed.
localparam CMD_CLK_HZ = INTERFACE_SPEED[0]=="Q" ? DDR3_CLK_HZ/4 :
INTERFACE_SPEED[0]=="q" ? DDR3_CLK_HZ/4 : DDR3_CLK_HZ/2 ; // Generate the correct CMD_CLK_HZ.
// ------------------------------------------------------------------------------------------------------------
wire i2s_3072k ; <<<<<<<<<<< need these 2 wires...
wire i2s_stb ;
fp_div #(
.INPUT_CLK_HZ ( CMD_CLK_HZ ), <<<< Choose one of the 2 below in case the tone isn't 1khz
// .INPUT_CLK_HZ ( 100000000 ),
.OUTPUT_CLK_HZ ( 3072000 ), <<<< You may optionally call this (48000 * 64), in case in the future you want to use 44100Hz and do not remember that I2S clock frequency.
.USE_FLOATING_DIVIDE ( 1 )
) fp_div_i2s (
.clk_in ( CMD_CLK ), <<<<<<<<<<<<<<
.clk_out ( i2s_3072k ),
.strobe_out ( i2s_stb )
);
// ***************************************************************************************************************
// Test Sine Wave Table Generator
// ***************************************************************************************************************
wire signed [15:0] aud_test ; <<<<< forgot signed.
wire i2s_sample_pulse ; <<< Need this wire
Sine_1KHz_16b_48ksps test_audio(
.clk ( CMD_CLK ), <<<<<<<<<<<<<
.clk_ena ( (i2s_stb && i2s_sample_pulse) ),
.audio ( aud_test )
);
// ***************************************************************************************************************
// HDMI Audio I2S interface
// ***************************************************************************************************************
audio_i2s u_AVG( <<<<<<<<<<<<<<<<<<<< W...? THIS IS NOT OUR I2S TRANSMITTER
//.clk ( pll_1536k ),
.clk ( i2s_3072k ),
.reset_n ( !RST_IN ),
//.audio_i ( aud_16_o ),
.audio_i ( aud_test ),
.sclk ( HDMI_SCLK ),
.lrclk ( HDMI_LRCLK ),
.i2s ( HDMI_I2S )
-------------------------------------------------------------------
THIS DOWN HERE
------------------------------------------------------------------
wire i2s_data ; <<<< need this temporary wire.
I2S_transmitter #(
.BITS ( 16 ), <<<<<< the size of the wire 'aud_test'.
.INV_BCLK ( 0 )
) I2S_TX (
.clk_in ( CMD_CLK ), // High speed clock
.clk_i2s ( i2s_3072k ), // 50/50 duty cycle serial audio clock
.clk_i2s_pulse ( i2s_stb ), // Strobe for 1 clk_in cycle at the beginning of each clk_i2s
.sample_in ( 1'b0 ), // Optional input to reset the sample position. This should either be tied to GND or only pulse once every 64 'clk_i2s_pulse's
.DAC_Left ( aud_test ), // Left channel digital audio sampled once every 'sample_pulse' output
.DAC_Right ( aud_test ), // Right channel digital audio sampled once every 'sample_pulse' output
.sample_pulse ( i2s_sample_pulse ), // Pulses once when a new stereo sample is taken from the DAC_Left/Right inputs. Hint: once every 64 clk_i2s_pulse's
.I2S_BCLK ( HDMI_SCLK ), // I2S serial bit clock output (SCLK), basically the clk_i2s input in the correct phase
.I2S_WCLK ( HDMI_LRCLK ), // I2S !left / right output (LRCLK)
.I2S_DATA ( i2s_data ) // Serial data output
);
// Wire all 4 stereo channels together.
// We must BLAST that incredible YM2149 sound on every speaker possible so that we are bathed in its infinite beauty!
assign HDMI_I2S[0] = i2s_data ; // (front left and right)
assign HDMI_I2S[1] = i2s_data ; // (rear left and right)
assign HDMI_I2S[2] = i2s_data ; // (Front Center and Sub-woofer)
assign HDMI_I2S[3] = i2s_data ; // (side left and right)
If you fail to get any sound, there is a slight chance you might need to set the HDMI transmitter's I2C config address 0x0A with 0x00, or 0x03.
See: I2C_HDMI_Config,
You will need to add a new entry to the bottom of the table:Code: [Select]31 : LUT_DATA <= 16'h0A00; // or 16'h0A03, default 16'h0A01 MCLK Ratio The ratio between the audio sampling frequency and the clock described using N and CTS
And adjust the parameter on line 32, LUT_SIZE = 31 to 32.
Do not do this until all other avenues of bugs have been worked out.
@nockieboy, I need to see a schematic of how the analog outputs for the YM2149 are wired to the audio jack. Since it has 3 individual outputs, 1 per channel, depending on the wiring, I believe that the jt49 filters we are using and the way they are wired will not generate the appropriate sound. We want to include the proper math formula to replicate the circuit's analog sound.
Ok, I can throw something together on the weekend.
The way you have that circuit, if you plug the headphone out to an audio amp or powered speakers, the bass should seem ok. But, if you plug in headphones, the bass should become crapped out and the volume should suffer.
Also, there is no low pass filter. Doesn't that output have a high pitched tin sound?
Anyways, copy my code from here: https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/msg4339420/#msg4339420 and get the 1khz sine test working. Make sure the tone is soft and pure without any clicks or pops.
Yes, getting a nice clear 1KHz tone from the TV now.
Then make a new PSG_TOP module to the name of your liking and stuff lines 25 through 152 of your TB inside and make the used relevant parameters & IO for that module and replace lines 25 through 152 in the TB with that one new module as it is your complete PSG ready to place in your GPU.
If I understand it all correctly, I'm going to need a 16-bit output to the I2S transmitter, which means DAC_BITS can only be 15, unless I add in some code to automatically 'make up' the width to 16 bits no matter what DAC_BITS value is entered - is that right?
Now, say we want 3 dacs in our system, a cheap 16 bit one with a headphone output and a 20 bit line level one and 24 bit for the HDMI, all with the same sound. Notice how the MSB is at the beginning. What would happen if we feed all 3 digital sources the same signal, all expecting 32 clocks per channel, but each outputting the most bits they can?
Ah of course, yes, I understand.
Also, look at it the other way around, say we can only generate 8 bit audio, meaning after our 8th bit lsb, we just send a bunch of blank zeros until the 32nd clock when the right channel begins and we send it's msb? Will all 3 dacs on our bus still work OK?
QUESTION: Why did you call it 'arya_top', what does 'arya' stand for?
Keep in mind that after we finish the filter, we will Github publish this customized fork of jt49's original. Maybe you should more carefully think about the name.
Too bad you didn't want to do this the right way. You could have had a 16-64 voice stereo HD audio experience with full stereo sampled instruments held in DDR3. Anyways... The stereo 8 channel YM2151 would have been a much nicer PSG.