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

0 Members and 1 Guest are viewing this topic.

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1225 on: July 05, 2020, 05:02:32 am »
Darn that Z80_bridge has turned into a mess, however, there are valid reasons why.
Do you have a simulation setup?  If so, post it here...

Yes, it has become a bit messy since I have added stuff for testing and trying to get IO RD/WR from the Z80 working.  I guess I should housekeep the code more often.  :-[

Test setup for the Z80_bridge attached.  This is what I used in the other thread when I was testing the IO cycle.

What do you mean by 'denounce'?  Not sure on the terminology here.

What where you able to discern from that?

I've attached the project with the actual Z80 vectors in the waveform editor. The Z80 clock is set to 8 Mhz and the gpu clk is set to 125MHz.  The bus transaction timing you see is real from the Z80 datasheet, or as close as I can get it based on the poor datasheets I have access to.

Is there anything new you can gather from my layout?
Do you have any new insights when zooming into the simulation?

You need to shore up the Z80_bridge and add a few test signal tap signals to see whats going on inside your bridge.

Also, now it may be time to look at taking into account the Z80 CLK so that you wait for the next edge before reading the bus status too quickly before all the data and address lines are ready.

Now that the Data_mux has been fixed, and you can simulate the Z80 buss interactions 'for real', we can fix that module and call it a day.

Note that we are missing the 'Z80_nWAIT' signal.  The Z80 seems to assert it during a port read or port write.
It also seems if you were to read or write a memory address that the access is 1 clock faster as those transfers do not force that 1 clock cycle wait state.

(Note that for the Z80 data input, I made the data = $D0 when the Z80 outputs the correct data and make that same signal $D1 for the complete amount of time the Z80 expects to receive read valid data.)
« Last Edit: July 05, 2020, 05:11:01 am by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1226 on: July 05, 2020, 10:40:53 am »
What do you mean by 'denounce'?  Not sure on the terminology here.
:palm: DE-Bounce.  Bloody auto-correct.

Sorry about that, if it wasn't so late at night and I wasn't so tired when I read the post, I'd have worked that out for myself.  :-\

Ok, I converted the GPU ram port from 8bit into a dynamic 16bit version.... I also had to modify the compiler settings to ensure the compiler would meet the timing for the GPU ram as the old settings were receiving a few address & write_enable bits a little late.  Though, it was there in your existing version, it probably didn't cause any problem as the silicon usually performs better than the compiler's report which takes into consideration the worst possible conditions based on the set operating specs.

Let me know if the attached project works.  If so, you will need to switch to that project from now on.

Yes, works fine (seems to have cut 30 seconds off the compile time too!) so I've switched to the updated version for the project.  Thanks. :)

Also, why do you have your palette system memory set shy of 32k and your palette memory set right after?

Probably because it seemed like a good idea at the time. :-//

Quartus still wasted the Cyclone's ram with the missing bytes in the main system memory with 32k and then wrote the separate palette memory in that shared address space.  Also, why is the main system memory an odd number of bytes?  You should have used 32768 for main ram and 32768 for the offset of the palette memory.  But, you could have gone even a bit larger on the main system memory.  See here:

(Attachment Link)

I went with 32 KB GPU RAM as it's the nearest 16 KB multiple.  The next (obviously) would be 48 KB, but the EP4CE10 doesn't have that much RAM.  The reason why this is (possibly un-)important is:

The host Z80's MMU can map 16 KB banks of RAM into the the Z80's logical 64 KB address space.  So the EP4CE10 presents two complete 16 KB banks of RAM that can be accessed by the Z80.  The way the Z80_bridge works at the moment is to return 0xFF's for any addresses the Z80 attempts to read (and prevents writes) to memory above 32 KB.  So although the new project has 40 KB of RAM, the Z80 can only see and write to the first 32 KB.

I could remove the check and allow the Z80 to try and read/write any address in the 512 KB space, but it would get random data back and I need 0xFF's so that the software can work out if there's actual RAM available or not.  The easiest way to do that was to check for addresses over 32 KB (15 bits) and return 0xFF.

Will need to re-visit that code in the Z80_bridge to allow the Z80 to access the GPU RAM up to an odd (i.e. non-multiple of 16KB) address range.  That's the mem_valid_range register, set on line 219 in Z80_bridge.


With the attached project and my settings, you now have 41kb, just enough memory for a 320x240 16 color screen plus a 256 character 8x8 pixel font.  Or, 640x240 4 color, or 640x480 2 color screen.  Even 160x240 @ 256 colors, 160x120 @ 65536 colors.

It should compile and function.

It sure does.  I just need to sort out the mem_valid_range register to allow the Z80 access to the additional 9 KB of RAM.  It doesn't matter if the third bank of GPU RAM is only 'RAM' for the first 9KB, so long as the remainder returns 0xFF.  It just means the additional 9 KB of RAM won't show up in the total memory reported by the system.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1227 on: July 05, 2020, 11:19:42 am »
What where you able to discern from that?

Well, the fact that z80_DATA_DIR and z80_BDIR_EN were going HIGH too early - I managed to get the PS/2 IO port from 100% not working to producing the odd duplicated character once in perhaps 20 key strokes.

I've attached the project with the actual Z80 vectors in the waveform editor. The Z80 clock is set to 8 Mhz and the gpu clk is set to 125MHz.  The bus transaction timing you see is real from the Z80 datasheet, or as close as I can get it based on the poor datasheets I have access to.

Is there anything new you can gather from my layout?
Do you have any new insights when zooming into the simulation?

I'm grasping at straws here, but perhaps the data for the IO RD cycle should be placed onto the z80_DATA bus a quarter of a (Z80) clock cycle later?

You need to shore up the Z80_bridge and add a few test signal tap signals to see whats going on inside your bridge.

Also, now it may be time to look at taking into account the Z80 CLK so that you wait for the next edge before reading the bus status too quickly before all the data and address lines are ready.

So wait for the next leading edge of the Z80's clock?

Note that we are missing the 'Z80_nWAIT' signal.  The Z80 seems to assert it during a port read or port write.

I don't have access to the WAIT signal from the Z80 on the current GPU card.  I could bodge-wire it into a spare IO, but didn't think it was necessary.

It also seems if you were to read or write a memory address that the access is 1 clock faster as those transfers do not force that 1 clock cycle wait state.

(Note that for the Z80 data input, I made the data = $D0 when the Z80 outputs the correct data and make that same signal $D1 for the complete amount of time the Z80 expects to receive read valid data.)

Are you thinking the D1s are faults?  The datasheet shows an overlap for valid data at the end of the MREQ / IOREQ cycle, but the timing charts quote 0 ns for that time for a 10 MHz Z80 CPU, so in reality there is no need for the data to be held past the end of the MREQ/IOREQ cycles.

It does seem that z80_DATA_DIR and z80_BDIR_EN are HIGH for a long time before the Z80 actually needs to read the data off the bus.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1228 on: July 05, 2020, 03:19:58 pm »
Are you thinking the D1s are faults?  The datasheet shows an overlap for valid data at the end of the MREQ / IOREQ cycle, but the timing charts quote 0 ns for that time for a 10 MHz Z80 CPU, so in reality there is no need for the data to be held past the end of the MREQ/IOREQ cycles.

It does seem that z80_DATA_DIR and z80_BDIR_EN are HIGH for a long time before the Z80 actually needs to read the data off the bus.
The way you read the data sheet, for the data in and data out, the small time slot where the Z80 has the 'D1' means that you need to present valid data to the Z80 beginning anytime before that time slot begins, and then hold data on the bus until after the 'D1' time slot ends.
Now, do we send data to the Z80, figuring it takes an additional 5-10ns for the data to get there from the assertion of the OE & data out signals, will the data reach the Z80 in time to ensure a good read?
Now, do we hold that data we are sending out to the Z80 long enough until the end of the Z80 'D1' time slot that we guarantee the Z80 will receive a correct byte?

Remember, the time scale on the simulation is accurate, so you have the ns ruler at the to.  In simulate in timing mode and it will even be closer.  (Adds around up to another 2.5ns of delay on the FPGA outputs.)

Also, about the wait state, if you look at the port read and write, there is an extra Z80 clock cycle, wait state which you may need to wait before beginning a transaction just to be safe.

You have the function in your Z80 module, but not a basic setup where you can manipulate a response.  You need to clean that up.


In the other direction, a Z80 write, you should be taking the data from the Z80 data bus after the valid 'D0' time has begun and before it ends.  Now there is an additional caveat here too.  Yo need to consider all the delays created by you bus' potential load on the data lines as well as the address lines.

« Last Edit: July 05, 2020, 03:40:17 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1229 on: July 05, 2020, 05:31:56 pm »
The way you read the data sheet, for the data in and data out, the small time slot where the Z80 has the 'D1' means that you need to present valid data to the Z80 beginning anytime before that time slot begins, and then hold data on the bus until after the 'D1' time slot ends.

So a two or three gpu_clk cycle delay after detecting the end of the MREQ or IORQ RD cycle is needed?

Now, do we send data to the Z80, figuring it takes an additional 5-10ns for the data to get there from the assertion of the OE & data out signals, will the data reach the Z80 in time to ensure a good read?
Now, do we hold that data we are sending out to the Z80 long enough until the end of the Z80 'D1' time slot that we guarantee the Z80 will receive a correct byte?

Well, the D1 slot ends at the same time as MREQ or IORQ goes HIGH at the end of the read cycle (the data sheet indicates that the Z80 has read the data by this point), so add in the 1 gpu_clk delay to detect the end-of-cycle and act upon it, then the delay inherent in the 245 and the FPGA's bidirectional IO pins, and you have a built-in delay holding the data on the bus slightly past the end of the read cycle anyway?

Memory reads have been rock solid, so I can't fault the timings of the function handling the MREQ RD cycle in the Z80_bridge.

Also, about the wait state, if you look at the port read and write, there is an extra Z80 clock cycle, wait state which you may need to wait before beginning a transaction just to be safe.

This is something I might have to test a little more.  From how I read the datasheet, there should be no issue with data being pushed onto the data bus by the peripheral (i.e. the FPGA) before the WAIT state.

You have the function in your Z80 module, but not a basic setup where you can manipulate a response.  You need to clean that up.

Where do I start? Set up a delay sequencer so that different delays can be tested?

In the other direction, a Z80 write, you should be taking the data from the Z80 data bus after the valid 'D0' time has begun and before it ends.  Now there is an additional caveat here too.  Yo need to consider all the delays created by you bus' potential load on the data lines as well as the address lines.

What sort of delays are we talking about here?  It seems to me that the odd nanosecond here and there aren't going to be a problem - the Z80's clock cycle is 125 ns long at 8 MHz...?
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1230 on: July 06, 2020, 02:44:27 am »
Looking at you existing Z80 bridge, you can see you don't hold the data output until the period 'D1' ends.  Electrical capacitance on the data bus or a fast Z80 may be whats keeping your read data clean.  See here:

1017734-0

Ok, I completely redone your Z80 bridge and present to you the new Z80_bridge_v2.sv.  It operated based on the bus commands which are each filtered through programmable bidirectional 'hysteresis' timers.

When parameter 'USE_Z80_CLK' is 0 (off), the 'Z80_CLK_FILTER' parameter sets the required number of GPU clk cycles of a valid bus command on the Z80 inputs before command will be considered true.  It will take once again the same number of GPU clk cycles for the current command to be considered false.  The default value for 'Z80_CLK_FILTER' should be 3, equivalent to a 24ns low pass filter.  (use 1 for a 20MHz Z80.  1 would probably still work fine with an 8 MHz Z80.)

When parameter 'USE_Z80_CLK' is 1 (on), the 'Z80_CLK_FILTER' parameter should be set to 0 as this means any valid command input will only become valid during the next Z80 clk transition.  If you set the 'Z80_CLK_FILTER' to 1, it would now wait for 2 Z80 clk cycle and this may miss a few commands.

I did almost everything except for the port inputs and outputs.  I did leave an example port read and write in the code with a dummy test counter for the keyboard read, use this to test the keyboard port access as each read should increment the returned value by 1, and an example port write to the speaker.  If reading the keyboard reveals a perfect 8 bit counter every read, but your keyboard interface still glitches with this Z80 bridge, then the error lies in you keyboard decoder source code.

This is a snapshot of the attached Quartus 9.1 simulation test bench with default filter setup.  As you can see, I have the commands labeled so you may change 1 or 2 to test your 3 port functions which I didn't add.  As you can see, the latest version gives ample time at each junction in the bus cycle to allow the address and data lines to settle and be captured both for input and output.

1017726-1

The code is much simpler than what you had.  I wasn't sure about the port address width so I made it 16 bits.  If it needs changing, I'm sure you can fix this yourself.

« Last Edit: July 06, 2020, 03:20:36 am by BrianHG »
 
The following users thanked this post: nockieboy

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1231 on: July 06, 2020, 11:25:22 am »
Looking at you existing Z80 bridge, you can see you don't hold the data output until the period 'D1' ends.  Electrical capacitance on the data bus or a fast Z80 may be whats keeping your read data clean.  See here:

(Attachment Link)

But the Z80 datasheet quotes ZERO time to hold the data on the line after the end of the RD cycle.  The timing diagram is misleading, as it seems to show the data being held a little way past RD/WR going high, but in reality there is no need for such a delay.

Timing diagram:
1017844-0

Timing values:
1017848-1

This is borne out with practical experience - I get zero memory read errors in practice, so holding the data past the end of a RD cycle seems unnecessary, unless I'm missing something?

Ok, I completely redone your Z80 bridge and present to you the new Z80_bridge_v2.sv.  It operated based on the bus commands which are each filtered through programmable bidirectional 'hysteresis' timers.

Thank you.  ^-^

I did almost everything except for the port inputs and outputs.  I did leave an example port read and write in the code with a dummy test counter for the keyboard read, use this to test the keyboard port access as each read should increment the returned value by 1, and an example port write to the speaker.  If reading the keyboard reveals a perfect 8 bit counter every read, but your keyboard interface still glitches with this Z80 bridge, then the error lies in you keyboard decoder source code.

I've spent the last hour or so trying to get IO reads to work - all I'm getting is 0x78 back, whether I try to read the PS2_DATA port or the PS2_STAT port, so there are timing issues here.  Writing to the IO_SPKR port seems to work - the speaker bleeps when I output 1 to the IO_SPKR port, but then it would do that whatever value it gets as long as it's not 0.

Also, I've got some modification of the code to do to get the BANK_ID returned to the Z80 again and to return 0xFF's for memory reads outside of mem_in_range.  Otherwise, memory reads and writes appear to be working just fine.

The code is much simpler than what you had.  I wasn't sure about the port address width so I made it 16 bits.  If it needs changing, I'm sure you can fix this yourself.

It sure is simpler.  Have made the port address width 8-bits - there are tricks to use the full 16-bit port address, but the Z80 was intended to use only 256 ports originally.  Also had to add in the assignments for EA_DIR and EA_OE - without these, the system hangs as there is contention on the extended address bus caused by the level converter not knowing which direction to go.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1232 on: July 06, 2020, 02:18:57 pm »

This is borne out with practical experience - I get zero memory read errors in practice, so holding the data past the end of a RD cycle seems unnecessary, unless I'm missing something?

With that data sheet, no do not need any data past the rise of the RDn flag.  You can use a filter value of 1 or 0 if you like.  However, I find it strange that we had to add a read/write request delay on the earlier Z80 module to get rid of a few errors.

As for the port reads, did you try using my dummy internal counter example read?
If that internal counter works, its the way you retrieve data from the PS2 keyboard vhdl module which is messing up.

Note that you can set the Z80 to operate off the Z80 clk input and for the ports, you can add a second filter parameter of 1 or 2 instead of 0 to delay the input/output data past that 'TW' added state.

This is why I made the module the way I did.  You can separate  clocks, either GPUclk or Z80clks for each command without modifying the basic input/output data and OE part.

Send me your updated .sv.
« Last Edit: July 06, 2020, 02:25:33 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1233 on: July 06, 2020, 02:32:46 pm »
This is borne out with practical experience - I get zero memory read errors in practice, so holding the data past the end of a RD cycle seems unnecessary, unless I'm missing something?
With that data sheet, no you are not.  You can use a filter value of 1 or 0 if you like.

Will give that a try later then.  :)

