Author Topic: FPGA VGA Controller for 8-bit computer  (Read 426487 times)

0 Members and 3 Guests are viewing this topic.

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3425 on: July 08, 2022, 11:32:52 pm »
Here is a snipet of my floating point clock divider:
Code: [Select]
// Forcing 64 bits is required due to a ModelSim internal bug where if 'PLL1_OUT_TRUE_HZ*4096' exceedes 31 bits, it's considered negative and cropped
// when computing the localparam.  So, never use 'localparam int' when going above 2 billion anywhere inside, or you will get bogus results.
localparam bit [63:0] aud_per_x4096  = PLL1_OUT_TRUE_HZ*4096/HDPLL_AUDIO_HZ ;                               // Determine the audio period 4096 fold.
localparam bit [63:0] aud_per_round  = aud_per_x4096 + 2048 ;                                               // Prepare a rounded version.
localparam bit [12:0] aud_per_int    = HDPLL_AUDIO_TCK_FLOAT ? aud_per_x4096[24:12] : aud_per_round[24:12]; // Select between the rounded integer period or true integer period.
localparam bit [11:0] aud_per_f      = HDPLL_AUDIO_TCK_FLOAT ? aud_per_x4096[11:0]  : 12'd0  ;              // select between no floating point and floating point adjusted audio clock generation.
localparam bit [63:0] aud_tru_hz     = PLL1_OUT_TRUE_HZ*4096 / (aud_per_int*4096+aud_per_f)  ;              // Calculate the true audio output clock based on oscilator frequencies & HDPLL_AUDIO_TCK_FLOAT settings.

assign          clk_audio_true_hz    = 32'( aud_tru_hz );        // pass the true audio sample frequency to an output port.
assign          clk_pixel_true_hz    = 32'( PLL1_OUT_TRUE_HZ ) ; // pass the true pixel clock frequency to an output port.

logic   [12:0]  aud_cnt_m  = 13'd0;
logic   [12:0]  aud_cnt_n  = 13'd0;

always_ff @(posedge clk_pixel) begin

if ( aud_cnt_m == (aud_per_int - !aud_cnt_n[12]) ) begin                          // Add 1 extra count to the period if the carry flag aud_cnt_n[12] is set.
                                        aud_cnt_m        <= 13'd0;
                                        audio_ena        <= 1'b1;
                                        clk_audio        <= 1'b1;
                                        aud_cnt_n        <= aud_cnt_n[11:0] + (aud_per_f) ; // add the floating point period while clearing the carry flag aud_cnt_n[12].
                        end else begin
                                        aud_cnt_m        <= aud_cnt_m + 1'b1;
                                        audio_ena        <= 1'b0;
                        if (aud_cnt_m[11:0]==aud_per_int[12:1]) clk_audio <= 1'b0; // generate an aproximate 50/50 duty cycle clk_audio output.
                        end

end

You need to simulate this one on it's own, making a testbench which provides a 100mhz clock and counting the ' audio_ena ' over a 0.1 second and 1 second optional.  You may use your clock divider instead.

You will need to add the input and output ports on the module.  Maybe a reset as well.  Rename the pixel clock to clk.  Add 2 parameters, a clock frequency in parameter and a clock output parameter in hz.

Once tested as is, we will increase the floating point bits from 12 to 16 or 24 depending on your tolerance for the final average frequency error of the output 1.78MHz.

Let's see your edits and sim just for this module.

This code was located at the bottom on my 'HDMI_PLL.sv' inside my HDMI serializer project.
« Last Edit: July 08, 2022, 11:43:37 pm by BrianHG »
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3426 on: July 10, 2022, 12:37:49 am »
Line 956:
Code: [Select]
ym2149_audio ARYA(

   // inputs
   .clk_i        ( CMD_CLK     ), // system clock
   .en_clk_psg_i ( strb_ovrd   ), // PSG clock enable strobe - 1.6875 MHz
   .sel_n_i      ( 1'b1        ), // divide select, 0 = clock-enable/2
   .reset_n_i    ( !reset      ), // active low
   .bc_i         ( psg_ctrl[0] ), // bus control
   .bdir_i       ( psg_ctrl[1] ), // bus direction
   .data_i       ( psg_data_i  ), // (7:0)
   // outputs
   .data_r_o     ( psg_data_o  ), // (7:0) -- registered output data
   .ch_a_o       (             ), // (11:0)
   .ch_b_o       (             ), // (11:0)
   .ch_c_o       (             ), // (11:0)
   .mix_audio_o  (             ), // (13:0)
   .pcm14s_o     ( pcm_14_o    ), // (13:0)   <<<<<<<<<<<<<<<<<<<<

Instead of the pcm14s_o, shouldn't you be using the mix_audio_o ?

Also, I looked at your 'clock_strobe', don't you want the 1.789MHz?

Also, you cannot use a clock enable to cross clock domains from the CLK_54MHz CMD_CLK, which may be 100MHz, or 75MHz, or 150Mhz.  This will cause random tone glitch clocking assuming my guesses about how the PSG works is correct.

Fix up my example code in the above post and run it from the CMD_CLK and create proper parameter inputs and a test bench to time the output and see how it works so you may extend it's precision.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3427 on: July 10, 2022, 07:54:54 am »
Instead of the pcm14s_o, shouldn't you be using the mix_audio_o ?

Maybe? :-\  Have switched to the mixed output (adding 2 LSbs to make it 16-bit).  Seems to sound more authentic now. :-+

Also, I looked at your 'clock_strobe', don't you want the 1.789MHz?

As close to it as I can get, but for testing it's not essential.  It'll just move the sound output higher or lower in the pitch range compared to the target systems of the 80's.  It's pretty much on the nose as far as I can tell, using SignalTap to calculate the pulse width (it needs to be 559ns).  Ignore the comments with other frequencies, I forgot to change/update them before posting that code, sorry. ::)

Also, you cannot use a clock enable to cross clock domains from the CLK_54MHz CMD_CLK, which may be 100MHz, or 75MHz, or 150Mhz.  This will cause random tone glitch clocking assuming my guesses about how the PSG works is correct.

Yes, I suspect this is the cause of a fair bit of interference in the output currently.  I think the PSG updates and outputs a new value every clock enable, so random/out-of-sync pulses on that line will cause glitches.  I knew this would be an issue when I initially solved the problem of the PSG missing IO RD/WRs from the host because of its slow clock speed. Injecting clk_ens to force the PSG to react to asynchronous IO interactions is, no doubt, causing sound issues too.  These are the two big problems I know I need to fix.

The interface speed issue will require some clever thinking, or editing of the PSG module itself to accept asynchronous interface commands and respond to them immediately (or on the next clock enable if the sound registers are being updated).  :-/O
« Last Edit: July 10, 2022, 07:58:02 am by nockieboy »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3428 on: July 10, 2022, 08:03:26 am »
Yes, I suspect this is the cause of a fair bit of interference in the output currently.  I think the PSG updates and outputs a new value every clock enable, so random/out-of-sync pulses on that line will cause glitches.  I knew this would be an issue when I initially solved the problem of the PSG missing IO RD/WRs from the host because of its slow clock speed. Injecting clk_ens to force the PSG to react to asynchronous IO interactions is, no doubt, causing sound issues too.  These are the two big problems I know I need to fix.

The interface speed issue will require some clever thinking, or editing of the PSG module itself to accept asynchronous interface commands and respond to them immediately (or on the next clock enable if the sound registers are being updated).  :-/O

That being said, switching from CLK_54 to CMDCLK for the PSG clock source seems to have cleared up just about all the problems.  I just need to sort out the correct divisor, but the tone output I got just now was really good.  My concerns re: the interface and botching asynchronous IO interactions actually seems to have a really minor, if any, effect. ^-^
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3429 on: July 10, 2022, 08:28:16 am »
Yes, I suspect this is the cause of a fair bit of interference in the output currently.  I think the PSG updates and outputs a new value every clock enable, so random/out-of-sync pulses on that line will cause glitches.  I knew this would be an issue when I initially solved the problem of the PSG missing IO RD/WRs from the host because of its slow clock speed. Injecting clk_ens to force the PSG to react to asynchronous IO interactions is, no doubt, causing sound issues too.  These are the two big problems I know I need to fix.

The interface speed issue will require some clever thinking, or editing of the PSG module itself to accept asynchronous interface commands and respond to them immediately (or on the next clock enable if the sound registers are being updated).  :-/O

That being said, switching from CLK_54 to CMDCLK for the PSG clock source seems to have cleared up just about all the problems.  I just need to sort out the correct divisor, but the tone output I got just now was really good.  My concerns re: the interface and botching asynchronous IO interactions actually seems to have a really minor, if any, effect. ^-^
Read my clock divider code at the top of this page.........
Adapt it....
Clean it up a little.....
Use it......
It will make any frequency you like with 2 parameter inputs.
Simulate it and see.
Show me your work.
Also, with a sample rate of 1.7Mhz for the PSG, a little jitter of +/-5ns there would not be heard.


As for sending commands, aren't they an async separate event from the 1.7mhz strobe?
Don't they take effect immediately, or aren't they latched once a block is sent?
You do have the link I sent earlier to the Verilog version of the PSG, right?
« Last Edit: July 11, 2022, 05:51:28 pm by BrianHG »
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3430 on: July 11, 2022, 10:36:53 pm »
Hello, did something go wrong?

     The my above clock divider code and the link to my VHDL-Verilog source gave you an example modelsim setup which was a single page of test-bench code which had a source 100MHz clock generator for you with a programmable end-time.

     All you had to do was rename a few things, give a name with inputs and outputs to my clock divider, or even begin by using your clock divider and just see it run.  Then, put my clock divider in place of yours and test again.

     The second step would be to add the PSB in the test-bench and a few more inputs to generate a sound with analog output to see the waveform output.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3431 on: July 12, 2022, 02:08:44 pm »
No, nothing has gone wrong - I just literally have had no time to work on any of this.  Maybe over the next week or so. :-+
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3432 on: July 19, 2022, 01:30:42 am »
Will we see anything this week?
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3433 on: July 21, 2022, 09:55:02 am »
Maybe.  I should have a little time later today perhaps to make a start on the sim stuff.  Concentrating on this is hard enough at the best of times with all the distractions I have going on around me.

I'm quite happy with my clock divider providing a reasonable 1.78 MHz signal to the PSG - it's a helluvalot closer to the target frequency than my hardware PSG card ever was.  I've also added in some HDL in the _top file to handle the asynchronous nature of the PSG module's interface, running at a much slower clock.  Any signals to the module are now held until the next 1.78 MHz strobe.  The only downside is that the Z80 is sometimes able to send two IO RD/WRs in-between the strobe pulses if the timing falls just right, but that was an issue with the original 80's hardware and why they made prolific use of NOPs in the assembly (or set up an interrupt on a similar frequency that send the commands), so I can work around that.

What do you want me to start on first?  I guess I'll use the 'cordic' project you linked to previously as a base and start getting a simulation of the PSG module up and running?
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3434 on: July 21, 2022, 04:25:06 pm »
Start with just wiring in your clock divider and showing that it works.

Will you correct your clock divider to auto receive and adjust it's rate based on parameters set by the CMD_CLK frequency?

You may also calculate and count the output frequency in the testbench if you like.

Quote
I'm quite happy with my clock divider providing a reasonable 1.78 MHz signal to the PSG - it's a helluvalot closer to the target frequency than my hardware PSG card ever was.

Yes, but if you want to run compatible music home computers which used this PSG, without having a clock within their crystal frequency, you may have slightly bad pitch and long term tempo if there is some kind of timer involved.

Quote
The only downside is that the Z80 is sometimes able to send two IO RD/WRs in-between the strobe pulses if the timing falls just right, but that was an issue with the original 80's hardware and why they made prolific use of NOPs in the assembly (or set up an interrupt on a similar frequency that send the commands), so I can work around that.

Well, if you are using an IO port, if you remember, we added a programmable Z80 wait state for the reads.  We can add a wait for the 1.78 MHz strobe when writing to the PSG's port.  However, I find it strange that the designer of the HDL for the PSG didn't allow multiple writes, accepting them all even in-between each 1.78 MHz strobe for the core audio clock.  I wonder if the Verilog version I pointed you to has the same limitation.  I mean, if you update the same voice's frequency once or twice within 1.78MHz, it should not be noticed.  If you update a number of voice settings within a strobe, then all those settings should take effect by the next strobe.

Well, if not, what you need to create is a 'PSG_Busy' flag.  This flag should go high after every write an clear itself at each strobe.  Make a parameter to select whether the write or strobe has higher priority.  This flag will need to be sent to the Z80 Bridge (which may need adjusting as I know we adapted an input for the IO port read, but not sure about an IO port write).  It needs to be setup so that when a matching port address write happens while the 'PSG_Busy' is high, that the Z80 wait state will be inserted until the busy is cleared.

Again, it helps that we can simulate this to verify that this is where your current bug originates as you did not create the PSG's VHDL, so you cannot be sure.  (Though, you can point me to the documentation for the PSG's VHDL which states this limitation.)
« Last Edit: July 21, 2022, 04:28:31 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3435 on: July 24, 2022, 01:38:45 pm »
Start with just wiring in your clock divider and showing that it works.

