Warning (13012): Latch key2ascii:inst26|ascii_code[6] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal keyboard:inst25|ps2_rx:ps2_rx_unit|d_reg[8]

ascii_code = 8'h00;
Hang on - think I've fixed the errors:Code: [Select]ascii_code = 8'h00;
Just needed to add that at the start of the 'always @*' block - seems the initial block wasn't quite making Quartus happy enough. On to the next step of debugging... watch this space!
I had to do some reading on it and still don't really understand it. 

If you're using Verilog code why are you messing with the schematic entry? Just use either Verilog or VHDL for the top level too, it ends up being much simpler and easier to work with.
translate the PS/2 data into a keycode and pass it to key2ascii.sv, which translates the keycode into an ASCII char and passes that out via an 8-bit parallel bus to the Z80 interface.
if the returned value is 0x00, it does nothing, otherwise it prints the character to the serial console. Once the character is read, Z80_bridge.sv resets PS2_CHAR to 0x00 again to prevent repetition. This should all happen so quickly there's no chance of a repeated (or held) keypress overwriting the last one before it's read.
I'll take a look at the code on the weekend, however, try tying the data outputs, before and after the key decoder, to a few spare inputs on the RS232 debugger 'debug' input ports and let me know what you see when running the debugger on the utility inputs.
Also, add 2x8 bit counters on the same keyboard clock, and tie the 'scan_code_ready' and 'ascii_code_ready' outputs to each counter's enable input. Tie those 8 bit outputs to the other 2 spare utility inputs on the RS232 debugger module and see what happens when you use the keyboard.
See if the counters increment once per key press.

How to manage special keys like shift, caps, ctrl, F1-12, etc?
They cannot be mapped as ASCII char.
How do you handle keys being held down, like holding the up arrow for walking forward in a video game.
Or multiple keys simultaneously being pressed...

No idea - haven't gotten that far yet. I can't do anything all the time I can't read what key is being pressed or all I can read is 0x78.
If it turns out the key2ascii.sv module doesn't cater for all my needs, I'll have to have a think about some other way to do it. Either way though, I need to be able to reliably do an IO read from the z80_bridge.
I think you're designing it backwards. I would start from figuring out what kind of interface I want to present to my CPU first, for input devices it's usual to have a bunch of status registers, an interrupt line to the CPU, and a control register which allows you setting various options (for example enabling/disabling interrupts).
Once you figure out that part, only then would I go about finding out how to implement a PHY (physical interface to the actual device).
No idea - haven't gotten that far yet. I can't do anything all the time I can't read what key is being pressed or all I can read is 0x78.
If it turns out the key2ascii.sv module doesn't cater for all my needs, I'll have to have a think about some other way to do it. Either way though, I need to be able to reliably do an IO read from the z80_bridge.I think you're designing it backwards. I would start from figuring out what kind of interface I want to present to my CPU first, for input devices it's usual to have a bunch of status registers, an interrupt line to the CPU, and a control register which allows you setting various options (for example enabling/disabling interrupts).
Once you figure out that part, only then would I go about finding out how to implement a PHY (physical interface to the actual device).
This is the result of taking an off the shelf existing public domain keyboard PHY / decoder and tying it into your existing design instead of doing it all from scratch to your liking.
Now, for a simple keyboard interface using the existing cores, I would probably choose to place a 16 word 'FIFO' (configured with overflow protection) between the existing interface and his Z80 bus. I would use the FIFO's empty flag on the output side to trigger a configurable interrupt. I would use the 4 bit 'used/filled' status output of the 'FIFO' at a second port address so the Z80 may see how many characters are in the keyboard buffer to be read. Sort of like the keyboard being read like a serial port.
Thanks for the replies - that's not my code, by the way, but an example I found on the interweb somewhere. The use of 'always @*' confused the heck out of me - as you know asmi, I'm a learner when it comes to HDL and suddenly walking into code that is combinatorial instead of synchronous was a bit of a shock.I had to do some reading on it and still don't really understand it.
always @(in_a or in_b or in_c)
begin
q = in_a & in_b & in_c;
end(and note the use of the blocking assignment.)fData <= PS2Data when ( nPS2cs = '0' and fnRd = '0' ) else
( others => 'Z');
fData_dir <= '1' when ( fnIorq = '0' or fnRd = '0' ) and ( nPS2cs = '0' ) else '0';
nPScs <= '0' when fAddress(7 downto 0) = "00000001" and ( fnIorq = '0' and fnRd = '0' ) else '1'; -- Z80 I/O port 01h
I have overcome similar issues doing I/O reads with a Z80 from devices in an FPGA (while also using level translators). I'd like to help but I am using VHDL and also very much a beginner...
I have overcome similar issues doing I/O reads with a Z80 from devices in an FPGA (while also using level translators). I'd like to help but I am using VHDL and also very much a beginner...
I haven't had time today to look at the code, so it's probably going to be a slow-burn all week, but I'm growing more convinced it's an HDL code problem, so shouldn't be too hard to find unless it turns out to be a timing problem. Did you have any issues with timing when responding to an IO read by the Z80?
Have you simulated the code?
, but I guess no time like the present to finally grip it and start learning.
Have you simulated the code?
No, I haven't - simulation seems like a bit of a dark art to me, but I guess no time like the present to finally grip it and start learning.



I'm still not quite sure why the issue is fixed, but I'm now getting 100% error-free values back from the virtual PS/2 port in z80_bridge. So next I'll reconnect the PS/2 interface back up and see what happens next... Watch this space.![]()
In a lot of examples on the Internet I see returning of value 0xff instead of 'Z' .That did not work for when when using a real Z80.Congrats!
That is exactly as I thoughtIn a lot of examples on the Internet I see returning of value 0xff instead of 'Z' .That did not work for when when using a real Z80.
Setting the DIR pin of the level converters properly is crucial, without it you'll get odd results.
Wrt timing issues: I see these only when the device internal in the FGPA is running at a different speed then the real Z80.
I'm now happy that the IO interface is working properly - I can read and write values to the FPGA with no errors at all now. I've now wired up the PS/2 socket and connected the keyboard and have connected up the PS/2 interface modules in the HDL as per my original post, but I'm still getting rubbish coming through when I type.
Here's an example:qAAAqAAAA@w@AA@AwAAAAAeAAAAeAAAAAr@@@@@r@@@@@t@@@@@@t@@@@@ssAAAAsAAAAA