As for the port reads, did you try using my dummy internal counter example read?
If that internal counter works, its the way you retrieve data from the PS2 keyboard vhdl module which is messing up.

Yes, I'm using the internal counter - I've amended the code slightly to use the counter on the IO_STAT port, otherwise the system would be unusable as the counter would be giving false ASCII codes whenever it was polled.

I've sorted the timing on the IO reads now, it just seems I need to work on the code.  I'm getting valid values when I attempt to read from a non-existent IO port (it returns 0x55 as I've set it to), but the IO_STAT port (with the counter) is missing counts.  If I run several 'IN 240' commands in a row, I'm getting values along the lines of:

23
69
104
128
160
196
238
252

So I'm just looking at the code and tightening it up a little, but it seems I'm missing something (probably very obvious).

On the other hand, I seem to be getting valid ASCII char values from the PS2_DATA port, I'm just not clearing them currently when I read them.  Is this next bit of code okay?
Code: [Select]
Z80_rData    <= PS2_CHAR;
PS2_CHAR     <= 8'b0;

This is where it should return the value in the PS2_CHAR register when the Z80 is polling the PS2_DATA port.  Once the data is read by the Z80, PS2_CHAR should be set to 0.  However, given that both those lines of code execute at the same time, I'm thinking I should perhaps delay the second line by one clock cycle?

Note that you can set the Z80 to operate off the Z80 clk input and for the ports, you can add a second filter parameter of 1 or 2 instead of 0 to delay the input/output data past that 'TW' added state.

This is why I made the module the way I did.  You can separate  clocks, either GPUclk or Z80clks for each command without modifying the basic input/output data and OE part.

Right, I'll have a closer look at how to do that in a sec.  I've gone and created another delay pipeline for IO reads which perhaps I should have done via the new method you've described.  :o

 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1234 on: July 06, 2020, 02:41:52 pm »
Ooops, you posted the 'OLD' bridge.sv...

Also, to get around your long compile times, send me your current project and I will send it back (renamed) with compiler setting plus a few items removed to get it to compile in 45 seconds...
« Last Edit: July 06, 2020, 02:44:22 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1235 on: July 06, 2020, 02:50:25 pm »
Ooops, you posted the 'OLD' bridge.sv...

D'oh!   :palm:

Also, to get around your long compile times, send me your current project and I will send it back (renamed) with compiler setting plus a few items removed to get it to compile in 45 seconds...

 :o  Okay, no worries.
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1236 on: July 06, 2020, 03:30:24 pm »
Think I've spotted the problem with the PS2_STAT not incrementing in 1's - has to do with how I was incrementing the port_dly pipeline.  Will edit this post when I've had a chance to test the code.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1237 on: July 06, 2020, 03:38:08 pm »
Here you go. 1min, 20 sec compile time. (Well on my PC, it used to be over 4min to compile.)

The main changes is that I set layers to 2, meaning you have enough for text. (Assuming you are only using the first 2 layers right now...)

And a few compiler fitter settings.
A few minor timing violations, but so minor that it should either properly work, or you will see speckles on the screen.

Careful, keep this folder separate...
 
The following users thanked this post: nockieboy

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1238 on: July 06, 2020, 03:51:16 pm »
I'm using a 13-bit pipeline to delay the return data going onto the bus for an IO read.  If I do this each clk:

Code: [Select]
port_dly[12:1] <= port_dly[11:0];
It works, but with the IO_STAT counter going up in big jumps between IO reads of the IO_STAT port.  Does Verilog add zeros on the LSB side in this case?  If not, port_dly will just fill with ones and that's probably why IO_STAT is jumping up all the time, because it's incrementing constantly, whether it's read or not.  If I do this:

Code: [Select]
port_dly[12:0] <= { port_dly[11:0], 1'b0 };
IO reads don't work at all, I just get 0x78 back (which means nothing was put onto the data bus).   :-//
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1239 on: July 06, 2020, 04:11:29 pm »
Ahhh, now we are zeroing in on the true problem.  That increment error means every time you access the read port once, the Z80 bridge is seeing multiple port reads.

Now, is this because of
(A) noise on the bus IO controls making the Z80 bridge thing multiple read ports are taking place.
(B) just the way the Z80 makes these random bus transition during the 'wait' state.
(C) other parts of your code are calling that read multiple random times in between you reading the test counter.

This problem will lead to false keyboard reads, however, the only reason why your keyboard might have worked so well is that the PS2 data coming in only changes 1 keypress and you were reading duplicate copies instead of treating a single port read as an actual single port read.  I think I have a way to fix this universally, but I need to look as the data sheets.

Send me your updated Z80bridgev2.sv code now.

BTW, Quartus 12.0 compiles your GPU in 1 minute, using only 1 cpu core (no choice here).
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1240 on: July 06, 2020, 04:23:37 pm »
??? How did you do that IO read delay????
It makes no sense...

You were only supposed to edit these lines:

Code: [Select]
        if ( ~z80_op_read_port    && (z80_read_port_fc    != 1'd0                ) ) z80_read_port_fc    <= z80_read_port_fc    - 1'd1;
   else if (  z80_op_read_port    && (z80_read_port_fc    != Z80_CLK_FILTER[2:0] ) ) z80_read_port_fc    <= z80_read_port_fc    + 1'd1;
        if ( ~z80_op_read_port    && (z80_read_port_fc    == 1'd0                ) ) z80_read_port       <= 1'b0;
   else if (  z80_op_read_port    && (z80_read_port_fc    == Z80_CLK_FILTER[2:0] ) ) z80_read_port       <= 1'b1;

To something like:
Code: [Select]
        if ( ~z80_op_read_port    && (z80_read_port_fc    != 1'd0                ) ) z80_read_port_fc    <= z80_read_port_fc    - 1'd1;
   else if (  z80_op_read_port    && (z80_read_port_fc    != Z80_CLK_FILTER_PORT[2:0] ) ) z80_read_port_fc    <= z80_read_port_fc    + 1'd1;
        if ( ~z80_op_read_port    && (z80_read_port_fc    == 1'd0                ) ) z80_read_port       <= 1'b0;
   else if (  z80_op_read_port    && (z80_read_port_fc    == Z80_CLK_FILTER_PORT[2:0] ) ) z80_read_port       <= 1'b1;

Same for the write port.

I went through all that hassle so you could keep the read and write ports and ram all the same as I had it, not special circumventing work around code.  If you wanted a special delay state for any of the bus transaction, just add or subtract a number in my command filter section.

Your test counter isn't even working in the simulation, though I think you screwed up my code's concept from the beginning.
« Last Edit: July 06, 2020, 04:27:23 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1241 on: July 06, 2020, 04:29:53 pm »
??? How did you do that IO read delay????

Using a specific pipeline, like we did previously, as I wasn't 100% sure about the new method you're using, so I jury-rigged a delay for quick testing. :-\

It makes no sense...

You were only supposed to edit these lines:

Code: [Select]
        if ( ~z80_op_read_port    && (z80_read_port_fc    != 1'd0                ) ) z80_read_port_fc    <= z80_read_port_fc    - 1'd1;
   else if (  z80_op_read_port    && (z80_read_port_fc    != Z80_CLK_FILTER[2:0] ) ) z80_read_port_fc    <= z80_read_port_fc    + 1'd1;
        if ( ~z80_op_read_port    && (z80_read_port_fc    == 1'd0                ) ) z80_read_port       <= 1'b0;
   else if (  z80_op_read_port    && (z80_read_port_fc    == Z80_CLK_FILTER[2:0] ) ) z80_read_port       <= 1'b1;

To something like:
Code: [Select]
        if ( ~z80_op_read_port    && (z80_read_port_fc    != 1'd0                ) ) z80_read_port_fc    <= z80_read_port_fc    - 1'd1;
   else if (  z80_op_read_port    && (z80_read_port_fc    != Z80_CLK_FILTER_PORT[2:0] ) ) z80_read_port_fc    <= z80_read_port_fc    + 1'd1;
        if ( ~z80_op_read_port    && (z80_read_port_fc    == 1'd0                ) ) z80_read_port       <= 1'b0;
   else if (  z80_op_read_port    && (z80_read_port_fc    == Z80_CLK_FILTER_PORT[2:0] ) ) z80_read_port       <= 1'b1;

Same for the write port.

I went through all that hassle so you could keep the read and write ports and ram all the same as I had it, not special circumventing work around code.  If you wanted a special delay state for any of the bus transaction, just add or subtract a number in my command filter section.

Now I have a better idea how it works, I'll do it properly - I just wanted to get the IO working, then I'd worry about the code after.

Current Z80_bridge code attached as requested.
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1242 on: July 06, 2020, 06:02:37 pm »
Ok, is this what you want?

1018054-0

I've cleaned up what you messed in my code.
I've attached the Quartus simulation project.  You should be taking a closer look at the simulation results and coding and asking questions.

I changed the GPU clk filter to using the Z80 clk filter.  This is because in the Z80 data sheet, the delayed data out is timed to an additional Z80 clock cycle, not a fixed amount of time.

Since this is the first time we are using the Z80 clk, I hope the memory read and write still works.
Remember to update the block diagram, clear the old one and re-paste to get all the new default parameters updated as well.  Otherwise you might get some old  figures.

Also, if you simulate, you will notice that using a 'Z80_CLK_FILTER_P = 3', 1 more Z80 clk, makes the data out window really small and sweat, but I not sure it will work without scoping your Z80 bus to ensure timing.  Either that, or if your port reads are making random increments, maybe a setting of 3 will do the trick as it waits quite a bit of time before assessing the port address and then deciding to output the data or not.
« Last Edit: July 06, 2020, 06:59:09 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1243 on: July 06, 2020, 06:09:39 pm »
It looks like you've saved the PNG image of the simulation timings as the Z80_bridge.zip file.   :)
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1244 on: July 06, 2020, 06:24:19 pm »
Make 1 new change to my new source:

Change this line (around 256):
Code: [Select]
if ( z80_read_opcode || z80_read_memory || z80_read_port ) begin  // this section sets the output enable sends the correct data back to the Z80
To this:
Code: [Select]
if ( ~Z80_RDn_r ) begin  // this section sets the output enable sends the correct data back to the Z80
This turns off the read OE 1 gpu clk after the read data line on the bus as soon as possible right after the Z80_RDn_r goes high the way you like it.
« Last Edit: July 06, 2020, 06:25:55 pm by BrianHG »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1245 on: July 06, 2020, 06:48:50 pm »
I can't download your new source - the file you've attached in that previous post isn't a zip file, it's a PNG saved with a .zip extension.  :-//
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1246 on: July 06, 2020, 06:57:39 pm »
Its a bug at eevblog forum with multiple attachements... Here you go....
 
The following users thanked this post: nockieboy

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: FPGA VGA Controller for 8-bit computer
« Reply #1247 on: July 06, 2020, 08:28:45 pm »
Something weird is going on with the keyboard input.  :o

If I do individual 'IN' commands, or a sequence of them, to the PS2_STAT port, I get a nice incrementing number.

If I switch to polled keyboard input (so the 'OS' is constantly polling the PS2_DATA port for ASCII chars) - and I press a key on the keyboard - the screen fills with that key and the system locks up.

All I have changed in the Z80_bridge you sent was this:
Code: [Select]
   if ( z80_read_port_1s && Z80_addr_r[7:0]==IO_DATA[7:0] ) begin  // Z80 is reading PS/2 port
      Z80_rData  <= PS2_CHAR;
      PS2_CHAR   <= 8'b0;
   end

I removed the incrementing value you'd made for the PS2_DATA port and made it return the PS2_CHAR value instead.  The value should be reset to 0x00 when it is read.

As soon as I get some time, I'll start simulating and looking to see if I can replicate the issue there.


 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1248 on: July 06, 2020, 08:47:03 pm »
Something weird is going on with the keyboard input.  :o

If I do individual 'IN' commands, or a sequence of them, to the PS2_STAT port, I get a nice incrementing number.
Yay, read port now works error free perfectly fine.  No glitching.  I assume that memory read and writes and port writes are good too.

Z80_bridge now good  :) .

Quote
If I switch to polled keyboard input (so the 'OS' is constantly polling the PS2_DATA port for ASCII chars) - and I press a key on the keyboard - the screen fills with that key and the system locks up.

All I have changed in the Z80_bridge you sent was this:
Code: [Select]
   if ( z80_read_port_1s && Z80_addr_r[7:0]==IO_DATA[7:0] ) begin  // Z80 is reading PS/2 port
      Z80_rData  <= PS2_CHAR;
      PS2_CHAR   <= 8'b0;
   end

Do not change these lines, they are correct.

This isn't where your error is.  This is the way the PS2 VHDL is written and that its working at 50MHz, not 125MHz. 

Your lines:
Code: [Select]
   if (PS2_RDY) begin           // valid data on PS2_DAT
      PS2_CHAR   <= PS2_DAT;    // Latch the character into Ps2_char register
   end

Is where the problem lies.

PS2_RDY input may remain high for an indefinite number of clock cycles.  In fact, it may stay high and go low only for a few clk cycles as a new character is updated, though, I have not read up on the unknown VHDL code you are using.

try this instead:
Code: [Select]
reg [7:0] PS2_RDY_r;
.......
PS2_RDY_r[7:0] <= {PS2_RDY_r[6:0],PS2_RDY};
   if (PS2_RDY_r[7:0] == 8'b00001111 ) begin           // valid data on PS2_DAT
      PS2_CHAR   <= PS2_DAT;    // Latch the character into Ps2_char register
   end

This means that the PS2_RDY needs to come in for 4 clocks low, then 4 clocks high in a row for the PS2_CHAR to latch the data on that 1 single clock shot, however, this will not solve reading the keyboard port & hitting a key simultaneously.

To fix that problem, you need to:
Code: [Select]
   if ( z80_read_port_1s && Z80_addr_r[7:0]==IO_DATA[7:0] ) begin  // Z80 is reading PS/2 port
      Z80_rData  <= PS2_CHAR;
      if (PS2_RDY_r[7:0] != 8'b00001111 )  PS2_CHAR   <= 8'b0;
end

That if will prevent the clearing of the PS2_CHAR if a new key is pressed at the same time you are reading the current character.
« Last Edit: July 06, 2020, 09:56:53 pm by BrianHG »
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 8126
  • Country: ca
Re: FPGA VGA Controller for 8-bit computer
« Reply #1249 on: July 06, 2020, 09:19:38 pm »
What you will need to eventually do is make an 8 byte port where if you have multiple keys pressed, each byte will retain one of the 8 keys while they are still pressed.  As they keys are released the keyboard HDL will clear the correct one of the 8 bytes to 0.  The read port will not clear each key's set byte, but HDL will react to you releasing each key on the keyboard by clearing to 0 of the correct one of the 8 bytes.

Your Z80 can scan the 8 bytes and decide what to do, like key repeats, or in game mode, have raw access to those 8 bytes for game controls.

If you want the Z80 to clear any one of the 8 keyboard bytes, you would just write to that port byte.

Or, just 'F' it and do it in software.  Use the current setup and use the bit 8 in the character to send to the Z80 normal key bottom 7 bit code plus the same code again with bit 8 signifying that the key was released.

This way it is backwards compatible with what you have now as long as you ignore any incoming characters with a value above 127.
« Last Edit: July 06, 2020, 09:52:48 pm by BrianHG »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf