mirror of
https://github.com/alangarf/apple-one.git
synced 2024-06-10 13:29:42 +00:00
Added Ulx4m support
This commit is contained in:
parent
a7c01443ae
commit
a20b44bfc7
21
boards/ulx4m/README.md
Normal file
21
boards/ulx4m/README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Ulx4m with HDMI
|
||||
|
||||
This adds support for building the Apple One design for [Ulx4m](https://intergalaktik.eu/projects/ulx4m/) with HDMI output and a PS/2 keyboard connected to a Digilent PS2 keyboard PMOD.
|
||||
|
||||
## Peripheral support
|
||||
|
||||
HDMI output on the built-in HDMI connector
|
||||
|
||||
PS/2 keyboard via a Digilent PS2 keyboard PMOD on gpio[25] and gpio[26].
|
||||
|
||||
## Building
|
||||
Install a recent ECP5 open source toolchain, and do:
|
||||
|
||||
```
|
||||
$ cd yosys
|
||||
$ make
|
||||
```
|
||||
|
||||
## Use
|
||||
|
||||
To load BASIC type "E000R" (with CAPS LOCK on if you are using the UART rather than the PS/2 keyboard).
|
73
boards/ulx4m/yosys/Makefile
Normal file
73
boards/ulx4m/yosys/Makefile
Normal file
|
@ -0,0 +1,73 @@
|
|||
DEVICE = um-45k
|
||||
PIN_DEF=ulx4m_v002.lpf
|
||||
|
||||
SOURCEDIR = ../../../rtl
|
||||
BUILDDIR = build
|
||||
|
||||
all: apple1 prog
|
||||
|
||||
info:
|
||||
@echo " To build: make apple1"
|
||||
@echo " To program: make prog or make dfu"
|
||||
@echo "To build report: make report"
|
||||
@echo " To clean up: make clean"
|
||||
|
||||
dir:
|
||||
mkdir -p $(BUILDDIR)
|
||||
|
||||
# ------ TEMPLATES ------
|
||||
$(BUILDDIR)/%.json: $(SOURCEDIR)/%.v
|
||||
yosys -q -p "chparam -list; hierarchy -top apple1_top; synth_ecp5 -json $@" $^
|
||||
|
||||
$(BUILDDIR)/%.config: $(PIN_DEF) $(BUILDDIR)/%.json
|
||||
nextpnr-ecp5 --${DEVICE} --package CABGA381 --freq 25 --textcfg $@ --json $(filter-out $<,$^) --lpf $<
|
||||
|
||||
$(BUILDDIR)/%.bit: $(BUILDDIR)/%.config
|
||||
ecppack --compress $^ $@
|
||||
|
||||
%_tb.vvp: %_tb.v %.v
|
||||
iverilog -o $@ $^
|
||||
|
||||
%_tb.vcd: %_tb.vvp
|
||||
vvp -N $< +vcd=$@
|
||||
|
||||
# ------ APPLE 1 ------
|
||||
apple1: dir $(BUILDDIR)/apple1.bit
|
||||
|
||||
$(BUILDDIR)/apple1.bin: $(BUILDDIR)/apple1.asc
|
||||
$(BUILDDIR)/apple1.asc: $(BUILDDIR)/apple1.json
|
||||
$(BUILDDIR)/apple1.json: $(SOURCEDIR)/apple1.v \
|
||||
$(SOURCEDIR)/clock.v \
|
||||
$(SOURCEDIR)/pwr_reset.v \
|
||||
$(SOURCEDIR)/ram.v \
|
||||
$(SOURCEDIR)/rom_wozmon.v \
|
||||
$(SOURCEDIR)/rom_basic.v \
|
||||
$(SOURCEDIR)/cpu/arlet_6502.v \
|
||||
$(SOURCEDIR)/cpu/arlet/ALU.v \
|
||||
$(SOURCEDIR)/cpu/arlet/cpu.v \
|
||||
$(SOURCEDIR)/uart/uart.v \
|
||||
$(SOURCEDIR)/uart/async_tx_rx.v \
|
||||
$(SOURCEDIR)/vga/vga.v \
|
||||
$(SOURCEDIR)/vga/vram.v \
|
||||
$(SOURCEDIR)/vga/font_rom.v \
|
||||
$(SOURCEDIR)/ps2keyboard/debounce.v \
|
||||
$(SOURCEDIR)/ps2keyboard/ps2keyboard.v \
|
||||
$(SOURCEDIR)/boards/ulx4m/apple1_dvi.v \
|
||||
$(SOURCEDIR)/boards/ulx4m/vga2dvid.v \
|
||||
$(SOURCEDIR)/boards/ulx4m/clk_25_250_125_25.v \
|
||||
$(SOURCEDIR)/boards/ulx4m/tmds_encoder.v \
|
||||
$(SOURCEDIR)/boards/ulx4m/fake_differential.v
|
||||
|
||||
prog: dir $(BUILDDIR)/apple1.bit
|
||||
fujprog $(filter-out $<,$^)
|
||||
|
||||
dfu: dir $(BUILDDIR)/apple1.bit
|
||||
dfu-util -a 0 -D $(filter-out $<,$^) -R
|
||||
|
||||
|
||||
# ------ HELPERS ------
|
||||
clean:
|
||||
rm -rf build
|
||||
|
||||
.SECONDARY:
|
||||
.PHONY: all info clean prog
|
BIN
boards/ulx4m/yosys/apple1.bit
Normal file
BIN
boards/ulx4m/yosys/apple1.bit
Normal file
Binary file not shown.
30
boards/ulx4m/yosys/slow.py
Executable file
30
boards/ulx4m/yosys/slow.py
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: " + sys.argv[0] + " <filename>")
|
||||
sys.exit(1)
|
||||
|
||||
os.system('stty -F /dev/ttyUSB0 raw -echo 115200')
|
||||
fin = open(sys.argv[1], "r")
|
||||
fout = open("/dev/ttyUSB0", "w")
|
||||
|
||||
for line in fin:
|
||||
for ch in line.strip('\n'):
|
||||
fout.write(ch)
|
||||
fout.flush()
|
||||
time.sleep(.1)
|
||||
fout.write('\r')
|
||||
fout.flush()
|
||||
time.sleep(.5)
|
||||
fin.close()
|
||||
fout.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
397
boards/ulx4m/yosys/ulx4m_v002.lpf
Normal file
397
boards/ulx4m/yosys/ulx4m_v002.lpf
Normal file
|
@ -0,0 +1,397 @@
|
|||
BLOCK RESETPATHS;
|
||||
BLOCK ASYNCPATHS;
|
||||
## ULX4M-LS v0.0.2
|
||||
|
||||
# The clock "usb" and "gpdi" sheet
|
||||
LOCATE COMP "clk_25mhz" SITE "G2";
|
||||
IOBUF PORT "clk_25mhz" PULLMODE=NONE IO_TYPE=LVCMOS33;
|
||||
FREQUENCY PORT "clk_25mhz" 25 MHZ;
|
||||
|
||||
# JTAG and SPI FLASH voltage 3.3V and options to boot from SPI flash
|
||||
# write to FLASH possible any time from JTAG:
|
||||
SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 SLAVE_SPI_PORT=DISABLE MASTER_SPI_PORT=ENABLE SLAVE_PARALLEL_PORT=DISABLE;
|
||||
# write to FLASH possible from user bitstream:
|
||||
# SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 SLAVE_SPI_PORT=DISABLE MASTER_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE;
|
||||
|
||||
## LED indicators "blinkey" and "gpio" sheet
|
||||
LOCATE COMP "led[3]" SITE "C1";
|
||||
LOCATE COMP "led[2]" SITE "B3";
|
||||
LOCATE COMP "led[1]" SITE "B1";
|
||||
LOCATE COMP "led[0]" SITE "B2";
|
||||
IOBUF PORT "led[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "led[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "led[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "led[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## Buttons "blinkey" and "gpio" sheet
|
||||
LOCATE COMP "btn[1]" SITE "C3";
|
||||
LOCATE COMP "btn[2]" SITE "C2";
|
||||
IOBUF PORT "btn[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "btn[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## SPI Flash chip "flash" sheet
|
||||
LOCATE COMP "flash_csn" SITE "R2";
|
||||
LOCATE COMP "flash_clk" SITE "U3";
|
||||
LOCATE COMP "flash_mosi" SITE "W2";
|
||||
LOCATE COMP "flash_miso" SITE "V2";
|
||||
LOCATE COMP "flash_holdn" SITE "W1";
|
||||
LOCATE COMP "flash_wpn" SITE "Y2";
|
||||
#LOCATE COMP "flash_csspin" SITE "AJ3";
|
||||
#LOCATE COMP "flash_initn" SITE "AG4";
|
||||
#LOCATE COMP "flash_done" SITE "AJ4";
|
||||
#LOCATE COMP "flash_programn" SITE "AH4";
|
||||
#LOCATE COMP "flash_cfg_select[0]" SITE "AM4";
|
||||
#LOCATE COMP "flash_cfg_select[1]" SITE "AL4";
|
||||
#LOCATE COMP "flash_cfg_select[2]" SITE "AK4";
|
||||
IOBUF PORT "flash_csn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "flash_clk" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "flash_mosi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "flash_miso" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "flash_holdn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "flash_wpn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_csspin" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_initn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_done" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_programn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_cfg_select[0]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_cfg_select[1]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "flash_cfg_select[2]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## SD card "sdcard", "usb" sheet
|
||||
LOCATE COMP "sd_clk" SITE "H2"; # sd_clk WiFi_GPIO14 CM4_GPIO12
|
||||
LOCATE COMP "sd_cmd" SITE "J1"; # sd_cmd_di (MOSI) WiFi_GPIO15 CM4_GPIO27
|
||||
LOCATE COMP "sd_d[0]" SITE "J3"; # sd_dat0_do (MISO) WiFi_GPIO2 CM4_GPIO4
|
||||
LOCATE COMP "sd_d[1]" SITE "H1"; # sd_dat1_irq WiFi_GPIO4 CM4_GPIO3
|
||||
LOCATE COMP "sd_d[2]" SITE "K1"; # sd_dat2 WiFi_GPIO12 CM4_GPIO2
|
||||
LOCATE COMP "sd_d[3]" SITE "K2"; # sd_dat3_csn WiFi_GPIO13 CM4_GPIO14
|
||||
LOCATE COMP "sd_wp" SITE "P5"; # not connected
|
||||
LOCATE COMP "sd_cdn" SITE "N5"; # not connected
|
||||
IOBUF PORT "sd_clk" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sd_cmd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sd_d[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sd_d[1]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sd_d[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; # WiFi GPIO12 pulldown bootstrapping requirement
|
||||
IOBUF PORT "sd_d[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sd_wp" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sd_cdn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
LOCATE COMP "sd_pwr_on" SITE "U17"; # J2_5- GN14
|
||||
IOBUF PORT "sd_pwr_on" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## Second USB port "US2" going directly into FPGA "usb", "ram" sheet
|
||||
LOCATE COMP "usb_fpga_dp" SITE "E16"; # same on ULX3S and ULX4M
|
||||
LOCATE COMP "usb_fpga_dn" SITE "F16"; # same on ULX3S and ULX4M
|
||||
IOBUF PORT "usb_fpga_dp" PULLMODE=NONE IO_TYPE=LVCMOS33D DRIVE=16;
|
||||
IOBUF PORT "usb_fpga_dn" PULLMODE=NONE IO_TYPE=LVCMOS33D DRIVE=16;
|
||||
LOCATE COMP "usb_fpga_bd_dp" SITE "D15"; # single-ended bidirectional same on ULX3S and ULX4M
|
||||
LOCATE COMP "usb_fpga_bd_dn" SITE "E15"; # single-ended bidirectional same on ULX3S and ULX4M
|
||||
IOBUF PORT "usb_fpga_bd_dp" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "usb_fpga_bd_dn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
LOCATE COMP "usb_fpga_pu_dp" SITE "A2"; # pull up/down control
|
||||
LOCATE COMP "usb_fpga_pu_dn" SITE "A3";
|
||||
IOBUF PORT "usb_fpga_pu_dp" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16;
|
||||
IOBUF PORT "usb_fpga_pu_dn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=16;
|
||||
LOCATE COMP "usb_fpga_otg_id" SITE "A4";
|
||||
IOBUF PORT "usb_fpga_otg_id" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
LOCATE COMP "n_extrst" SITE "U16";
|
||||
IOBUF PORT "n_extrst" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## JTAG ESP-32 "usb" sheet
|
||||
# connected to FT231X and ESP-32
|
||||
# commented out because those are dedicated pins, not directly useable as GPIO
|
||||
# but could be used by some vendor-specific JTAG bridging (boundary scan) module
|
||||
#LOCATE COMP "jtag_tdi" SITE "R5"; # FTDI_nRI FPGA receives
|
||||
#LOCATE COMP "jtag_tdo" SITE "V4"; # FTDI_nCTS FPGA transmits
|
||||
#LOCATE COMP "jtag_tck" SITE "T5"; # FTDI_nDSR FPGA receives
|
||||
#LOCATE COMP "jtag_tms" SITE "U5"; # FTDI_nDCD FPGA receives
|
||||
#IOBUF PORT "jtag_tdi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "jtag_tdo" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "jtag_tck" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "jtag_tms" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## SDRAM "ram" sheet
|
||||
LOCATE COMP "sdram_clk" SITE "G19";
|
||||
LOCATE COMP "sdram_cke" SITE "G20";
|
||||
LOCATE COMP "sdram_csn" SITE "P18";
|
||||
LOCATE COMP "sdram_wen" SITE "N20";
|
||||
LOCATE COMP "sdram_rasn" SITE "M18";
|
||||
LOCATE COMP "sdram_casn" SITE "N18";
|
||||
LOCATE COMP "sdram_a[0]" SITE "L19";
|
||||
LOCATE COMP "sdram_a[1]" SITE "L20";
|
||||
LOCATE COMP "sdram_a[2]" SITE "M19";
|
||||
LOCATE COMP "sdram_a[3]" SITE "H17";
|
||||
LOCATE COMP "sdram_a[4]" SITE "F20";
|
||||
LOCATE COMP "sdram_a[5]" SITE "F18";
|
||||
LOCATE COMP "sdram_a[6]" SITE "E19";
|
||||
LOCATE COMP "sdram_a[7]" SITE "F19";
|
||||
LOCATE COMP "sdram_a[8]" SITE "E20";
|
||||
LOCATE COMP "sdram_a[9]" SITE "C20";
|
||||
LOCATE COMP "sdram_a[10]" SITE "N19";
|
||||
LOCATE COMP "sdram_a[11]" SITE "D20";
|
||||
LOCATE COMP "sdram_a[12]" SITE "E18";
|
||||
LOCATE COMP "sdram_ba[0]" SITE "L18";
|
||||
LOCATE COMP "sdram_ba[1]" SITE "M20";
|
||||
LOCATE COMP "sdram_dqm[0]" SITE "P20";
|
||||
LOCATE COMP "sdram_dqm[1]" SITE "D19";
|
||||
LOCATE COMP "sdram_d[0]" SITE "U20";
|
||||
LOCATE COMP "sdram_d[1]" SITE "T20";
|
||||
LOCATE COMP "sdram_d[2]" SITE "U19";
|
||||
LOCATE COMP "sdram_d[3]" SITE "T19";
|
||||
LOCATE COMP "sdram_d[4]" SITE "T18";
|
||||
LOCATE COMP "sdram_d[5]" SITE "T17";
|
||||
LOCATE COMP "sdram_d[6]" SITE "R20";
|
||||
LOCATE COMP "sdram_d[7]" SITE "P19";
|
||||
LOCATE COMP "sdram_d[8]" SITE "H20";
|
||||
LOCATE COMP "sdram_d[9]" SITE "J19";
|
||||
LOCATE COMP "sdram_d[10]" SITE "K18";
|
||||
LOCATE COMP "sdram_d[11]" SITE "J18";
|
||||
LOCATE COMP "sdram_d[12]" SITE "H18";
|
||||
LOCATE COMP "sdram_d[13]" SITE "J16";
|
||||
LOCATE COMP "sdram_d[14]" SITE "K19";
|
||||
LOCATE COMP "sdram_d[15]" SITE "J17";
|
||||
IOBUF PORT "sdram_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_cke" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_csn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_wen" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_rasn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_casn" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_a[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_ba[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_ba[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_dqm[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_dqm[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sdram_d[15]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
# GPDI differential interface (Video) "gpdi" sheet
|
||||
LOCATE COMP "gpdi_dp[0]" SITE "F17"; # Blue +
|
||||
LOCATE COMP "gpdi_dn[0]" SITE "G18"; # Blue -
|
||||
LOCATE COMP "gpdi_dp[1]" SITE "D18"; # Green +
|
||||
LOCATE COMP "gpdi_dn[1]" SITE "E17"; # Green -
|
||||
LOCATE COMP "gpdi_dp[2]" SITE "C18"; # Red +
|
||||
LOCATE COMP "gpdi_dn[2]" SITE "D17"; # Red -
|
||||
LOCATE COMP "gpdi_dp[3]" SITE "J20"; # Clock +
|
||||
LOCATE COMP "gpdi_dn[3]" SITE "K20"; # Clock -
|
||||
#LOCATE COMP "gpdi_ethp" SITE "A19"; # Ethernet +
|
||||
#LOCATE COMP "gpdi_ethn" SITE "B20"; # Ethernet -
|
||||
LOCATE COMP "gpdi_cec" SITE "A18";
|
||||
#LOCATE COMP "gpdi_sda" SITE "B19"; # I2C shared with RTC
|
||||
#LOCATE COMP "gpdi_scl" SITE "E12"; # I2C shared with RTC C12->E12
|
||||
IOBUF PORT "gpdi_dp[0]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_dn[0]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpdi_dp[1]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_dn[1]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpdi_dp[2]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_dn[2]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpdi_dp[3]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_dn[3]" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_ethp" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_ethn" IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpdi_cec" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_sda" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
#IOBUF PORT "gpdi_scl" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
LOCATE COMP "gpdi_dp[4]" SITE "B9"; # Blue +
|
||||
#LOCATE COMP "gpdi_dn[4]" SITE "C10"; # Blue -
|
||||
LOCATE COMP "gpdi_dp[5]" SITE "A7"; # Green +
|
||||
#LOCATE COMP "gpdi_dn[5]" SITE "A8"; # Green -
|
||||
LOCATE COMP "gpdi_dp[6]" SITE "C8"; # Red +
|
||||
#LOCATE COMP "gpdi_dn[6]" SITE "B8"; # Red -
|
||||
LOCATE COMP "gpdi_dp[7]" SITE "B11"; # Clock +
|
||||
#LOCATE COMP "gpdi_dn[7]" SITE "C11"; # Clock -
|
||||
IOBUF PORT "gpdi_dp[4]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dn[4]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dp[5]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dn[5]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dp[6]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dn[6]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dp[7]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
IOBUF PORT "gpdi_dn[7]" IO_TYPE=LVCMOS33D DRIVE=4;
|
||||
|
||||
# wifi - do not use together with CM4 GPIO
|
||||
LOCATE COMP "wifi_gpio0" SITE "U1";
|
||||
LOCATE COMP "wifi_gpio2" SITE "K4"; # sd_d0_do (MISO) WiFi GPIO2
|
||||
LOCATE COMP "wifi_gpio4" SITE "J5"; # sd_d1_irq WiFi GPIO4
|
||||
LOCATE COMP "wifi_gpio5" SITE "U5"; #
|
||||
LOCATE COMP "wifi_gpio12" SITE "K5"; # sd_d2 WiFi_GPIO12
|
||||
LOCATE COMP "wifi_gpio13" SITE "L4"; # sd_d3_csn WiFi_GPIO13
|
||||
LOCATE COMP "wifi_gpio14" SITE "L5"; # sd_clk WiFi_GPIO14
|
||||
LOCATE COMP "wifi_gpio15" SITE "N16"; # sd_cmd_di (MOSI) WiFi GPIO15
|
||||
LOCATE COMP "wifi_gpio19" SITE "P4";
|
||||
LOCATE COMP "wifi_gpio21" SITE "P17";
|
||||
LOCATE COMP "wifi_gpio22" SITE "P16";
|
||||
LOCATE COMP "wifi_gpio25" SITE "L16";
|
||||
LOCATE COMP "wifi_gpio26" SITE "N17";
|
||||
LOCATE COMP "wifi_gpio27" SITE "G16";
|
||||
LOCATE COMP "wifi_gpio33" SITE "H16";
|
||||
LOCATE COMP "wifi_gpio34" SITE "V4";
|
||||
LOCATE COMP "wifi_gpio35" SITE "N17";
|
||||
|
||||
IOBUF PORT "wifi_gpio0" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio2" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; # pull down or drive 0 for esp32 programming
|
||||
IOBUF PORT "wifi_gpio4" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio5" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio12" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio13" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; # pull down or drive 0 for esp32 programming
|
||||
IOBUF PORT "wifi_gpio14" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio15" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio19" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio21" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio22" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio25" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio26" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio27" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio33" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio34" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_gpio35" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
LOCATE COMP "ftdi_txden" SITE "T1"; # FTDI_TXDEN
|
||||
LOCATE COMP "LED1_HAT" SITE "N5"; # LED1 on HAT
|
||||
LOCATE COMP "wifi_en" SITE "U18";# WIFI_EN
|
||||
LOCATE COMP "ftdi_txd" SITE "N4"; # FTDI_TXD
|
||||
LOCATE COMP "ftdi_rxd" SITE "N3"; # FTDI_RXD
|
||||
LOCATE COMP "wifi_txd" SITE "P5"; # WIFI_TXD
|
||||
LOCATE COMP "wifi_rxd" SITE "V1"; # WIFI_RXD
|
||||
|
||||
IOBUF PORT "ftdi_txden" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "LED1_HAT" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_en" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "ftdi_txd" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "ftdi_rxd" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_txd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "wifi_rxd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
LOCATE COMP "btn[3]" SITE "E3";
|
||||
LOCATE COMP "btn[4]" SITE "E4";
|
||||
LOCATE COMP "btn[5]" SITE "E5";
|
||||
LOCATE COMP "btn[6]" SITE "H5";
|
||||
LOCATE COMP "btn[0]" SITE "H4";
|
||||
LOCATE COMP "nc1" SITE "F2";
|
||||
LOCATE COMP "sw" SITE "G3";
|
||||
IOBUF PORT "btn[3]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "btn[4]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "btn[5]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "btn[6]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "btn[0]" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "nc1" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "sw[0]" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## CM4 GPIO
|
||||
LOCATE COMP "gpio[0]" SITE "R16"; # SDA0 - WIFI_GPIO21
|
||||
LOCATE COMP "gpio[1]" SITE "R17"; # SCL0 - WIFI_GPIO22
|
||||
LOCATE COMP "gpio[2]" SITE "K5"; # SD_D2 - ESP32 SD share
|
||||
LOCATE COMP "gpio[3]" SITE "J5"; # SD_D1 - ESP32 SD share
|
||||
LOCATE COMP "gpio[4]" SITE "K4"; # SD_D0 - ESP32 SD share
|
||||
LOCATE COMP "gpio[5]" SITE "H16"; # WIFI_GPIO33
|
||||
LOCATE COMP "gpio[6]" SITE "R1"; # BTN1 on HAT
|
||||
LOCATE COMP "gpio[7]" SITE "P3"; # BTN2 on HAT
|
||||
LOCATE COMP "gpio[8]" SITE "P4"; # WIFI_GPIO19
|
||||
LOCATE COMP "gpio[9]" SITE "G16"; # WIFI_GPIO27
|
||||
LOCATE COMP "gpio[10]" SITE "N17";# WIFI_GPIO26
|
||||
LOCATE COMP "gpio[11]" SITE "L16";# WIFI_GPIO25
|
||||
LOCATE COMP "gpio[12]" SITE "C4"; # FPGA TDI do not use - not connected!
|
||||
LOCATE COMP "gpio[13]" SITE "T1"; # FTDI_TXDEN
|
||||
LOCATE COMP "gpio[14]" SITE "L4"; # SD_D3 - ESP32 SD share
|
||||
LOCATE COMP "gpio[15]" SITE "L5"; # SD_CLK - ESP32 SD share
|
||||
LOCATE COMP "gpio[16]" SITE "B4"; # FPGA TDO do not use - not connected!
|
||||
LOCATE COMP "gpio[17]" SITE "M17";# WIFI_GPIO35
|
||||
LOCATE COMP "gpio[18]" SITE "N5"; # LED1 on HAT
|
||||
LOCATE COMP "gpio[19]" SITE "U1"; # WIFI_GPIO0
|
||||
LOCATE COMP "gpio[20]" SITE "E4"; # FPGA TCK do not use - not connected!
|
||||
LOCATE COMP "gpio[21]" SITE "D5"; # FPGA TMS do not use - not connected!
|
||||
LOCATE COMP "gpio[22]" SITE "U18";# WIFI_EN
|
||||
LOCATE COMP "gpio[23]" SITE "N4"; # FTDI_TXD
|
||||
LOCATE COMP "gpio[24]" SITE "N3"; # FTDI_RXD
|
||||
LOCATE COMP "gpio[25]" SITE "P5"; # WIFI_TXD
|
||||
LOCATE COMP "gpio[26]" SITE "V1"; # WIFI_RXD
|
||||
LOCATE COMP "gpio[27]" SITE "N16";# SD_CMD - ESP32 SD share
|
||||
IOBUF PORT "gpio[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[15]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[16]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[17]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[18]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[19]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[20]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[21]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[22]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[23]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[24]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[25]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[26]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
IOBUF PORT "gpio[27]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## DSI
|
||||
#
|
||||
LOCATE COMP "dsiRX0_dp[0]" SITE "B12"; # Clk +
|
||||
LOCATE COMP "dsiRX0_dn[0]" SITE "C12"; # Clk -
|
||||
LOCATE COMP "dsiRX0_dp[1]" SITE "A12"; # DSI RX D0 +
|
||||
LOCATE COMP "dsiRX0_dn[1]" SITE "A13"; # DSI RX D0 -
|
||||
LOCATE COMP "dsiRX0_dp[2]" SITE "B13"; # DSI RX D1 +
|
||||
LOCATE COMP "dsiRX0_dn[2]" SITE "C13"; # DSI RX D1 -
|
||||
LOCATE COMP "dsiTX0_dp[0]" SITE "D12"; # Clk +
|
||||
LOCATE COMP "dsiTX0_dn[0]" SITE "E12"; # Clk -
|
||||
LOCATE COMP "dsiTX0_dp[1]" SITE "D13"; # DSI TX D0 +
|
||||
LOCATE COMP "dsiTX0_dn[1]" SITE "E13"; # DSI TX D0 -
|
||||
LOCATE COMP "dsiTX0_dp[2]" SITE "A14"; # DSI TX D1 +
|
||||
LOCATE COMP "dsiTX0_dn[2]" SITE "C14"; # DSI TX D1 -
|
||||
IOBUF PORT "dsiRX0_dp[0]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiRX0_dn[0]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiRX0_dp[1]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiRX0_dn[1]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiRX0_dp[2]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiRX0_dn[2]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiTX0_dp[0]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiTX0_dp[0]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiTX0_dp[1]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiTX0_dp[1]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiTX0_dp[2]" IO_TYPE=LVCMOS12 ;
|
||||
IOBUF PORT "dsiTX0_dp[2]" IO_TYPE=LVCMOS12 ;
|
||||
|
||||
## PROGRAMN (reload bitstream from FLASH, exit from bootloader)
|
||||
# PCB v2.0.5 and higher
|
||||
LOCATE COMP "user_programn" SITE "M4";
|
||||
IOBUF PORT "user_programn" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
||||
|
||||
## SHUTDOWN "power", "ram" sheet (connected from PCB v1.7.5)
|
||||
# on PCB v1.7 shutdown is not connected to FPGA
|
||||
LOCATE COMP "shutdown" SITE "G16"; # FPGA receives
|
||||
IOBUF PORT "shutdown" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
|
183
rtl/boards/ulx4m/apple1_dvi.v
Normal file
183
rtl/boards/ulx4m/apple1_dvi.v
Normal file
|
@ -0,0 +1,183 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
// Description: Apple 1 implementation for the Ulx4m
|
||||
//
|
||||
// Author.....: Lawrie Griffiths and Alan Garfield
|
||||
// Date.......: 31-3-2018
|
||||
//
|
||||
|
||||
module apple1_top #(
|
||||
parameter BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk_25mhz, // 25 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input ftdi_txd, // asynchronous serial data input from computer
|
||||
output ftdi_rxd, // asynchronous serial data output to computer
|
||||
//output uart_cts, // clear to send flag to computer - not used
|
||||
|
||||
// I/O interface to keyboard
|
||||
//input ps2_clk, // PS/2 keyboard serial clock input
|
||||
//input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
//output usb_fpga_pu_dp,
|
||||
//output usb_fpga_pu_dn,
|
||||
|
||||
input [26:25] gpio,
|
||||
|
||||
output [3:0] gpdi_dp, gpdi_dn,
|
||||
|
||||
// Debugging ports
|
||||
output [3:0] led,
|
||||
input [2:1] btn // 2 buttons on board
|
||||
);
|
||||
wire uart_cts;
|
||||
|
||||
parameter C_ddr = 1'b1; // 0:SDR 1:DDR
|
||||
|
||||
// clock generator
|
||||
wire clk_250MHz, clk_125MHz, clk_25MHz, clk_locked;
|
||||
clk_25_250_125_25
|
||||
clock_instance
|
||||
(
|
||||
.clki(clk_25mhz),
|
||||
.clko(clk_250MHz),
|
||||
.clks1(clk_125MHz),
|
||||
.clks2(clk_25MHz),
|
||||
.locked(clk_locked)
|
||||
);
|
||||
|
||||
// shift clock choice SDR/DDR
|
||||
wire clk_pixel, clk_shift;
|
||||
assign clk_pixel = clk_25MHz;
|
||||
generate
|
||||
if(C_ddr == 1'b1)
|
||||
assign clk_shift = clk_125MHz;
|
||||
else
|
||||
assign clk_shift = clk_250MHz;
|
||||
endgenerate
|
||||
|
||||
//assign usb_fpga_pu_dp = 1;
|
||||
//assign usb_fpga_pu_dn = 1;
|
||||
|
||||
assign led[0] = 1;
|
||||
assign led[1] = reset_n;
|
||||
assign led[2] = clr_screen_n;
|
||||
assign led[3] = 0;
|
||||
|
||||
wire vga_bit;
|
||||
|
||||
// VGA signal generator
|
||||
wire [7:0] vga_r, vga_g, vga_b;
|
||||
wire vga_h_sync, vga_v_sync, vga_blank;
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r = vga_bit ? 8'b10000000 : 8'b00000000;
|
||||
assign vga_g = vga_bit ? 8'b11111111 : 8'b00000000;
|
||||
assign vga_b = vga_bit ? 8'b10000000 : 8'b00000000;
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk_25MHz),
|
||||
.rst(1'b0),
|
||||
.sig_in(~btn[1]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk_25MHz),
|
||||
.rst(~reset_n),
|
||||
.sig_in(~btn[2]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk_25MHz),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(ftdi_txd),
|
||||
.uart_tx(ftdi_rxd),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(gpio[26]),
|
||||
.ps2_din(gpio[25]),
|
||||
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
//.vga_grn(vga_bit),
|
||||
//.vga_blu(vga_bit),
|
||||
.vga_blank(vga_blank),
|
||||
.vga_cls(~clr_screen_n)
|
||||
);
|
||||
|
||||
// VGA to digital video converter
|
||||
wire [1:0] tmds[3:0];
|
||||
vga2dvid
|
||||
#(
|
||||
.C_ddr(C_ddr),
|
||||
.C_shift_clock_synchronizer(1'b1)
|
||||
)
|
||||
vga2dvid_instance
|
||||
(
|
||||
.clk_pixel(clk_pixel),
|
||||
.clk_shift(clk_shift),
|
||||
.in_red(vga_r),
|
||||
.in_green(vga_g),
|
||||
.in_blue(vga_b),
|
||||
.in_hsync(vga_h_sync),
|
||||
.in_vsync(vga_v_sync),
|
||||
.in_blank(vga_blank),
|
||||
.out_clock(tmds[3]),
|
||||
.out_red(tmds[2]),
|
||||
.out_green(tmds[1]),
|
||||
.out_blue(tmds[0])
|
||||
);
|
||||
|
||||
// output TMDS SDR/DDR data to fake differential lanes
|
||||
fake_differential
|
||||
#(
|
||||
.C_ddr(C_ddr)
|
||||
)
|
||||
fake_differential_instance
|
||||
(
|
||||
.clk_shift(clk_shift),
|
||||
.in_clock(tmds[3]),
|
||||
.in_red(tmds[2]),
|
||||
.in_green(tmds[1]),
|
||||
.in_blue(tmds[0]),
|
||||
.out_p(gpdi_dp),
|
||||
.out_n(gpdi_dn)
|
||||
);
|
||||
|
||||
endmodule
|
118
rtl/boards/ulx4m/apple1_vga.v
Normal file
118
rtl/boards/ulx4m/apple1_vga.v
Normal file
|
@ -0,0 +1,118 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
// Description: Apple 1 implementation for the Blackeice II ICE40HX8K +
|
||||
//
|
||||
// Author.....: Lawrie Griffiths and Alan Garfield
|
||||
// Date.......: 31-3-2018
|
||||
//
|
||||
|
||||
module apple1_top #(
|
||||
parameter BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk_25mhz, // 25 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
|
||||
output usb_fpga_pu_dp,
|
||||
output usb_fpga_pu_dn,
|
||||
|
||||
// Debugging ports
|
||||
output [3:0] led,
|
||||
input [1:0] button // 2 buttons on board
|
||||
);
|
||||
|
||||
assign usb_fpga_pu_dp = 1;
|
||||
assign usb_fpga_pu_dn = 1;
|
||||
|
||||
assign led[0] = 1;
|
||||
assign led[1] = reset_n;
|
||||
assign led[2] = clr_screen_n;
|
||||
assign led[3] = 0;
|
||||
|
||||
wire vga_bit;
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk_25mhz),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk_25mhz),
|
||||
.rst(~reset_n),
|
||||
.sig_in(~button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk_25mhz),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
|
||||
//.ps2_select(1'b0), // PS/2 disabled, UART TX enabled
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
//.vga_grn(vga_bit),
|
||||
//.vga_blu(vga_bit),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
endmodule
|
60
rtl/boards/ulx4m/clk_25_250_125_25.v
Normal file
60
rtl/boards/ulx4m/clk_25_250_125_25.v
Normal file
|
@ -0,0 +1,60 @@
|
|||
// diamond 3.7 accepts this PLL
|
||||
// diamond 3.8-3.9 is untested
|
||||
// diamond 3.10 or higher is likely to abort with error about unable to use feedback signal
|
||||
// cause of this could be from wrong CPHASE/FPHASE parameters
|
||||
module clk_25_250_125_25
|
||||
(
|
||||
input clki, // 25 MHz, 0 deg
|
||||
output clko, // 250 MHz, 0 deg
|
||||
output clks1, // 125 MHz, 0 deg
|
||||
output clks2, // 25 MHz, 0 deg
|
||||
output locked
|
||||
);
|
||||
(* FREQUENCY_PIN_CLKI="25" *)
|
||||
(* FREQUENCY_PIN_CLKOP="250" *)
|
||||
(* FREQUENCY_PIN_CLKOS="125" *)
|
||||
(* FREQUENCY_PIN_CLKOS2="25" *)
|
||||
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
|
||||
EHXPLLL #(
|
||||
.PLLRST_ENA("DISABLED"),
|
||||
.INTFB_WAKE("DISABLED"),
|
||||
.STDBY_ENABLE("DISABLED"),
|
||||
.DPHASE_SOURCE("DISABLED"),
|
||||
.OUTDIVIDER_MUXA("DIVA"),
|
||||
.OUTDIVIDER_MUXB("DIVB"),
|
||||
.OUTDIVIDER_MUXC("DIVC"),
|
||||
.OUTDIVIDER_MUXD("DIVD"),
|
||||
.CLKI_DIV(1),
|
||||
.CLKOP_ENABLE("ENABLED"),
|
||||
.CLKOP_DIV(2),
|
||||
.CLKOP_CPHASE(0),
|
||||
.CLKOP_FPHASE(0),
|
||||
.CLKOS_ENABLE("ENABLED"),
|
||||
.CLKOS_DIV(4),
|
||||
.CLKOS_CPHASE(0),
|
||||
.CLKOS_FPHASE(0),
|
||||
.CLKOS2_ENABLE("ENABLED"),
|
||||
.CLKOS2_DIV(20),
|
||||
.CLKOS2_CPHASE(0),
|
||||
.CLKOS2_FPHASE(0),
|
||||
.FEEDBK_PATH("CLKOP"),
|
||||
.CLKFB_DIV(10)
|
||||
) pll_i (
|
||||
.RST(1'b0),
|
||||
.STDBY(1'b0),
|
||||
.CLKI(clki),
|
||||
.CLKOP(clko),
|
||||
.CLKOS(clks1),
|
||||
.CLKOS2(clks2),
|
||||
.CLKFB(clko),
|
||||
.CLKINTFB(),
|
||||
.PHASESEL0(1'b0),
|
||||
.PHASESEL1(1'b0),
|
||||
.PHASEDIR(1'b1),
|
||||
.PHASESTEP(1'b1),
|
||||
.PHASELOADREG(1'b1),
|
||||
.PLLWAKESYNC(1'b0),
|
||||
.ENCLKOP(1'b0),
|
||||
.LOCK(locked)
|
||||
);
|
||||
endmodule
|
63
rtl/boards/ulx4m/fake_differential.v
Normal file
63
rtl/boards/ulx4m/fake_differential.v
Normal file
|
@ -0,0 +1,63 @@
|
|||
// DDR mode uses Lattice ECP5 vendor-specific module ODDRX1F
|
||||
|
||||
module fake_differential
|
||||
(
|
||||
input clk_shift, // used only in DDR mode
|
||||
// [1:0]:DDR [0]:SDR TMDS
|
||||
input [1:0] in_clock, in_red, in_green, in_blue,
|
||||
// [3]:clock [2]:red [1]:green [0]:blue
|
||||
output [3:0] out_p, out_n
|
||||
);
|
||||
parameter C_ddr = 1'b0; // 0:SDR 1:DDR
|
||||
|
||||
wire [1:0] tmds[3:0];
|
||||
assign tmds[3] = in_clock;
|
||||
assign tmds[2] = in_red;
|
||||
assign tmds[1] = in_green;
|
||||
assign tmds[0] = in_blue;
|
||||
|
||||
// register stage to improve timing of the fake differential
|
||||
reg [1:0] R_tmds_p[3:0], R_tmds_n[3:0];
|
||||
generate
|
||||
genvar i;
|
||||
for(i = 0; i < 4; i++)
|
||||
begin : TMDS_pn_registers
|
||||
always @(posedge clk_shift) R_tmds_p[i] <= tmds[i];
|
||||
always @(posedge clk_shift) R_tmds_n[i] <= ~tmds[i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// output SDR/DDR to fake differential
|
||||
generate
|
||||
genvar i;
|
||||
if(C_ddr == 1'b1)
|
||||
for(i = 0; i < 4; i++)
|
||||
begin : DDR_output_mode
|
||||
ODDRX1F
|
||||
ddr_p_instance
|
||||
(
|
||||
.D0(R_tmds_p[i][0]),
|
||||
.D1(R_tmds_p[i][1]),
|
||||
.Q(out_p[i]),
|
||||
.SCLK(clk_shift),
|
||||
.RST(0)
|
||||
);
|
||||
ODDRX1F
|
||||
ddr_n_instance
|
||||
(
|
||||
.D0(R_tmds_n[i][0]),
|
||||
.D1(R_tmds_n[i][1]),
|
||||
.Q(out_n[i]),
|
||||
.SCLK(clk_shift),
|
||||
.RST(0)
|
||||
);
|
||||
end
|
||||
else
|
||||
for(i = 0; i < 4; i++)
|
||||
begin : SDR_output_mode
|
||||
assign out_p[i] = R_tmds_p[i][0];
|
||||
assign out_n[i] = R_tmds_n[i][0];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
155
rtl/boards/ulx4m/tmds_encoder.v
Normal file
155
rtl/boards/ulx4m/tmds_encoder.v
Normal file
|
@ -0,0 +1,155 @@
|
|||
// File hdl/tmds_encoder.vhd translated with vhd2vl v3.0 VHDL to Verilog RTL translator
|
||||
// vhd2vl settings:
|
||||
// * Verilog Module Declaration Style: 2001
|
||||
|
||||
// vhd2vl is Free (libre) Software:
|
||||
// Copyright (C) 2001 Vincenzo Liguori - Ocean Logic Pty Ltd
|
||||
// http://www.ocean-logic.com
|
||||
// Modifications Copyright (C) 2006 Mark Gonzales - PMC Sierra Inc
|
||||
// Modifications (C) 2010 Shankar Giri
|
||||
// Modifications Copyright (C) 2002-2017 Larry Doolittle
|
||||
// http://doolittle.icarus.com/~larry/vhd2vl/
|
||||
// Modifications (C) 2017 Rodrigo A. Melo
|
||||
//
|
||||
// vhd2vl comes with ABSOLUTELY NO WARRANTY. Always check the resulting
|
||||
// Verilog for correctness, ideally with a formal verification tool.
|
||||
//
|
||||
// You are welcome to redistribute vhd2vl under certain conditions.
|
||||
// See the license (GPLv2) file included with the source for details.
|
||||
|
||||
// The result of translation follows. Its copyright status should be
|
||||
// considered unchanged from the original VHDL.
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Engineer: Mike Field <hamster@snap.net.nz>
|
||||
//
|
||||
// Description: TMDS Encoder
|
||||
// 8 bits colour, 2 control bits and one blanking bits in
|
||||
// 10 bits of TMDS encoded data out
|
||||
// Clocked at the pixel clock
|
||||
//
|
||||
//--------------------------------------------------------------------------------
|
||||
// See: http://hamsterworks.co.nz/mediawiki/index.php/Dvid_test
|
||||
// http://hamsterworks.co.nz/mediawiki/index.php/FPGA_Projects
|
||||
//
|
||||
// Copyright (c) 2012 Mike Field <hamster@snap.net.nz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// no timescale needed
|
||||
|
||||
module tmds_encoder(
|
||||
input wire clk,
|
||||
input wire [7:0] data,
|
||||
input wire [1:0] c,
|
||||
input wire blank,
|
||||
output reg [9:0] encoded
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
wire [8:0] xored;
|
||||
wire [8:0] xnored;
|
||||
wire [3:0] ones;
|
||||
reg [8:0] data_word;
|
||||
reg [8:0] data_word_inv;
|
||||
wire [3:0] data_word_disparity;
|
||||
reg [3:0] dc_bias = 1'b0;
|
||||
|
||||
// Work our the two different encodings for the byte
|
||||
assign xored[0] = data[0];
|
||||
assign xored[1] = data[1] ^ xored[0];
|
||||
assign xored[2] = data[2] ^ xored[1];
|
||||
assign xored[3] = data[3] ^ xored[2];
|
||||
assign xored[4] = data[4] ^ xored[3];
|
||||
assign xored[5] = data[5] ^ xored[4];
|
||||
assign xored[6] = data[6] ^ xored[5];
|
||||
assign xored[7] = data[7] ^ xored[6];
|
||||
assign xored[8] = 1'b1;
|
||||
assign xnored[0] = data[0];
|
||||
assign xnored[1] = ~(data[1] ^ xnored[0]);
|
||||
assign xnored[2] = ~(data[2] ^ xnored[1]);
|
||||
assign xnored[3] = ~(data[3] ^ xnored[2]);
|
||||
assign xnored[4] = ~(data[4] ^ xnored[3]);
|
||||
assign xnored[5] = ~(data[5] ^ xnored[4]);
|
||||
assign xnored[6] = ~(data[6] ^ xnored[5]);
|
||||
assign xnored[7] = ~(data[7] ^ xnored[6]);
|
||||
assign xnored[8] = 1'b0;
|
||||
// Count how many ones are set in data
|
||||
assign ones = 4'b0000 + data[0] + data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
|
||||
// Decide which encoding to use
|
||||
always @(ones, data[0], xnored, xored) begin
|
||||
if(ones > 4 || (ones == 4 && data[0] == 1'b0)) begin
|
||||
data_word <= xnored;
|
||||
data_word_inv <= ~(xnored);
|
||||
end
|
||||
else begin
|
||||
data_word <= xored;
|
||||
data_word_inv <= ~(xored);
|
||||
end
|
||||
end
|
||||
|
||||
// Work out the DC bias of the dataword;
|
||||
assign data_word_disparity = 4'b1100 + data_word[0] + data_word[1] + data_word[2] + data_word[3] + data_word[4] + data_word[5] + data_word[6] + data_word[7];
|
||||
// Now work out what the output should be
|
||||
always @(posedge clk) begin
|
||||
if(blank == 1'b1) begin
|
||||
// In the control periods, all values have and have balanced bit count
|
||||
case(c)
|
||||
2'b00 : begin
|
||||
encoded <= 10'b1101010100;
|
||||
end
|
||||
2'b01 : begin
|
||||
encoded <= 10'b0010101011;
|
||||
end
|
||||
2'b10 : begin
|
||||
encoded <= 10'b0101010100;
|
||||
end
|
||||
default : begin
|
||||
encoded <= 10'b1010101011;
|
||||
end
|
||||
endcase
|
||||
dc_bias <= {4{1'b0}};
|
||||
end
|
||||
else begin
|
||||
if(dc_bias == 5'b00000 || data_word_disparity == 0) begin
|
||||
// dataword has no disparity
|
||||
if(data_word[8] == 1'b1) begin
|
||||
encoded <= {2'b01,data_word[7:0]};
|
||||
dc_bias <= dc_bias + data_word_disparity;
|
||||
end
|
||||
else begin
|
||||
encoded <= {2'b10,data_word_inv[7:0]};
|
||||
dc_bias <= dc_bias - data_word_disparity;
|
||||
end
|
||||
end
|
||||
else if((dc_bias[3] == 1'b0 && data_word_disparity[3] == 1'b0) || (dc_bias[3] == 1'b1 && data_word_disparity[3] == 1'b1)) begin
|
||||
encoded <= {1'b1,data_word[8],data_word_inv[7:0]};
|
||||
dc_bias <= dc_bias + data_word[8] - data_word_disparity;
|
||||
end
|
||||
else begin
|
||||
encoded <= {1'b0,data_word};
|
||||
dc_bias <= dc_bias - data_word_inv[8] + data_word_disparity;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
262
rtl/boards/ulx4m/vga2dvid.v
Normal file
262
rtl/boards/ulx4m/vga2dvid.v
Normal file
|
@ -0,0 +1,262 @@
|
|||
// File vga2dvid.vhd translated with vhd2vl v3.0 VHDL to Verilog RTL translator
|
||||
// vhd2vl settings:
|
||||
// * Verilog Module Declaration Style: 2001
|
||||
|
||||
// vhd2vl is Free (libre) Software:
|
||||
// Copyright (C) 2001 Vincenzo Liguori - Ocean Logic Pty Ltd
|
||||
// http://www.ocean-logic.com
|
||||
// Modifications Copyright (C) 2006 Mark Gonzales - PMC Sierra Inc
|
||||
// Modifications (C) 2010 Shankar Giri
|
||||
// Modifications Copyright (C) 2002-2017 Larry Doolittle
|
||||
// http://doolittle.icarus.com/~larry/vhd2vl/
|
||||
// Modifications (C) 2017 Rodrigo A. Melo
|
||||
//
|
||||
// vhd2vl comes with ABSOLUTELY NO WARRANTY. Always check the resulting
|
||||
// Verilog for correctness, ideally with a formal verification tool.
|
||||
//
|
||||
// You are welcome to redistribute vhd2vl under certain conditions.
|
||||
// See the license (GPLv2) file included with the source for details.
|
||||
|
||||
// The result of translation follows. Its copyright status should be
|
||||
// considered unchanged from the original VHDL.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Engineer: Mike Field <hamster@snap.net.nz>
|
||||
// Description: Converts VGA signals into DVID bitstreams.
|
||||
//
|
||||
// 'clk_shift' 10x clk_pixel for SDR
|
||||
// 'clk_shift' 5x clk_pixel for DDR
|
||||
//
|
||||
// 'blank' should be asserted during the non-display
|
||||
// portions of the frame
|
||||
//------------------------------------------------------------------------------
|
||||
// See: http://hamsterworks.co.nz/mediawiki/index.php/Dvid_test
|
||||
// http://hamsterworks.co.nz/mediawiki/index.php/FPGA_Projects
|
||||
//
|
||||
// Copyright (c) 2012 Mike Field <hamster@snap.net.nz>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// takes VGA input and prepares output
|
||||
// for SDR buffer, which send 1 bit per 1 clock period output out_red(0), out_green(0), ... etc.
|
||||
// for DDR buffers, which send 2 bits per 1 clock period output out_red(1 downto 0), ...
|
||||
// EMARD unified SDR and DDR into one module
|
||||
// no timescale needed
|
||||
|
||||
module vga2dvid(
|
||||
input wire clk_pixel,
|
||||
input wire clk_shift,
|
||||
input wire [C_depth - 1:0] in_red,
|
||||
input wire [C_depth - 1:0] in_green,
|
||||
input wire [C_depth - 1:0] in_blue,
|
||||
input wire in_blank,
|
||||
input wire in_hsync,
|
||||
input wire in_vsync,
|
||||
output wire [9:0] outp_red,
|
||||
output wire [9:0] outp_green,
|
||||
output wire [9:0] outp_blue,
|
||||
output wire [1:0] out_red,
|
||||
output wire [1:0] out_green,
|
||||
output wire [1:0] out_blue,
|
||||
output wire [1:0] out_clock
|
||||
);
|
||||
|
||||
parameter C_shift_clock_synchronizer=1'b1;
|
||||
parameter C_parallel=1'b1;
|
||||
parameter C_serial=1'b1;
|
||||
parameter C_ddr=1'b0;
|
||||
parameter [31:0] C_depth=8;
|
||||
// VGA pixel clock, 25 MHz for 640x480
|
||||
// SDR: 10x clk_pixel, DDR: 5x clk_pixel, in phase with clk_pixel
|
||||
// parallel outputs
|
||||
// serial outputs
|
||||
|
||||
|
||||
|
||||
wire [9:0] encoded_red; wire [9:0] encoded_green; wire [9:0] encoded_blue;
|
||||
reg [9:0] latched_red = 1'b0; reg [9:0] latched_green = 1'b0; reg [9:0] latched_blue = 1'b0;
|
||||
reg [9:0] shift_red = 1'b0; reg [9:0] shift_green = 1'b0; reg [9:0] shift_blue = 1'b0;
|
||||
parameter C_shift_clock_initial = 10'b0000011111;
|
||||
reg [9:0] shift_clock = C_shift_clock_initial;
|
||||
reg R_shift_clock_off_sync = 1'b0;
|
||||
reg [7:0] R_shift_clock_synchronizer = 1'b0;
|
||||
reg [6:0] R_sync_fail; // counts sync fails, after too many, reinitialize shift_clock
|
||||
parameter c_red = 1'b0;
|
||||
parameter c_green = 1'b0;
|
||||
wire [1:0] c_blue;
|
||||
wire [7:0] red_d;
|
||||
wire [7:0] green_d;
|
||||
wire [7:0] blue_d;
|
||||
|
||||
assign c_blue = {in_vsync,in_hsync};
|
||||
assign red_d[7:8 - C_depth] = in_red[C_depth - 1:0];
|
||||
assign green_d[7:8 - C_depth] = in_green[C_depth - 1:0];
|
||||
assign blue_d[7:8 - C_depth] = in_blue[C_depth - 1:0];
|
||||
// fill vacant low bits with value repeated (so min/max value is always 0 or 255)
|
||||
generate if (C_depth < 8) begin: G_vacant_bits
|
||||
genvar i;
|
||||
generate for (i=0; i <= 8 - C_depth - 1; i = i + 1) begin: G_bits
|
||||
assign red_d[i] = in_red[0];
|
||||
assign green_d[i] = in_green[0];
|
||||
assign blue_d[i] = in_blue[0];
|
||||
end
|
||||
endgenerate
|
||||
end
|
||||
endgenerate
|
||||
generate if (C_shift_clock_synchronizer == 1'b1) begin: G_shift_clock_synchronizer
|
||||
// sampler verifies is shift_clock state synchronous with pixel_clock
|
||||
always @(posedge clk_pixel) begin
|
||||
// does 0 to 1 transition at bits 5 downto 4 happen at rising_edge of clk_pixel?
|
||||
// if shift_clock = C_shift_clock_initial then
|
||||
if(shift_clock[5:4] == C_shift_clock_initial[5:4]) begin
|
||||
// same as above line but simplified
|
||||
R_shift_clock_off_sync <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
R_shift_clock_off_sync <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// every N cycles of clk_shift: signal to skip 1 cycle in order to get in sync
|
||||
always @(posedge clk_shift) begin
|
||||
if(R_shift_clock_off_sync == 1'b1) begin
|
||||
if(R_shift_clock_synchronizer[(7)] == 1'b1) begin
|
||||
R_shift_clock_synchronizer <= {8{1'b0}};
|
||||
end
|
||||
else begin
|
||||
R_shift_clock_synchronizer <= R_shift_clock_synchronizer + 1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
R_shift_clock_synchronizer <= {8{1'b0}};
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
// shift_clock_synchronizer
|
||||
tmds_encoder u21(
|
||||
.clk(clk_pixel),
|
||||
.data(red_d),
|
||||
.c(c_red),
|
||||
.blank(in_blank),
|
||||
.encoded(encoded_red));
|
||||
|
||||
tmds_encoder u22(
|
||||
.clk(clk_pixel),
|
||||
.data(green_d),
|
||||
.c(c_green),
|
||||
.blank(in_blank),
|
||||
.encoded(encoded_green));
|
||||
|
||||
tmds_encoder u23(
|
||||
.clk(clk_pixel),
|
||||
.data(blue_d),
|
||||
.c(c_blue),
|
||||
.blank(in_blank),
|
||||
.encoded(encoded_blue));
|
||||
|
||||
always @(posedge clk_pixel) begin
|
||||
latched_red <= encoded_red;
|
||||
latched_green <= encoded_green;
|
||||
latched_blue <= encoded_blue;
|
||||
end
|
||||
|
||||
generate if (C_parallel == 1'b1) begin: G_parallel
|
||||
assign outp_red = latched_red;
|
||||
assign outp_green = latched_green;
|
||||
assign outp_blue = latched_blue;
|
||||
end
|
||||
endgenerate
|
||||
generate if ((C_serial & ~C_ddr) == 1'b1) begin: G_SDR
|
||||
always @(posedge clk_shift) begin
|
||||
//if shift_clock = "0000011111" then
|
||||
if(shift_clock[5:4] == C_shift_clock_initial[5:4]) begin
|
||||
// same as above line but simplified
|
||||
shift_red <= latched_red;
|
||||
shift_green <= latched_green;
|
||||
shift_blue <= latched_blue;
|
||||
end
|
||||
else begin
|
||||
shift_red <= {1'b0,shift_red[9:1]};
|
||||
shift_green <= {1'b0,shift_green[9:1]};
|
||||
shift_blue <= {1'b0,shift_blue[9:1]};
|
||||
end
|
||||
if(R_shift_clock_synchronizer[(7)] == 1'b0) begin
|
||||
shift_clock <= {shift_clock[0],shift_clock[9:1]};
|
||||
end
|
||||
else begin
|
||||
// synchronization failed.
|
||||
// after too many fails, reinitialize shift_clock
|
||||
if(R_sync_fail[(6)] == 1'b1) begin
|
||||
shift_clock <= C_shift_clock_initial;
|
||||
R_sync_fail <= {7{1'b0}};
|
||||
end
|
||||
else begin
|
||||
R_sync_fail <= R_sync_fail + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
generate if ((C_serial & C_ddr) == 1'b1) begin: G_DDR
|
||||
always @(posedge clk_shift) begin
|
||||
//if shift_clock = "0000011111" then
|
||||
if(shift_clock[5:4] == C_shift_clock_initial[5:4]) begin
|
||||
// same as above line but simplified
|
||||
shift_red <= latched_red;
|
||||
shift_green <= latched_green;
|
||||
shift_blue <= latched_blue;
|
||||
end
|
||||
else begin
|
||||
shift_red <= {2'b00,shift_red[9:2]};
|
||||
shift_green <= {2'b00,shift_green[9:2]};
|
||||
shift_blue <= {2'b00,shift_blue[9:2]};
|
||||
end
|
||||
if(R_shift_clock_synchronizer[(7)] == 1'b0) begin
|
||||
shift_clock <= {shift_clock[1:0],shift_clock[9:2]};
|
||||
end
|
||||
else begin
|
||||
// synchronization failed.
|
||||
// after too many fails, reinitialize shift_clock
|
||||
if(R_sync_fail[(6)] == 1'b1) begin
|
||||
shift_clock <= C_shift_clock_initial;
|
||||
R_sync_fail <= {7{1'b0}};
|
||||
end
|
||||
else begin
|
||||
R_sync_fail <= R_sync_fail + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
// SDR: use only bit 0 from each out_* channel
|
||||
// DDR: 2 bits per 1 clock period,
|
||||
// (one bit output on rising edge, other on falling edge of clk_shift)
|
||||
generate if (C_serial == 1'b1) begin: G_serial
|
||||
assign out_red = shift_red[1:0];
|
||||
assign out_green = shift_green[1:0];
|
||||
assign out_blue = shift_blue[1:0];
|
||||
assign out_clock = shift_clock[1:0];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user