It's been busy here - first chance I've had today to work on this, but I've got the clock divider test bench up and running.  Here's the output:



I've also attached the test bench for info.

Will you correct your clock divider to auto receive and adjust it's rate based on parameters set by the CMD_CLK frequency?

Yes, that's something I'd like to add later.

You may also calculate and count the output frequency in the testbench if you like.

The output period of the strobe is 560ns currently, which equates to 1.786 MHz.

Quote
The only downside is that the Z80 is sometimes able to send two IO RD/WRs in-between the strobe pulses if the timing falls just right, but that was an issue with the original 80's hardware and why they made prolific use of NOPs in the assembly (or set up an interrupt on a similar frequency that send the commands), so I can work around that.

Well, if you are using an IO port, if you remember, we added a programmable Z80 wait state for the reads.  We can add a wait for the 1.78 MHz strobe when writing to the PSG's port.  However, I find it strange that the designer of the HDL for the PSG didn't allow multiple writes, accepting them all even in-between each 1.78 MHz strobe for the core audio clock.  I wonder if the Verilog version I pointed you to has the same limitation.  I mean, if you update the same voice's frequency once or twice within 1.78MHz, it should not be noticed.  If you update a number of voice settings within a strobe, then all those settings should take effect by the next strobe.

Not sure if I did it before or after I wrote the above, but IO reads from the PSG insert WAIT states as required and hold the Z80 until data is valid from the PSG.  The amount of WAIT states inserted varies according to where in the 1.78 MHz cycle the IO read occurs.  It's just IO writes to the PSG that don't insert WAITs, instead relying on the Z80 leaving a little breathing space between IO writes.

Again, it helps that we can simulate this to verify that this is where your current bug originates as you did not create the PSG's VHDL, so you cannot be sure.  (Though, you can point me to the documentation for the PSG's VHDL which states this limitation.)

Here's the source I'm using for the PSG module: https://github.com/dnotq/ym2149_audio - there's information on the module there, though I think I surmised the asynchronous interface nature from my own experiments rather than it being documented.

Next step is to get the PSG module integrated into the testbench then?
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3436 on: July 24, 2022, 07:02:59 pm »
Excellent work.

Next, what would happen if you added to your _tb this line right at the end:

Code: [Select]
always @(posedge clk) if (p_stb) f_count <= f_count + 1 ;  // Make f_count a 24 bit reg, or just a normal integer.

endmodule

This line in your setup:

Code: [Select]
add wave -hexadecimal sim:/clock_strobe_tb/DUT/strb_o
add wave -decimal     sim:/clock_strobe_tb/f_count       <<<<<<<<<<<

do run_div.do

And changed your _tb endtime to :
localparam  ENDTIME    = 1000 * 1000 ; // Number of ns to stop simulation at.

What will you see at the end of your simulation?

Also, try  ENDTIME    = 1000 * 1000  * 100 ;
Now what will the f_count show at the end of the sim?

*** Do not bother with ' 1000 * 1000  * 1000 ', it will take forever to simulate.  Once you understand the concept, 1000*1000 is plenty.

Next, after you instantiate your 'clock_strobe' in the _tb, next instantiate and wire the VHDL PSG.
You will define a few regs before to drive the input and to show in the simulation waveform.  The wiring should look exactly like what you would be doing in in you GPU source.  The setup waveform display should show the digital inputs and 4 analog output waveforms.  I believe the output wires should be signed numbers, but if the output show a crap step, then they should be changed to 'unsigned' and go from 0-max, max being the number of 2^bits.

Also remember in your setup/run.do, you use the 'vlog -sv ...' for verilog source files and 'vcom -93 ...' for VHDL source files.
« Last Edit: July 24, 2022, 07:06:45 pm by BrianHG »
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3437 on: July 24, 2022, 09:32:42 pm »
Next step after you get the PSG working, we need another clock generator for the I2S audio which runs at exactly 48000Hz X 32.  Or, within +/- 1hz.  Then, you will need to modify or create your own parallel audio to I2S serial audio running on that 48000Hzx32 clock.  (IE: 1536000Hz, or 1.536000MHz.)

Then, copy/plug/rename the TB into a single sound module copied into your GPU_TOP and you should be able to get PSG out of your GPU's HDMI.
« Last Edit: July 24, 2022, 09:36:34 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3438 on: July 24, 2022, 09:33:35 pm »
Excellent work.

Next, what would happen if you added to your _tb this line right at the end:

Code: [Select]
always @(posedge clk) if (p_stb) f_count <= f_count + 1 ;  // Make f_count a 24 bit reg, or just a normal integer.

endmodule

This line in your setup:

Code: [Select]
add wave -hexadecimal sim:/clock_strobe_tb/DUT/strb_o
add wave -decimal     sim:/clock_strobe_tb/f_count       <<<<<<<<<<<

do run_div.do

And changed your _tb endtime to :
localparam  ENDTIME    = 1000 * 1000 ; // Number of ns to stop simulation at.

What will you see at the end of your simulation?

Also, try  ENDTIME    = 1000 * 1000  * 100 ;
Now what will the f_count show at the end of the sim?

*** Do not bother with ' 1000 * 1000  * 1000 ', it will take forever to simulate.  Once you understand the concept, 1000*1000 is plenty.

Okay, a little light HDL coding before bedtime.  ;)  So it's a pulse counter, basically - running the sim for a million cycles results in the final f_count value being 1785, suspiciously close to my calculated clock speed (minus three orders of magnitude) for the PSG.  Looks like a handy (and simpler) way of calculating the output clock frequency?  Thanks for that.  :-+

Will work on getting the VHDL PSG module wired-in to the test bench tomorrow, hopefully.
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3439 on: July 24, 2022, 09:40:01 pm »
Okay, a little light HDL coding before bedtime.  ;)  So it's a pulse counter, basically - running the sim for a million cycles results in the final f_count value being 1785, suspiciously close to my calculated clock speed (minus three orders of magnitude) for the PSG.  Looks like a handy (and simpler) way of calculating the output clock frequency?  Thanks for that.  :-+

Will work on getting the VHDL PSG module wired-in to the test bench tomorrow, hopefully.

You are learning to exactly prove your code.
You also notice that the last pulse doesn't end right at the 1000000ns mark, so, there is a bit of error there.  This is also why you get additional decimal places when you run the sim for a greater time.  Running the sim for the full 1000x1000x1000 would leave you with a 1hz accurate readout.

As for easy calculation, your code calculation should be exactly 100000000 / loop_size.  That easy.  My divider code is a little more complex as it has an accumulated floating point error correction feature, but all the pre-calculations are in my posted source with 2 integers which reveal the true audio frequency output down to the Hz.

My source is posted here: https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/msg4288510/#msg4288510
Your gonna need it to get an accurate audio clock for the HDMI sample rate.
« Last Edit: July 24, 2022, 09:45:09 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3440 on: July 25, 2022, 11:03:53 am »
Update - I've wired-in the YM2149 VHDL module.  I just need to work out how to send some test commands to get it to output some audio now.

« Last Edit: July 25, 2022, 02:10:52 pm by nockieboy »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3441 on: July 25, 2022, 02:10:13 pm »
Update 2 - now have commands to the PSG working.  Trace below shows a simple command being sent to the PSG to make it play a tone.

 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3442 on: July 25, 2022, 05:22:26 pm »
Ok, after running your sim, no audio out.  (0.001 seconds in real life)
After increasing the sim end time by 10x, still nothing.  (0.01 seconds in real life)
After increasing the sim end time by another 10x, still nothing. (0.1 seconds in real life)
After increasing the sim end time by another 10x, still nothing.  (1 second in real life)
( :-\ Pathetic PSG if it cannot produce a tone within 1 second of the issued command.)

Well, after that sim:


Looking at the 1 000 000 000ns point (1 second), your f_count made it past 1785714 times, or 1785714Hz.  Plus a few extra fractional 0.xxx hz as it reached that count just before the 1 second point.  This should match your calculated hz.  (Fin=100 000 000hz / divider 56 = 1785714.286 hz)


Assuming you sent the commands correctly and the same way you have been doing it currently with the 'Z80', you may have just identified your first bug.  Now, this may be an issue with the way the VHDL is either configured, or the way it is designed to interface with.

Ok, your setup is ok, in a Verilog way, though you did not need to write such code, but I will make a suggestion for the reset, place it inside the initial like this:

Code: [Select]
    initial begin

        clk     = 1'b0  ;
        f_count = 24'b0 ;
        step    = 3'b0  ;
        reset   = 1'b0  ;

        #(CLK_PERIOD*5) reset   = 1'b1  ; // release reset after 5 clocks

    end


In fact, get rid of your verilog at the bottom and do this:

Code: [Select]
    initial begin

        clk     = 1'b0  ;
        f_count = 24'b0 ;
        step    = 3'b0  ;
        reset   = 1'b0  ;

        #(CLK_PERIOD*CMD_CLKS)  // Wait for CMD_CLKS oscillations of the system clk period before releasing reset

        reset   = 1'b1  ;       // release reset.

        #(CLK_PERIOD*CMD_CLKS)  // Wait for CMD_CLKS oscillations of the system clk period before sending commands.

        // Count the command counter until the end, waiting a CMD_CLKS between each command step.
        for (step = 0; step < (CMD_COUNT -1); step++ ) #(CLK_PERIOD*CMD_CLKS) ;

    end
With this new parameter at the top:
Code: [Select]
    // Test parameters
    parameter DIVISOR = 28'd56   ; // clock divisor value
    parameter CMD_CLKS = DIVISOR ; // numbers of clk per command.

This With this, you can now set the CMD_CLKS to anything, like 1 which would send a command every 100MHz system clock.

I also added a blank dead '0' beginning command.  (See attached updated source _tb code).

Now, we know the PSG is doing something as after the last command is sent, the 'pcm14s_o' output changes to 0x0353 at the last transmitted command byte, but, nothing after that.

Playing with then new 'CMD_CLKS' parameter doesn't seem to help.
I made it 4x longer and the 'pcm14s_o' now changes before the last command is sent.
Perhaps your command output is wrong in some way?

I made it literally equal to 1 and 2, but now, nothing happens.  This confirms that the poor VHDL PSG needs the commands to be slowed down, though I suspect it was done for backwards compatibility with the original IC.  I also tried 1/2 your divisor 'DIVISOR' parameter making the command exactly twice as fast and it still fails.

I also tried inverting the 'bc' and nothing again.

So, we can assume you are sending a proper command timing, but something is missing in the commands as there is no triangle waveform coming out.

There is also that verilog version of the Yamaha PSG I linked to earlier which you may give a try.  It should have the same IO ports.  If it has the same slow input road-block, you might be able to easily bypass it and write commands right up to the top 100MHz clk input speed.
« Last Edit: July 25, 2022, 05:42:48 pm by BrianHG »
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3443 on: July 25, 2022, 07:40:28 pm »
Have any VHDL programmers have seen this warning before:
Code: [Select]
# Loading work.ym2149_audio(rtl)
# ** Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
#    Time: 0 ns  Iteration: 0  Instance: /psg_tb/PSG
# ** Warning: NUMERIC_STD."<": metavalue detected, returning FALSE
#    Time: 0 ns  Iteration: 0  Instance: /psg_tb/PSG
# ** Warning: NUMERIC_STD."<": metavalue detected, returning FALSE
#    Time: 0 ns  Iteration: 0  Instance: /psg_tb/PSG
# ** Warning: NUMERIC_STD."<": metavalue detected, returning FALSE
#    Time: 0 ns  Iteration: 0  Instance: /psg_tb/PSG
# ** Warning: NUMERIC_STD."<": metavalue detected, returning FALSE
#    Time: 0 ns  Iteration: 0  Instance: /psg_tb/PSG
# ** Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
#    Time: 0 ns  Iteration: 0  Instance: /psg_tb/PSG
# ** Note: $stop    : psg_tb.sv(92)

How do we fix this, how do we figure out where the bug is?
The source code is called 'ym2149_audio.vhd' located inside this .zip:
https://www.eevblog.com/forum/fpga/fpga-vga-controller-for-8-bit-computer/?action=dlattach;attach=1548325
Or, located here:
https://github.com/dnotq/ym2149_audio/blob/master/rtl/ym2149_audio.vhd
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3444 on: July 26, 2022, 11:24:07 am »
 
