mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-03-01 07:20:42 +01:00
More FPGA bitstream updates
This commit is contained in:
parent
a1f3312aa2
commit
c4ff4eb62e
4
.github/scripts/buildRelease.sh
vendored
4
.github/scripts/buildRelease.sh
vendored
@ -35,7 +35,9 @@ make \
|
|||||||
BUILD=Release \
|
BUILD=Release \
|
||||||
PREFIX="$TOOLCHAIN_DIR/bin/mipsel-none-elf" \
|
PREFIX="$TOOLCHAIN_DIR/bin/mipsel-none-elf" \
|
||||||
FORMAT=elf32-littlemips \
|
FORMAT=elf32-littlemips \
|
||||||
FASTBOOT=true \
|
BOARD=system573 \
|
||||||
|
BOOT_MODE=psexe \
|
||||||
|
SPLASH_SCREEN=true \
|
||||||
EMBED_PSEXE="$PROJECT_DIR/build/${RELEASE_NAME}-tiny.psexe" \
|
EMBED_PSEXE="$PROJECT_DIR/build/${RELEASE_NAME}-tiny.psexe" \
|
||||||
|| exit 2
|
|| exit 2
|
||||||
|
|
||||||
|
BIN
data/fpga.bit
BIN
data/fpga.bit
Binary file not shown.
19
doc/fpga.md
19
doc/fpga.md
@ -79,28 +79,27 @@ Note that the number is different from the one used by Konami (`0x1234`).
|
|||||||
| 14 | W | Output D2 (0 = grounded, 1 = high-z) |
|
| 14 | W | Output D2 (0 = grounded, 1 = high-z) |
|
||||||
| 15 | W | Output D3 (0 = grounded, 1 = high-z) |
|
| 15 | W | Output D3 (0 = grounded, 1 = high-z) |
|
||||||
|
|
||||||
### `0x1f6400ee` (FPGA, DDR/Mambo bitstream): **1-wire bus**
|
### `0x1f6400ee`: **1-wire bus**
|
||||||
|
|
||||||
When read:
|
When read:
|
||||||
|
|
||||||
| Bits | RW | Description |
|
| Bits | RW | Description |
|
||||||
| ----: | :- | :------------------------ |
|
| ----: | :- | :------------------------ |
|
||||||
| 0-11 | | _Unused_ |
|
| 0-7 | | _Unused_ |
|
||||||
|
| 8 | R | DS2433 1-wire bus readout |
|
||||||
|
| 9-11 | | _Unused_ |
|
||||||
| 12 | R | DS2401 1-wire bus readout |
|
| 12 | R | DS2401 1-wire bus readout |
|
||||||
| 13 | R | DS2433 1-wire bus readout |
|
| 13-15 | | _Unused_ |
|
||||||
| 14-15 | | _Unused_ |
|
|
||||||
|
|
||||||
When written:
|
When written:
|
||||||
|
|
||||||
| Bits | RW | Description |
|
| Bits | RW | Description |
|
||||||
| ----: | :- | :----------------------------------------------------------- |
|
| ----: | :- | :----------------------------------------------------------- |
|
||||||
| 0-11 | | _Unused_ |
|
| 0-7 | | _Unused_ |
|
||||||
|
| 8 | W | Drive DS2433 1-wire bus low (1 = pull to ground, 0 = high-z) |
|
||||||
|
| 9-11 | | _Unused_ |
|
||||||
| 12 | W | Drive DS2401 1-wire bus low (1 = pull to ground, 0 = high-z) |
|
| 12 | W | Drive DS2401 1-wire bus low (1 = pull to ground, 0 = high-z) |
|
||||||
| 13 | W | Drive DS2433 1-wire bus low (1 = pull to ground, 0 = high-z) |
|
| 13-15 | | _Unused_ |
|
||||||
| 14-15 | | _Unused_ |
|
|
||||||
|
|
||||||
Bit 13 is mapped to the bus of the (normally unpopulated) DS2433 footprint. It
|
|
||||||
is currently unclear whether and how Konami's bitstreams expose this bus.
|
|
||||||
|
|
||||||
## Building the bitstream
|
## Building the bitstream
|
||||||
|
|
||||||
|
285
fpga/fpga.ucf
285
fpga/fpga.ucf
@ -5,252 +5,199 @@ CONFIG PROHIBIT = "P154"; # DOUT
|
|||||||
|
|
||||||
## System clocks
|
## System clocks
|
||||||
|
|
||||||
|
TIMESPEC "TS_clock29M" = PERIOD "clock29M" 29.4500 MHz HIGH 50 %;
|
||||||
|
#TIMESPEC "TS_clock19M" = PERIOD "clock19M" 19.6608 MHz HIGH 50 %;
|
||||||
|
|
||||||
NET "clockIn29M" LOC = "P160";
|
NET "clockIn29M" LOC = "P160";
|
||||||
|
NET "clock29M" TNM = "clock29M";
|
||||||
#NET "clockIn19M" LOC = "P207";
|
#NET "clockIn19M" LOC = "P207";
|
||||||
|
#NET "clock19M" TNM = "clock19M";
|
||||||
|
|
||||||
## Host interface
|
## Host interface
|
||||||
|
|
||||||
NET "nHostRead" LOC = "P146";
|
NET "nHostRead" LOC = "P146";
|
||||||
NET "nHostRead" NODELAY;
|
|
||||||
NET "nHostWrite" LOC = "P145";
|
NET "nHostWrite" LOC = "P145";
|
||||||
NET "nHostWrite" NODELAY;
|
|
||||||
NET "nHostEnable" LOC = "P142";
|
NET "nHostEnable" LOC = "P142";
|
||||||
NET "nHostEnable" NODELAY;
|
|
||||||
|
|
||||||
NET "hostAddress[0]" LOC = "P117";
|
NET "hostAddress[0]" LOC = "P117";
|
||||||
NET "hostAddress[0]" NODELAY;
|
|
||||||
NET "hostAddress[1]" LOC = "P116";
|
NET "hostAddress[1]" LOC = "P116";
|
||||||
NET "hostAddress[1]" NODELAY;
|
|
||||||
NET "hostAddress[2]" LOC = "P115";
|
NET "hostAddress[2]" LOC = "P115";
|
||||||
NET "hostAddress[2]" NODELAY;
|
|
||||||
NET "hostAddress[3]" LOC = "P114";
|
NET "hostAddress[3]" LOC = "P114";
|
||||||
NET "hostAddress[3]" NODELAY;
|
|
||||||
NET "hostAddress[4]" LOC = "P113";
|
NET "hostAddress[4]" LOC = "P113";
|
||||||
NET "hostAddress[4]" NODELAY;
|
|
||||||
NET "hostAddress[5]" LOC = "P112";
|
NET "hostAddress[5]" LOC = "P112";
|
||||||
NET "hostAddress[5]" NODELAY;
|
|
||||||
NET "hostAddress[6]" LOC = "P110";
|
NET "hostAddress[6]" LOC = "P110";
|
||||||
NET "hostAddress[6]" NODELAY;
|
|
||||||
|
|
||||||
NET "hostData[0]" LOC = "P138";
|
NET "hostData[0]" LOC = "P138";
|
||||||
NET "hostData[0]" FAST;
|
|
||||||
NET "hostData[0]" DRIVE = 12;
|
|
||||||
NET "hostData[0]" NODELAY;
|
|
||||||
NET "hostData[1]" LOC = "P137";
|
NET "hostData[1]" LOC = "P137";
|
||||||
NET "hostData[1]" FAST;
|
|
||||||
NET "hostData[1]" DRIVE = 12;
|
|
||||||
NET "hostData[1]" NODELAY;
|
|
||||||
NET "hostData[2]" LOC = "P136";
|
NET "hostData[2]" LOC = "P136";
|
||||||
NET "hostData[2]" FAST;
|
|
||||||
NET "hostData[2]" DRIVE = 12;
|
|
||||||
NET "hostData[2]" NODELAY;
|
|
||||||
NET "hostData[3]" LOC = "P135";
|
NET "hostData[3]" LOC = "P135";
|
||||||
NET "hostData[3]" FAST;
|
|
||||||
NET "hostData[3]" DRIVE = 12;
|
|
||||||
NET "hostData[3]" NODELAY;
|
|
||||||
NET "hostData[4]" LOC = "P134";
|
NET "hostData[4]" LOC = "P134";
|
||||||
NET "hostData[4]" FAST;
|
|
||||||
NET "hostData[4]" DRIVE = 12;
|
|
||||||
NET "hostData[4]" NODELAY;
|
|
||||||
NET "hostData[5]" LOC = "P133";
|
NET "hostData[5]" LOC = "P133";
|
||||||
NET "hostData[5]" FAST;
|
|
||||||
NET "hostData[5]" DRIVE = 12;
|
|
||||||
NET "hostData[5]" NODELAY;
|
|
||||||
NET "hostData[6]" LOC = "P132";
|
NET "hostData[6]" LOC = "P132";
|
||||||
NET "hostData[6]" FAST;
|
|
||||||
NET "hostData[6]" DRIVE = 12;
|
|
||||||
NET "hostData[6]" NODELAY;
|
|
||||||
NET "hostData[7]" LOC = "P129";
|
NET "hostData[7]" LOC = "P129";
|
||||||
NET "hostData[7]" FAST;
|
|
||||||
NET "hostData[7]" DRIVE = 12;
|
|
||||||
NET "hostData[7]" NODELAY;
|
|
||||||
NET "hostData[8]" LOC = "P128";
|
NET "hostData[8]" LOC = "P128";
|
||||||
NET "hostData[8]" FAST;
|
|
||||||
NET "hostData[8]" DRIVE = 12;
|
|
||||||
NET "hostData[8]" NODELAY;
|
|
||||||
NET "hostData[9]" LOC = "P127";
|
NET "hostData[9]" LOC = "P127";
|
||||||
NET "hostData[9]" FAST;
|
|
||||||
NET "hostData[9]" DRIVE = 12;
|
|
||||||
NET "hostData[9]" NODELAY;
|
|
||||||
NET "hostData[10]" LOC = "P126";
|
NET "hostData[10]" LOC = "P126";
|
||||||
NET "hostData[10]" FAST;
|
|
||||||
NET "hostData[10]" DRIVE = 12;
|
|
||||||
NET "hostData[10]" NODELAY;
|
|
||||||
NET "hostData[11]" LOC = "P125";
|
NET "hostData[11]" LOC = "P125";
|
||||||
NET "hostData[11]" FAST;
|
|
||||||
NET "hostData[11]" DRIVE = 12;
|
|
||||||
NET "hostData[11]" NODELAY;
|
|
||||||
NET "hostData[12]" LOC = "P124";
|
NET "hostData[12]" LOC = "P124";
|
||||||
NET "hostData[12]" FAST;
|
|
||||||
NET "hostData[12]" DRIVE = 12;
|
|
||||||
NET "hostData[12]" NODELAY;
|
|
||||||
NET "hostData[13]" LOC = "P123";
|
NET "hostData[13]" LOC = "P123";
|
||||||
NET "hostData[13]" FAST;
|
|
||||||
NET "hostData[13]" DRIVE = 12;
|
|
||||||
NET "hostData[13]" NODELAY;
|
|
||||||
NET "hostData[14]" LOC = "P122";
|
NET "hostData[14]" LOC = "P122";
|
||||||
NET "hostData[14]" FAST;
|
|
||||||
NET "hostData[14]" DRIVE = 12;
|
|
||||||
NET "hostData[14]" NODELAY;
|
|
||||||
NET "hostData[15]" LOC = "P120";
|
NET "hostData[15]" LOC = "P120";
|
||||||
NET "hostData[15]" FAST;
|
|
||||||
NET "hostData[15]" DRIVE = 12;
|
|
||||||
NET "hostData[15]" NODELAY;
|
|
||||||
|
|
||||||
## SRAM interface
|
## SRAM interface
|
||||||
|
|
||||||
NET "nSRAMRead" LOC = "P40";
|
NET "nSRAMRead" LOC = "P40";
|
||||||
NET "nSRAMRead" FAST;
|
NET "nSRAMRead" FAST;
|
||||||
NET "nSRAMRead" DRIVE = 12;
|
|
||||||
NET "nSRAMWrite" LOC = "P55";
|
NET "nSRAMWrite" LOC = "P55";
|
||||||
NET "nSRAMWrite" FAST;
|
NET "nSRAMWrite" FAST;
|
||||||
NET "nSRAMWrite" DRIVE = 12;
|
|
||||||
NET "nSRAMEnable" LOC = "P34";
|
NET "nSRAMEnable" LOC = "P34";
|
||||||
NET "nSRAMEnable" FAST;
|
NET "nSRAMEnable" FAST;
|
||||||
NET "nSRAMEnable" DRIVE = 12;
|
|
||||||
|
|
||||||
NET "sramAddress[0]" LOC = "P30";
|
NET "sramAddress[0]" LOC = "P30";
|
||||||
NET "sramAddress[0]" FAST;
|
|
||||||
NET "sramAddress[0]" DRIVE = 12;
|
|
||||||
NET "sramAddress[1]" LOC = "P32";
|
NET "sramAddress[1]" LOC = "P32";
|
||||||
NET "sramAddress[1]" FAST;
|
|
||||||
NET "sramAddress[1]" DRIVE = 12;
|
|
||||||
NET "sramAddress[2]" LOC = "P35";
|
NET "sramAddress[2]" LOC = "P35";
|
||||||
NET "sramAddress[2]" FAST;
|
|
||||||
NET "sramAddress[2]" DRIVE = 12;
|
|
||||||
NET "sramAddress[3]" LOC = "P37";
|
NET "sramAddress[3]" LOC = "P37";
|
||||||
NET "sramAddress[3]" FAST;
|
|
||||||
NET "sramAddress[3]" DRIVE = 12;
|
|
||||||
NET "sramAddress[4]" LOC = "P41";
|
NET "sramAddress[4]" LOC = "P41";
|
||||||
NET "sramAddress[4]" FAST;
|
|
||||||
NET "sramAddress[4]" DRIVE = 12;
|
|
||||||
NET "sramAddress[5]" LOC = "P43";
|
NET "sramAddress[5]" LOC = "P43";
|
||||||
NET "sramAddress[5]" FAST;
|
|
||||||
NET "sramAddress[5]" DRIVE = 12;
|
|
||||||
NET "sramAddress[6]" LOC = "P45";
|
NET "sramAddress[6]" LOC = "P45";
|
||||||
NET "sramAddress[6]" FAST;
|
|
||||||
NET "sramAddress[6]" DRIVE = 12;
|
|
||||||
NET "sramAddress[7]" LOC = "P47";
|
NET "sramAddress[7]" LOC = "P47";
|
||||||
NET "sramAddress[7]" FAST;
|
|
||||||
NET "sramAddress[7]" DRIVE = 12;
|
|
||||||
NET "sramAddress[8]" LOC = "P46";
|
NET "sramAddress[8]" LOC = "P46";
|
||||||
NET "sramAddress[8]" FAST;
|
|
||||||
NET "sramAddress[8]" DRIVE = 12;
|
|
||||||
NET "sramAddress[9]" LOC = "P44";
|
NET "sramAddress[9]" LOC = "P44";
|
||||||
NET "sramAddress[9]" FAST;
|
|
||||||
NET "sramAddress[9]" DRIVE = 12;
|
|
||||||
NET "sramAddress[10]" LOC = "P36";
|
NET "sramAddress[10]" LOC = "P36";
|
||||||
NET "sramAddress[10]" FAST;
|
|
||||||
NET "sramAddress[10]" DRIVE = 12;
|
|
||||||
NET "sramAddress[11]" LOC = "P42";
|
NET "sramAddress[11]" LOC = "P42";
|
||||||
NET "sramAddress[11]" FAST;
|
|
||||||
NET "sramAddress[11]" DRIVE = 12;
|
|
||||||
NET "sramAddress[12]" LOC = "P49";
|
NET "sramAddress[12]" LOC = "P49";
|
||||||
NET "sramAddress[12]" FAST;
|
|
||||||
NET "sramAddress[12]" DRIVE = 12;
|
|
||||||
NET "sramAddress[13]" LOC = "P48";
|
NET "sramAddress[13]" LOC = "P48";
|
||||||
NET "sramAddress[13]" FAST;
|
|
||||||
NET "sramAddress[13]" DRIVE = 12;
|
|
||||||
NET "sramAddress[14]" LOC = "P56";
|
NET "sramAddress[14]" LOC = "P56";
|
||||||
NET "sramAddress[14]" FAST;
|
|
||||||
NET "sramAddress[14]" DRIVE = 12;
|
|
||||||
NET "sramAddress[15]" LOC = "P58";
|
NET "sramAddress[15]" LOC = "P58";
|
||||||
NET "sramAddress[15]" FAST;
|
|
||||||
NET "sramAddress[15]" DRIVE = 12;
|
|
||||||
NET "sramAddress[16]" LOC = "P57";
|
NET "sramAddress[16]" LOC = "P57";
|
||||||
NET "sramAddress[16]" FAST;
|
|
||||||
NET "sramAddress[16]" DRIVE = 12;
|
|
||||||
|
|
||||||
NET "sramData[0]" LOC = "P28";
|
NET "sramData[0]" LOC = "P28";
|
||||||
NET "sramData[0]" FAST;
|
|
||||||
NET "sramData[0]" DRIVE = 12;
|
|
||||||
NET "sramData[0]" NODELAY;
|
|
||||||
NET "sramData[1]" LOC = "P24";
|
NET "sramData[1]" LOC = "P24";
|
||||||
NET "sramData[1]" FAST;
|
|
||||||
NET "sramData[1]" DRIVE = 12;
|
|
||||||
NET "sramData[1]" NODELAY;
|
|
||||||
NET "sramData[2]" LOC = "P22";
|
NET "sramData[2]" LOC = "P22";
|
||||||
NET "sramData[2]" FAST;
|
|
||||||
NET "sramData[2]" DRIVE = 12;
|
|
||||||
NET "sramData[2]" NODELAY;
|
|
||||||
NET "sramData[3]" LOC = "P21";
|
NET "sramData[3]" LOC = "P21";
|
||||||
NET "sramData[3]" FAST;
|
|
||||||
NET "sramData[3]" DRIVE = 12;
|
|
||||||
NET "sramData[3]" NODELAY;
|
|
||||||
NET "sramData[4]" LOC = "P23";
|
NET "sramData[4]" LOC = "P23";
|
||||||
NET "sramData[4]" FAST;
|
|
||||||
NET "sramData[4]" DRIVE = 12;
|
|
||||||
NET "sramData[4]" NODELAY;
|
|
||||||
NET "sramData[5]" LOC = "P27";
|
NET "sramData[5]" LOC = "P27";
|
||||||
NET "sramData[5]" FAST;
|
|
||||||
NET "sramData[5]" DRIVE = 12;
|
|
||||||
NET "sramData[5]" NODELAY;
|
|
||||||
NET "sramData[6]" LOC = "P29";
|
NET "sramData[6]" LOC = "P29";
|
||||||
NET "sramData[6]" FAST;
|
|
||||||
NET "sramData[6]" DRIVE = 12;
|
|
||||||
NET "sramData[6]" NODELAY;
|
|
||||||
NET "sramData[7]" LOC = "P31";
|
NET "sramData[7]" LOC = "P31";
|
||||||
NET "sramData[7]" FAST;
|
|
||||||
NET "sramData[7]" DRIVE = 12;
|
## DRAM interface
|
||||||
NET "sramData[7]" NODELAY;
|
|
||||||
|
# TODO: trace these pins out
|
||||||
|
NET "dramControl[0]" LOC = "P188";
|
||||||
|
NET "dramControl[1]" LOC = "P189";
|
||||||
|
NET "dramControl[2]" LOC = "P190";
|
||||||
|
NET "dramControl[3]" LOC = "P191";
|
||||||
|
NET "dramControl[4]" LOC = "P193";
|
||||||
|
NET "dramControl[5]" LOC = "P194";
|
||||||
|
NET "dramControl[6]" LOC = "P196";
|
||||||
|
NET "dramControl[7]" LOC = "P197";
|
||||||
|
NET "dramControl[8]" LOC = "P198";
|
||||||
|
NET "dramControl[9]" LOC = "P199";
|
||||||
|
NET "dramControl[10]" LOC = "P200";
|
||||||
|
NET "dramControl[11]" LOC = "P201";
|
||||||
|
|
||||||
|
NET "dramAddress[0]" LOC = "P186";
|
||||||
|
NET "dramAddress[1]" LOC = "P184";
|
||||||
|
NET "dramAddress[2]" LOC = "P180";
|
||||||
|
NET "dramAddress[3]" LOC = "P178";
|
||||||
|
NET "dramAddress[4]" LOC = "P176";
|
||||||
|
NET "dramAddress[5]" LOC = "P174";
|
||||||
|
NET "dramAddress[6]" LOC = "P175";
|
||||||
|
NET "dramAddress[7]" LOC = "P177";
|
||||||
|
NET "dramAddress[8]" LOC = "P179";
|
||||||
|
NET "dramAddress[9]" LOC = "P181";
|
||||||
|
NET "dramAddress[10]" LOC = "P185";
|
||||||
|
NET "dramAddress[11]" LOC = "P187";
|
||||||
|
|
||||||
|
NET "dramData[0]" LOC = "P15";
|
||||||
|
NET "dramData[1]" LOC = "P14";
|
||||||
|
NET "dramData[2]" LOC = "P10";
|
||||||
|
NET "dramData[3]" LOC = "P8";
|
||||||
|
NET "dramData[4]" LOC = "P2";
|
||||||
|
NET "dramData[5]" LOC = "P206";
|
||||||
|
NET "dramData[6]" LOC = "P205";
|
||||||
|
NET "dramData[7]" LOC = "P204";
|
||||||
|
NET "dramData[8]" LOC = "P3";
|
||||||
|
NET "dramData[9]" LOC = "P4";
|
||||||
|
NET "dramData[10]" LOC = "P5";
|
||||||
|
NET "dramData[11]" LOC = "P9";
|
||||||
|
NET "dramData[12]" LOC = "P11";
|
||||||
|
NET "dramData[13]" LOC = "P17";
|
||||||
|
NET "dramData[14]" LOC = "P19";
|
||||||
|
NET "dramData[15]" LOC = "P20";
|
||||||
|
|
||||||
|
## MP3 decoder interface
|
||||||
|
|
||||||
|
NET "mp3Reset" LOC = "P152";
|
||||||
|
NET "mp3Ready" LOC = "P159";
|
||||||
|
NET "mp3ClockIn" LOC = "P163";
|
||||||
|
NET "mp3ClockOut" LOC = "P162";
|
||||||
|
NET "mp3SDA" LOC = "P150";
|
||||||
|
NET "mp3SCL" LOC = "P151";
|
||||||
|
|
||||||
|
NET "mp3StatusCS" LOC = "P149";
|
||||||
|
NET "mp3StatusError" LOC = "P168";
|
||||||
|
NET "mp3StatusFrameSync" LOC = "P161";
|
||||||
|
NET "mp3StatusDataReq" LOC = "P148";
|
||||||
|
|
||||||
|
NET "mp3InSDIN" LOC = "P167";
|
||||||
|
NET "mp3InBCLK" LOC = "P164";
|
||||||
|
NET "mp3InLRCK" LOC = "P166";
|
||||||
|
NET "mp3OutSDOUT" LOC = "P172";
|
||||||
|
NET "mp3OutBCLK" LOC = "P169";
|
||||||
|
NET "mp3OutLRCK" LOC = "P171";
|
||||||
|
|
||||||
|
## I2S audio output
|
||||||
|
|
||||||
|
NET "dacSDIN" LOC = "P96";
|
||||||
|
NET "dacBCLK" LOC = "P94";
|
||||||
|
NET "dacLRCK" LOC = "P95";
|
||||||
|
NET "dacMCLK" LOC = "P97";
|
||||||
|
|
||||||
## Light outputs
|
## Light outputs
|
||||||
|
|
||||||
# TODO: figure out the actual pin order of the outputs
|
NET "lightBankAH[0]" LOC = "P84";
|
||||||
NET "lightBankA[0]" LOC = "P69";
|
NET "lightBankAH[1]" LOC = "P83";
|
||||||
NET "lightBankA[0]" SLOW;
|
NET "lightBankAH[2]" LOC = "P82";
|
||||||
NET "lightBankA[0]" DRIVE = 24;
|
NET "lightBankAH[3]" LOC = "P81";
|
||||||
NET "lightBankA[1]" LOC = "P70";
|
|
||||||
NET "lightBankA[1]" SLOW;
|
NET "lightBankAL[0]" LOC = "P80";
|
||||||
NET "lightBankA[1]" DRIVE = 24;
|
NET "lightBankAL[1]" LOC = "P76";
|
||||||
NET "lightBankA[2]" LOC = "P72";
|
NET "lightBankAL[2]" LOC = "P75";
|
||||||
NET "lightBankA[2]" SLOW;
|
NET "lightBankAL[3]" LOC = "P74";
|
||||||
NET "lightBankA[2]" DRIVE = 24;
|
|
||||||
NET "lightBankA[3]" LOC = "P73";
|
NET "lightBankBH[0]" LOC = "P73";
|
||||||
NET "lightBankA[3]" SLOW;
|
NET "lightBankBH[1]" LOC = "P72";
|
||||||
NET "lightBankA[3]" DRIVE = 24;
|
NET "lightBankBH[2]" LOC = "P70";
|
||||||
NET "lightBankA[4]" LOC = "P74";
|
NET "lightBankBH[3]" LOC = "P69";
|
||||||
NET "lightBankA[4]" SLOW;
|
|
||||||
NET "lightBankA[4]" DRIVE = 24;
|
|
||||||
NET "lightBankA[5]" LOC = "P75";
|
|
||||||
NET "lightBankA[5]" SLOW;
|
|
||||||
NET "lightBankA[5]" DRIVE = 24;
|
|
||||||
NET "lightBankA[6]" LOC = "P76";
|
|
||||||
NET "lightBankA[6]" SLOW;
|
|
||||||
NET "lightBankA[6]" DRIVE = 24;
|
|
||||||
NET "lightBankA[7]" LOC = "P80";
|
|
||||||
NET "lightBankA[7]" SLOW;
|
|
||||||
NET "lightBankA[7]" DRIVE = 24;
|
|
||||||
NET "lightBankB[0]" LOC = "P81";
|
|
||||||
NET "lightBankB[0]" SLOW;
|
|
||||||
NET "lightBankB[0]" DRIVE = 24;
|
|
||||||
NET "lightBankB[1]" LOC = "P82";
|
|
||||||
NET "lightBankB[1]" SLOW;
|
|
||||||
NET "lightBankB[1]" DRIVE = 24;
|
|
||||||
NET "lightBankB[2]" LOC = "P83";
|
|
||||||
NET "lightBankB[2]" SLOW;
|
|
||||||
NET "lightBankB[2]" DRIVE = 24;
|
|
||||||
NET "lightBankB[3]" LOC = "P84";
|
|
||||||
NET "lightBankB[3]" SLOW;
|
|
||||||
NET "lightBankB[3]" DRIVE = 24;
|
|
||||||
NET "lightBankD[0]" LOC = "P68";
|
NET "lightBankD[0]" LOC = "P68";
|
||||||
NET "lightBankD[0]" SLOW;
|
|
||||||
NET "lightBankD[0]" DRIVE = 24;
|
|
||||||
NET "lightBankD[1]" LOC = "P67";
|
NET "lightBankD[1]" LOC = "P67";
|
||||||
NET "lightBankD[1]" SLOW;
|
|
||||||
NET "lightBankD[1]" DRIVE = 24;
|
|
||||||
NET "lightBankD[2]" LOC = "P60";
|
NET "lightBankD[2]" LOC = "P60";
|
||||||
NET "lightBankD[2]" SLOW;
|
|
||||||
NET "lightBankD[2]" DRIVE = 24;
|
|
||||||
NET "lightBankD[3]" LOC = "P59";
|
NET "lightBankD[3]" LOC = "P59";
|
||||||
NET "lightBankD[3]" SLOW;
|
|
||||||
NET "lightBankD[3]" DRIVE = 24;
|
## General-purpose inputs (unused)
|
||||||
|
|
||||||
|
#NET "inputBank[0]" LOC = "P61";
|
||||||
|
#NET "inputBank[1]" LOC = "P62";
|
||||||
|
#NET "inputBank[2]" LOC = "P63";
|
||||||
|
#NET "inputBank[3]" LOC = "P64";
|
||||||
|
|
||||||
|
## Serial interfaces
|
||||||
|
|
||||||
|
# TODO: are pins 98 and 99 swapped?
|
||||||
|
NET "networkTXEnable" LOC = "P98";
|
||||||
|
NET "networkTX" LOC = "P99";
|
||||||
|
NET "networkRX" LOC = "P100";
|
||||||
|
|
||||||
|
NET "serialTX" LOC = "P89";
|
||||||
|
NET "serialRX" LOC = "P88";
|
||||||
|
NET "serialRTS" LOC = "P93";
|
||||||
|
NET "serialCTS" LOC = "P90";
|
||||||
|
NET "serialDTR" LOC = "P87";
|
||||||
|
NET "serialDSR" LOC = "P85";
|
||||||
|
|
||||||
## 1-wire bus
|
## 1-wire bus
|
||||||
|
|
||||||
NET "ds2401" LOC = "P109";
|
|
||||||
NET "ds2401" SLOW;
|
|
||||||
NET "ds2401" DRIVE = 24;
|
|
||||||
NET "ds2433" LOC = "P107";
|
NET "ds2433" LOC = "P107";
|
||||||
NET "ds2433" SLOW;
|
NET "ds2401" LOC = "P109";
|
||||||
NET "ds2433" DRIVE = 24;
|
|
||||||
|
15
fpga/fpga.ys
15
fpga/fpga.ys
@ -6,6 +6,7 @@
|
|||||||
## Input and preliminary optimization
|
## Input and preliminary optimization
|
||||||
|
|
||||||
read_verilog src/main.v
|
read_verilog src/main.v
|
||||||
|
read_verilog src/spartanxl.v
|
||||||
hierarchy -check -top FPGA
|
hierarchy -check -top FPGA
|
||||||
|
|
||||||
proc
|
proc
|
||||||
@ -39,23 +40,23 @@ clean
|
|||||||
## FPGA-specific mapping
|
## FPGA-specific mapping
|
||||||
|
|
||||||
dfflegalize -cell $_DFFE_PP?P_ r -cell $_DLATCH_PP?_ r
|
dfflegalize -cell $_DFFE_PP?P_ r -cell $_DLATCH_PP?_ r
|
||||||
|
|
||||||
opt_expr -mux_undef -noclkinv
|
opt_expr -mux_undef -noclkinv
|
||||||
abc -g gates
|
abc -g gates
|
||||||
techmap -map src/techmap.v
|
|
||||||
clean
|
|
||||||
|
|
||||||
xilinx_dffopt -lut4
|
xilinx_dffopt -lut4
|
||||||
clkbufmap -buf BUFGLS O:I
|
|
||||||
iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O -toutpad OBUFT ~T:I:O -tinoutpad IOBUFT ~T:O:I:IO -ignore IFDX D -ignore IFDXI D -ignore OFDX Q -ignore OFDXI Q -ignore OFDTX O -ignore OFDTXI O
|
#clkbufmap -buf BUFGLS O:I
|
||||||
|
iopadmap -bits -inpad IBUF O:I -ignore IPAD IPAD -ignore OPAD OPAD -ignore IOPAD IOPAD -ignore IFDX D -ignore IFDXI D -ignore BUFGLS I
|
||||||
|
iopadmap -bits -outpad OBUF I:O -toutpad OBUFT ~T:I:O -tinoutpad IOBUFT ~T:O:I:IO -ignore IPAD IPAD -ignore OPAD OPAD -ignore IOPAD IOPAD -ignore OFDX Q -ignore OFDXI Q -ignore OFDTX O -ignore OFDTXI O
|
||||||
extractinv -inv INV O:I
|
extractinv -inv INV O:I
|
||||||
techmap -map src/techmap.v
|
techmap -map src/techmap.v
|
||||||
clean
|
clean
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
|
||||||
|
# FIXME: for some reason invoking hierarchy here results in $or/$reduce_or
|
||||||
|
# primitives being added back when using wired-or
|
||||||
|
#hierarchy -check
|
||||||
autoname
|
autoname
|
||||||
hierarchy -check
|
|
||||||
stat -tech xilinx
|
stat -tech xilinx
|
||||||
check -noinit
|
check -noinit
|
||||||
blackbox =A:whitebox
|
blackbox =A:whitebox
|
||||||
|
@ -20,7 +20,7 @@ ngdbuild synth.edf synth.ngd ^
|
|||||||
-uc ..\fpga.ucf ^
|
-uc ..\fpga.ucf ^
|
||||||
-p %TARGET% ^
|
-p %TARGET% ^
|
||||||
|| exit /b 2
|
|| exit /b 2
|
||||||
map -o mapped.ncd synth.ngd ^
|
map -o mapped.ncd synth.ngd mapped.pcf ^
|
||||||
-p %TARGET% ^
|
-p %TARGET% ^
|
||||||
-cm %COVER_MODE% ^
|
-cm %COVER_MODE% ^
|
||||||
-os %OPTIMIZATION_MODE% ^
|
-os %OPTIMIZATION_MODE% ^
|
||||||
@ -29,7 +29,7 @@ map -o mapped.ncd synth.ngd ^
|
|||||||
-detail ^
|
-detail ^
|
||||||
|| exit /b 2
|
|| exit /b 2
|
||||||
|
|
||||||
par mapped.ncd fpga.ncd ^
|
par mapped.ncd fpga.ncd mapped.pcf ^
|
||||||
-w ^
|
-w ^
|
||||||
-detail ^
|
-detail ^
|
||||||
|| exit /b 3
|
|| exit /b 3
|
||||||
|
356
fpga/src/main.v
356
fpga/src/main.v
@ -1,40 +1,11 @@
|
|||||||
|
|
||||||
/* Spartan-XL primitive library */
|
|
||||||
|
|
||||||
module BUF (input I, output O); endmodule
|
|
||||||
module INV (input I, output O); endmodule
|
|
||||||
module AND2 (input I0, input I1, output O); endmodule
|
|
||||||
module NAND2 (input I0, input I1, output O); endmodule
|
|
||||||
module AND2B1 (input I0, input I1, output O); endmodule
|
|
||||||
module OR2 (input I0, input I1, output O); endmodule
|
|
||||||
module NOR2 (input I0, input I1, output O); endmodule
|
|
||||||
module OR2B1 (input I0, input I1, output O); endmodule
|
|
||||||
module XOR2 (input I0, input I1, output O); endmodule
|
|
||||||
module XNOR2 (input I0, input I1, output O); endmodule
|
|
||||||
module BUFT (input I, input T, output O); endmodule
|
|
||||||
module FDCE (input D, input C, input CLR, input CE, output Q); endmodule
|
|
||||||
module FDPE (input D, input C, input PRE, input CE, output Q); endmodule
|
|
||||||
module LDCE_1 (input D, input G, input CLR, input GE, output Q); endmodule
|
|
||||||
module LDPE_1 (input D, input G, input PRE, input GE, output Q); endmodule
|
|
||||||
|
|
||||||
module IPAD (output IPAD); endmodule
|
|
||||||
module OPAD (input OPAD); endmodule
|
|
||||||
module IOPAD (inout IOPAD); endmodule
|
|
||||||
module IBUF (input I, output O); endmodule
|
|
||||||
module OBUF (input I, output O); endmodule
|
|
||||||
module OBUFT (input I, input T, output O); endmodule
|
|
||||||
module IOBUFT (input I, input T, output O, inout IO); endmodule
|
|
||||||
module BUFGLS (input I, output O); endmodule
|
|
||||||
module IFDX (input D, input C, input CE, output Q); endmodule
|
|
||||||
module IFDXI (input D, input C, input CE, output Q); endmodule
|
|
||||||
module OFDX (input D, input C, input CE, output Q); endmodule
|
|
||||||
module OFDXI (input D, input C, input CE, output Q); endmodule
|
|
||||||
module OFDTX (input D, input C, input CE, input T, output O); endmodule
|
|
||||||
module OFDTXI (input D, input C, input CE, input T, output O); endmodule
|
|
||||||
|
|
||||||
/* Top-level module */
|
|
||||||
|
|
||||||
module FPGA (
|
module FPGA (
|
||||||
|
// These are technically inputs, however they are already wired up to pad
|
||||||
|
// primitives within the module. They are only exposed here in order to
|
||||||
|
// allow for a testbench to inject the clocks during simulation.
|
||||||
|
inout clockIn29M,
|
||||||
|
inout clockIn19M,
|
||||||
|
|
||||||
input nHostRead,
|
input nHostRead,
|
||||||
input nHostWrite,
|
input nHostWrite,
|
||||||
input nHostEnable,
|
input nHostEnable,
|
||||||
@ -47,54 +18,161 @@ module FPGA (
|
|||||||
output [16:0] sramAddress,
|
output [16:0] sramAddress,
|
||||||
inout [7:0] sramData,
|
inout [7:0] sramData,
|
||||||
|
|
||||||
output [7:0] lightBankA,
|
output [11:0] dramControl,
|
||||||
output [3:0] lightBankB,
|
output [11:0] dramAddress,
|
||||||
|
inout [15:0] dramData,
|
||||||
|
|
||||||
|
output mp3Reset,
|
||||||
|
input mp3Ready,
|
||||||
|
output mp3ClockIn,
|
||||||
|
input mp3ClockOut,
|
||||||
|
inout mp3SDA,
|
||||||
|
inout mp3SCL,
|
||||||
|
|
||||||
|
output mp3StatusCS,
|
||||||
|
input mp3StatusError,
|
||||||
|
input mp3StatusFrameSync,
|
||||||
|
input mp3StatusDataReq,
|
||||||
|
|
||||||
|
output mp3InSDIN,
|
||||||
|
output mp3InBCLK,
|
||||||
|
output mp3InLRCK,
|
||||||
|
input mp3OutSDOUT,
|
||||||
|
input mp3OutBCLK,
|
||||||
|
input mp3OutLRCK,
|
||||||
|
|
||||||
|
output dacSDIN,
|
||||||
|
output dacBCLK,
|
||||||
|
output dacLRCK,
|
||||||
|
output dacMCLK,
|
||||||
|
|
||||||
|
output [3:0] lightBankAH,
|
||||||
|
output [3:0] lightBankAL,
|
||||||
|
output [3:0] lightBankBH,
|
||||||
output [3:0] lightBankD,
|
output [3:0] lightBankD,
|
||||||
|
|
||||||
inout ds2401,
|
output networkTXEnable,
|
||||||
inout ds2433
|
output networkTX,
|
||||||
|
input networkRX,
|
||||||
|
|
||||||
|
output serialTX,
|
||||||
|
input serialRX,
|
||||||
|
output serialRTS,
|
||||||
|
input serialCTS,
|
||||||
|
output serialDTR,
|
||||||
|
input serialDSR,
|
||||||
|
|
||||||
|
inout ds2433,
|
||||||
|
inout ds2401
|
||||||
);
|
);
|
||||||
genvar i;
|
genvar i;
|
||||||
|
|
||||||
|
/* Register definitions */
|
||||||
|
|
||||||
|
localparam SYS573D_FPGA_MAGIC = 8'h80;
|
||||||
|
|
||||||
|
localparam SYS573D_FPGA_MP3_PTR_H = 8'ha0;
|
||||||
|
localparam SYS573D_FPGA_MP3_PTR_L = 8'ha2;
|
||||||
|
localparam SYS573D_FPGA_MP3_ENDPTR_H = 8'ha4;
|
||||||
|
localparam SYS573D_FPGA_MP3_ENDPTR_L = 8'ha6;
|
||||||
|
localparam SYS573D_FPGA_MP3_COUNTER = 8'ha8;
|
||||||
|
localparam SYS573D_FPGA_MP3_KEY1 = 8'ha8;
|
||||||
|
localparam SYS573D_FPGA_MP3_FEED_STAT = 8'haa;
|
||||||
|
localparam SYS573D_FPGA_MP3_I2C = 8'hac;
|
||||||
|
localparam SYS573D_FPGA_MP3_FEED_CTRL = 8'hae;
|
||||||
|
|
||||||
|
localparam SYS573D_FPGA_DRAM_WRPTR_H = 8'hb0;
|
||||||
|
localparam SYS573D_FPGA_DRAM_WRPTR_L = 8'hb2;
|
||||||
|
localparam SYS573D_FPGA_DRAM_DATA = 8'hb4;
|
||||||
|
localparam SYS573D_FPGA_DRAM_RDPTR_H = 8'hb6;
|
||||||
|
localparam SYS573D_FPGA_DRAM_RDPTR_L = 8'hb8;
|
||||||
|
|
||||||
|
localparam SYS573D_FPGA_NET_DATA = 8'hc0;
|
||||||
|
localparam SYS573D_FPGA_DAC_COUNTER_H = 8'hca;
|
||||||
|
localparam SYS573D_FPGA_DAC_COUNTER_L = 8'hcc;
|
||||||
|
localparam SYS573D_FPGA_DAC_COUNTER_D = 8'hce;
|
||||||
|
|
||||||
|
localparam SYS573D_FPGA_LIGHTS_AH = 8'he0;
|
||||||
|
localparam SYS573D_FPGA_LIGHTS_AL = 8'he2;
|
||||||
|
localparam SYS573D_FPGA_LIGHTS_BH = 8'he4;
|
||||||
|
localparam SYS573D_FPGA_LIGHTS_D = 8'he6;
|
||||||
|
localparam SYS573D_FPGA_INIT = 8'he8;
|
||||||
|
localparam SYS573D_FPGA_MP3_KEY2 = 8'hea;
|
||||||
|
localparam SYS573D_FPGA_MP3_KEY3 = 8'hec;
|
||||||
|
localparam SYS573D_FPGA_DS_BUS = 8'hee;
|
||||||
|
|
||||||
/* System clocks */
|
/* System clocks */
|
||||||
|
|
||||||
wire clockIn29M, _clock29M;
|
wire clock29M, clock19M;
|
||||||
wire clockIn19M, _clock19M;
|
|
||||||
|
|
||||||
IPAD _clockPad29M ( .IPAD(clockIn29M) );
|
// ISE rejects global buffer primitives unless they are wired either to an
|
||||||
IPAD _clockPad19M ( .IPAD(clockIn19M) );
|
// IBUF (which results in suboptimal routing, as the dedicated IOB clock
|
||||||
BUFGLS _clockBuf29M ( .I(clockIn29M), .O(_clock29M) );
|
// output is left unused) or directly to a pad primitive.
|
||||||
BUFGLS _clockBuf19M ( .I(clockIn19M), .O(_clock19M) );
|
IPAD clockPad29M (.IPAD(clockIn29M));
|
||||||
|
IPAD clockPad19M (.IPAD(clockIn19M));
|
||||||
|
BUFGLS clockBuf29M (.I(clockIn29M), .O(clock29M));
|
||||||
|
BUFGLS clockBuf19M (.I(clockIn19M), .O(clock19M));
|
||||||
|
|
||||||
|
/* Host address decoding */
|
||||||
|
|
||||||
|
// The FPGA shall only respond to addresses in 0x80-0xef range, as 0xf0-0xff
|
||||||
|
// is used by the CPLD and 0x00-0x7f seems to be reserved for debugging
|
||||||
|
// hardware. Bit 0 of the 573's address bus is not wired to the FPGA as all
|
||||||
|
// registers are 16 bits wide.
|
||||||
|
wire hostAddrValid = hostAddress[6] & (hostAddress[5:3] != 3'b111);
|
||||||
|
wire hostRegRead = ~nHostEnable & ~nHostRead & nHostWrite;
|
||||||
|
wire hostRegWrite = ~nHostEnable & nHostRead & ~nHostWrite;
|
||||||
|
|
||||||
|
wire [7:0] hostRegister = { 1'b1, hostAddress[5:0], 1'b0 };
|
||||||
|
|
||||||
/* Host interface */
|
/* Host interface */
|
||||||
|
|
||||||
wire _nHostRead, _nHostWrite, _nHostEnable;
|
reg [2:0] _delayedHostRegRead = 3'b000;
|
||||||
wire [6:0] _hostAddress;
|
wire _hostDataInClock;
|
||||||
wire [15:0] _hostDataIn;
|
|
||||||
wire [15:0] _hostDataOut;
|
|
||||||
|
|
||||||
wire _nHostReadFPGA = _nHostRead || _nHostEnable;
|
wire [15:0] hostDataIn;
|
||||||
wire _nHostWriteFPGA = _nHostWrite || _nHostEnable;
|
wor [15:0] hostDataOut;
|
||||||
|
|
||||||
// IOB flip-flop primitives (IFDX, OFDX) are explicitly used whenever
|
reg hostDataInValid = 1'b0;
|
||||||
// possible in order to minimize propagation delays and CLB usage.
|
reg hostDataOutValid = 1'b0;
|
||||||
IFDX _nHostReadBuf ( .C(_clock29M), .D(nHostRead), .Q(_nHostRead), .CE(1'b1) );
|
|
||||||
IFDX _nHostWriteBuf ( .C(_clock29M), .D(nHostWrite), .Q(_nHostWrite), .CE(1'b1) );
|
// Data is latched in the input flip flops once the 573 *deasserts* either
|
||||||
IFDX _nHostEnableBuf ( .C(_clock29M), .D(nHostEnable), .Q(_nHostEnable), .CE(1'b1) );
|
// the chip select or the write strobe. Konami's bitstream routes this
|
||||||
|
// signal through a global net (_hostDataInClock), possibly since it is
|
||||||
|
// asynchronous and not tied to the main clock.
|
||||||
|
BUFGLS hostDataInUpdateBuf(.I(hostRegWrite), .O(_hostDataInClock));
|
||||||
|
|
||||||
|
wire hostDataInPending = ~hostRegWrite & hostDataInValid;
|
||||||
|
|
||||||
|
always @(posedge clock29M) begin
|
||||||
|
// Konami's bitstream pulls the output flip flops' clock enable low
|
||||||
|
// after 3 cycles if the register being read is in 0xa0-0xaf range (i.e.
|
||||||
|
// MP3 status and counters), in order to prevent any further updates
|
||||||
|
// while the counters are running. A 3-bit shift register is used to
|
||||||
|
// implement the delay.
|
||||||
|
_delayedHostRegRead <= { _delayedHostRegRead[1:0], hostRegRead };
|
||||||
|
|
||||||
|
// The direction of the bus is only changed on clock edges in order to
|
||||||
|
// prevent any data from being output before the output flip flops are
|
||||||
|
// updated.
|
||||||
|
hostDataInValid <= hostRegWrite;
|
||||||
|
hostDataOutValid <= hostAddrValid & hostRegRead;
|
||||||
|
end
|
||||||
|
|
||||||
generate
|
generate
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 16; i = i + 1) begin
|
||||||
IFDX _hostAddressBuf (
|
IFDX hostDataInReg (
|
||||||
.C(_clock29M), .D(hostAddress[i]), .Q(_hostAddress[i])
|
.D(hostData[i]),
|
||||||
|
.C(~_hostDataInClock),
|
||||||
|
.CE(1'b1),
|
||||||
|
.Q(hostDataIn[i])
|
||||||
);
|
);
|
||||||
|
OFDTX hostDataOutReg (
|
||||||
for (i = 0; i < 16; i++) begin
|
.D(hostDataOut[i]),
|
||||||
IFDX _hostDataInBuf (
|
.C(clock29M),
|
||||||
.C(_clock29M), .D(hostData[i]), .Q(_hostDataIn[i]), .CE(1'b1)
|
.CE(~_delayedHostRegRead[2]),
|
||||||
);
|
.T(~hostDataOutValid),
|
||||||
OFDTX _hostDataOutBuf (
|
.O(hostData[i])
|
||||||
.C(_clock29M), .O(hostData[i]), .D(_hostDataOut[i]),
|
|
||||||
.CE(~_nHostReadFPGA), .T(_nHostReadFPGA)
|
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
@ -105,71 +183,107 @@ module FPGA (
|
|||||||
assign nSRAMWrite = 1'b1;
|
assign nSRAMWrite = 1'b1;
|
||||||
assign nSRAMEnable = 1'b1;
|
assign nSRAMEnable = 1'b1;
|
||||||
assign sramAddress = 17'h1ffff;
|
assign sramAddress = 17'h1ffff;
|
||||||
assign sramData = 8'hff;
|
|
||||||
|
/* DRAM interface (currently unused) */
|
||||||
|
|
||||||
|
assign dramControl = 12'hfff;
|
||||||
|
assign dramAddress = 12'hfff;
|
||||||
|
|
||||||
|
/* MP3 decoder interface (currently unused) */
|
||||||
|
|
||||||
|
assign mp3Reset = 1'b1;
|
||||||
|
assign mp3ClockIn = 1'b1;
|
||||||
|
assign mp3StatusCS = 1'b1;
|
||||||
|
|
||||||
|
assign mp3InSDIN = 1'b1;
|
||||||
|
assign mp3InBCLK = 1'b1;
|
||||||
|
assign mp3InLRCK = 1'b1;
|
||||||
|
|
||||||
|
assign hostDataOut = (hostRegister == SYS573D_FPGA_MP3_I2C)
|
||||||
|
? { 2'h0, mp3SCL, mp3SDA, 12'h000 }
|
||||||
|
: 16'h0000;
|
||||||
|
|
||||||
|
reg mp3SDAState = 1'b0;
|
||||||
|
reg mp3SCLState = 1'b0;
|
||||||
|
|
||||||
|
always @(posedge clock29M)
|
||||||
|
if (hostDataInPending & (hostRegister == SYS573D_FPGA_MP3_I2C)) begin
|
||||||
|
mp3SDAState <= hostDataIn[12];
|
||||||
|
mp3SCLState <= hostDataIn[13];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign mp3SDA = mp3SDAState ? 1'bz : 1'b0;
|
||||||
|
assign mp3SCL = mp3SCLState ? 1'bz : 1'b0;
|
||||||
|
|
||||||
|
/* I2S audio output */
|
||||||
|
|
||||||
|
assign dacSDIN = mp3OutSDOUT;
|
||||||
|
assign dacBCLK = mp3OutBCLK;
|
||||||
|
assign dacLRCK = mp3OutLRCK;
|
||||||
|
assign dacMCLK = mp3ClockOut;
|
||||||
|
|
||||||
|
/* Magic number */
|
||||||
|
|
||||||
|
assign hostDataOut = (hostRegister == SYS573D_FPGA_MAGIC)
|
||||||
|
? 16'h573f
|
||||||
|
: 16'h0000;
|
||||||
|
|
||||||
/* Light outputs */
|
/* Light outputs */
|
||||||
|
|
||||||
wire [3:0] _lightBankData = _hostDataIn[15:12];
|
|
||||||
|
|
||||||
wire _lightBankA0Write = ~_nHostWriteFPGA & (_hostAddress == 7'h70);
|
|
||||||
wire _lightBankA1Write = ~_nHostWriteFPGA & (_hostAddress == 7'h71);
|
|
||||||
wire _lightBankBWrite = ~_nHostWriteFPGA & (_hostAddress == 7'h72);
|
|
||||||
wire _lightBankDWrite = ~_nHostWriteFPGA & (_hostAddress == 7'h73);
|
|
||||||
|
|
||||||
generate
|
generate
|
||||||
for (i = 0; i < 4; i++) begin
|
for (i = 0; i < 4; i = i + 1) begin
|
||||||
// Use "inverted" flip-flops so that all lights are turned off on
|
reg [3:0] lightBankState = 4'b1111;
|
||||||
// startup.
|
|
||||||
OFDXI _lightBankA0Buf (
|
wire dataIn = hostDataIn[i + 12];
|
||||||
.C(_clock29M), .Q(lightBankA[i + 4]), .D(_lightBankData[i]),
|
|
||||||
.CE(_lightBankA0Write)
|
always @(posedge clock29M)
|
||||||
);
|
if (hostDataInPending)
|
||||||
OFDXI _lightBankA1Buf (
|
case (hostRegister)
|
||||||
.C(_clock29M), .Q(lightBankA[i]), .D(_lightBankData[i]),
|
SYS573D_FPGA_LIGHTS_AH:
|
||||||
.CE(_lightBankA1Write)
|
lightBankState[0] <= dataIn;
|
||||||
);
|
SYS573D_FPGA_LIGHTS_AL:
|
||||||
OFDXI _lightBankBBuf (
|
lightBankState[1] <= dataIn;
|
||||||
.C(_clock29M), .Q(lightBankB[i]), .D(_lightBankData[i]),
|
SYS573D_FPGA_LIGHTS_BH:
|
||||||
.CE(_lightBankBWrite)
|
lightBankState[2] <= dataIn;
|
||||||
);
|
SYS573D_FPGA_LIGHTS_D:
|
||||||
OFDXI _lightBankDBuf (
|
lightBankState[3] <= dataIn;
|
||||||
.C(_clock29M), .Q(lightBankD[i]), .D(_lightBankData[i]),
|
endcase
|
||||||
.CE(_lightBankDWrite)
|
|
||||||
);
|
// Note that XCS40XL IOBs actually have a tristate flip flop, but
|
||||||
|
// there seems to be no primitive exposed by ISE to force its usage.
|
||||||
|
assign lightBankAH[i] = lightBankState[0] ? 1'bz : 1'b0;
|
||||||
|
assign lightBankAL[i] = lightBankState[1] ? 1'bz : 1'b0;
|
||||||
|
assign lightBankBH[i] = lightBankState[2] ? 1'bz : 1'b0;
|
||||||
|
assign lightBankD[i] = lightBankState[3] ? 1'bz : 1'b0;
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
/* Serial interfaces (currently unused) */
|
||||||
|
|
||||||
|
assign networkTXEnable = 1'b1;
|
||||||
|
assign networkTX = 1'b1;
|
||||||
|
|
||||||
|
assign serialTX = 1'b1;
|
||||||
|
assign serialRTS = 1'b1;
|
||||||
|
assign serialDTR = 1'b1;
|
||||||
|
|
||||||
/* 1-wire bus */
|
/* 1-wire bus */
|
||||||
|
|
||||||
wire _ds2401In, _ds2433In;
|
assign hostDataOut = (hostRegister == SYS573D_FPGA_DS_BUS)
|
||||||
reg _ds2401Out, _ds2433Out;
|
? { 3'h0, ds2401, 3'h0, ds2433, 8'h00 }
|
||||||
|
: 16'h0000;
|
||||||
|
|
||||||
// Note that the 1-wire pins are open drain and pulled low by writing 1
|
reg ds2433State = 1'b0;
|
||||||
// (rather than 0) to the respective register bits, but not inverted when
|
reg ds2401State = 1'b0;
|
||||||
// read.
|
|
||||||
IFDX _ds2401InBuf ( .C(_clock29M), .D(ds2401), .Q(_ds2401In), .CE(1'b1) );
|
|
||||||
IFDX _ds2433InBuf ( .C(_clock29M), .D(ds2433), .Q(_ds2433In), .CE(1'b1) );
|
|
||||||
OBUFT _ds2401OutBuf ( .O(ds2401), .I(1'b0), .T(~_ds2401Out) );
|
|
||||||
OBUFT _ds2433OutBuf ( .O(ds2433), .I(1'b0), .T(~_ds2433Out) );
|
|
||||||
|
|
||||||
wire _dsBusWrite = ~_nHostWriteFPGA & (_hostAddress == 7'h77);
|
always @(posedge clock29M)
|
||||||
|
if (hostDataInPending & (hostRegister == SYS573D_FPGA_DS_BUS)) begin
|
||||||
always @(posedge _clock29M)
|
ds2433State <= hostDataIn[8];
|
||||||
if (_dsBusWrite) begin
|
ds2401State <= hostDataIn[12];
|
||||||
_ds2401Out <= _hostDataIn[12];
|
|
||||||
_ds2433Out <= _hostDataIn[13];
|
|
||||||
end
|
end
|
||||||
|
|
||||||
/* Readable registers */
|
// The 1-wire pins are pulled low by writing 1 (rather than 0) to the
|
||||||
|
// respective register bits, but not inverted when read.
|
||||||
wire [15:0] _magicNumberData = 16'h573f;
|
assign ds2433 = ds2433State ? 1'b0 : 1'bz;
|
||||||
wire [15:0] _dsBusData = { 2'h0, _ds2433In, _ds2401In, 12'h000 };
|
assign ds2401 = ds2401State ? 1'b0 : 1'bz;
|
||||||
|
|
||||||
wire _magicNumberRead = ~_nHostReadFPGA & (_hostAddress == 7'h40);
|
|
||||||
wire _dsBusRead = ~_nHostReadFPGA & (_hostAddress == 7'h77);
|
|
||||||
|
|
||||||
assign _hostDataOut =
|
|
||||||
_magicNumberRead ? _magicNumberData :
|
|
||||||
_dsBusRead ? _dsBusData :
|
|
||||||
16'h0000;
|
|
||||||
endmodule
|
endmodule
|
||||||
|
368
fpga/src/spartanxl.v
Normal file
368
fpga/src/spartanxl.v
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
|
||||||
|
/* Logic primitives */
|
||||||
|
|
||||||
|
module BUF (input I, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = I;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module INV (input I, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = ~I;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module AND2 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = I0 & I1;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NAND2 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = ~(I0 & I1);
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module AND2B1 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = I0 & ~I1;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module OR2 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = I0 | I1;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module NOR2 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = ~(I0 | I1);
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module OR2B1 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = I0 | ~I1;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module XOR2 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = (I0 != I1);
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module XNOR2 (input I0, input I1, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = (I0 == I1);
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module BUFT (input I, input T, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = T ? 1'bz : I;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FDCE (input D, input C, input CLR, input CE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg data;
|
||||||
|
assign Q = data;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 1'b0;
|
||||||
|
always @(CLR)
|
||||||
|
data <= 1'b0;
|
||||||
|
always @(posedge C)
|
||||||
|
data <= CE ? D : data;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FDPE (input D, input C, input PRE, input CE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg data;
|
||||||
|
assign Q = data;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 1'b1;
|
||||||
|
always @(PRE)
|
||||||
|
data <= 1'b1;
|
||||||
|
always @(posedge C)
|
||||||
|
data <= CE ? D : data;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module LDCE_1 (input D, input G, input CLR, input GE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg data;
|
||||||
|
assign Q = data;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 1'b0;
|
||||||
|
always @(CLR)
|
||||||
|
data <= 1'b0;
|
||||||
|
always @(~G)
|
||||||
|
data <= GE ? D : data;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module LDPE_1 (input D, input G, input PRE, input GE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg data;
|
||||||
|
assign Q = data;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 1'b1;
|
||||||
|
always @(PRE)
|
||||||
|
data <= 1'b1;
|
||||||
|
always @(~G)
|
||||||
|
data <= GE ? D : data;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
/* I/O primitives */
|
||||||
|
|
||||||
|
(* keep *) module BUFGLS (input I, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
BUF buffer (.I(I), .O(O));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module IBUF (input I, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
BUF buffer (.I(I), .O(O));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OBUF (input I, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
BUF buffer (.I(I), .O(O));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OBUFT (input I, input T, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
BUFT buffer (.I(I), .T(T), .O(O));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module IOBUFT (input I, input T, output O, inout IO);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
assign O = IO;
|
||||||
|
|
||||||
|
BUFT buffer (.I(I), .T(T), .O(IO));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module IFDX (input D, input C, input CE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg data;
|
||||||
|
assign Q = data;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 1'b0;
|
||||||
|
always @(posedge C)
|
||||||
|
data <= CE ? D : data;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module IFDXI (input D, input C, input CE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg data;
|
||||||
|
assign Q = data;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 1'b1;
|
||||||
|
always @(posedge C)
|
||||||
|
data <= CE ? D : data;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OFDX (input D, input C, input CE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
IFDX ff (.D(D), .C(C), .CE(CE), .Q(Q));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OFDXI (input D, input C, input CE, output Q);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
IFDXI ff (.D(D), .C(C), .CE(CE), .Q(Q));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OFDTX (input D, input C, input CE, input T, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
wire Q;
|
||||||
|
|
||||||
|
IFDX ff (.D(D), .C(C), .CE(CE), .Q(Q));
|
||||||
|
BUFT buffer (.I(Q), .T(T), .O(O));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OFDTXI (input D, input C, input CE, input T, output O);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
wire Q;
|
||||||
|
|
||||||
|
IFDXI ff (.D(D), .C(C), .CE(CE), .Q(Q));
|
||||||
|
BUFT buffer (.I(Q), .T(T), .O(O));
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
/* I/O pads */
|
||||||
|
|
||||||
|
(* keep *) module IPAD (output IPAD);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OPAD (input OPAD);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module IOPAD (inout IOPAD);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module UPAD (inout UPAD);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module TDI (inout I);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module TDO (input O);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module TCK (inout I);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module TMS (inout I);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
/* Fixed-function blocks (not simulated) */
|
||||||
|
|
||||||
|
(* keep *) module STARTUP (
|
||||||
|
input GSR,
|
||||||
|
input GTS,
|
||||||
|
input CLK,
|
||||||
|
|
||||||
|
output DONEIN,
|
||||||
|
output Q1Q4,
|
||||||
|
output Q2,
|
||||||
|
output Q3
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module OSC4 (
|
||||||
|
output F8M,
|
||||||
|
output F500K,
|
||||||
|
output F16K,
|
||||||
|
output F490,
|
||||||
|
output F15
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module BSCAN(
|
||||||
|
input TDI,
|
||||||
|
input TDO1,
|
||||||
|
input TDO2,
|
||||||
|
input TCK,
|
||||||
|
input TMS,
|
||||||
|
|
||||||
|
output TDO,
|
||||||
|
output DRCK,
|
||||||
|
output IDLE,
|
||||||
|
output SEL1,
|
||||||
|
output SEL2
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module RDBK (input TRIG, output DATA, output RIP);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* keep *) module RDCLK (input I);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
/* ISE built-in macros */
|
||||||
|
|
||||||
|
module CC8CE (
|
||||||
|
input C, input CLR, input CE, output [7:0] Q, output CEO, output TC
|
||||||
|
);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg [7:0] data;
|
||||||
|
|
||||||
|
assign Q = data;
|
||||||
|
assign TC = &data;
|
||||||
|
assign CEO = TC & CE;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 8'h00;
|
||||||
|
always @(CLR)
|
||||||
|
data <= 8'h00;
|
||||||
|
always @(posedge C)
|
||||||
|
data <= data + CE;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CC8CLE (
|
||||||
|
input [7:0] D, input L, input C, input CLR, input CE, output [7:0] Q,
|
||||||
|
output CEO, output TC
|
||||||
|
);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg [7:0] data;
|
||||||
|
|
||||||
|
assign Q = data;
|
||||||
|
assign TC = &data;
|
||||||
|
assign CEO = TC & CE;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 8'h00;
|
||||||
|
always @(CLR)
|
||||||
|
data <= 8'h00;
|
||||||
|
always @(posedge C)
|
||||||
|
if (L)
|
||||||
|
data <= D;
|
||||||
|
else
|
||||||
|
data <= data + CE;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CC16CE (
|
||||||
|
input C, input CLR, input CE, output [15:0] Q, output CEO, output TC
|
||||||
|
);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg [15:0] data;
|
||||||
|
|
||||||
|
assign Q = data;
|
||||||
|
assign TC = &data;
|
||||||
|
assign CEO = TC & CE;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 16'h0000;
|
||||||
|
always @(CLR)
|
||||||
|
data <= 16'h0000;
|
||||||
|
always @(posedge C)
|
||||||
|
data <= data + CE;
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module CC16CLE (
|
||||||
|
input [15:0] D, input L, input C, input CLR, input CE, output [15:0] Q,
|
||||||
|
output CEO, output TC
|
||||||
|
);
|
||||||
|
`ifndef SYNTHESIS
|
||||||
|
reg [15:0] data;
|
||||||
|
|
||||||
|
assign Q = data;
|
||||||
|
assign TC = &data;
|
||||||
|
assign CEO = TC & CE;
|
||||||
|
|
||||||
|
initial
|
||||||
|
data = 16'h0000;
|
||||||
|
always @(CLR)
|
||||||
|
data <= 16'h0000;
|
||||||
|
always @(posedge C)
|
||||||
|
if (L)
|
||||||
|
data <= D;
|
||||||
|
else
|
||||||
|
data <= data + CE;
|
||||||
|
`endif
|
||||||
|
endmodule
|
@ -6,82 +6,85 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(* techmap_celltype = "IOBUFT" *)
|
(* techmap_celltype = "IOBUFT" *)
|
||||||
module _ISE_IOBUFT (inout IO, input I, output O, input T);
|
module _ISE_IOBUFT (input I, input T, output O, inout IO);
|
||||||
IBUF _TECHMAP_REPLACE_.ibuf ( .I(IO), .O(O) );
|
IBUF _TECHMAP_REPLACE_.ibuf (.I(IO), .O(O));
|
||||||
OBUFT _TECHMAP_REPLACE_.obuf ( .O(IO), .I(I), .T(T) );
|
OBUFT _TECHMAP_REPLACE_.obuf (.O(IO), .I(I), .T(T));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_BUF_" *)
|
(* techmap_celltype = "$_BUF_" *)
|
||||||
module _ISE_BUF (input A, output Y);
|
module _ISE_BUF (input A, output Y);
|
||||||
BUF _TECHMAP_REPLACE_ ( .I(A), .O(Y) );
|
BUF _TECHMAP_REPLACE_ (.I(A), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_NOT_" *)
|
(* techmap_celltype = "$_NOT_" *)
|
||||||
module _ISE_INV (input A, output Y);
|
module _ISE_INV (input A, output Y);
|
||||||
INV _TECHMAP_REPLACE_ ( .I(A), .O(Y) );
|
INV _TECHMAP_REPLACE_ (.I(A), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_AND_" *)
|
(* techmap_celltype = "$_AND_" *)
|
||||||
module _ISE_AND2 (input A, input B, output Y);
|
module _ISE_AND2 (input A, input B, output Y);
|
||||||
AND2 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
AND2 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_NAND_" *)
|
(* techmap_celltype = "$_NAND_" *)
|
||||||
module _ISE_NAND2 (input A, input B, output Y);
|
module _ISE_NAND2 (input A, input B, output Y);
|
||||||
NAND2 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
NAND2 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_ANDNOT_" *)
|
(* techmap_celltype = "$_ANDNOT_" *)
|
||||||
module _ISE_AND2B1 (input A, input B, output Y);
|
module _ISE_AND2B1 (input A, input B, output Y);
|
||||||
AND2B1 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
AND2B1 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_OR_" *)
|
(* techmap_celltype = "$_OR_" *)
|
||||||
module _ISE_OR2 (input A, input B, output Y);
|
module _ISE_OR2 (input A, input B, output Y);
|
||||||
OR2 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
OR2 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_NOR_" *)
|
(* techmap_celltype = "$_NOR_" *)
|
||||||
module _ISE_NOR2 (input A, input B, output Y);
|
module _ISE_NOR2 (input A, input B, output Y);
|
||||||
NOR2 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
NOR2 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_ORNOT_" *)
|
(* techmap_celltype = "$_ORNOT_" *)
|
||||||
module _ISE_OR2B1 (input A, input B, output Y);
|
module _ISE_OR2B1 (input A, input B, output Y);
|
||||||
OR2B1 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
OR2B1 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_XOR_" *)
|
(* techmap_celltype = "$_XOR_" *)
|
||||||
module _ISE_XOR2 (input A, input B, output Y);
|
module _ISE_XOR2 (input A, input B, output Y);
|
||||||
XOR2 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
XOR2 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_XNOR_" *)
|
(* techmap_celltype = "$_XNOR_" *)
|
||||||
module _ISE_XNOR2 (input A, input B, output Y);
|
module _ISE_XNOR2 (input A, input B, output Y);
|
||||||
XNOR2 _TECHMAP_REPLACE_ ( .I0(A), .I1(B), .O(Y) );
|
XNOR2 _TECHMAP_REPLACE_ (.I0(A), .I1(B), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_TBUF_" *)
|
(* techmap_celltype = "$_TBUF_" *)
|
||||||
module _ISE_BUFT (input A, input E, output Y);
|
module _ISE_BUFT (input A, input E, output Y);
|
||||||
BUFT _TECHMAP_REPLACE_ ( .I(A), .T(~E), .O(Y) );
|
wire T;
|
||||||
|
|
||||||
|
INV _TECHMAP_REPLACE_.inv (.I(E), .O(T));
|
||||||
|
BUFT _TECHMAP_REPLACE_.buffer (.I(A), .T(T), .O(Y));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_DFFE_PP0P_" *)
|
(* techmap_celltype = "$_DFFE_PP0P_" *)
|
||||||
module _ISE_FDCE (input D, input C, input R, input E, output Q);
|
module _ISE_FDCE (input D, input C, input R, input E, output Q);
|
||||||
FDCE _TECHMAP_REPLACE_ ( .D(D), .C(C), .CLR(R), .CE(E), .Q(Q) );
|
FDCE _TECHMAP_REPLACE_ (.D(D), .C(C), .CLR(R), .CE(E), .Q(Q));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_DFFE_PP1P_" *)
|
(* techmap_celltype = "$_DFFE_PP1P_" *)
|
||||||
module _ISE_FDPE (input D, input C, input R, input E, output Q);
|
module _ISE_FDPE (input D, input C, input R, input E, output Q);
|
||||||
FDPE _TECHMAP_REPLACE_ ( .D(D), .C(C), .PRE(R), .CE(E), .Q(Q) );
|
FDPE _TECHMAP_REPLACE_ (.D(D), .C(C), .PRE(R), .CE(E), .Q(Q));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_DLATCH_PP0_" *)
|
(* techmap_celltype = "$_DLATCH_PP0_" *)
|
||||||
module _ISE_LDCE_1 (input E, input R, input D, output Q);
|
module _ISE_LDCE_1 (input E, input R, input D, output Q);
|
||||||
LDCE_1 _TECHMAP_REPLACE_ ( .D(D), .G(E), .CLR(R), .GE(1'b1), .Q(Q) );
|
LDCE_1 _TECHMAP_REPLACE_ (.D(D), .G(E), .CLR(R), .GE(1'b1), .Q(Q));
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_celltype = "$_DLATCH_PP1_" *)
|
(* techmap_celltype = "$_DLATCH_PP1_" *)
|
||||||
module _ISE_LDPE_1 (input E, input R, input D, output Q);
|
module _ISE_LDPE_1 (input E, input R, input D, output Q);
|
||||||
LDPE_1 _TECHMAP_REPLACE_ ( .D(D), .G(E), .PRE(R), .GE(1'b1), .Q(Q) );
|
LDPE_1 _TECHMAP_REPLACE_ (.D(D), .G(E), .PRE(R), .GE(1'b1), .Q(Q));
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -13,8 +13,12 @@ uint16_t _bankSwitchReg, _cartOutputReg, _miscOutputReg;
|
|||||||
|
|
||||||
/* System initialization */
|
/* System initialization */
|
||||||
|
|
||||||
static constexpr int _RESET_DELAY = 5000;
|
static constexpr int _IDE_RESET_ASSERT_DELAY = 5000;
|
||||||
static constexpr int _FPGA_INIT_DELAY = 1000;
|
static constexpr int _IDE_RESET_CLEAR_DELAY = 50000;
|
||||||
|
|
||||||
|
static constexpr int _FPGA_RESET_DELAY = 5000;
|
||||||
|
static constexpr int _FPGA_STARTUP_DELAY = 50000;
|
||||||
|
static constexpr int _FPGA_INIT_REG_DELAY = 5000;
|
||||||
|
|
||||||
void init(void) {
|
void init(void) {
|
||||||
// Remapping the base address is required in order for IDE DMA to work
|
// Remapping the base address is required in order for IDE DMA to work
|
||||||
@ -62,9 +66,9 @@ void initIOBoard(void) {
|
|||||||
// Some of the digital I/O board's light outputs are controlled by the FPGA
|
// Some of the digital I/O board's light outputs are controlled by the FPGA
|
||||||
// and cannot be turned off until the FPGA is initialized.
|
// and cannot be turned off until the FPGA is initialized.
|
||||||
if (isDigitalIOPresent()) {
|
if (isDigitalIOPresent()) {
|
||||||
//SYS573D_CPLD_LIGHTS_B0 = 0xf000;
|
SYS573D_CPLD_LIGHTS_BL = 0xf000;
|
||||||
SYS573D_CPLD_LIGHTS_C0 = 0xf000;
|
SYS573D_CPLD_LIGHTS_CL = 0xf000;
|
||||||
SYS573D_CPLD_LIGHTS_C1 = 0xf000;
|
SYS573D_CPLD_LIGHTS_CH = 0xf000;
|
||||||
} else {
|
} else {
|
||||||
SYS573A_LIGHTS_A = 0x00ff;
|
SYS573A_LIGHTS_A = 0x00ff;
|
||||||
SYS573A_LIGHTS_B = 0x00ff;
|
SYS573A_LIGHTS_B = 0x00ff;
|
||||||
@ -75,10 +79,10 @@ void initIOBoard(void) {
|
|||||||
|
|
||||||
void resetIDEDevices(void) {
|
void resetIDEDevices(void) {
|
||||||
SYS573_IDE_RESET = 0;
|
SYS573_IDE_RESET = 0;
|
||||||
delayMicroseconds(_RESET_DELAY);
|
delayMicroseconds(_IDE_RESET_ASSERT_DELAY);
|
||||||
|
|
||||||
SYS573_IDE_RESET = 1;
|
SYS573_IDE_RESET = 1;
|
||||||
delayMicroseconds(_RESET_DELAY);
|
delayMicroseconds(_IDE_RESET_CLEAR_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* JAMMA and RTC functions */
|
/* JAMMA and RTC functions */
|
||||||
@ -231,6 +235,8 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
|
|||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const uint16_t mask = SYS573D_CPLD_STAT_INIT | SYS573D_CPLD_STAT_DONE;
|
||||||
|
|
||||||
for (int i = 3; i; i--) {
|
for (int i = 3; i; i--) {
|
||||||
SYS573D_CPLD_UNK_RESET = 0;
|
SYS573D_CPLD_UNK_RESET = 0;
|
||||||
|
|
||||||
@ -243,22 +249,18 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
|
|||||||
| SYS573D_CPLD_CTRL_DONE
|
| SYS573D_CPLD_CTRL_DONE
|
||||||
| SYS573D_CPLD_CTRL_PROGRAM
|
| SYS573D_CPLD_CTRL_PROGRAM
|
||||||
| SYS573D_CPLD_CTRL_UNKNOWN;
|
| SYS573D_CPLD_CTRL_UNKNOWN;
|
||||||
|
delayMicroseconds(_FPGA_RESET_DELAY);
|
||||||
|
|
||||||
delayMicroseconds(_RESET_DELAY);
|
if ((SYS573D_CPLD_STAT & mask) != SYS573D_CPLD_STAT_INIT)
|
||||||
|
|
||||||
if (!(SYS573D_CPLD_STAT & SYS573D_CPLD_STAT_INIT))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
writeFunc(data, length);
|
writeFunc(data, length);
|
||||||
|
delayMicroseconds(_FPGA_STARTUP_DELAY);
|
||||||
|
|
||||||
const uint16_t mask = SYS573D_CPLD_STAT_INIT | SYS573D_CPLD_STAT_DONE;
|
if ((SYS573D_CPLD_STAT & mask) != mask)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (int j = 15; j; j--) {
|
return true;
|
||||||
if ((SYS573D_CPLD_STAT & mask) == mask)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
delayMicroseconds(_FPGA_INIT_DELAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -267,19 +269,19 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
|
|||||||
void initKonamiBitstream(void) {
|
void initKonamiBitstream(void) {
|
||||||
SYS573D_FPGA_INIT = 0xf000;
|
SYS573D_FPGA_INIT = 0xf000;
|
||||||
SYS573D_FPGA_INIT = 0x0000;
|
SYS573D_FPGA_INIT = 0x0000;
|
||||||
delayMicroseconds(_FPGA_INIT_DELAY);
|
delayMicroseconds(_FPGA_INIT_REG_DELAY);
|
||||||
|
|
||||||
SYS573D_FPGA_INIT = 0xf000;
|
SYS573D_FPGA_INIT = 0xf000;
|
||||||
delayMicroseconds(_FPGA_INIT_DELAY);
|
delayMicroseconds(_FPGA_INIT_REG_DELAY);
|
||||||
|
|
||||||
// Turn off all lights including the ones that were left on by init().
|
// Turn off all lights including the ones that were left on by init().
|
||||||
SYS573D_FPGA_LIGHTS_A0 = 0xf000;
|
SYS573D_FPGA_LIGHTS_AL = 0xf000;
|
||||||
SYS573D_FPGA_LIGHTS_A1 = 0xf000;
|
SYS573D_FPGA_LIGHTS_AH = 0xf000;
|
||||||
SYS573D_CPLD_LIGHTS_B0 = 0xf000;
|
SYS573D_CPLD_LIGHTS_BL = 0xf000;
|
||||||
SYS573D_FPGA_LIGHTS_B1 = 0xf000;
|
SYS573D_FPGA_LIGHTS_BH = 0xf000;
|
||||||
SYS573D_CPLD_LIGHTS_C0 = 0xf000;
|
SYS573D_CPLD_LIGHTS_CL = 0xf000;
|
||||||
SYS573D_CPLD_LIGHTS_C1 = 0xf000;
|
SYS573D_CPLD_LIGHTS_CH = 0xf000;
|
||||||
SYS573D_FPGA_LIGHTS_D0 = 0xf000;
|
SYS573D_FPGA_LIGHTS_D = 0xf000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* I2C driver */
|
/* I2C driver */
|
||||||
|
@ -153,11 +153,11 @@ static inline bool isDigitalIOPresent(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool getDIO1Wire(void) {
|
static inline bool getDIO1Wire(void) {
|
||||||
return (SYS573D_FPGA_DS2401 >> 12) & 1;
|
return (SYS573D_FPGA_DS_BUS / SYS573D_FPGA_DS_BUS_DS2401) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void setDIO1Wire(bool value) {
|
static inline void setDIO1Wire(bool value) {
|
||||||
SYS573D_FPGA_DS2401 = (value ^ 1) << 12;
|
SYS573D_FPGA_DS_BUS = (value ^ 1) * SYS573D_FPGA_DS_BUS_DS2401;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Other APIs */
|
/* Other APIs */
|
||||||
|
@ -268,8 +268,11 @@ bool App::_atapiEjectWorker(void) {
|
|||||||
if (!(dev.flags & ide::DEVICE_ATAPI))
|
if (!(dev.flags & ide::DEVICE_ATAPI))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto error =
|
auto error = ide::DISC_CHANGED;
|
||||||
ide::devices[0].startStopUnit(ide::START_STOP_MODE_OPEN_TRAY);
|
|
||||||
|
while (error == ide::DISC_CHANGED)
|
||||||
|
error =
|
||||||
|
ide::devices[0].startStopUnit(ide::START_STOP_MODE_OPEN_TRAY);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
_messageScreen.setMessage(
|
_messageScreen.setMessage(
|
||||||
|
@ -137,18 +137,47 @@ typedef enum {
|
|||||||
SYS573D_CPLD_CTRL_UNKNOWN = 1 << 15
|
SYS573D_CPLD_CTRL_UNKNOWN = 1 << 15
|
||||||
} Sys573DCPLDControlFlag;
|
} Sys573DCPLDControlFlag;
|
||||||
|
|
||||||
#define SYS573D_FPGA_MAGIC _MMIO16(DEV0_BASE | 0x640080)
|
typedef enum {
|
||||||
#define SYS573D_FPGA_LIGHTS_A1 _MMIO16(DEV0_BASE | 0x6400e0)
|
SYS573D_FPGA_DS_BUS_DS2433 = 1 << 8,
|
||||||
#define SYS573D_FPGA_LIGHTS_A0 _MMIO16(DEV0_BASE | 0x6400e2)
|
SYS573D_FPGA_DS_BUS_DS2401 = 1 << 12
|
||||||
#define SYS573D_FPGA_LIGHTS_B1 _MMIO16(DEV0_BASE | 0x6400e4)
|
} Sys573DFPGADSBusFlag;
|
||||||
#define SYS573D_FPGA_LIGHTS_D0 _MMIO16(DEV0_BASE | 0x6400e6)
|
|
||||||
|
#define SYS573D_FPGA_MAGIC _MMIO16(DEV0_BASE | 0x640080)
|
||||||
|
|
||||||
|
#define SYS573D_FPGA_MP3_PTR_H _MMIO16(DEV0_BASE | 0x6400a0)
|
||||||
|
#define SYS573D_FPGA_MP3_PTR_L _MMIO16(DEV0_BASE | 0x6400a2)
|
||||||
|
#define SYS573D_FPGA_MP3_ENDPTR_H _MMIO16(DEV0_BASE | 0x6400a4)
|
||||||
|
#define SYS573D_FPGA_MP3_ENDPTR_L _MMIO16(DEV0_BASE | 0x6400a6)
|
||||||
|
#define SYS573D_FPGA_MP3_COUNTER _MMIO16(DEV0_BASE | 0x6400a8)
|
||||||
|
#define SYS573D_FPGA_MP3_KEY1 _MMIO16(DEV0_BASE | 0x6400a8)
|
||||||
|
#define SYS573D_FPGA_MP3_FEED_STAT _MMIO16(DEV0_BASE | 0x6400aa)
|
||||||
|
#define SYS573D_FPGA_MP3_I2C _MMIO16(DEV0_BASE | 0x6400ac)
|
||||||
|
#define SYS573D_FPGA_MP3_FEED_CTRL _MMIO16(DEV0_BASE | 0x6400ae)
|
||||||
|
|
||||||
|
#define SYS573D_FPGA_DRAM_WRPTR_H _MMIO16(DEV0_BASE | 0x6400b0)
|
||||||
|
#define SYS573D_FPGA_DRAM_WRPTR_L _MMIO16(DEV0_BASE | 0x6400b2)
|
||||||
|
#define SYS573D_FPGA_DRAM_DATA _MMIO16(DEV0_BASE | 0x6400b4)
|
||||||
|
#define SYS573D_FPGA_DRAM_RDPTR_H _MMIO16(DEV0_BASE | 0x6400b6)
|
||||||
|
#define SYS573D_FPGA_DRAM_RDPTR_L _MMIO16(DEV0_BASE | 0x6400b8)
|
||||||
|
|
||||||
|
#define SYS573D_FPGA_NET_DATA _MMIO16(DEV0_BASE | 0x6400c0)
|
||||||
|
#define SYS573D_FPGA_DAC_COUNTER_H _MMIO16(DEV0_BASE | 0x6400ca)
|
||||||
|
#define SYS573D_FPGA_DAC_COUNTER_L _MMIO16(DEV0_BASE | 0x6400cc)
|
||||||
|
#define SYS573D_FPGA_DAC_COUNTER_D _MMIO16(DEV0_BASE | 0x6400ce)
|
||||||
|
|
||||||
|
#define SYS573D_FPGA_LIGHTS_AH _MMIO16(DEV0_BASE | 0x6400e0)
|
||||||
|
#define SYS573D_FPGA_LIGHTS_AL _MMIO16(DEV0_BASE | 0x6400e2)
|
||||||
|
#define SYS573D_FPGA_LIGHTS_BH _MMIO16(DEV0_BASE | 0x6400e4)
|
||||||
|
#define SYS573D_FPGA_LIGHTS_D _MMIO16(DEV0_BASE | 0x6400e6)
|
||||||
#define SYS573D_FPGA_INIT _MMIO16(DEV0_BASE | 0x6400e8)
|
#define SYS573D_FPGA_INIT _MMIO16(DEV0_BASE | 0x6400e8)
|
||||||
#define SYS573D_FPGA_DS2401 _MMIO16(DEV0_BASE | 0x6400ee)
|
#define SYS573D_FPGA_MP3_KEY2 _MMIO16(DEV0_BASE | 0x6400ea)
|
||||||
|
#define SYS573D_FPGA_MP3_KEY3 _MMIO16(DEV0_BASE | 0x6400ec)
|
||||||
|
#define SYS573D_FPGA_DS_BUS _MMIO16(DEV0_BASE | 0x6400ee)
|
||||||
|
|
||||||
#define SYS573D_CPLD_UNK_RESET _MMIO16(DEV0_BASE | 0x6400f4)
|
#define SYS573D_CPLD_UNK_RESET _MMIO16(DEV0_BASE | 0x6400f4)
|
||||||
#define SYS573D_CPLD_STAT _MMIO16(DEV0_BASE | 0x6400f6)
|
#define SYS573D_CPLD_STAT _MMIO16(DEV0_BASE | 0x6400f6)
|
||||||
#define SYS573D_CPLD_CTRL _MMIO16(DEV0_BASE | 0x6400f6)
|
#define SYS573D_CPLD_CTRL _MMIO16(DEV0_BASE | 0x6400f6)
|
||||||
#define SYS573D_CPLD_BITSTREAM _MMIO16(DEV0_BASE | 0x6400f8)
|
#define SYS573D_CPLD_BITSTREAM _MMIO16(DEV0_BASE | 0x6400f8)
|
||||||
#define SYS573D_CPLD_LIGHTS_C0 _MMIO16(DEV0_BASE | 0x6400fa)
|
#define SYS573D_CPLD_LIGHTS_CL _MMIO16(DEV0_BASE | 0x6400fa)
|
||||||
#define SYS573D_CPLD_LIGHTS_C1 _MMIO16(DEV0_BASE | 0x6400fc)
|
#define SYS573D_CPLD_LIGHTS_CH _MMIO16(DEV0_BASE | 0x6400fc)
|
||||||
#define SYS573D_CPLD_LIGHTS_B0 _MMIO16(DEV0_BASE | 0x6400fe)
|
#define SYS573D_CPLD_LIGHTS_BL _MMIO16(DEV0_BASE | 0x6400fe)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user