I think this design will fit
Tonight's work is a two-parter. Firstly, the two-line upscaler for the HDMI output. While the 240p output from the synthesized ULA is perfect for driving a 320x240 screen, the probabilities surrounding getting a TV to accept 240p over HDMI is a little more hit and miss. Some TVs will do it, some won't. Let's not enough talk about projectors.
So a scan doubler has been added for the HDMI output. Or more accurately, a pixel quadrupler. The way it works is quite sneaky, and allows scan doubling with only 64µs lag.
Inside the FPGA, there are two banks of 320x4bit dual port RAM. Two processes run concurrently, synchronised to the horizontal start of display area (16 pixels from the left hand border). The output process runs at 28MHz, which is four times the input process at 7Mhz. This results in two output lines at 896 pixels in the same time as two input lines at 448 pixels.
(Remember previously about the need for overscan? There are 320 active pixels out of 448 horizontally on the low-resolution side, and 640 active pixels out of 896 on the high resolution side).
The 28MHz clock generates two identical pixels at each memory position. Because of the quad clock speed, it means that 4 input lines of data are output in the same time as one input line is scanned. The horizontal pixel doubling causes this to drop back to 2 output lines for 1 input line, but at double data rate (keeping up?).
Now here's where the two banks come in. During the inactive area, the banks are swapped. The high-resolution output draws from the oppposing bank to where the low resolution output is storing (hence the one scanline or 64µs delay).
This gives a 640x480 display at 28MHz that is identical to and synchronised with the 320x240 display at 7MHz. With line frequencies at 15kHz and 30kHz respectively, both at 50Hz field rate.
Meanwhile....
I was finally in a position to assign pins and map the logic onto the device. Here are some stats:
Register bits: 684
Look-up tables: 2406
I/O Pins: 106
That complete signal set in full:
PORTABIT_S[0-2]: Status bits from the PortaBit microcontroller
KA[0-2]: Keyboard row address for keymapping
KJD[0-5]: Keyboard column data for keymapping or joystick input data
RST: Reset PortaCore
ATN: Attention - basically the Z80's NMI line
TRAP_RST: Reset trap address counter
TRAP_A: Trap address part (0=LSB,1=MSB)
TRAP_S: Trap part (0=Address, 1=model/bank)
TRAP_CLK: Write trap data to trap memory and increment trap address
MCLK: Master 28MHz clock
MODEL[1-0]: Select ZX Spectrum model or Firmware Update mode
FLASHCLK: Increment flash programming address
KW: Write keyboard data
JW: Write joystick data
I2S_MCK: I²S Master 11.2896 MHz clock
I2S_LRCK: I²S 44.1kHz channel clock
I2S_DCK: I²S 1.1411MHz data clock
I2S_D: I²S audio data
UA[0-16]: Uncontended RAM address/Flash ROM address
VID_R/G/B[0-1]: Low resolution video output data.
VID_HR/HG/HB[0-1] High resolution video output data.
VID_DE: Low resolution video data enable
VID_HDE: High resolution video data enable
VID_CLK: 7MHz low resolution dot clock
CRAMCS: Contended RAM chip select
CRAMRD: Contended RAM output enable
CRAMWR: Contended RAM write enable
URAMCS: Uncontended RAM chip select
URD: Uncontended RAM/Flash EEPROM output enable
UWR: Uncontnded RAM write enable
PORTABIT: PortaBit microcontroller chip select
PORTABIT_C: PortaBit control bits
CA[0-16]: Contended RAM address
ROMCS: Flash EEPROM chip select
UD[0-7]: Uncontended RAM/Flash EEPROM data bus
CD[0-7]: Contended RAM data bus
Now to design a development board.
So a scan doubler has been added for the HDMI output. Or more accurately, a pixel quadrupler. The way it works is quite sneaky, and allows scan doubling with only 64µs lag.
Inside the FPGA, there are two banks of 320x4bit dual port RAM. Two processes run concurrently, synchronised to the horizontal start of display area (16 pixels from the left hand border). The output process runs at 28MHz, which is four times the input process at 7Mhz. This results in two output lines at 896 pixels in the same time as two input lines at 448 pixels.
(Remember previously about the need for overscan? There are 320 active pixels out of 448 horizontally on the low-resolution side, and 640 active pixels out of 896 on the high resolution side).
The 28MHz clock generates two identical pixels at each memory position. Because of the quad clock speed, it means that 4 input lines of data are output in the same time as one input line is scanned. The horizontal pixel doubling causes this to drop back to 2 output lines for 1 input line, but at double data rate (keeping up?).
Now here's where the two banks come in. During the inactive area, the banks are swapped. The high-resolution output draws from the oppposing bank to where the low resolution output is storing (hence the one scanline or 64µs delay).
This gives a 640x480 display at 28MHz that is identical to and synchronised with the 320x240 display at 7MHz. With line frequencies at 15kHz and 30kHz respectively, both at 50Hz field rate.
Meanwhile....
I was finally in a position to assign pins and map the logic onto the device. Here are some stats:
Register bits: 684
Look-up tables: 2406
I/O Pins: 106
That complete signal set in full:
PORTABIT_S[0-2]: Status bits from the PortaBit microcontroller
KA[0-2]: Keyboard row address for keymapping
KJD[0-5]: Keyboard column data for keymapping or joystick input data
RST: Reset PortaCore
ATN: Attention - basically the Z80's NMI line
TRAP_RST: Reset trap address counter
TRAP_A: Trap address part (0=LSB,1=MSB)
TRAP_S: Trap part (0=Address, 1=model/bank)
TRAP_CLK: Write trap data to trap memory and increment trap address
MCLK: Master 28MHz clock
MODEL[1-0]: Select ZX Spectrum model or Firmware Update mode
FLASHCLK: Increment flash programming address
KW: Write keyboard data
JW: Write joystick data
I2S_MCK: I²S Master 11.2896 MHz clock
I2S_LRCK: I²S 44.1kHz channel clock
I2S_DCK: I²S 1.1411MHz data clock
I2S_D: I²S audio data
UA[0-16]: Uncontended RAM address/Flash ROM address
VID_R/G/B[0-1]: Low resolution video output data.
VID_HR/HG/HB[0-1] High resolution video output data.
VID_DE: Low resolution video data enable
VID_HDE: High resolution video data enable
VID_CLK: 7MHz low resolution dot clock
CRAMCS: Contended RAM chip select
CRAMRD: Contended RAM output enable
CRAMWR: Contended RAM write enable
URAMCS: Uncontended RAM chip select
URD: Uncontended RAM/Flash EEPROM output enable
UWR: Uncontnded RAM write enable
PORTABIT: PortaBit microcontroller chip select
PORTABIT_C: PortaBit control bits
CA[0-16]: Contended RAM address
ROMCS: Flash EEPROM chip select
UD[0-7]: Uncontended RAM/Flash EEPROM data bus
CD[0-7]: Contended RAM data bus
Now to design a development board.

Comments
Post a Comment