The following users thanked this post: nockieboy

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3445 on: July 26, 2022, 12:19:53 pm »
@nockieboy, it may be useful to try this verilog version:
https://github.com/jotego/jt49

It has features like DC removal filter (don't want to blow your amp or speakers (this would be done with a series cap on the computer sound card PCB)) and enough people used it that there were posted issues and they were fixed.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3446 on: July 26, 2022, 12:25:39 pm »
@nockieboy, it may be useful to try this verilog version:
https://github.com/jotego/jt49

It has features like DC removal filter (don't want to blow your amp or speakers (this would be done with a series cap on the computer sound card PCB)) and enough people used it that there were posted issues and they were fixed.

Already have that repo in the GPU project folder - just never tried it as it appears more complicated than the YM2149 single-file module (though I've never taken the time to look, really).  If you're thinking the YM2149 is bugged, then I'll start looking at getting the jt49 set up.  I've already tried the other Verilog module - yt49 - and had a hard time getting it to work.
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3447 on: July 26, 2022, 01:00:30 pm »
The simulator will help.
All you need to run/instantiate is the jt49.v in place of VHDL and match the IOs names.

You will need to add these vlog files:
 - jt49.v
  - jt49_div.v
  - jt49_cen.v
  - jt49_eg.v
  - jt49_exp.v
  - jt49_noise.v

Skip the 'jt49_bus.v' as it is just a different CPU interface.
Note that this does not include the DC filter, but that's ok for now.

I do not necessarily think the VHDL PSG is flawed, just something which may require an extra equals or quote somewhere in its source.  That is unless it doesn't sound exactly correct.

Note that there also exists this YM2151, 8 channel, 16bit stereo, but more controls needed to make a sound:
https://github.com/jotego/jt51/tree/master/doc/yamaha
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #3448 on: July 26, 2022, 04:01:59 pm »
Here's the jt49 testbench setup.  Haven't tried the jt49 in hardware yet, but it looks like something is happening on the A-channel output.



Zooming right out shows the output flipping between 0xB4 and 0x00 values.  No idea if that's a valid output or not, to be honest.  I'm not 100% certain my commands are correct, but they are identical to the ones sent by the DMI to make a 'beep' sound when the user tries to delete past the first screen column.  The only difference is that the DMI tells the PSG to stop making the noise after a predetermined time, whereas I don't do that in the simulation.
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 7747
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #3449 on: July 26, 2022, 06:33:50 pm »
Ok, I got it working.

Take a look: (Note that I shrunk your clock divider from 56 down to 2 so that we see a waveform without having to simulate for 100s seconds before we see anything meaningful...)



     Now, download my source code and read every line in the _tb.  You went way overboard with the coding.  This Verilog PSG source is easy to interface with and does NOT require you to time your commands.  You can send commands at a full 100MHz ignoring that clk_strobe timing and the PSG will registers them all.  This means all you had to do was feed an address and a data in parallel with the write strobe.

     In other words, use Z80 port #10 bottom 4 bits into the address, use Z80 port #11 into data, and use the data strobe of port #11, invert it, feed it to the the wr_n input.  To send a command, just write port 10 with the address 0-15, and then write port 11 with the data and you are done.  No delay, no waits, no absurd routine to generate that 8bit multiplexed bus timed to the clk_enable.

     Now, we have one new problem.  This PSG was designed with a cheap DC output,  the actual IC.  The HDL is just replicating it.  This is very bad for HiFi audio equipment, but good enough for a tiny PC speaker.  Like I said earlier, this problem would be solved with analog circuitry in the PC RF modulator, or output op-amp with nothing more than a wired series cap which blocks DC.  But with direct digital audio or a HiFi DAC which supports low frequencies, you could be sending frequencies below 10hz, or even below 1hz every time the sound starts and stops.  For this, we will need to add this software DC filter code (emulated that DC blocking series cap) to the 10bit 'sound' output:

https://github.com/jotego/jt49/tree/master/hdl/filter

I'll take a look later tonight as it has some extra unused components for simulation, not the way we would do it.  (And if we never simulated this chip, I would have never known and you would have potentially burned out someones expensive amp, burned out or popped out some unsuspecting user's expensive woofer/subwoofer.)
« Last Edit: July 26, 2022, 07:11:28 pm by BrianHG »
 
The following users thanked this post: nockieboy


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf