mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-24 03:51:57 +01:00
[SC64][FW][HW][SW] New version based on LCMXO2 FPGA (#19)
* isv support + usb/dd improvements
* make room for saves
* update offset
* fixed debug address
* idk
* exception
* ironed out all broken stuff
* cleanup
* return epc fix
* better
* more cleanup
* even more cleanup
* mooore cleanup
* fixed printf
* no assert
* improved docker build, pyft232 instead of pyserial
* fixed displaying long message strings
description test
* just straight cleanup
* smallest cleanup
* PAL
* cpu buffer
* n64 bootloader done
* super slow usb storage reading implemented
* reduced buffer size
* usb gets fast
* little cleanup
* double buffered reads
* removed separate event id
* ISV in hardware finally
* small exception changes
* mac testing
* py spacing
* fsd write, rtc, isv and reset fixes
* fixxx
* good stopping point
* usb fixed?
* pretend we have 128 MB sdram
* backup
* chmod
* test
* test done
* more tests
* user rm
* help
* final fix
* updated component values
* nice asset names
* cic 64dd support
* ddipl enable separation
* pre DMA rewrite, created dedicated buffer memory space, simplified code
* dma rewrite, needs testing
* moved xml
* dd basics
* timing
* 64dd working yet again, isv brought back, dma fixes, usb path rewrite, pc code rewrite
* added usb read functionality, general cleanup
* changed mem addressing
* added fpga flash update access
* added mcu update
* chmod
* little cleanup
* update format and stuff
* fixes
* uninitialized fix
* small fixes
* update fixes
* update stuff done
* fpga update tested
* build time fix
* boot fix
* test timing
* readme test
* test 2
* reports
* testseet
* final
* build test
* forgot
* button and naming
* General cleanup
And multiline commit message test
* Exception screen UI touch ups
* display separation and tests beginning
* pc software update
* pc software done
* timing test
* delete launch.json
* sw fixes
* fixed button hole diameter in shell
* small cleanup, rpi testing
* shell fillet fix, pc rtc printing
* added cfg lock mechanism
* moved lock to cfg address space
* extended ROM and ISV fixes
* preliminary sd card support
* little sd card cleanup
* sd menu fixes
* 5 second limit
* reduced shell thickness
* basic led act blinking
* faster sd menu loading
* inst cache invalidate
* sd card writing is working
* SD card CSD and CID registers
* wait for previous command
* led error codes
* fixed cfg_translate_address use
* 64dd from sd card working
* 64dd speedup and button handling
* delayed address latching cycle - might break other builds, needs testing
* bootloader improvements
* small fixes
* return previous cfg when setting new
* cache stuff
* unfloader debug protocol support
* UNFLoader style debug command line support
* requirements.txt
* shell groove fillet
* reset state inside controller
* fixed fast PI read, added PI R/W fifo debug info
* PI access prioritize
* SD clock stop when RX FIFO is more than half full
* flash erase method change
* CFG error handling, TLOZ MM debug ISV support
* CIC5167 support
* general fixes
* USB unplugged cable handling
* turn off led when changing between error/act modes
* rtc 2 bit clock stop support
* line endings
* Revert "line endings"
This reverts commit d0ddfe5ec7
.
* PI address debug
* readme test
* diagram update
* diagram background
* diagram background
* diagram background
* updated readme
This commit is contained in:
parent
92e5c5747b
commit
ff69030643
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@ -1 +0,0 @@
|
||||
ko_fi: polprzewodnikowy
|
BIN
.github/sc64_clean_pcb.jpg
vendored
BIN
.github/sc64_clean_pcb.jpg
vendored
Binary file not shown.
Before Width: | Height: | Size: 1.4 MiB |
BIN
.github/sc64_in_n64.jpg
vendored
BIN
.github/sc64_in_n64.jpg
vendored
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
BIN
.github/sc64_on_table.jpg
vendored
BIN
.github/sc64_on_table.jpg
vendored
Binary file not shown.
Before Width: | Height: | Size: 1.8 MiB |
4
.github/sc64_v2_block_diagram.svg
vendored
Normal file
4
.github/sc64_v2_block_diagram.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 92 KiB |
BIN
.github/sc64_v2_example.jpg
vendored
Normal file
BIN
.github/sc64_v2_example.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
18
.github/workflows/main.yml
vendored
18
.github/workflows/main.yml
vendored
@ -20,15 +20,25 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Prepare Lattice Diamond license
|
||||
env:
|
||||
ENCODED_LICENSE: ${{ secrets.LATTICE_DIAMOND_LICENSE }}
|
||||
run: |
|
||||
mkdir -p ./flexlm
|
||||
echo "$ENCODED_LICENSE" > ./flexlm/encoded_license
|
||||
base64 -d ./flexlm/encoded_license > ./flexlm/license.dat
|
||||
|
||||
- name: Build script
|
||||
env:
|
||||
MAC_ADDRESS: ${{ secrets.LATTICE_DIAMOND_MAC }}
|
||||
run: ./docker_build.sh release --force-clean
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: SummerCart64
|
||||
path: SummerCart64.zip
|
||||
name: SC64
|
||||
path: SC64.zip
|
||||
|
||||
- name: Get release
|
||||
if: github.event_name == 'release' && github.event.action == 'created'
|
||||
@ -44,6 +54,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ steps.get_release.outputs.upload_url }}
|
||||
asset_path: SummerCart64.zip
|
||||
asset_name: SummerCart64.zip
|
||||
asset_path: SC64.zip
|
||||
asset_name: SC64.zip
|
||||
asset_content_type: application/zip
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,4 +1,7 @@
|
||||
**/.DS_Store
|
||||
**/.vscode
|
||||
**/.vscode/
|
||||
**/*.bak
|
||||
**/*.zip
|
||||
/flexlm
|
||||
|
||||
!**/.vscode/tasks.json
|
||||
|
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -1,8 +0,0 @@
|
||||
[submodule "fw/picorv32"]
|
||||
path = fw/picorv32
|
||||
url = https://github.com/cliffordwolf/picorv32.git
|
||||
ignore = dirty
|
||||
[submodule "sw/cic"]
|
||||
path = sw/cic
|
||||
url = https://github.com/ManCloud/UltraCIC-III.git
|
||||
ignore = dirty
|
73
.vscode/tasks.json
vendored
Normal file
73
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build_bootloader",
|
||||
"type": "shell",
|
||||
"command": "./docker_build.sh bootloader",
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
},
|
||||
"windows": {
|
||||
"command": "wsl -- ./docker_build.sh bootloader"
|
||||
},
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "build_controller",
|
||||
"type": "shell",
|
||||
"command": "./docker_build.sh controller",
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
},
|
||||
"windows": {
|
||||
"command": "wsl -- ./docker_build.sh controller"
|
||||
},
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "build_fpga",
|
||||
"type": "shell",
|
||||
"command": "./docker_build.sh fpga",
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
},
|
||||
"windows": {
|
||||
"command": "wsl -- ./docker_build.sh fpga"
|
||||
},
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "build_update",
|
||||
"type": "shell",
|
||||
"command": "./docker_build.sh update",
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
},
|
||||
"windows": {
|
||||
"command": "wsl -- ./docker_build.sh update"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build_release",
|
||||
"type": "shell",
|
||||
"command": "./docker_build.sh release --force-clean",
|
||||
"presentation": {
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
},
|
||||
"windows":{
|
||||
"command": "wsl -- ./docker_build.sh release --force-clean"
|
||||
},
|
||||
"group": "build"
|
||||
},
|
||||
]
|
||||
}
|
91
README.md
91
README.md
@ -1,78 +1,29 @@
|
||||
# SummerCollection
|
||||
|
||||
A collection of hardware, firmware and software designs of SummerCart64 - Nintendo 64 FlashCart/DevKit.
|
||||
# SC64 - an open source Nintendo 64 flashcart
|
||||
|
||||
|
||||
## Project parts
|
||||
|
||||
### Firmware
|
||||
|
||||
Folder **`fw`** contains firmware written in Verilog for Intel MAX10 FPGA.
|
||||
|
||||
### Hardware
|
||||
|
||||
Folder **`hw`** contains PCB design made in Autodesk Eagle.
|
||||
|
||||
### Software
|
||||
|
||||
Folder **`sw`** contains several helper programs that makes flash cart work all together, including bootloader and CIC emulation.
|
||||
## Features
|
||||
- 64 MB SDRAM memory for game and save data
|
||||
- 16 MB FLASH memory for bootloader and extended game data
|
||||
- 8 kB on-chip buffer for general use
|
||||
- 25 MB/s peak transfer rate USB interface for data upload/download and debug functionality
|
||||
- 25 MB/s peak transfer rate SD card interface
|
||||
- EEPROM, SRAM and FlashRAM save types ~~with automatic writeback to SD card~~ (_not implemented yet_)
|
||||
- Battery backed real time clock (RTC)
|
||||
- Status LED and button for general use
|
||||
- 64DD add-on emulation
|
||||
- IS-Viewer 64 debug interface
|
||||
- Software and firmware update via USB interface
|
||||
- N64 bootloader with support for IPL2 registers spoofing and loading menu from SD card
|
||||
- Enhanced [UltraCIC_C](https://github.com/jago85/UltraCIC_C) emulation with automatic region switching and programmable seed/checksum values
|
||||
- PC app for communicating with flashcart (game/save data upload/download, feature enable control and debug console)
|
||||
- [UNFLoader](https://github.com/buu342/N64-UNFLoader) support
|
||||
|
||||
|
||||
## What works
|
||||
## High-level flashcart block diagram
|
||||
|
||||
### **OLD STATUS, WILL BE UPDATED SOON**
|
||||
|
||||
~~Currently hardware implements basic functionality for playing games - ROM emulation, 4/16K EEPROM, bootloader and PC communication. You can send any ROM to the SDRAM from PC and if game doesn't check for save hardware other than EEPROM then it most likely will work. Bootloader does all the work necessary to setup the console registers for specific CIC chip that game requires.~~
|
||||
[<img src=".github/sc64_v2_block_diagram.svg" width="800" />](.github/sc64_v2_block_diagram.svg)
|
||||
|
||||
|
||||
## How to build
|
||||
## Finished sample
|
||||
|
||||
### **OLD INSTRUCTIONS, WILL BE UPDATED SOON**
|
||||
|
||||
~~Instructions below are mostly written for Windows users and point to Windows specific executables.~~
|
||||
|
||||
1. ~~Download latest zip files from [releases tab](https://github.com/Polprzewodnikowy/SummerCollection/releases).~~
|
||||
2. ~~Order PCBs in your farovite company, all gerbers, bill of materials and schematics are in **`SummerCart64_PCB-[version].zip`** file.~~
|
||||
3. ~~Order all necessary components, eg. in [Mouser](https://mouser.com/).~~
|
||||
4. ~~Solder all components onto the PCB.~~
|
||||
5. ~~Connect flashcart to PC.~~
|
||||
6. ~~Download [FT_PROG](https://www.ftdichip.com/Support/Utilities.htm#FT_PROG) from FTDI website.~~
|
||||
7. ~~Open FT_PROG and scan for devices.~~
|
||||
8. ~~Load `ftdi-template.xml` from **`SummerCart64-[version].zip`** located in `hw` folder.~~
|
||||
9. ~~Program FTDI chip, then right click on the device and select "Cycle port"~~
|
||||
10. ~~Download and install [Arrow USB Blaster drivers](https://shop.trenz-electronic.de/en/Download/?path=Trenz_Electronic/Software/Drivers/Arrow_USB_Programmer/Arrow_USB_Programmer_2.4) from Trenz Electronic website.~~
|
||||
11. ~~Download and install [QuartusProgrammer](https://download.altera.com/akdlm/software/acdsinst/20.1std/711/ib_installers/QuartusProgrammerSetup-20.1.0.711-windows.exe) from Intel website.~~
|
||||
12. ~~Click on "Hardware Setup..." button and select "Arrow-USB-Blaster [AR*xxxxxx*]" in "Currently selected hardware", then close window.~~
|
||||
13. ~~Click on "Auto Detect" button and select "10M08SC" option.~~
|
||||
14. ~~Click on the newly shown row, then click on "Change File..." button and select `SummerCart64.pof` file from **`SummerCart64-[version].zip`** located in `fw/output_files` folder.~~
|
||||
15. ~~Select "Program/Configure" and "Verify" checkboxes.~~
|
||||
16. ~~Click on "Start" button and wait for operation to finish.~~
|
||||
17. ~~Download and install avrdude.~~
|
||||
18. ~~Program ATtiny45 with `UltraCIC-III.hex` file from **`SummerCart64-[version].zip`** located in `sw/cic` folder, more information is available [here](https://github.com/ManCloud/UltraCIC-III).~~
|
||||
19. ~~Download latest release of [N64-UNFLoader](https://github.com/buu342/N64-UNFLoader).~~
|
||||
20. ~~Insert flashcart in the Nintendo 64.~~
|
||||
21. ~~Upload ROM by executing `UNFLoader -r your_rom_file.n64`~~
|
||||
22. ~~Turn on console and enjoy playing homebrew games on real hardware.~~
|
||||
|
||||
|
||||
## Issues
|
||||
|
||||
### **OLD STATUS, WILL BE UPDATED SOON**
|
||||
|
||||
~~There are several issues with the project at the moment in order of importance. Keep in mind that core flashcart functionality is fully working:~~
|
||||
|
||||
- ~~No save write-back to SD card without console reset implementation.~~
|
||||
|
||||
|
||||
## What's next
|
||||
|
||||
Current goal is to rewrite README.md
|
||||
|
||||
|
||||
## Finished sample (obsolete v1 version, to be replaced with v2)
|
||||
|
||||
![SummerCart64 clean PCB](.github/sc64_clean_pcb.jpg)
|
||||
|
||||
![SummerCart64 on table](.github/sc64_on_table.jpg)
|
||||
|
||||
![SummerCart64 in partialy disassembled Nintendo 64](.github/sc64_in_n64.jpg)
|
||||
[<img src=".github/sc64_v2_example.jpg" alt="SC64 HW ver: 2.0" width="800" />](.github/sc64_v2_example.jpg)
|
||||
|
BIN
assets/sc64_logo.blend
Normal file
BIN
assets/sc64_logo.blend
Normal file
Binary file not shown.
148
build.sh
148
build.sh
@ -2,80 +2,66 @@
|
||||
|
||||
set -e
|
||||
|
||||
PACKAGE_FILE_NAME="SummerCart64"
|
||||
PACKAGE_FILE_NAME="SC64"
|
||||
|
||||
FILES=(
|
||||
"./fw/output_files/SC64_firmware.pof"
|
||||
"./fw/output_files/SC64_update.bin"
|
||||
"./hw/ftdi-template.xml"
|
||||
"./sw/cic/UltraCIC-III.hex"
|
||||
"./fw/ftdi/ft232h_config.xml"
|
||||
"./fw/project/lcmxo2/impl1/sc64_impl1.mrp"
|
||||
"./fw/project/lcmxo2/impl1/sc64_impl1.twr"
|
||||
"./sw/pc/dd64.py"
|
||||
"./sw/pc/sc64.py"
|
||||
"./sw/update/sc64.upd"
|
||||
"./LICENSE"
|
||||
"./README.md"
|
||||
)
|
||||
|
||||
BUILT_CIC=false
|
||||
BUILT_N64=false
|
||||
BUILT_RISCV=false
|
||||
BUILT_BOOTLOADER=false
|
||||
BUILT_CONTROLLER=false
|
||||
BUILT_FPGA=false
|
||||
BUILT_UPDATE=false
|
||||
BUILT_RELEASE=false
|
||||
|
||||
FORCE_CLEAN=false
|
||||
SKIP_FPGA_REBUILD=false
|
||||
DEBUG_ENABLED=false
|
||||
USER_FLAGS+=" -D__SC64_VERSION=\"$__SC64_VERSION\""
|
||||
|
||||
build_cic () {
|
||||
if [ "$BUILT_CIC" = true ]; then return; fi
|
||||
build_bootloader () {
|
||||
if [ "$BUILT_BOOTLOADER" = true ]; then return; fi
|
||||
|
||||
pushd sw/cic > /dev/null
|
||||
avra UltraCIC-III.asm -D attiny45
|
||||
popd > /dev/null
|
||||
|
||||
BUILT_CIC=true
|
||||
}
|
||||
|
||||
build_n64 () {
|
||||
if [ "$BUILT_N64" = true ]; then return; fi
|
||||
|
||||
pushd sw/n64 > /dev/null
|
||||
pushd sw/bootloader > /dev/null
|
||||
if [ "$FORCE_CLEAN" = true ]; then
|
||||
make clean
|
||||
fi
|
||||
make all -j USER_FLAGS="$USER_FLAGS"
|
||||
FLAGS="$USER_FLAGS"
|
||||
if [ ! -z "${GIT_BRANCH+x}" ]; then FLAGS+=" -DGIT_BRANCH='\"$GIT_BRANCH\"'"; fi
|
||||
if [ ! -z "${GIT_TAG+x}" ]; then FLAGS+=" -DGIT_TAG='\"$GIT_TAG\"'"; fi
|
||||
if [ ! -z "${GIT_SHA+x}" ]; then FLAGS+=" -DGIT_SHA='\"$GIT_SHA\"'"; fi
|
||||
if [ ! -z "${GIT_MESSAGE+x}" ]; then FLAGS+=" -DGIT_MESSAGE='\"$GIT_MESSAGE\"'"; fi
|
||||
make all -j USER_FLAGS="$FLAGS"
|
||||
popd > /dev/null
|
||||
|
||||
BUILT_N64=true
|
||||
BUILT_BOOTLOADER=true
|
||||
}
|
||||
|
||||
build_riscv () {
|
||||
if [ "$BUILT_RISCV" = true ]; then return; fi
|
||||
build_controller () {
|
||||
if [ "$BUILT_CONTROLLER" = true ]; then return; fi
|
||||
|
||||
pushd sw/riscv > /dev/null
|
||||
pushd sw/controller > /dev/null
|
||||
if [ "$FORCE_CLEAN" = true ]; then
|
||||
make clean
|
||||
./build.sh clean
|
||||
fi
|
||||
make all -j USER_FLAGS="$USER_FLAGS"
|
||||
USER_FLAGS="$USER_FLAGS" ./build.sh all
|
||||
popd > /dev/null
|
||||
|
||||
BUILT_RISCV=true
|
||||
BUILT_CONTROLLER=true
|
||||
}
|
||||
|
||||
build_fpga () {
|
||||
if [ "$BUILT_FPGA" = true ]; then return; fi
|
||||
|
||||
build_n64
|
||||
build_riscv
|
||||
|
||||
pushd fw > /dev/null
|
||||
if [ "$SKIP_FPGA_REBUILD" = true ] && [ -f output_files/SummerCart64.sof ]; then
|
||||
quartus_cpf -c SummerCart64.cof
|
||||
else
|
||||
if [ "$DEBUG_ENABLED" = true ]; then
|
||||
quartus_sh --set VERILOG_MACRO="DEBUG" ./SummerCart64.qpf
|
||||
fi
|
||||
quartus_sh --flow compile ./SummerCart64.qpf
|
||||
quartus_sh --set -remove VERILOG_MACRO="DEBUG" ./SummerCart64.qpf
|
||||
pushd fw/project/lcmxo2 > /dev/null
|
||||
if [ "$FORCE_CLEAN" = true ]; then
|
||||
rm -rf ./impl1/
|
||||
fi
|
||||
./build.sh
|
||||
popd > /dev/null
|
||||
|
||||
BUILT_FPGA=true
|
||||
@ -84,12 +70,26 @@ build_fpga () {
|
||||
build_update () {
|
||||
if [ "$BUILT_UPDATE" = true ]; then return; fi
|
||||
|
||||
build_bootloader
|
||||
build_controller
|
||||
build_fpga
|
||||
|
||||
pushd fw/output_files > /dev/null
|
||||
cat sc64_firmware_ufm_auto.rpd sc64_firmware_cfm0_auto.rpd > SC64_update_tmp.bin
|
||||
objcopy -I binary -O binary --reverse-bytes=4 SC64_update_tmp.bin SC64_update.bin
|
||||
rm SC64_update_tmp.bin
|
||||
pushd sw/update > /dev/null
|
||||
if [ "$FORCE_CLEAN" = true ]; then
|
||||
rm -f ./sc64.upd
|
||||
fi
|
||||
GIT_INFO=""
|
||||
if [ ! -z "${GIT_BRANCH}" ]; then GIT_INFO+="branch: [$GIT_BRANCH] "; fi
|
||||
if [ ! -z "${GIT_TAG}" ]; then GIT_INFO+="tag: [$GIT_TAG] "; fi
|
||||
if [ ! -z "${GIT_SHA}" ]; then GIT_INFO+="sha: [$GIT_SHA] "; fi
|
||||
if [ ! -z "${GIT_MESSAGE}" ]; then GIT_INFO+="message: [$GIT_MESSAGE] "; fi
|
||||
GIT_INFO=$(echo "$GIT_INFO" | xargs)
|
||||
python3 update.py \
|
||||
--git "$GIT_INFO" \
|
||||
--mcu ../controller/build/app/app.bin \
|
||||
--fpga ../../fw/project/lcmxo2/impl1/sc64_impl1.jed \
|
||||
--boot ../bootloader/build/bootloader.bin \
|
||||
sc64.upd
|
||||
popd > /dev/null
|
||||
|
||||
BUILT_UPDATE=true
|
||||
@ -98,7 +98,6 @@ build_update () {
|
||||
build_release () {
|
||||
if [ "$BUILT_RELEASE" = true ]; then return; fi
|
||||
|
||||
build_cic
|
||||
build_update
|
||||
|
||||
if [ -e "./${PACKAGE_FILE_NAME}.zip" ]; then
|
||||
@ -110,22 +109,17 @@ build_release () {
|
||||
}
|
||||
|
||||
print_usage () {
|
||||
echo "builder script for SummerCart64"
|
||||
echo "usage: ./build.sh [cic] [n64] [riscv] [fpga] [update] [release] [-c] [-s] [-d] [--help]"
|
||||
echo "builder script for SC64"
|
||||
echo "usage: ./build.sh [bootloader] [controller] [fpga] [update] [release] [-c] [--help]"
|
||||
echo "parameters:"
|
||||
echo " cic - assemble UltraCIC-III software"
|
||||
echo " n64 - compile N64 bootloader software"
|
||||
echo " riscv - compile cart governor software"
|
||||
echo " fpga - compile FPGA design (triggers 'n64' and 'riscv' build)"
|
||||
echo " update - convert programming .pof file to raw binary for self-upgrade (triggers 'fpga' build)"
|
||||
echo " release - collect and zip files for release (triggers 'cic' and 'update' build)"
|
||||
echo " bootloader - compile N64 bootloader software"
|
||||
echo " controller - compile ARM controller software"
|
||||
echo " fpga - compile FPGA design"
|
||||
echo " update - compile all software and designs"
|
||||
echo " release - collect and zip files for release (triggers 'update' build)"
|
||||
echo " -c | --force-clean"
|
||||
echo " - clean software compilation result directories before build"
|
||||
echo " -s | --skip-fpga-rebuild"
|
||||
echo " - do not recompile whole FPGA design if it's already done, just update software binaries"
|
||||
echo " -d | --debug"
|
||||
echo " - enable debug features"
|
||||
echo " --help - print this guide"
|
||||
echo " - clean compilation result directories before build"
|
||||
echo " --help - print this guide"
|
||||
}
|
||||
|
||||
if test $# -eq 0; then
|
||||
@ -135,23 +129,19 @@ if test $# -eq 0; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TRIGGER_CIC=false
|
||||
TRIGGER_N64=false
|
||||
TRIGGER_RISCV=false
|
||||
TRIGGER_BOOTLOADER=false
|
||||
TRIGGER_CONTROLLER=false
|
||||
TRIGGER_FPGA=false
|
||||
TRIGGER_UPDATE=false
|
||||
TRIGGER_RELEASE=false
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
cic)
|
||||
TRIGGER_CIC=true
|
||||
bootloader)
|
||||
TRIGGER_BOOTLOADER=true
|
||||
;;
|
||||
n64)
|
||||
TRIGGER_N64=true
|
||||
;;
|
||||
riscv)
|
||||
TRIGGER_RISCV=true
|
||||
controller)
|
||||
TRIGGER_CONTROLLER=true
|
||||
;;
|
||||
fpga)
|
||||
TRIGGER_FPGA=true
|
||||
@ -165,12 +155,6 @@ while test $# -gt 0; do
|
||||
-c|--force-clean)
|
||||
FORCE_CLEAN=true
|
||||
;;
|
||||
-s|--skip-fpga-rebuild)
|
||||
SKIP_FPGA_REBUILD=true
|
||||
;;
|
||||
-d|--debug)
|
||||
DEBUG_ENABLED=true
|
||||
;;
|
||||
--help)
|
||||
print_usage
|
||||
exit 0
|
||||
@ -185,10 +169,8 @@ while test $# -gt 0; do
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$DEBUG_ENABLED" = true ]; then USER_FLAGS+=" -DDEBUG"; fi
|
||||
if [ "$TRIGGER_CIC" = true ]; then build_cic; fi
|
||||
if [ "$TRIGGER_N64" = true ]; then build_n64; fi
|
||||
if [ "$TRIGGER_RISCV" = true ]; then build_riscv; fi
|
||||
if [ "$TRIGGER_BOOTLOADER" = true ]; then build_bootloader; fi
|
||||
if [ "$TRIGGER_CONTROLLER" = true ]; then build_controller; fi
|
||||
if [ "$TRIGGER_FPGA" = true ]; then build_fpga; fi
|
||||
if [ "$TRIGGER_UPDATE" = true ]; then build_update; fi
|
||||
if [ "$TRIGGER_RELEASE" = true ]; then build_release; fi
|
||||
|
@ -1,18 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
GIT_SHA=$(git rev-parse --short HEAD)
|
||||
GIT_TAG=$(git describe --tags --exact-match 2> /dev/null)
|
||||
BUILDER_IMAGE="ghcr.io/polprzewodnikowy/sc64env:v1.5"
|
||||
|
||||
if [ ! -z $GIT_TAG ]; then
|
||||
__SC64_VERSION=$(printf "%.7q\ %.7q" $GIT_SHA $GIT_TAG)
|
||||
else
|
||||
__SC64_VERSION=$(printf "%.7q\ develop" $GIT_SHA)
|
||||
pushd $(dirname $0) > /dev/null
|
||||
|
||||
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
GIT_TAG=$(git describe --tags 2> /dev/null)
|
||||
GIT_SHA=$(git rev-parse HEAD)
|
||||
GIT_MESSAGE=$(git log --oneline --format=%B -n 1 HEAD | head -n 1)
|
||||
|
||||
if [ -t 1 ]; then
|
||||
DOCKER_OPTIONS="-it"
|
||||
fi
|
||||
|
||||
docker run \
|
||||
$DOCKER_OPTIONS \
|
||||
--rm \
|
||||
--user $(id -u):$(id -g) \
|
||||
--mac-address ${MAC_ADDRESS:-F8:12:34:56:78:90} \
|
||||
--mount type=bind,src="$(pwd)/flexlm",target="/flexlm" \
|
||||
--mount type=bind,src="$(pwd)",target="/workdir" \
|
||||
-e __SC64_VERSION="$__SC64_VERSION" \
|
||||
ghcr.io/polprzewodnikowy/sc64env:v1.2 \
|
||||
-h=`hostname` \
|
||||
-e GIT_BRANCH="$GIT_BRANCH" \
|
||||
-e GIT_TAG="$GIT_TAG" \
|
||||
-e GIT_SHA="$GIT_SHA" \
|
||||
-e GIT_MESSAGE="$GIT_MESSAGE" \
|
||||
$BUILDER_IMAGE \
|
||||
./build.sh $@
|
||||
|
||||
BUILD_ERROR=$?
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
if [ $BUILD_ERROR -ne 0 ]; then
|
||||
exit -1
|
||||
fi
|
||||
|
13
fw/.gitignore
vendored
13
fw/.gitignore
vendored
@ -1,13 +0,0 @@
|
||||
/db
|
||||
/greybox_tmp
|
||||
/incremental_db
|
||||
/output_files
|
||||
**/.qsys_edit
|
||||
**/*.bin
|
||||
**/*.dat
|
||||
**/*.elf
|
||||
*.qws
|
||||
*.rpt
|
||||
*.sopcinfo
|
||||
*.srf
|
||||
*.txt
|
@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
|
||||
<cof>
|
||||
<output_filename>output_files/SC64_firmware.pof</output_filename>
|
||||
<n_pages>1</n_pages>
|
||||
<width>1</width>
|
||||
<mode>14</mode>
|
||||
<sof_data>
|
||||
<user_name>Page_0</user_name>
|
||||
<page_flags>1</page_flags>
|
||||
<bit0>
|
||||
<sof_filename>output_files/SummerCart64.sof<compress_bitstream>1</compress_bitstream></sof_filename>
|
||||
</bit0>
|
||||
</sof_data>
|
||||
<version>10</version>
|
||||
<create_cvp_file>0</create_cvp_file>
|
||||
<create_hps_iocsr>0</create_hps_iocsr>
|
||||
<auto_create_rpd>1</auto_create_rpd>
|
||||
<rpd_little_endian>0</rpd_little_endian>
|
||||
<options>
|
||||
<map_file>1</map_file>
|
||||
</options>
|
||||
<MAX10_device_options>
|
||||
<por>0</por>
|
||||
<io_pullup>1</io_pullup>
|
||||
<config_from_cfm0_only>0</config_from_cfm0_only>
|
||||
<isp_source>0</isp_source>
|
||||
<verify_protect>0</verify_protect>
|
||||
<epof>0</epof>
|
||||
<ufm_source>2</ufm_source>
|
||||
<ufm_filepath>../sw/n64/build/n64boot.hex</ufm_filepath>
|
||||
<cfm0_filepath>../sw/riscv/build/governor.hex</cfm0_filepath>
|
||||
<cfm0_file_start_addr>305152</cfm0_file_start_addr>
|
||||
</MAX10_device_options>
|
||||
<advanced_options>
|
||||
<ignore_epcs_id_check>1</ignore_epcs_id_check>
|
||||
<ignore_condone_check>2</ignore_condone_check>
|
||||
<plc_adjustment>0</plc_adjustment>
|
||||
<post_chain_bitstream_pad_bytes>-1</post_chain_bitstream_pad_bytes>
|
||||
<post_device_bitstream_pad_bytes>-1</post_device_bitstream_pad_bytes>
|
||||
<bitslice_pre_padding>1</bitslice_pre_padding>
|
||||
</advanced_options>
|
||||
</cof>
|
@ -1,31 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
# Your use of Intel Corporation's design tools, logic functions
|
||||
# and other software and tools, and any partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Intel Program License
|
||||
# Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
# the Intel FPGA IP License Agreement, or other applicable license
|
||||
# agreement, including, without limitation, that your use is for
|
||||
# the sole purpose of programming logic devices manufactured by
|
||||
# Intel and sold by Intel or its authorized distributors. Please
|
||||
# refer to the applicable agreement for further details, at
|
||||
# https://fpgasoftware.intel.com/eula.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
# Date created = 10:53:32 August 01, 2021
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "20.1"
|
||||
DATE = "10:53:32 August 01, 2021"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "SummerCart64"
|
@ -1,292 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
# Your use of Intel Corporation's design tools, logic functions
|
||||
# and other software and tools, and any partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Intel Program License
|
||||
# Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
# the Intel FPGA IP License Agreement, or other applicable license
|
||||
# agreement, including, without limitation, that your use is for
|
||||
# the sole purpose of programming logic devices manufactured by
|
||||
# Intel and sold by Intel or its authorized distributors. Please
|
||||
# refer to the applicable agreement for further details, at
|
||||
# https://fpgasoftware.intel.com/eula.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
# Date created = 13:29:40 November 11, 2021
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# SummerCart64_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Intel recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus Prime software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.1
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "10:53:32 AUGUST 01, 2021"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "21.1.0 Lite Edition"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
|
||||
set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON
|
||||
set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys
|
||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/intel_fifo_8.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip
|
||||
set_global_assignment -name SDC_FILE SummerCart64.sdc
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dd.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_flash.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_flashram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_sdram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_si.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_wrapper.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_sdram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_dd.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_flashram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi_fifo.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_si.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/config.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/sc64.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv
|
||||
set_global_assignment -name POST_MODULE_SCRIPT_FILE "quartus_sh:scripts/post_module.tcl"
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_location_assignment PIN_6 -to o_usb_clk
|
||||
set_location_assignment PIN_7 -to io_usb_miosi[2]
|
||||
set_location_assignment PIN_8 -to io_usb_miosi[3]
|
||||
set_location_assignment PIN_10 -to io_usb_miosi[0]
|
||||
set_location_assignment PIN_11 -to io_usb_miosi[1]
|
||||
set_location_assignment PIN_12 -to i_uart_rxd
|
||||
set_location_assignment PIN_13 -to o_uart_txd
|
||||
set_location_assignment PIN_17 -to o_led
|
||||
set_location_assignment PIN_21 -to o_rtc_scl
|
||||
set_location_assignment PIN_22 -to io_rtc_sda
|
||||
set_location_assignment PIN_24 -to io_n64_si_dq
|
||||
set_location_assignment PIN_25 -to i_n64_nmi
|
||||
set_location_assignment PIN_26 -to i_clk
|
||||
set_location_assignment PIN_27 -to i_n64_reset
|
||||
set_location_assignment PIN_28 -to i_n64_si_clk
|
||||
set_location_assignment PIN_32 -to io_n64_pi_ad[7]
|
||||
set_location_assignment PIN_33 -to io_n64_pi_ad[8]
|
||||
set_location_assignment PIN_38 -to io_n64_pi_ad[6]
|
||||
set_location_assignment PIN_39 -to io_n64_pi_ad[9]
|
||||
set_location_assignment PIN_41 -to io_n64_pi_ad[5]
|
||||
set_location_assignment PIN_43 -to io_n64_pi_ad[10]
|
||||
set_location_assignment PIN_44 -to io_n64_pi_ad[4]
|
||||
set_location_assignment PIN_45 -to io_n64_pi_ad[11]
|
||||
set_location_assignment PIN_46 -to i_n64_pi_aleh
|
||||
set_location_assignment PIN_47 -to i_n64_pi_read
|
||||
set_location_assignment PIN_48 -to i_n64_pi_write
|
||||
set_location_assignment PIN_50 -to i_n64_pi_alel
|
||||
set_location_assignment PIN_52 -to io_n64_pi_ad[12]
|
||||
set_location_assignment PIN_54 -to io_n64_pi_ad[3]
|
||||
set_location_assignment PIN_55 -to io_n64_pi_ad[13]
|
||||
set_location_assignment PIN_56 -to io_n64_pi_ad[2]
|
||||
set_location_assignment PIN_57 -to io_n64_pi_ad[14]
|
||||
set_location_assignment PIN_58 -to io_n64_pi_ad[1]
|
||||
set_location_assignment PIN_59 -to io_n64_pi_ad[15]
|
||||
set_location_assignment PIN_60 -to io_n64_pi_ad[0]
|
||||
set_location_assignment PIN_61 -to o_sdram_a[4]
|
||||
set_location_assignment PIN_62 -to o_sdram_a[5]
|
||||
set_location_assignment PIN_64 -to o_sdram_a[6]
|
||||
set_location_assignment PIN_65 -to o_sdram_a[7]
|
||||
set_location_assignment PIN_66 -to o_sdram_a[8]
|
||||
set_location_assignment PIN_69 -to o_sdram_a[9]
|
||||
set_location_assignment PIN_70 -to o_sdram_a[11]
|
||||
set_location_assignment PIN_74 -to o_sdram_a[12]
|
||||
set_location_assignment PIN_75 -to o_sdram_clk
|
||||
set_location_assignment PIN_76 -to o_sdram_a[3]
|
||||
set_location_assignment PIN_77 -to o_sdram_a[2]
|
||||
set_location_assignment PIN_78 -to o_sdram_a[1]
|
||||
set_location_assignment PIN_79 -to o_sdram_a[0]
|
||||
set_location_assignment PIN_80 -to o_sdram_a[10]
|
||||
set_location_assignment PIN_81 -to o_sdram_ba[1]
|
||||
set_location_assignment PIN_84 -to o_sdram_ba[0]
|
||||
set_location_assignment PIN_85 -to o_sdram_cs
|
||||
set_location_assignment PIN_86 -to o_sdram_ras
|
||||
set_location_assignment PIN_87 -to o_sdram_cas
|
||||
set_location_assignment PIN_88 -to o_sdram_we
|
||||
set_location_assignment PIN_89 -to io_sdram_dq[7]
|
||||
set_location_assignment PIN_90 -to io_sdram_dq[6]
|
||||
set_location_assignment PIN_91 -to io_sdram_dq[5]
|
||||
set_location_assignment PIN_92 -to io_sdram_dq[4]
|
||||
set_location_assignment PIN_93 -to io_sdram_dq[3]
|
||||
set_location_assignment PIN_96 -to io_sdram_dq[2]
|
||||
set_location_assignment PIN_97 -to io_sdram_dq[1]
|
||||
set_location_assignment PIN_98 -to io_sdram_dq[0]
|
||||
set_location_assignment PIN_99 -to io_sdram_dq[8]
|
||||
set_location_assignment PIN_100 -to io_sdram_dq[9]
|
||||
set_location_assignment PIN_101 -to io_sdram_dq[10]
|
||||
set_location_assignment PIN_102 -to io_sdram_dq[11]
|
||||
set_location_assignment PIN_105 -to io_sdram_dq[12]
|
||||
set_location_assignment PIN_106 -to io_sdram_dq[13]
|
||||
set_location_assignment PIN_110 -to io_sdram_dq[14]
|
||||
set_location_assignment PIN_111 -to io_sdram_dq[15]
|
||||
set_location_assignment PIN_112 -to io_sd_dat[1]
|
||||
set_location_assignment PIN_113 -to io_sd_dat[0]
|
||||
set_location_assignment PIN_114 -to o_sd_clk
|
||||
set_location_assignment PIN_118 -to io_sd_cmd
|
||||
set_location_assignment PIN_119 -to io_sd_dat[3]
|
||||
set_location_assignment PIN_120 -to io_sd_dat[2]
|
||||
set_location_assignment PIN_123 -to o_n64_irq
|
||||
set_location_assignment PIN_138 -to i_usb_pwren
|
||||
set_location_assignment PIN_140 -to o_usb_cs
|
||||
set_location_assignment PIN_141 -to i_usb_miso
|
||||
|
||||
# Classic Timing Assignments
|
||||
# ==========================
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON
|
||||
|
||||
# Compiler Assignments
|
||||
# ====================
|
||||
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
||||
|
||||
# Analysis & Synthesis Assignments
|
||||
# ================================
|
||||
set_global_assignment -name FAMILY "MAX 10"
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE EQFP
|
||||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
|
||||
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
|
||||
set_global_assignment -name PROJECT_IP_REGENERATION_POLICY ALWAYS_REGENERATE_IP
|
||||
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
|
||||
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
|
||||
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
|
||||
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY SummerCart64
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
set_global_assignment -name DEVICE 10M08SCE144C8G
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256
|
||||
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
|
||||
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
|
||||
set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE "SINGLE COMP IMAGE"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
|
||||
|
||||
# Assembler Assignments
|
||||
# =====================
|
||||
set_global_assignment -name ENABLE_OCT_DONE OFF
|
||||
set_global_assignment -name EXTERNAL_FLASH_FALLBACK_ADDRESS 00000000
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
|
||||
|
||||
# Power Estimation Assignments
|
||||
# ============================
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_global_assignment -name POWER_DEFAULT_INPUT_IO_TOGGLE_RATE "12.5 %"
|
||||
|
||||
# Advanced I/O Timing Assignments
|
||||
# ===============================
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
|
||||
# --------------------------
|
||||
# start ENTITY(SummerCart64)
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_si_dq
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_aleh
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_read
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_write
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sd_*
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_pwren
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_*
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sd_clk
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sd_*
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sdram_dq[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sd_*
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_rtc_sda
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_rxd
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_reset
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_si_clk
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_write
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_n64_irq
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_pwren
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_miso
|
||||
|
||||
# start DESIGN_PARTITION(Top)
|
||||
# ---------------------------
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(SummerCart64)
|
||||
# ------------------------
|
@ -1,81 +0,0 @@
|
||||
# Clocks
|
||||
|
||||
derive_pll_clocks -create_base_clocks
|
||||
|
||||
set sys_clk {system_inst|intel_pll_inst|altpll_component|auto_generated|pll1|clk[0]}
|
||||
set sdram_pll_clk {system_inst|intel_pll_inst|altpll_component|auto_generated|pll1|clk[1]}
|
||||
# set sd_reg_clk {sd_interface_inst|sd_clk_inst|o_sd_clk|q}
|
||||
|
||||
create_generated_clock -name sdram_clk -source [get_pins $sdram_pll_clk] [get_ports {o_sdram_clk}]
|
||||
# create_generated_clock -name sd_reg_clk -source [get_pins {sd_interface_inst|sd_clk_inst|o_sd_clk|clk}] -divide_by 2 [get_pins $sd_reg_clk]
|
||||
# create_generated_clock -name sd_clk -source [get_pins $sd_reg_clk] [get_ports {o_sd_clk}]
|
||||
|
||||
create_generated_clock -name flash_se_neg_reg \
|
||||
-source [get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|clk}] \
|
||||
-divide_by 2 \
|
||||
[get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|q}]
|
||||
|
||||
derive_clock_uncertainty
|
||||
|
||||
|
||||
# SDRAM timings
|
||||
|
||||
set sdram_outputs {o_sdram_cs o_sdram_ras o_sdram_cas o_sdram_we o_sdram_a[*] o_sdram_ba[*] io_sdram_dq[*]}
|
||||
set sdram_inputs {io_sdram_dq[*]}
|
||||
|
||||
set_output_delay -clock [get_clocks {sdram_clk}] -max 1.5 [get_ports $sdram_outputs]
|
||||
set_output_delay -clock [get_clocks {sdram_clk}] -min -0.8 [get_ports $sdram_outputs]
|
||||
|
||||
set_input_delay -clock [get_clocks {sdram_clk}] -max 5.4 [get_ports $sdram_inputs]
|
||||
set_input_delay -clock [get_clocks {sdram_clk}] -min 2.5 [get_ports $sdram_inputs]
|
||||
|
||||
set_multicycle_path -setup -end 2 -from [get_clocks {sdram_clk}] -to [get_clocks $sys_clk]
|
||||
|
||||
|
||||
# SD card timings
|
||||
|
||||
# set_output_delay -clock [get_clocks {sd_clk}] -max 6.0 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
# set_output_delay -clock [get_clocks {sd_clk}] -min -2.0 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
|
||||
# set_input_delay -clock [get_clocks {sd_clk}] -max 15.0 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
# set_input_delay -clock [get_clocks {sd_clk}] -min 6.5 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
|
||||
# set_multicycle_path -hold -start 1 -from [get_clocks $sys_clk] -to [get_clocks {sd_clk}]
|
||||
|
||||
# set_multicycle_path -setup -end 3 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk]
|
||||
# set_multicycle_path -hold -end 1 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk]
|
||||
|
||||
|
||||
# FT1248 timings
|
||||
|
||||
set_false_path -to [get_ports {o_usb_clk io_usb_miosi[*] o_usb_cs}]
|
||||
set_false_path -from [get_ports {io_usb_miosi[*] i_usb_miso i_usb_pwren}]
|
||||
|
||||
|
||||
# N64, PI and SI timings
|
||||
|
||||
set_false_path -to [get_ports {o_n64_irq}]
|
||||
set_false_path -from [get_ports {i_n64_reset i_n64_nmi}]
|
||||
|
||||
set_false_path -to [get_ports {io_n64_pi_ad[*]}]
|
||||
set_false_path -from [get_ports {i_n64_pi_* io_n64_pi_ad[*]}]
|
||||
|
||||
set_false_path -to [get_ports {io_n64_si_dq}]
|
||||
set_false_path -from [get_ports {i_n64_si_clk io_n64_si_dq}]
|
||||
|
||||
|
||||
# LED timings
|
||||
|
||||
set_false_path -to [get_ports {o_led}]
|
||||
|
||||
|
||||
# UART timings
|
||||
|
||||
set_false_path -to [get_ports {o_uart_txd}]
|
||||
set_false_path -from [get_ports {i_uart_rxd}]
|
||||
|
||||
|
||||
# I2C timings
|
||||
|
||||
set_false_path -to [get_ports {o_rtc_scl io_rtc_sda}]
|
||||
set_false_path -from [get_ports {io_rtc_sda}]
|
Binary file not shown.
@ -1 +0,0 @@
|
||||
Subproject commit f9b1beb4cfd6b382157b54bc8f38c61d5ae7d785
|
17
fw/project/lcmxo2/.gitignore
vendored
Normal file
17
fw/project/lcmxo2/.gitignore
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
.recovery
|
||||
*.dir/
|
||||
*.ccl
|
||||
*.dmp
|
||||
*.html
|
||||
*.ini
|
||||
*.rva
|
||||
*.rvl
|
||||
*.rvs
|
||||
*.svf
|
||||
*.tcl
|
||||
*.tpf
|
||||
*.trc
|
||||
*.xml
|
||||
impl*/
|
||||
|
||||
!build.tcl
|
5
fw/project/lcmxo2/build.sh
Executable file
5
fw/project/lcmxo2/build.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
source $bindir/diamond_env
|
||||
|
||||
diamondc build.tcl
|
2
fw/project/lcmxo2/build.tcl
Normal file
2
fw/project/lcmxo2/build.tcl
Normal file
@ -0,0 +1,2 @@
|
||||
prj_project open sc64.ldf
|
||||
prj_run Export -impl impl1 -task Jedecgen
|
205
fw/project/lcmxo2/debug.sty
Normal file
205
fw/project/lcmxo2/debug.sty
Normal file
@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE strategy>
|
||||
<Strategy version="1.0" predefined="0" description="" label="debug">
|
||||
<Property name="PROP_BD_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_BD_EdfHardtimer" value="Enable" time="0"/>
|
||||
<Property name="PROP_BD_EdfInBusNameConv" value="None" time="0"/>
|
||||
<Property name="PROP_BD_EdfInLibPath" value="" time="0"/>
|
||||
<Property name="PROP_BD_EdfInRemLoc" value="Off" time="0"/>
|
||||
<Property name="PROP_BD_EdfMemPath" value="" time="0"/>
|
||||
<Property name="PROP_BD_ParSearchPath" value="" time="0"/>
|
||||
<Property name="PROP_BIT_AddressBitGen" value="Increment" time="0"/>
|
||||
<Property name="PROP_BIT_AllowReadBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ByteWideBitMirror" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_CapReadBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ConModBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_CreateBitFile" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_DisRAMResBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_DisableUESBitgen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_DonePinBitGen" value="Pullup" time="0"/>
|
||||
<Property name="PROP_BIT_DoneSigBitGen" value="4" time="0"/>
|
||||
<Property name="PROP_BIT_EnIOBitGen" value="TriStateDuringReConfig" time="0"/>
|
||||
<Property name="PROP_BIT_EnIntOscBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ExtClockBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_GSREnableBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_GSRRelOnBitGen" value="DoneIn" time="0"/>
|
||||
<Property name="PROP_BIT_GranTimBitGen" value="0" time="0"/>
|
||||
<Property name="PROP_BIT_IOTriRelBitGen" value="Cycle 2" time="0"/>
|
||||
<Property name="PROP_BIT_JTAGEnableBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_LenBitsBitGen" value="24" time="0"/>
|
||||
<Property name="PROP_BIT_MIFFileBitGen" value="" time="0"/>
|
||||
<Property name="PROP_BIT_NoHeader" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatBitGen" value="Bit File (Binary)" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatBitGen_REF" value="" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatPromGen" value="Intel Hex 32-bit" time="0"/>
|
||||
<Property name="PROP_BIT_ParityCheckBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_ReadBackBitGen" value="Flash" time="0"/>
|
||||
<Property name="PROP_BIT_ReadCaptureBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_RemZeroFramesBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_RunDRCBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_SearchPthBitGen" value="" time="0"/>
|
||||
<Property name="PROP_BIT_StartUpClkBitGen" value="Cclk" time="0"/>
|
||||
<Property name="PROP_BIT_SynchIOBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_SysClockConBitGen" value="Reset" time="0"/>
|
||||
<Property name="PROP_BIT_SysConBitGen" value="Reset" time="0"/>
|
||||
<Property name="PROP_BIT_WaitStTimBitGen" value="5" time="0"/>
|
||||
<Property name="PROP_IOTIMING_AllSpeed" value="False" time="0"/>
|
||||
<Property name="PROP_LST_AllowDUPMod" value="False" time="0"/>
|
||||
<Property name="PROP_LST_CarryChain" value="True" time="0"/>
|
||||
<Property name="PROP_LST_CarryChainLength" value="0" time="0"/>
|
||||
<Property name="PROP_LST_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_LST_DSPStyle" value="DSP" time="0"/>
|
||||
<Property name="PROP_LST_DSPUtil" value="100" time="0"/>
|
||||
<Property name="PROP_LST_DecodeUnreachableStates" value="False" time="0"/>
|
||||
<Property name="PROP_LST_DisableDistRam" value="False" time="0"/>
|
||||
<Property name="PROP_LST_EBRUtil" value="100" time="0"/>
|
||||
<Property name="PROP_LST_EdfFrequency" value="200" time="0"/>
|
||||
<Property name="PROP_LST_EdfHardtimer" value="Enable" time="0"/>
|
||||
<Property name="PROP_LST_EdfInLibPath" value="" time="0"/>
|
||||
<Property name="PROP_LST_EdfInRemLoc" value="Off" time="0"/>
|
||||
<Property name="PROP_LST_EdfMemPath" value="" time="0"/>
|
||||
<Property name="PROP_LST_FIXGATEDCLKS" value="True" time="0"/>
|
||||
<Property name="PROP_LST_FSMEncodeStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_ForceGSRInfer" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_IOInsertion" value="True" time="0"/>
|
||||
<Property name="PROP_LST_InterFileDump" value="False" time="0"/>
|
||||
<Property name="PROP_LST_LoopLimit" value="1950" time="0"/>
|
||||
<Property name="PROP_LST_MaxFanout" value="1000" time="0"/>
|
||||
<Property name="PROP_LST_MuxStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_NumCriticalPaths" value="3" time="0"/>
|
||||
<Property name="PROP_LST_OptimizeGoal" value="Balanced" time="0"/>
|
||||
<Property name="PROP_LST_PropagatConst" value="True" time="0"/>
|
||||
<Property name="PROP_LST_RAMStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_ROMStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_RemoveDupRegs" value="True" time="0"/>
|
||||
<Property name="PROP_LST_ResolvedMixedDrivers" value="False" time="0"/>
|
||||
<Property name="PROP_LST_ResourceShare" value="True" time="0"/>
|
||||
<Property name="PROP_LST_UseIOReg" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_UseLPF" value="True" time="0"/>
|
||||
<Property name="PROP_LST_VHDL2008" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_AnalysisOption" value="Standard Setup and Hold Analysis" time="0"/>
|
||||
<Property name="PROP_MAPSTA_AutoTiming" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_CheckUnconstrainedConns" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_CheckUnconstrainedPaths" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_FullName" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_NumUnconstrainedPaths" value="0" time="0"/>
|
||||
<Property name="PROP_MAPSTA_ReportStyle" value="Verbose Timing Report" time="0"/>
|
||||
<Property name="PROP_MAPSTA_RouteEstAlogtithm" value="0" time="0"/>
|
||||
<Property name="PROP_MAPSTA_RptAsynTimLoop" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_WordCasePaths" value="1" time="0"/>
|
||||
<Property name="PROP_MAP_IgnorePreErr" value="True" time="0"/>
|
||||
<Property name="PROP_MAP_MAPIORegister" value="Auto" time="0"/>
|
||||
<Property name="PROP_MAP_MAPInferGSR" value="True" time="0"/>
|
||||
<Property name="PROP_MAP_MapModArgs" value="" time="0"/>
|
||||
<Property name="PROP_MAP_OvermapDevice" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_PackLogMapDes" value="" time="0"/>
|
||||
<Property name="PROP_MAP_RegRetiming" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_SigCrossRef" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_SymCrossRef" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDriven" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDrivenNodeRep" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDrivenPack" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_AnalysisOption" value="Standard Setup and Hold Analysis" time="0"/>
|
||||
<Property name="PROP_PARSTA_AutoTiming" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_CheckUnconstrainedConns" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_CheckUnconstrainedPaths" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_FullName" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_NumUnconstrainedPaths" value="0" time="0"/>
|
||||
<Property name="PROP_PARSTA_ReportStyle" value="Verbose Timing Report" time="0"/>
|
||||
<Property name="PROP_PARSTA_RptAsynTimLoop" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_SpeedForHoldAnalysis" value="6" time="0"/>
|
||||
<Property name="PROP_PARSTA_SpeedForSetupAnalysis" value="6" time="0"/>
|
||||
<Property name="PROP_PARSTA_WordCasePaths" value="10" time="0"/>
|
||||
<Property name="PROP_PAR_CrDlyStFileParDes" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_DisableTDParDes" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_EffortParDes" value="5" time="0"/>
|
||||
<Property name="PROP_PAR_MultiSeedSortMode" value="Worst Slack" time="0"/>
|
||||
<Property name="PROP_PAR_NewRouteParDes" value="NBR" time="0"/>
|
||||
<Property name="PROP_PAR_PARClockSkew" value="Off" time="0"/>
|
||||
<Property name="PROP_PAR_PARModArgs" value="" time="0"/>
|
||||
<Property name="PROP_PAR_ParMultiNodeList" value="" time="0"/>
|
||||
<Property name="PROP_PAR_ParRunPlaceOnly" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_PlcIterParDes" value="5" time="0"/>
|
||||
<Property name="PROP_PAR_PlcStCostTblParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_PrefErrorOut" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_RemoveDir" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_RouteDlyRedParDes" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutePassParDes" value="6" time="0"/>
|
||||
<Property name="PROP_PAR_RouteResOptParDes" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutingCDP" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutingCDR" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RunParWithTrce" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_RunTimeReduction" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_SaveBestRsltParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_StopZero" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_parHold" value="On" time="0"/>
|
||||
<Property name="PROP_PAR_parPathBased" value="Off" time="0"/>
|
||||
<Property name="PROP_PRE_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_PRE_EdfArrayBoundsCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfAutoResOfRam" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfClockDomainCross" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfDSPAcrossHie" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfFullCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfIgnoreRamRWCol" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfMissConstraint" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfNetFanout" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfParaCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfReencodeFSM" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfResSharing" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfTimingViolation" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfUseSafeFSM" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfVlog2001" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynComArea" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynCritcal" value="3" time="0"/>
|
||||
<Property name="PROP_PRE_VSynFSM" value="Auto" time="0"/>
|
||||
<Property name="PROP_PRE_VSynFreq" value="200" time="0"/>
|
||||
<Property name="PROP_PRE_VSynGSR" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynGatedClk" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynIOPad" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynOutNetForm" value="None" time="0"/>
|
||||
<Property name="PROP_PRE_VSynOutPref" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynRepClkFreq" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynRetime" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynTimSum" value="10" time="0"/>
|
||||
<Property name="PROP_PRE_VSynTransform" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSyninpd" value="0" time="0"/>
|
||||
<Property name="PROP_PRE_VSynoutd" value="0" time="0"/>
|
||||
<Property name="PROP_SYN_ClockConversion" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_SYN_DisableRegisterRep" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfAllowDUPMod" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfArea" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfArrangeVHDLFiles" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfDefEnumEncode" value="Default" time="0"/>
|
||||
<Property name="PROP_SYN_EdfFanout" value="1000" time="0"/>
|
||||
<Property name="PROP_SYN_EdfFrequency" value="110" time="0"/>
|
||||
<Property name="PROP_SYN_EdfGSR" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfInsertIO" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfNumCritPath" value="" time="0"/>
|
||||
<Property name="PROP_SYN_EdfNumStartEnd" value="" time="0"/>
|
||||
<Property name="PROP_SYN_EdfOutNetForm" value="None" time="0"/>
|
||||
<Property name="PROP_SYN_EdfPushTirstates" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfResSharing" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfRunRetiming" value="Pipelining Only" time="0"/>
|
||||
<Property name="PROP_SYN_EdfSymFSM" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfUnconsClk" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfVerilogInput" value="Verilog 2001" time="0"/>
|
||||
<Property name="PROP_SYN_ExportSetting" value="No" time="0"/>
|
||||
<Property name="PROP_SYN_LibPath" value="" time="0"/>
|
||||
<Property name="PROP_SYN_ResolvedMixedDrivers" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_UpdateCompilePtTimData" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_UseLPF" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_VHDL2008" value="False" time="0"/>
|
||||
<Property name="PROP_THERMAL_DefaultFreq" value="0" time="0"/>
|
||||
<Property name="PROP_TIM_MaxDelSimDes" value="" time="0"/>
|
||||
<Property name="PROP_TIM_MinSpeedGrade" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_ModPreSimDes" value="" time="0"/>
|
||||
<Property name="PROP_TIM_NegStupHldTim" value="True" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimGenPUR" value="True" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimGenX" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimHierSep" value="" time="0"/>
|
||||
<Property name="PROP_TIM_TransportModeOfPathDelay" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_TrgtSpeedGrade" value="" time="0"/>
|
||||
<Property name="PROP_TIM_WriteVerboseNetlist" value="False" time="0"/>
|
||||
<Property name="PROP_TMCHK_EnableCheck" value="True" time="0"/>
|
||||
</Strategy>
|
205
fw/project/lcmxo2/release.sty
Normal file
205
fw/project/lcmxo2/release.sty
Normal file
@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE strategy>
|
||||
<Strategy version="1.0" predefined="0" description="" label="release">
|
||||
<Property name="PROP_BD_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_BD_EdfHardtimer" value="Enable" time="0"/>
|
||||
<Property name="PROP_BD_EdfInBusNameConv" value="None" time="0"/>
|
||||
<Property name="PROP_BD_EdfInLibPath" value="" time="0"/>
|
||||
<Property name="PROP_BD_EdfInRemLoc" value="Off" time="0"/>
|
||||
<Property name="PROP_BD_EdfMemPath" value="" time="0"/>
|
||||
<Property name="PROP_BD_ParSearchPath" value="" time="0"/>
|
||||
<Property name="PROP_BIT_AddressBitGen" value="Increment" time="0"/>
|
||||
<Property name="PROP_BIT_AllowReadBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ByteWideBitMirror" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_CapReadBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ConModBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_CreateBitFile" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_DisRAMResBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_DisableUESBitgen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_DonePinBitGen" value="Pullup" time="0"/>
|
||||
<Property name="PROP_BIT_DoneSigBitGen" value="4" time="0"/>
|
||||
<Property name="PROP_BIT_EnIOBitGen" value="TriStateDuringReConfig" time="0"/>
|
||||
<Property name="PROP_BIT_EnIntOscBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ExtClockBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_GSREnableBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_GSRRelOnBitGen" value="DoneIn" time="0"/>
|
||||
<Property name="PROP_BIT_GranTimBitGen" value="0" time="0"/>
|
||||
<Property name="PROP_BIT_IOTriRelBitGen" value="Cycle 2" time="0"/>
|
||||
<Property name="PROP_BIT_JTAGEnableBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_LenBitsBitGen" value="24" time="0"/>
|
||||
<Property name="PROP_BIT_MIFFileBitGen" value="" time="0"/>
|
||||
<Property name="PROP_BIT_NoHeader" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatBitGen" value="Bit File (Binary)" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatBitGen_REF" value="" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatPromGen" value="Intel Hex 32-bit" time="0"/>
|
||||
<Property name="PROP_BIT_ParityCheckBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_ReadBackBitGen" value="Flash" time="0"/>
|
||||
<Property name="PROP_BIT_ReadCaptureBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_RemZeroFramesBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_RunDRCBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_SearchPthBitGen" value="" time="0"/>
|
||||
<Property name="PROP_BIT_StartUpClkBitGen" value="Cclk" time="0"/>
|
||||
<Property name="PROP_BIT_SynchIOBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_SysClockConBitGen" value="Reset" time="0"/>
|
||||
<Property name="PROP_BIT_SysConBitGen" value="Reset" time="0"/>
|
||||
<Property name="PROP_BIT_WaitStTimBitGen" value="5" time="0"/>
|
||||
<Property name="PROP_IOTIMING_AllSpeed" value="False" time="0"/>
|
||||
<Property name="PROP_LST_AllowDUPMod" value="False" time="0"/>
|
||||
<Property name="PROP_LST_CarryChain" value="True" time="0"/>
|
||||
<Property name="PROP_LST_CarryChainLength" value="0" time="0"/>
|
||||
<Property name="PROP_LST_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_LST_DSPStyle" value="DSP" time="0"/>
|
||||
<Property name="PROP_LST_DSPUtil" value="100" time="0"/>
|
||||
<Property name="PROP_LST_DecodeUnreachableStates" value="False" time="0"/>
|
||||
<Property name="PROP_LST_DisableDistRam" value="False" time="0"/>
|
||||
<Property name="PROP_LST_EBRUtil" value="100" time="0"/>
|
||||
<Property name="PROP_LST_EdfFrequency" value="200" time="0"/>
|
||||
<Property name="PROP_LST_EdfHardtimer" value="Enable" time="0"/>
|
||||
<Property name="PROP_LST_EdfInLibPath" value="" time="0"/>
|
||||
<Property name="PROP_LST_EdfInRemLoc" value="Off" time="0"/>
|
||||
<Property name="PROP_LST_EdfMemPath" value="" time="0"/>
|
||||
<Property name="PROP_LST_FIXGATEDCLKS" value="True" time="0"/>
|
||||
<Property name="PROP_LST_FSMEncodeStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_ForceGSRInfer" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_IOInsertion" value="True" time="0"/>
|
||||
<Property name="PROP_LST_InterFileDump" value="False" time="0"/>
|
||||
<Property name="PROP_LST_LoopLimit" value="1950" time="0"/>
|
||||
<Property name="PROP_LST_MaxFanout" value="1000" time="0"/>
|
||||
<Property name="PROP_LST_MuxStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_NumCriticalPaths" value="3" time="0"/>
|
||||
<Property name="PROP_LST_OptimizeGoal" value="Balanced" time="0"/>
|
||||
<Property name="PROP_LST_PropagatConst" value="True" time="0"/>
|
||||
<Property name="PROP_LST_RAMStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_ROMStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_RemoveDupRegs" value="True" time="0"/>
|
||||
<Property name="PROP_LST_ResolvedMixedDrivers" value="False" time="0"/>
|
||||
<Property name="PROP_LST_ResourceShare" value="True" time="0"/>
|
||||
<Property name="PROP_LST_UseIOReg" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_UseLPF" value="True" time="0"/>
|
||||
<Property name="PROP_LST_VHDL2008" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_AnalysisOption" value="Standard Setup and Hold Analysis" time="0"/>
|
||||
<Property name="PROP_MAPSTA_AutoTiming" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_CheckUnconstrainedConns" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_CheckUnconstrainedPaths" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_FullName" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_NumUnconstrainedPaths" value="0" time="0"/>
|
||||
<Property name="PROP_MAPSTA_ReportStyle" value="Verbose Timing Report" time="0"/>
|
||||
<Property name="PROP_MAPSTA_RouteEstAlogtithm" value="0" time="0"/>
|
||||
<Property name="PROP_MAPSTA_RptAsynTimLoop" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_WordCasePaths" value="1" time="0"/>
|
||||
<Property name="PROP_MAP_IgnorePreErr" value="True" time="0"/>
|
||||
<Property name="PROP_MAP_MAPIORegister" value="Auto" time="0"/>
|
||||
<Property name="PROP_MAP_MAPInferGSR" value="True" time="0"/>
|
||||
<Property name="PROP_MAP_MapModArgs" value="" time="0"/>
|
||||
<Property name="PROP_MAP_OvermapDevice" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_PackLogMapDes" value="" time="0"/>
|
||||
<Property name="PROP_MAP_RegRetiming" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_SigCrossRef" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_SymCrossRef" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDriven" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDrivenNodeRep" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDrivenPack" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_AnalysisOption" value="Standard Setup and Hold Analysis" time="0"/>
|
||||
<Property name="PROP_PARSTA_AutoTiming" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_CheckUnconstrainedConns" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_CheckUnconstrainedPaths" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_FullName" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_NumUnconstrainedPaths" value="0" time="0"/>
|
||||
<Property name="PROP_PARSTA_ReportStyle" value="Verbose Timing Report" time="0"/>
|
||||
<Property name="PROP_PARSTA_RptAsynTimLoop" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_SpeedForHoldAnalysis" value="6" time="0"/>
|
||||
<Property name="PROP_PARSTA_SpeedForSetupAnalysis" value="6" time="0"/>
|
||||
<Property name="PROP_PARSTA_WordCasePaths" value="10" time="0"/>
|
||||
<Property name="PROP_PAR_CrDlyStFileParDes" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_DisableTDParDes" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_EffortParDes" value="5" time="0"/>
|
||||
<Property name="PROP_PAR_MultiSeedSortMode" value="Worst Slack" time="0"/>
|
||||
<Property name="PROP_PAR_NewRouteParDes" value="NBR" time="0"/>
|
||||
<Property name="PROP_PAR_PARClockSkew" value="Off" time="0"/>
|
||||
<Property name="PROP_PAR_PARModArgs" value="" time="0"/>
|
||||
<Property name="PROP_PAR_ParMultiNodeList" value="" time="0"/>
|
||||
<Property name="PROP_PAR_ParRunPlaceOnly" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_PlcIterParDes" value="10" time="0"/>
|
||||
<Property name="PROP_PAR_PlcStCostTblParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_PrefErrorOut" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_RemoveDir" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_RouteDlyRedParDes" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutePassParDes" value="10" time="0"/>
|
||||
<Property name="PROP_PAR_RouteResOptParDes" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutingCDP" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_RoutingCDR" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_RunParWithTrce" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_RunTimeReduction" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_SaveBestRsltParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_StopZero" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_parHold" value="On" time="0"/>
|
||||
<Property name="PROP_PAR_parPathBased" value="On" time="0"/>
|
||||
<Property name="PROP_PRE_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_PRE_EdfArrayBoundsCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfAutoResOfRam" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfClockDomainCross" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfDSPAcrossHie" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfFullCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfIgnoreRamRWCol" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfMissConstraint" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfNetFanout" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfParaCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfReencodeFSM" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfResSharing" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfTimingViolation" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfUseSafeFSM" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfVlog2001" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynComArea" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynCritcal" value="3" time="0"/>
|
||||
<Property name="PROP_PRE_VSynFSM" value="Auto" time="0"/>
|
||||
<Property name="PROP_PRE_VSynFreq" value="200" time="0"/>
|
||||
<Property name="PROP_PRE_VSynGSR" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynGatedClk" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynIOPad" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynOutNetForm" value="None" time="0"/>
|
||||
<Property name="PROP_PRE_VSynOutPref" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynRepClkFreq" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynRetime" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynTimSum" value="10" time="0"/>
|
||||
<Property name="PROP_PRE_VSynTransform" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSyninpd" value="0" time="0"/>
|
||||
<Property name="PROP_PRE_VSynoutd" value="0" time="0"/>
|
||||
<Property name="PROP_SYN_ClockConversion" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_SYN_DisableRegisterRep" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfAllowDUPMod" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfArea" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfArrangeVHDLFiles" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfDefEnumEncode" value="Default" time="0"/>
|
||||
<Property name="PROP_SYN_EdfFanout" value="1000" time="0"/>
|
||||
<Property name="PROP_SYN_EdfFrequency" value="110" time="0"/>
|
||||
<Property name="PROP_SYN_EdfGSR" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfInsertIO" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfNumCritPath" value="" time="0"/>
|
||||
<Property name="PROP_SYN_EdfNumStartEnd" value="" time="0"/>
|
||||
<Property name="PROP_SYN_EdfOutNetForm" value="None" time="0"/>
|
||||
<Property name="PROP_SYN_EdfPushTirstates" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfResSharing" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfRunRetiming" value="Pipelining Only" time="0"/>
|
||||
<Property name="PROP_SYN_EdfSymFSM" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfUnconsClk" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfVerilogInput" value="Verilog 2001" time="0"/>
|
||||
<Property name="PROP_SYN_ExportSetting" value="No" time="0"/>
|
||||
<Property name="PROP_SYN_LibPath" value="" time="0"/>
|
||||
<Property name="PROP_SYN_ResolvedMixedDrivers" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_UpdateCompilePtTimData" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_UseLPF" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_VHDL2008" value="False" time="0"/>
|
||||
<Property name="PROP_THERMAL_DefaultFreq" value="0" time="0"/>
|
||||
<Property name="PROP_TIM_MaxDelSimDes" value="" time="0"/>
|
||||
<Property name="PROP_TIM_MinSpeedGrade" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_ModPreSimDes" value="" time="0"/>
|
||||
<Property name="PROP_TIM_NegStupHldTim" value="True" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimGenPUR" value="True" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimGenX" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimHierSep" value="" time="0"/>
|
||||
<Property name="PROP_TIM_TransportModeOfPathDelay" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_TrgtSpeedGrade" value="" time="0"/>
|
||||
<Property name="PROP_TIM_WriteVerboseNetlist" value="False" time="0"/>
|
||||
<Property name="PROP_TMCHK_EnableCheck" value="True" time="0"/>
|
||||
</Strategy>
|
126
fw/project/lcmxo2/sc64.ldf
Normal file
126
fw/project/lcmxo2/sc64.ldf
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<BaliProject version="3.2" title="sc64" device="LCMXO2-7000HC-6TG144C" default_implementation="impl1">
|
||||
<Options/>
|
||||
<Implementation title="impl1" dir="impl1" description="impl1" synthesis="synplify" default_strategy="release">
|
||||
<Options VerilogStandard="System Verilog" def_top="top" top="top"/>
|
||||
<Source name="../../rtl/memory/mem_bus.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/fifo/fifo_bus.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/fifo/fifo_junction.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/mcu/mcu_spi.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/mcu/mcu_top.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/memory/memory_arbiter.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/memory/memory_bram.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/memory/memory_dma.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/memory/memory_flash.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/memory/memory_sdram.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_cfg.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_dd.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_flashram.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_pi.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_pi_fifo.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_reg_bus.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_scb.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_si.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/n64/n64_top.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_clk.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_cmd.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_crc_7.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_crc_16.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_dat.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_scb.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/sd/sd_top.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/usb/usb_ft1248.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/vendor_scb.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/lcmxo2/fifo_8kb.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/lcmxo2/pll.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/lcmxo2/vendor.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog"/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/lcmxo2/generated/efb_lattice_generated.v" type="Verilog" type_short="Verilog">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/lcmxo2/generated/fifo_8kb_lattice_generated.v" type="Verilog" type_short="Verilog">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="../../rtl/vendor/lcmxo2/generated/pll_lattice_generated.v" type="Verilog" type_short="Verilog">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="../../rtl/top.sv" type="Verilog" type_short="Verilog">
|
||||
<Options VerilogStandard="System Verilog" top_module="top"/>
|
||||
</Source>
|
||||
<Source name="impl1/sc64.xcf" type="Programming Project File" type_short="Programming">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="sc64.lpf" type="Logic Preference" type_short="LPF">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="si.rva" type="Reveal Analyzer Project File" type_short="RVA" excluded="TRUE">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="si.rvl" type="Reveal" type_short="Reveal" excluded="TRUE">
|
||||
<Options/>
|
||||
</Source>
|
||||
</Implementation>
|
||||
<Strategy name="debug" file="debug.sty"/>
|
||||
<Strategy name="release" file="release.sty"/>
|
||||
</BaliProject>
|
209
fw/project/lcmxo2/sc64.lpf
Normal file
209
fw/project/lcmxo2/sc64.lpf
Normal file
@ -0,0 +1,209 @@
|
||||
RVL_ALIAS "clk" "clk";
|
||||
BANK 0 VCCIO 3.3 V;
|
||||
BANK 1 VCCIO 3.3 V;
|
||||
BANK 2 VCCIO 3.3 V;
|
||||
BANK 3 VCCIO 3.3 V;
|
||||
BANK 4 VCCIO 3.3 V;
|
||||
BANK 5 VCCIO 3.3 V;
|
||||
BLOCK ASYNCPATHS ;
|
||||
BLOCK JTAGPATHS ;
|
||||
BLOCK PATH FROM PORT "button" ;
|
||||
BLOCK RESETPATHS ;
|
||||
IOBUF ALLPORTS IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "button" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "flash_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "flash_cs" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "flash_dq[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "flash_dq[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "flash_dq[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "flash_dq[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "inclk" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "mcu_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "mcu_cs" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "mcu_int" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "mcu_miso" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
|
||||
IOBUF PORT "mcu_mosi" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
|
||||
IOBUF PORT "n64_irq" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_nmi" PULLMODE=DOWN IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[15]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_ad[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_aleh" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_alel" PULLMODE=DOWN IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_read" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_pi_write" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_reset" PULLMODE=DOWN IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_si_clk" PULLMODE=DOWN IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "n64_si_dq" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_clk" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_cmd" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_dat[0]" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_dat[1]" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_dat[2]" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_dat[3]" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sd_det" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_a[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_ba[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_ba[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_cas" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_cs" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[10]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[11]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[12]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[13]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[14]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[15]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[8]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dq[9]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dqm[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_dqm[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_ras" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "sdram_we" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_clk" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_cs" PULLMODE=UP IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miosi[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_miso" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "usb_pwrsav" PULLMODE=NONE IO_TYPE=LVCMOS33 ;
|
||||
LOCATE COMP "button" SITE "1" ;
|
||||
LOCATE COMP "flash_clk" SITE "142" ;
|
||||
LOCATE COMP "flash_cs" SITE "138" ;
|
||||
LOCATE COMP "flash_dq[0]" SITE "141" ;
|
||||
LOCATE COMP "flash_dq[1]" SITE "139" ;
|
||||
LOCATE COMP "flash_dq[2]" SITE "140" ;
|
||||
LOCATE COMP "flash_dq[3]" SITE "143" ;
|
||||
LOCATE COMP "inclk" SITE "3" ;
|
||||
LOCATE COMP "mcu_clk" SITE "121" ;
|
||||
LOCATE COMP "mcu_cs" SITE "122" ;
|
||||
LOCATE COMP "mcu_int" SITE "117" ;
|
||||
LOCATE COMP "mcu_miso" SITE "119" ;
|
||||
LOCATE COMP "mcu_mosi" SITE "120" ;
|
||||
LOCATE COMP "n64_irq" SITE "32" ;
|
||||
LOCATE COMP "n64_nmi" SITE "28" ;
|
||||
LOCATE COMP "n64_pi_ad[0]" SITE "60" ;
|
||||
LOCATE COMP "n64_pi_ad[1]" SITE "58" ;
|
||||
LOCATE COMP "n64_pi_ad[10]" SITE "42" ;
|
||||
LOCATE COMP "n64_pi_ad[11]" SITE "44" ;
|
||||
LOCATE COMP "n64_pi_ad[12]" SITE "52" ;
|
||||
LOCATE COMP "n64_pi_ad[13]" SITE "55" ;
|
||||
LOCATE COMP "n64_pi_ad[14]" SITE "57" ;
|
||||
LOCATE COMP "n64_pi_ad[15]" SITE "59" ;
|
||||
LOCATE COMP "n64_pi_ad[2]" SITE "56" ;
|
||||
LOCATE COMP "n64_pi_ad[3]" SITE "54" ;
|
||||
LOCATE COMP "n64_pi_ad[4]" SITE "45" ;
|
||||
LOCATE COMP "n64_pi_ad[5]" SITE "43" ;
|
||||
LOCATE COMP "n64_pi_ad[6]" SITE "40" ;
|
||||
LOCATE COMP "n64_pi_ad[7]" SITE "38" ;
|
||||
LOCATE COMP "n64_pi_ad[8]" SITE "39" ;
|
||||
LOCATE COMP "n64_pi_ad[9]" SITE "41" ;
|
||||
LOCATE COMP "n64_pi_aleh" SITE "48" ;
|
||||
LOCATE COMP "n64_pi_alel" SITE "50" ;
|
||||
LOCATE COMP "n64_pi_read" SITE "47" ;
|
||||
LOCATE COMP "n64_pi_write" SITE "49" ;
|
||||
LOCATE COMP "n64_reset" SITE "31" ;
|
||||
LOCATE COMP "n64_si_clk" SITE "33" ;
|
||||
LOCATE COMP "n64_si_dq" SITE "27" ;
|
||||
LOCATE COMP "sd_clk" SITE "111" ;
|
||||
LOCATE COMP "sd_cmd" SITE "112" ;
|
||||
LOCATE COMP "sd_dat[0]" SITE "110" ;
|
||||
LOCATE COMP "sd_dat[1]" SITE "109" ;
|
||||
LOCATE COMP "sd_dat[2]" SITE "114" ;
|
||||
LOCATE COMP "sd_dat[3]" SITE "113" ;
|
||||
LOCATE COMP "sd_det" SITE "115" ;
|
||||
LOCATE COMP "sdram_a[0]" SITE "85" ;
|
||||
LOCATE COMP "sdram_a[1]" SITE "86" ;
|
||||
LOCATE COMP "sdram_a[10]" SITE "84" ;
|
||||
LOCATE COMP "sdram_a[11]" SITE "63" ;
|
||||
LOCATE COMP "sdram_a[12]" SITE "62" ;
|
||||
LOCATE COMP "sdram_a[2]" SITE "87" ;
|
||||
LOCATE COMP "sdram_a[3]" SITE "89" ;
|
||||
LOCATE COMP "sdram_a[4]" SITE "71" ;
|
||||
LOCATE COMP "sdram_a[5]" SITE "70" ;
|
||||
LOCATE COMP "sdram_a[6]" SITE "69" ;
|
||||
LOCATE COMP "sdram_a[7]" SITE "68" ;
|
||||
LOCATE COMP "sdram_a[8]" SITE "67" ;
|
||||
LOCATE COMP "sdram_a[9]" SITE "65" ;
|
||||
LOCATE COMP "sdram_ba[0]" SITE "92" ;
|
||||
LOCATE COMP "sdram_ba[1]" SITE "91" ;
|
||||
LOCATE COMP "sdram_cas" SITE "95" ;
|
||||
LOCATE COMP "sdram_clk" SITE "61" ;
|
||||
LOCATE COMP "sdram_cs" SITE "93" ;
|
||||
LOCATE COMP "sdram_dq[0]" SITE "107" ;
|
||||
LOCATE COMP "sdram_dq[1]" SITE "106" ;
|
||||
LOCATE COMP "sdram_dq[10]" SITE "76" ;
|
||||
LOCATE COMP "sdram_dq[11]" SITE "77" ;
|
||||
LOCATE COMP "sdram_dq[12]" SITE "78" ;
|
||||
LOCATE COMP "sdram_dq[13]" SITE "81" ;
|
||||
LOCATE COMP "sdram_dq[14]" SITE "82" ;
|
||||
LOCATE COMP "sdram_dq[15]" SITE "83" ;
|
||||
LOCATE COMP "sdram_dq[2]" SITE "105" ;
|
||||
LOCATE COMP "sdram_dq[3]" SITE "104" ;
|
||||
LOCATE COMP "sdram_dq[4]" SITE "103" ;
|
||||
LOCATE COMP "sdram_dq[5]" SITE "100" ;
|
||||
LOCATE COMP "sdram_dq[6]" SITE "99" ;
|
||||
LOCATE COMP "sdram_dq[7]" SITE "98" ;
|
||||
LOCATE COMP "sdram_dq[8]" SITE "74" ;
|
||||
LOCATE COMP "sdram_dq[9]" SITE "75" ;
|
||||
LOCATE COMP "sdram_dqm[0]" SITE "97" ;
|
||||
LOCATE COMP "sdram_dqm[1]" SITE "73" ;
|
||||
LOCATE COMP "sdram_ras" SITE "94" ;
|
||||
LOCATE COMP "sdram_we" SITE "96" ;
|
||||
LOCATE COMP "usb_clk" SITE "12" ;
|
||||
LOCATE COMP "usb_cs" SITE "11" ;
|
||||
LOCATE COMP "usb_miosi[0]" SITE "22" ;
|
||||
LOCATE COMP "usb_miosi[1]" SITE "21" ;
|
||||
LOCATE COMP "usb_miosi[2]" SITE "20" ;
|
||||
LOCATE COMP "usb_miosi[3]" SITE "19" ;
|
||||
LOCATE COMP "usb_miosi[4]" SITE "17" ;
|
||||
LOCATE COMP "usb_miosi[5]" SITE "15" ;
|
||||
LOCATE COMP "usb_miosi[6]" SITE "14" ;
|
||||
LOCATE COMP "usb_miosi[7]" SITE "13" ;
|
||||
LOCATE COMP "usb_miso" SITE "10" ;
|
||||
LOCATE COMP "usb_pwrsav" SITE "2" ;
|
||||
SYSCONFIG SDM_PORT=DISABLE ;
|
||||
VOLTAGE 3.300 V;
|
||||
FREQUENCY NET "clk" 100.000000 MHz PAR_ADJ 10.000000 ;
|
||||
BLOCK PATH TO PORT "mcu_int" ;
|
||||
BLOCK PATH TO PORT "n64_irq" ;
|
||||
BLOCK PATH FROM PORT "usb_pwrsav" ;
|
||||
BLOCK PATH FROM PORT "sd_det" ;
|
@ -1,154 +0,0 @@
|
||||
module SummerCart64 (
|
||||
input i_clk,
|
||||
|
||||
input i_n64_reset,
|
||||
input i_n64_nmi,
|
||||
output o_n64_irq,
|
||||
|
||||
input i_n64_pi_alel,
|
||||
input i_n64_pi_aleh,
|
||||
input i_n64_pi_read,
|
||||
input i_n64_pi_write,
|
||||
inout [15:0] io_n64_pi_ad,
|
||||
|
||||
input i_n64_si_clk,
|
||||
inout io_n64_si_dq,
|
||||
|
||||
output o_sdram_clk,
|
||||
output o_sdram_cs,
|
||||
output o_sdram_ras,
|
||||
output o_sdram_cas,
|
||||
output o_sdram_we,
|
||||
output [1:0] o_sdram_ba,
|
||||
output [12:0] o_sdram_a,
|
||||
inout [15:0] io_sdram_dq,
|
||||
|
||||
output o_rtc_scl,
|
||||
inout io_rtc_sda,
|
||||
|
||||
output o_usb_clk,
|
||||
output o_usb_cs,
|
||||
input i_usb_miso,
|
||||
inout [3:0] io_usb_miosi,
|
||||
input i_usb_pwren,
|
||||
|
||||
input i_uart_rxd,
|
||||
output o_uart_txd,
|
||||
|
||||
output o_sd_clk,
|
||||
inout io_sd_cmd,
|
||||
inout [3:0] io_sd_dat,
|
||||
|
||||
output o_led
|
||||
);
|
||||
|
||||
logic [7:0] gpio_o;
|
||||
logic [7:0] gpio_i;
|
||||
logic [7:0] gpio_oe;
|
||||
|
||||
logic dd_interrupt;
|
||||
|
||||
if_system sys (
|
||||
.in_clk(i_clk),
|
||||
.n64_reset(i_n64_reset),
|
||||
.n64_nmi(i_n64_nmi)
|
||||
);
|
||||
|
||||
if_config cfg ();
|
||||
|
||||
if_dma dma ();
|
||||
|
||||
if_sdram sdram ();
|
||||
|
||||
if_flashram flashram ();
|
||||
|
||||
if_si si ();
|
||||
|
||||
if_flash flash ();
|
||||
|
||||
if_dd dd (
|
||||
.dd_interrupt(dd_interrupt)
|
||||
);
|
||||
|
||||
system system_inst (
|
||||
.sys(sys)
|
||||
);
|
||||
|
||||
intel_gpio_ddro sdram_clk_ddro (
|
||||
.outclock(sys.sdram.sdram_clk),
|
||||
.din({1'b0, 1'b1}),
|
||||
.pad_out(o_sdram_clk)
|
||||
);
|
||||
|
||||
n64_soc n64_soc_inst (
|
||||
.sys(sys),
|
||||
.cfg(cfg),
|
||||
.dma(dma),
|
||||
.sdram(sdram),
|
||||
.flashram(flashram),
|
||||
.si(si),
|
||||
.flash(flash),
|
||||
.dd(dd),
|
||||
|
||||
.n64_pi_alel(i_n64_pi_alel),
|
||||
.n64_pi_aleh(i_n64_pi_aleh),
|
||||
.n64_pi_read(i_n64_pi_read),
|
||||
.n64_pi_write(i_n64_pi_write),
|
||||
.n64_pi_ad(io_n64_pi_ad),
|
||||
|
||||
.n64_si_clk(i_n64_si_clk),
|
||||
.n64_si_dq(io_n64_si_dq),
|
||||
|
||||
.sdram_cs(o_sdram_cs),
|
||||
.sdram_ras(o_sdram_ras),
|
||||
.sdram_cas(o_sdram_cas),
|
||||
.sdram_we(o_sdram_we),
|
||||
.sdram_ba(o_sdram_ba),
|
||||
.sdram_a(o_sdram_a),
|
||||
.sdram_dq(io_sdram_dq)
|
||||
);
|
||||
|
||||
cpu_soc cpu_soc_inst (
|
||||
.sys(sys),
|
||||
.cfg(cfg),
|
||||
.dma(dma),
|
||||
.sdram(sdram),
|
||||
.flashram(flashram),
|
||||
.si(si),
|
||||
.flash(flash),
|
||||
.dd(dd),
|
||||
|
||||
.gpio_o(gpio_o),
|
||||
.gpio_i(gpio_i),
|
||||
.gpio_oe(gpio_oe),
|
||||
|
||||
.i2c_scl(o_rtc_scl),
|
||||
.i2c_sda(io_rtc_sda),
|
||||
|
||||
.usb_clk(o_usb_clk),
|
||||
.usb_cs(o_usb_cs),
|
||||
.usb_miso(i_usb_miso),
|
||||
.usb_miosi(io_usb_miosi),
|
||||
.usb_pwren(i_usb_pwren),
|
||||
|
||||
.uart_rxd(i_uart_rxd),
|
||||
.uart_txd(o_uart_txd),
|
||||
|
||||
.sd_clk(o_sd_clk),
|
||||
.sd_cmd(io_sd_cmd),
|
||||
.sd_dat(io_sd_dat)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
o_n64_irq = dd_interrupt ? 1'b0 : 1'bZ;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
o_led = gpio_oe[0] ? gpio_o[0] : 1'bZ;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
gpio_i <= {4'b0000, i_n64_nmi, i_n64_reset, gpio_o[1:0]};
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,54 +0,0 @@
|
||||
interface if_cpu_bus ();
|
||||
|
||||
localparam [3:0] NUM_DEVICES = sc64::__ID_CPU_END;
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic [3:0] wmask;
|
||||
logic [31:0] address;
|
||||
logic [31:0] wdata;
|
||||
logic [31:0] rdata;
|
||||
|
||||
logic device_ack [(NUM_DEVICES - 1):0];
|
||||
logic [31:0] device_rdata [(NUM_DEVICES - 1):0];
|
||||
|
||||
always_comb begin
|
||||
ack = 1'b0;
|
||||
rdata = 32'd0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
ack = ack | device_ack[i];
|
||||
rdata = rdata | device_rdata[i];
|
||||
end
|
||||
end
|
||||
|
||||
modport cpu (
|
||||
output request,
|
||||
input ack,
|
||||
output wmask,
|
||||
output address,
|
||||
output wdata,
|
||||
input rdata
|
||||
);
|
||||
|
||||
genvar n;
|
||||
generate
|
||||
for (n = 0; n < NUM_DEVICES; n++) begin : at
|
||||
logic device_request;
|
||||
|
||||
always_comb begin
|
||||
device_request = request && address[31:28] == n[3:0];
|
||||
end
|
||||
|
||||
modport device (
|
||||
input .request(device_request),
|
||||
output .ack(device_ack[n]),
|
||||
input .wmask(wmask),
|
||||
input .address(address),
|
||||
input .wdata(wdata),
|
||||
output .rdata(device_rdata[n])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endinterface
|
@ -1,164 +0,0 @@
|
||||
module cpu_cfg (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_config.cpu cfg
|
||||
);
|
||||
|
||||
logic skip_bootloader;
|
||||
logic trigger_reconfiguration;
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
R_SCR,
|
||||
R_DDIPL_OFFSET,
|
||||
R_SAVE_OFFSET,
|
||||
R_COMMAND,
|
||||
R_DATA_0,
|
||||
R_DATA_1,
|
||||
R_VERSION,
|
||||
R_RECONFIGURE
|
||||
} e_reg_id;
|
||||
|
||||
const logic [31:0] RECONFIGURE_MAGIC = 32'h52535446;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[4:2])
|
||||
R_SCR: bus.rdata = {
|
||||
cfg.cpu_ready,
|
||||
cfg.cpu_busy,
|
||||
1'b0,
|
||||
cfg.cmd_error,
|
||||
21'd0,
|
||||
skip_bootloader,
|
||||
cfg.flashram_enabled,
|
||||
cfg.sram_banked,
|
||||
cfg.sram_enabled,
|
||||
cfg.dd_enabled,
|
||||
cfg.sdram_writable,
|
||||
cfg.sdram_switch
|
||||
};
|
||||
R_DDIPL_OFFSET: bus.rdata = {6'd0, cfg.ddipl_offset};
|
||||
R_SAVE_OFFSET: bus.rdata = {6'd0, cfg.save_offset};
|
||||
R_COMMAND: bus.rdata = {24'd0, cfg.cmd};
|
||||
R_DATA_0: bus.rdata = cfg.data[0];
|
||||
R_DATA_1: bus.rdata = cfg.data[1];
|
||||
R_VERSION: bus.rdata = sc64::SC64_VER;
|
||||
R_RECONFIGURE: bus.rdata = RECONFIGURE_MAGIC;
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
cfg.wdata = bus.wdata;
|
||||
cfg.data_write = 2'b00;
|
||||
if (bus.request && (&bus.wmask)) begin
|
||||
cfg.data_write[0] = bus.address[4:2] == R_DATA_0;
|
||||
cfg.data_write[1] = bus.address[4:2] == R_DATA_1;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
cfg.cpu_ready <= 1'b0;
|
||||
cfg.cpu_busy <= 1'b0;
|
||||
cfg.cmd_error <= 1'b0;
|
||||
cfg.sdram_switch <= 1'b0;
|
||||
cfg.sdram_writable <= 1'b0;
|
||||
cfg.dd_enabled <= 1'b0;
|
||||
cfg.sram_enabled <= 1'b0;
|
||||
cfg.sram_banked <= 1'b0;
|
||||
cfg.flashram_enabled <= 1'b0;
|
||||
cfg.ddipl_offset <= 26'h3BE_0000;
|
||||
cfg.save_offset <= 26'h3FE_0000;
|
||||
skip_bootloader <= 1'b0;
|
||||
trigger_reconfiguration <= 1'b0;
|
||||
end else begin
|
||||
if (sys.n64_soft_reset) begin
|
||||
cfg.sdram_switch <= skip_bootloader;
|
||||
cfg.sdram_writable <= 1'b0;
|
||||
end
|
||||
if (cfg.cmd_request) begin
|
||||
cfg.cpu_busy <= 1'b1;
|
||||
end
|
||||
if (bus.request) begin
|
||||
case (bus.address[4:2])
|
||||
R_SCR: begin
|
||||
if (bus.wmask[3]) begin
|
||||
{
|
||||
cfg.cpu_ready,
|
||||
cfg.cpu_busy,
|
||||
cfg.cmd_error
|
||||
} <= {bus.wdata[31:30], bus.wdata[28]};
|
||||
end
|
||||
if (bus.wmask[0]) begin
|
||||
{
|
||||
skip_bootloader,
|
||||
cfg.flashram_enabled,
|
||||
cfg.sram_banked,
|
||||
cfg.sram_enabled,
|
||||
cfg.dd_enabled,
|
||||
cfg.sdram_writable,
|
||||
cfg.sdram_switch
|
||||
} <= bus.wdata[6:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_DDIPL_OFFSET: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.ddipl_offset <= bus.wdata[25:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_SAVE_OFFSET: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.save_offset <= bus.wdata[25:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_RECONFIGURE: begin
|
||||
if (&bus.wmask && bus.wdata == RECONFIGURE_MAGIC) begin
|
||||
trigger_reconfiguration <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
logic [1:0] ru_clk;
|
||||
logic ru_rconfig;
|
||||
logic ru_regout;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
ru_clk <= 2'd0;
|
||||
ru_rconfig <= 1'b0;
|
||||
end else begin
|
||||
ru_clk <= ru_clk + 1'd1;
|
||||
|
||||
if (ru_clk == 2'd1) begin
|
||||
ru_rconfig <= trigger_reconfiguration;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
fiftyfivenm_rublock fiftyfivenm_rublock_inst (
|
||||
.clk(ru_clk[1]),
|
||||
.shiftnld(1'b0),
|
||||
.captnupdt(1'b0),
|
||||
.regin(1'b0),
|
||||
.rsttimer(1'b0),
|
||||
.rconfig(ru_rconfig),
|
||||
.regout(ru_regout)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,141 +0,0 @@
|
||||
module cpu_dd (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_dd.cpu dd
|
||||
);
|
||||
|
||||
const bit [8:0] M_SECTOR_BUFFER = 9'h100;
|
||||
|
||||
logic bm_ack;
|
||||
logic [31:0] seek_timer;
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
R_SCR,
|
||||
R_CMD_DATA,
|
||||
R_HEAD_TRACK,
|
||||
R_SECTOR_INFO,
|
||||
R_DRIVE_ID,
|
||||
R_SEEK_TIMER
|
||||
} e_reg_id;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
if (bus.address[8] == M_SECTOR_BUFFER[8]) begin
|
||||
bus.rdata = {
|
||||
dd.sector_rdata[7:0],
|
||||
dd.sector_rdata[15:8],
|
||||
dd.sector_rdata[23:16],
|
||||
dd.sector_rdata[31:24]
|
||||
};
|
||||
end else begin
|
||||
case (bus.address[5:2])
|
||||
R_SCR: bus.rdata = {
|
||||
14'd0,
|
||||
bm_ack,
|
||||
dd.bm_micro_error,
|
||||
dd.bm_transfer_c2,
|
||||
dd.bm_transfer_data,
|
||||
dd.bm_transfer_blocks,
|
||||
dd.bm_transfer_mode,
|
||||
1'b0,
|
||||
dd.bm_stop_pending,
|
||||
1'b0,
|
||||
dd.bm_start_pending,
|
||||
dd.disk_changed,
|
||||
dd.disk_inserted,
|
||||
1'b0,
|
||||
dd.bm_pending,
|
||||
1'b0,
|
||||
dd.cmd_pending,
|
||||
1'b0,
|
||||
dd.hard_reset
|
||||
};
|
||||
R_CMD_DATA: bus.rdata = {8'd0, dd.cmd, dd.data};
|
||||
R_HEAD_TRACK: bus.rdata = {18'd0, dd.index_lock, dd.head_track};
|
||||
R_SECTOR_INFO: bus.rdata = {
|
||||
dd.sectors_in_block,
|
||||
dd.sector_size_full,
|
||||
dd.sector_size,
|
||||
dd.sector_num
|
||||
};
|
||||
R_DRIVE_ID: bus.rdata = {dd.drive_id};
|
||||
R_SEEK_TIMER: bus.rdata = seek_timer;
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
dd.sector_address = bus.address[7:2];
|
||||
dd.sector_address_valid = bus.request && bus.address[8] == M_SECTOR_BUFFER[8];
|
||||
dd.sector_write = (&bus.wmask) && dd.sector_address_valid;
|
||||
dd.sector_wdata = {bus.wdata[7:0], bus.wdata[15:8], bus.wdata[23:16], bus.wdata[31:24]};
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
dd.hard_reset_clear <= 1'b0;
|
||||
dd.cmd_ready <= 1'b0;
|
||||
dd.bm_start_clear <= 1'b0;
|
||||
dd.bm_stop_clear <= 1'b0;
|
||||
dd.bm_clear <= 1'b0;
|
||||
dd.bm_ready <= 1'b0;
|
||||
|
||||
if (dd.bm_interrupt_ack) begin
|
||||
bm_ack <= 1'b1;
|
||||
end
|
||||
|
||||
if (!(&seek_timer)) begin
|
||||
seek_timer <= seek_timer + 1'd1;
|
||||
end
|
||||
|
||||
if (sys.reset) begin
|
||||
bm_ack <= 1'b0;
|
||||
end else begin
|
||||
if (bus.request && (!bus.address[8])) begin
|
||||
case (bus.address[4:2])
|
||||
R_SCR: if (&bus.wmask) begin
|
||||
if (bus.wdata[20]) begin
|
||||
seek_timer <= 32'd0;
|
||||
end
|
||||
dd.bm_clear <= bus.wdata[19];
|
||||
if (bus.wdata[18]) begin
|
||||
bm_ack <= 1'b0;
|
||||
end
|
||||
dd.bm_micro_error <= bus.wdata[16];
|
||||
dd.bm_transfer_c2 <= bus.wdata[15];
|
||||
dd.bm_transfer_data <= bus.wdata[14];
|
||||
dd.bm_stop_clear <= bus.wdata[11];
|
||||
dd.bm_start_clear <= bus.wdata[9];
|
||||
dd.disk_changed <= bus.wdata[7];
|
||||
dd.disk_inserted <= bus.wdata[6];
|
||||
dd.bm_ready <= bus.wdata[5];
|
||||
dd.cmd_ready <= bus.wdata[3];
|
||||
dd.hard_reset_clear <= bus.wdata[1];
|
||||
end
|
||||
|
||||
R_CMD_DATA: if (&bus.wmask[1:0]) begin
|
||||
dd.cmd_data <= bus.wdata[15:0];
|
||||
end
|
||||
|
||||
R_HEAD_TRACK: if (&bus.wmask[1:0]) begin
|
||||
{dd.index_lock, dd.head_track} <= bus.wdata[13:0];
|
||||
end
|
||||
|
||||
R_DRIVE_ID: if (&bus.wmask[1:0]) begin
|
||||
dd.drive_id <= bus.wdata[15:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,222 +0,0 @@
|
||||
interface if_dma ();
|
||||
|
||||
localparam [1:0] NUM_DEVICES = sc64::__ID_DMA_END;
|
||||
|
||||
sc64::e_dma_id id;
|
||||
|
||||
logic rx_empty;
|
||||
logic rx_read;
|
||||
logic [7:0] rx_rdata;
|
||||
logic tx_full;
|
||||
logic tx_write;
|
||||
logic [7:0] tx_wdata;
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic write;
|
||||
logic [31:0] address;
|
||||
logic [15:0] rdata;
|
||||
logic [15:0] wdata;
|
||||
|
||||
modport controller (
|
||||
output id,
|
||||
|
||||
input rx_empty,
|
||||
output rx_read,
|
||||
input rx_rdata,
|
||||
input tx_full,
|
||||
output tx_write,
|
||||
output tx_wdata,
|
||||
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output address,
|
||||
input rdata,
|
||||
output wdata
|
||||
);
|
||||
|
||||
modport memory (
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input address,
|
||||
output rdata,
|
||||
input wdata
|
||||
);
|
||||
|
||||
logic [7:0] device_rx_rdata [(NUM_DEVICES - 1):0];
|
||||
logic device_rx_empty [(NUM_DEVICES - 1):0];
|
||||
logic device_tx_full [(NUM_DEVICES - 1):0];
|
||||
|
||||
always_comb begin
|
||||
rx_rdata = 8'd0;
|
||||
rx_empty = 1'b0;
|
||||
tx_full = 1'b0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
rx_rdata = rx_rdata | (id == i[1:0] ? device_rx_rdata[i] : 8'd0);
|
||||
rx_empty = rx_empty | (device_rx_empty[i] && id == i[1:0]);
|
||||
tx_full = tx_full | (device_tx_full[i] && id == i[1:0]);
|
||||
end
|
||||
end
|
||||
|
||||
genvar n;
|
||||
generate
|
||||
for (n = 0; n < NUM_DEVICES; n++) begin : at
|
||||
logic device_selected;
|
||||
logic device_rx_read;
|
||||
logic device_tx_write;
|
||||
|
||||
always_comb begin
|
||||
device_selected = id == n[1:0];
|
||||
device_rx_read = device_selected && rx_read;
|
||||
device_tx_write = device_selected && tx_write;
|
||||
end
|
||||
|
||||
modport device (
|
||||
output .rx_empty(device_rx_empty[n]),
|
||||
input .rx_read(device_rx_read),
|
||||
output .rx_rdata(device_rx_rdata[n]),
|
||||
output .tx_full(device_tx_full[n]),
|
||||
input .tx_write(device_tx_write),
|
||||
input .tx_wdata(tx_wdata)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module cpu_dma (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_dma.controller dma
|
||||
);
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
S_IDLE,
|
||||
S_FETCH,
|
||||
S_TRANSFER
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
logic pending_stop;
|
||||
logic direction;
|
||||
logic [27:0] length;
|
||||
logic [15:0] rdata_buffer;
|
||||
logic byte_counter;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[3:2])
|
||||
0: bus.rdata = {28'd0, state != S_IDLE, direction, 2'b00};
|
||||
1: bus.rdata = dma.address;
|
||||
2: bus.rdata = {2'b00, dma.id, length};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
|
||||
dma.rx_read <= 1'b0;
|
||||
dma.tx_write <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
pending_stop <= 1'b0;
|
||||
dma.request <= 1'b0;
|
||||
end else begin
|
||||
if (bus.request && bus.address[3:2] == 0 && bus.wmask[0]) begin
|
||||
pending_stop <= bus.wdata[1];
|
||||
end
|
||||
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
pending_stop <= 1'b0;
|
||||
|
||||
if (bus.request) begin
|
||||
case (bus.address[3:2])
|
||||
0: if (bus.wmask[0]) begin
|
||||
direction <= bus.wdata[2];
|
||||
if (bus.wdata[0]) begin
|
||||
state <= S_FETCH;
|
||||
byte_counter <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
1: if (&bus.wmask) begin
|
||||
dma.address <= bus.wdata;
|
||||
end
|
||||
|
||||
2: if (&bus.wmask) begin
|
||||
{dma.id, length} <= {bus.wdata[29:1], 1'b0};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
S_FETCH: begin
|
||||
if (length != 28'd0 && !pending_stop) begin
|
||||
if (direction) begin
|
||||
if (!dma.rx_empty && !dma.rx_read) begin
|
||||
dma.rx_read <= 1'b1;
|
||||
dma.wdata <= {dma.wdata[7:0], dma.rx_rdata};
|
||||
byte_counter <= ~byte_counter;
|
||||
if (byte_counter) begin
|
||||
state <= S_TRANSFER;
|
||||
dma.request <= 1'b1;
|
||||
dma.write <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
dma.request <= 1'b1;
|
||||
dma.write <= 1'b0;
|
||||
if (dma.ack) begin
|
||||
state <= S_TRANSFER;
|
||||
dma.request <= 1'b0;
|
||||
rdata_buffer <= dma.rdata;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_TRANSFER: begin
|
||||
if (direction) begin
|
||||
if (dma.ack) begin
|
||||
state <= S_FETCH;
|
||||
dma.request <= 1'b0;
|
||||
dma.address <= dma.address + 2'd2;
|
||||
length <= length - 2'd2;
|
||||
end
|
||||
end else begin
|
||||
if (!dma.tx_full && !dma.tx_write) begin
|
||||
dma.tx_write <= 1'b1;
|
||||
dma.tx_wdata <= byte_counter ? rdata_buffer[7:0] : rdata_buffer[15:8];
|
||||
byte_counter <= ~byte_counter;
|
||||
if (byte_counter) begin
|
||||
state <= S_FETCH;
|
||||
dma.address <= dma.address + 2'd2;
|
||||
length <= length - 2'd2;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state <= S_IDLE;
|
||||
dma.request <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,61 +0,0 @@
|
||||
interface if_flash ();
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic write;
|
||||
logic [31:0] address;
|
||||
logic [31:0] rdata;
|
||||
logic [31:0] wdata;
|
||||
|
||||
modport cpu (
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output address,
|
||||
input rdata,
|
||||
output wdata
|
||||
);
|
||||
|
||||
modport memory (
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input address,
|
||||
output rdata,
|
||||
input wdata
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module cpu_flash (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_flash.cpu flash
|
||||
);
|
||||
|
||||
logic request;
|
||||
|
||||
always_comb begin
|
||||
bus.ack = flash.ack;
|
||||
bus.rdata = flash.rdata;
|
||||
flash.request = bus.request || request;
|
||||
flash.write = &bus.wmask;
|
||||
flash.address = bus.address;
|
||||
flash.wdata = bus.wdata;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
request <= 1'b0;
|
||||
end else begin
|
||||
if (bus.request) begin
|
||||
request <= 1'b1;
|
||||
end
|
||||
if (flash.ack) begin
|
||||
request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,77 +0,0 @@
|
||||
interface if_flashram ();
|
||||
|
||||
logic [4:0] address;
|
||||
logic [31:0] rdata;
|
||||
logic [9:0] sector;
|
||||
logic operation_pending;
|
||||
logic write_or_erase;
|
||||
logic sector_or_all;
|
||||
logic operation_done;
|
||||
|
||||
modport cpu (
|
||||
output address,
|
||||
input rdata,
|
||||
input sector,
|
||||
input operation_pending,
|
||||
input write_or_erase,
|
||||
input sector_or_all,
|
||||
output operation_done
|
||||
);
|
||||
|
||||
modport flashram (
|
||||
input address,
|
||||
output rdata,
|
||||
output sector,
|
||||
output operation_pending,
|
||||
output write_or_erase,
|
||||
output sector_or_all,
|
||||
input operation_done
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module cpu_flashram (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_flashram.cpu flashram
|
||||
);
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
bus.rdata = {
|
||||
14'd0,
|
||||
flashram.sector,
|
||||
4'd0,
|
||||
flashram.sector_or_all,
|
||||
flashram.write_or_erase,
|
||||
1'b0,
|
||||
flashram.operation_pending
|
||||
};
|
||||
if (bus.address[7]) begin
|
||||
bus.rdata = {flashram.rdata[7:0], flashram.rdata[15:8], flashram.rdata[23:16], flashram.rdata[31:24]};
|
||||
end
|
||||
end
|
||||
|
||||
flashram.address = bus.address[6:2];
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
flashram.operation_done <= 1'b0;
|
||||
|
||||
if (bus.request) begin
|
||||
if (!bus.address[7] && bus.wmask[0]) begin
|
||||
flashram.operation_done <= bus.wdata[1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,42 +0,0 @@
|
||||
module cpu_gpio (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
|
||||
input [7:0] gpio_i,
|
||||
output [7:0] gpio_o,
|
||||
output [7:0] gpio_oe
|
||||
);
|
||||
|
||||
logic [1:0][7:0] gpio_i_ff;
|
||||
logic [7:0] gpio_o_value;
|
||||
logic [7:0] gpio_oe_value;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
bus.rdata = {8'd0, gpio_oe_value, gpio_i_ff[1], gpio_o_value};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
gpio_i_ff <= {gpio_i_ff[0], gpio_i};
|
||||
gpio_o <= gpio_o_value;
|
||||
gpio_oe <= gpio_oe_value;
|
||||
|
||||
if (sys.reset) begin
|
||||
gpio_o_value <= 8'd0;
|
||||
gpio_oe_value <= 8'd0;
|
||||
end else if (bus.request) begin
|
||||
if (bus.wmask[0]) gpio_o_value <= bus.wdata[7:0];
|
||||
if (bus.wmask[2]) gpio_oe_value <= bus.wdata[23:16];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,155 +0,0 @@
|
||||
module cpu_i2c (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
|
||||
output i2c_scl,
|
||||
inout i2c_sda
|
||||
);
|
||||
|
||||
reg [1:0] state;
|
||||
reg mack;
|
||||
reg [8:0] trx_data;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[2])
|
||||
0: bus.rdata = {27'd0, |state, ~trx_data[0], mack, 2'b00};
|
||||
1: bus.rdata = {23'd0, trx_data[0], trx_data[8:1]};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
|
||||
if (sys.reset) begin
|
||||
mack <= 1'b0;
|
||||
end else if (bus.request && bus.wmask[0] && !bus.address[2]) begin
|
||||
mack <= bus.wdata[2];
|
||||
end
|
||||
end
|
||||
|
||||
reg [5:0] clock_div;
|
||||
reg [3:0] clock_phase_gen;
|
||||
|
||||
wire clock_tick = &clock_div;
|
||||
wire [3:0] clock_phase = {4{clock_tick}} & clock_phase_gen;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
clock_div <= 6'd0;
|
||||
end else begin
|
||||
clock_div <= clock_div + 1'd1;
|
||||
end
|
||||
|
||||
if (sys.reset || state == 2'd0) begin
|
||||
clock_phase_gen <= 4'b0001;
|
||||
end else if (clock_tick) begin
|
||||
clock_phase_gen <= {clock_phase_gen[2:0], clock_phase_gen[3]};
|
||||
end
|
||||
end
|
||||
|
||||
reg [3:0] bit_counter;
|
||||
|
||||
reg sda_i_ff1, sda_i_ff2;
|
||||
reg scl_o;
|
||||
reg sda_o;
|
||||
|
||||
assign i2c_scl = scl_o ? 1'bZ : 1'b0;
|
||||
assign i2c_sda = sda_o ? 1'bZ : 1'b0;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
{sda_i_ff2, sda_i_ff1} <= {sda_i_ff1, i2c_sda};
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= 2'd0;
|
||||
scl_o <= 1'b1;
|
||||
sda_o <= 1'b1;
|
||||
end else begin
|
||||
case (state)
|
||||
2'd0: begin
|
||||
bit_counter <= 4'd0;
|
||||
|
||||
if (bus.request && bus.wmask[0]) begin
|
||||
case (bus.address[2])
|
||||
0: begin
|
||||
if (bus.wdata[1]) state <= 2'd2;
|
||||
if (bus.wdata[0]) state <= 2'd1;
|
||||
end
|
||||
|
||||
1: begin
|
||||
state <= 2'd3;
|
||||
trx_data <= {bus.wdata[7:0], ~mack};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
2'd1: begin
|
||||
if (clock_phase[0]) begin
|
||||
scl_o <= 1'b1;
|
||||
sda_o <= 1'b1;
|
||||
end
|
||||
|
||||
if (clock_phase[1]) begin
|
||||
sda_o <= 1'b0;
|
||||
end
|
||||
|
||||
if (clock_phase[3]) begin
|
||||
state <= 2'd0;
|
||||
scl_o <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
2'd2: begin
|
||||
if (clock_phase[0]) begin
|
||||
scl_o <= 1'b0;
|
||||
sda_o <= 1'b0;
|
||||
end
|
||||
|
||||
if (clock_phase[1]) begin
|
||||
scl_o <= 1'b1;
|
||||
end
|
||||
|
||||
if (clock_phase[3]) begin
|
||||
state <= 2'd0;
|
||||
sda_o <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
2'd3: begin
|
||||
if (clock_phase[0]) begin
|
||||
bit_counter <= bit_counter + 1'd1;
|
||||
scl_o <= 1'b0;
|
||||
sda_o <= trx_data[8];
|
||||
end
|
||||
|
||||
if (clock_phase[1]) begin
|
||||
scl_o <= 1'b1;
|
||||
end
|
||||
|
||||
if (clock_phase[3]) begin
|
||||
trx_data <= {trx_data[7:0], sda_i_ff2};
|
||||
scl_o <= 1'b0;
|
||||
end
|
||||
|
||||
if (bit_counter == 4'b1010) begin
|
||||
state <= 2'd0;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state <= 2'd0;
|
||||
scl_o <= 1'b1;
|
||||
sda_o <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,33 +0,0 @@
|
||||
module cpu_ram (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus
|
||||
);
|
||||
|
||||
logic [3:0][7:0] ram [0:4095];
|
||||
logic [31:0] q;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
bus.rdata = q;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
q <= ram[bus.address[13:2]];
|
||||
if (bus.request) begin
|
||||
if (bus.wmask[0]) ram[bus.address[13:2]][0] <= bus.wdata[7:0];
|
||||
if (bus.wmask[1]) ram[bus.address[13:2]][1] <= bus.wdata[15:8];
|
||||
if (bus.wmask[2]) ram[bus.address[13:2]][2] <= bus.wdata[23:16];
|
||||
if (bus.wmask[3]) ram[bus.address[13:2]][3] <= bus.wdata[31:24];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,76 +0,0 @@
|
||||
interface if_sdram ();
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic write;
|
||||
logic [31:0] address;
|
||||
logic [15:0] rdata;
|
||||
logic [15:0] wdata;
|
||||
|
||||
modport cpu (
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output address,
|
||||
input rdata,
|
||||
output wdata
|
||||
);
|
||||
|
||||
modport memory (
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input address,
|
||||
output rdata,
|
||||
input wdata
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module cpu_sdram (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_sdram.cpu sdram
|
||||
);
|
||||
|
||||
logic request;
|
||||
logic current_word;
|
||||
logic [31:0] rdata;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
bus.rdata = {rdata[7:0], rdata[15:8], rdata[23:16], rdata[31:24]};
|
||||
end
|
||||
|
||||
sdram.write = current_word ? &bus.wmask[1:0] : &bus.wmask[3:2];
|
||||
sdram.address = {1'b0, bus.address[30:2], current_word, 1'b0};
|
||||
sdram.wdata = current_word ? {bus.wdata[23:16], bus.wdata[31:24]} : {bus.wdata[7:0], bus.wdata[15:8]};
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
sdram.request <= 1'b0;
|
||||
end else begin
|
||||
if (bus.request) begin
|
||||
sdram.request <= 1'b1;
|
||||
current_word <= 1'b0;
|
||||
end
|
||||
|
||||
if (sdram.ack) begin
|
||||
if (!current_word) begin
|
||||
current_word <= 1'b1;
|
||||
rdata[31:16] <= sdram.rdata;
|
||||
end else begin
|
||||
bus.ack <= 1'b1;
|
||||
sdram.request <= 1'b0;
|
||||
rdata[15:0] <= sdram.rdata;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,59 +0,0 @@
|
||||
module cpu_si (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_si.cpu si
|
||||
);
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[3:2])
|
||||
0: bus.rdata = {
|
||||
20'd0,
|
||||
si.rx_length[6:3],
|
||||
4'd0,
|
||||
si.tx_busy,
|
||||
1'b0,
|
||||
si.rx_data[0],
|
||||
si.rx_ready
|
||||
};
|
||||
1: bus.rdata = {si.rx_data[56:49], si.rx_data[64:57], si.rx_data[72:65], si.rx_data[80:73]};
|
||||
2: bus.rdata = {si.rx_data[24:17], si.rx_data[32:25], si.rx_data[40:33], si.rx_data[48:41]};
|
||||
3: bus.rdata = {16'd0, si.rx_data[8:1], si.rx_data[16:9]};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
si.tx_data = {bus.wdata[7:0], bus.wdata[15:8], bus.wdata[23:16], bus.wdata[31:24]};
|
||||
si.tx_length = bus.wdata[22:16];
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
si.tx_reset <= 1'b0;
|
||||
si.rx_reset <= 1'b0;
|
||||
si.tx_start <= 1'b0;
|
||||
si.tx_wmask <= 3'b000;
|
||||
|
||||
if (bus.request && (&bus.wmask)) begin
|
||||
case (bus.address[3:2])
|
||||
0: begin
|
||||
si.tx_reset <= bus.wdata[7];
|
||||
si.rx_reset <= bus.wdata[6];
|
||||
si.tx_start <= bus.wdata[2];
|
||||
end
|
||||
1: si.tx_wmask[0] <= 1'b1;
|
||||
2: si.tx_wmask[1] <= 1'b1;
|
||||
3: si.tx_wmask[2] <= 1'b1;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,127 +0,0 @@
|
||||
module cpu_soc (
|
||||
if_system.sys sys,
|
||||
if_config.cpu cfg,
|
||||
if_dma dma,
|
||||
if_sdram.cpu sdram,
|
||||
if_flashram.cpu flashram,
|
||||
if_si.cpu si,
|
||||
if_flash.cpu flash,
|
||||
if_dd.cpu dd,
|
||||
|
||||
input [7:0] gpio_i,
|
||||
output [7:0] gpio_o,
|
||||
output [7:0] gpio_oe,
|
||||
|
||||
output i2c_scl,
|
||||
inout i2c_sda,
|
||||
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
input usb_miso,
|
||||
inout [3:0] usb_miosi,
|
||||
input usb_pwren,
|
||||
|
||||
input uart_rxd,
|
||||
output uart_txd,
|
||||
|
||||
output sd_clk,
|
||||
inout sd_cmd,
|
||||
inout [3:0] sd_dat
|
||||
);
|
||||
|
||||
if_cpu_bus bus ();
|
||||
|
||||
cpu_wrapper cpu_wrapper_inst (
|
||||
.sys(sys),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
cpu_ram cpu_ram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_RAM].device)
|
||||
);
|
||||
|
||||
cpu_flash cpu_flash_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_FLASH].device),
|
||||
.flash(flash)
|
||||
);
|
||||
|
||||
cpu_gpio cpu_gpio_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_GPIO].device),
|
||||
.gpio_i(gpio_i),
|
||||
.gpio_o(gpio_o),
|
||||
.gpio_oe(gpio_oe)
|
||||
);
|
||||
|
||||
cpu_i2c cpu_i2c_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_I2C].device),
|
||||
.i2c_scl(i2c_scl),
|
||||
.i2c_sda(i2c_sda)
|
||||
);
|
||||
|
||||
cpu_usb cpu_usb_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_USB].device),
|
||||
.dma(dma.at[sc64::ID_DMA_USB].device),
|
||||
.usb_clk(usb_clk),
|
||||
.usb_cs(usb_cs),
|
||||
.usb_miso(usb_miso),
|
||||
.usb_miosi(usb_miosi),
|
||||
.usb_pwren(usb_pwren)
|
||||
);
|
||||
|
||||
generate
|
||||
if (sc64::CPU_HAS_UART) begin
|
||||
cpu_uart cpu_uart_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_UART].device),
|
||||
.uart_rxd(uart_rxd),
|
||||
.uart_txd(uart_txd)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
cpu_dma cpu_dma_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_DMA].device),
|
||||
.dma(dma)
|
||||
);
|
||||
|
||||
cpu_cfg cpu_cfg_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_CFG].device),
|
||||
.cfg(cfg)
|
||||
);
|
||||
|
||||
cpu_sdram cpu_sdram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_SDRAM].device),
|
||||
.sdram(sdram)
|
||||
);
|
||||
|
||||
cpu_flashram cpu_flashram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_FLASHRAM].device),
|
||||
.flashram(flashram)
|
||||
);
|
||||
|
||||
cpu_si cpu_si_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_SI].device),
|
||||
.si(si)
|
||||
);
|
||||
|
||||
cpu_dd cpu_dd_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_DD].device),
|
||||
.dd(dd)
|
||||
);
|
||||
|
||||
assign sd_clk = 1'bZ;
|
||||
assign sd_cmd = 1'bZ;
|
||||
assign sd_dat = 4'bZZZZ;
|
||||
|
||||
endmodule
|
@ -1,153 +0,0 @@
|
||||
module cpu_uart (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
|
||||
input uart_rxd,
|
||||
output uart_txd
|
||||
);
|
||||
|
||||
localparam BAUD_GEN_VALUE = int'(sc64::CLOCK_FREQUENCY / sc64::UART_BAUD_RATE) - 1'd1;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
S_TRX_IDLE,
|
||||
S_TRX_DATA,
|
||||
S_TRX_SAMPLING_OFFSET
|
||||
} e_trx_state;
|
||||
|
||||
|
||||
// CPU bus controller
|
||||
|
||||
e_trx_state tx_state;
|
||||
e_trx_state rx_state;
|
||||
logic [7:0] rx_data;
|
||||
logic rx_available;
|
||||
logic rx_overrun;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[2:2])
|
||||
0: bus.rdata = {29'd0, rx_overrun, tx_state == S_TRX_IDLE, rx_available};
|
||||
1: bus.rdata = {24'd0, rx_data};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// TX path
|
||||
|
||||
logic [6:0] tx_baud_counter;
|
||||
logic [3:0] tx_bit_counter;
|
||||
logic [9:0] tx_shifter;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
tx_baud_counter <= tx_baud_counter + 1'd1;
|
||||
uart_txd <= tx_shifter[0];
|
||||
|
||||
if (sys.reset) begin
|
||||
tx_state <= S_TRX_IDLE;
|
||||
tx_shifter <= 10'h3FF;
|
||||
end else begin
|
||||
case (tx_state)
|
||||
S_TRX_IDLE: begin
|
||||
if (bus.request && bus.wmask[0] && bus.address[2]) begin
|
||||
tx_state <= S_TRX_DATA;
|
||||
tx_baud_counter <= 7'd0;
|
||||
tx_bit_counter <= 4'd0;
|
||||
tx_shifter <= {1'b1, bus.wdata[7:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
S_TRX_DATA: begin
|
||||
if (tx_baud_counter == BAUD_GEN_VALUE) begin
|
||||
tx_baud_counter <= 7'd0;
|
||||
tx_bit_counter <= tx_bit_counter + 1'd1;
|
||||
tx_shifter <= {1'b1, tx_shifter[9:1]};
|
||||
if (tx_bit_counter == 4'd9) begin
|
||||
tx_state <= S_TRX_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
tx_state <= S_TRX_IDLE;
|
||||
tx_shifter <= 10'h3FF;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// RX path
|
||||
|
||||
logic [6:0] rx_baud_counter;
|
||||
logic [3:0] rx_bit_counter;
|
||||
logic [7:0] rx_shifter;
|
||||
logic [1:0] rxd_ff;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
rx_baud_counter <= rx_baud_counter + 1'd1;
|
||||
rxd_ff <= {rxd_ff[0], uart_rxd};
|
||||
|
||||
if (bus.request && bus.wmask[0] && !bus.address[2]) begin
|
||||
rx_overrun <= bus.wdata[2];
|
||||
end
|
||||
if (bus.request && !bus.wmask[0] && bus.address[2]) begin
|
||||
rx_available <= 1'b0;
|
||||
end
|
||||
|
||||
if (sys.reset) begin
|
||||
rx_state <= S_TRX_IDLE;
|
||||
rx_available <= 1'b0;
|
||||
rx_overrun <= 1'b0;
|
||||
end else begin
|
||||
case (rx_state)
|
||||
S_TRX_IDLE: begin
|
||||
if (!rxd_ff[1]) begin
|
||||
rx_state <= S_TRX_SAMPLING_OFFSET;
|
||||
rx_baud_counter <= 7'd0;
|
||||
rx_bit_counter <= 4'd0;
|
||||
end
|
||||
end
|
||||
|
||||
S_TRX_SAMPLING_OFFSET: begin
|
||||
if (rx_baud_counter == (BAUD_GEN_VALUE / 2)) begin
|
||||
rx_state <= S_TRX_DATA;
|
||||
rx_baud_counter <= 7'd0;
|
||||
end
|
||||
end
|
||||
|
||||
S_TRX_DATA: begin
|
||||
if (rx_baud_counter == BAUD_GEN_VALUE) begin
|
||||
rx_baud_counter <= 7'd0;
|
||||
rx_bit_counter <= rx_bit_counter + 1'd1;
|
||||
rx_shifter <= {rxd_ff[1], rx_shifter[7:1]};
|
||||
if (rx_bit_counter == 4'd8) begin
|
||||
rx_state <= S_TRX_IDLE;
|
||||
if (rxd_ff[1]) begin
|
||||
rx_data <= rx_shifter[7:0];
|
||||
rx_available <= 1'b1;
|
||||
rx_overrun <= rx_available;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
rx_state <= S_TRX_IDLE;
|
||||
rx_available <= 1'b0;
|
||||
rx_overrun <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,119 +0,0 @@
|
||||
module cpu_usb (
|
||||
if_system sys,
|
||||
if_cpu_bus bus,
|
||||
if_dma dma,
|
||||
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
input usb_miso,
|
||||
inout [3:0] usb_miosi,
|
||||
input usb_pwren
|
||||
);
|
||||
|
||||
logic rx_flush;
|
||||
logic rx_empty;
|
||||
logic rx_read;
|
||||
logic [7:0] rx_rdata;
|
||||
|
||||
logic tx_flush;
|
||||
logic tx_full;
|
||||
logic tx_write;
|
||||
logic [7:0] tx_wdata;
|
||||
|
||||
logic rx_escape_valid;
|
||||
logic rx_escape_ack;
|
||||
logic [7:0] rx_escape;
|
||||
|
||||
logic cpu_rx_read;
|
||||
logic cpu_tx_write;
|
||||
|
||||
logic usb_enabled;
|
||||
|
||||
always_comb begin
|
||||
dma.rx_empty = rx_empty;
|
||||
rx_read = cpu_rx_read || dma.rx_read;
|
||||
dma.rx_rdata = rx_rdata;
|
||||
|
||||
dma.tx_full = tx_full;
|
||||
tx_write = cpu_tx_write || dma.tx_write;
|
||||
tx_wdata = dma.tx_write ? dma.tx_wdata : bus.wdata[7:0];
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[3:2])
|
||||
0: bus.rdata = {25'd0, rx_escape_valid, usb_pwren, usb_enabled, 2'b00, ~tx_full, ~rx_empty};
|
||||
1: bus.rdata = {24'd0, rx_rdata};
|
||||
2: bus.rdata = {24'd0, rx_escape};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
rx_flush <= 1'b0;
|
||||
cpu_rx_read <= 1'b0;
|
||||
|
||||
tx_flush <= 1'b0;
|
||||
cpu_tx_write <= 1'b0;
|
||||
|
||||
rx_escape_ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
usb_enabled <= 1'b0;
|
||||
end else begin
|
||||
if (bus.request) begin
|
||||
case (bus.address[2:2])
|
||||
2'd0: begin
|
||||
if (bus.wmask[0]) begin
|
||||
rx_escape_ack <= bus.wdata[7];
|
||||
{usb_enabled, tx_flush, rx_flush} <= bus.wdata[4:2];
|
||||
end
|
||||
end
|
||||
|
||||
2'd1: begin
|
||||
if (bus.wmask[0]) begin
|
||||
cpu_tx_write <= 1'b1;
|
||||
end else begin
|
||||
cpu_rx_read <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
usb_ft1248 usb_ft1248_inst (
|
||||
.sys(sys),
|
||||
|
||||
.usb_enabled(usb_enabled),
|
||||
|
||||
.usb_clk(usb_clk),
|
||||
.usb_cs(usb_cs),
|
||||
.usb_miso(usb_miso),
|
||||
.usb_miosi(usb_miosi),
|
||||
|
||||
.rx_flush(rx_flush),
|
||||
.rx_empty(rx_empty),
|
||||
.rx_read(rx_read),
|
||||
.rx_rdata(rx_rdata),
|
||||
|
||||
.tx_flush(tx_flush),
|
||||
.tx_full(tx_full),
|
||||
.tx_write(tx_write),
|
||||
.tx_wdata(tx_wdata),
|
||||
|
||||
.rx_escape_valid(rx_escape_valid),
|
||||
.rx_escape_ack(rx_escape_ack),
|
||||
.rx_escape(rx_escape)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,49 +0,0 @@
|
||||
module cpu_wrapper (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus.cpu bus
|
||||
);
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAITING
|
||||
} e_bus_state;
|
||||
|
||||
e_bus_state state;
|
||||
|
||||
logic mem_la_read;
|
||||
logic mem_la_write;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.request <= 1'b0;
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
end else begin
|
||||
if (state == S_IDLE && (mem_la_read || mem_la_write)) begin
|
||||
state <= S_WAITING;
|
||||
bus.request <= 1'b1;
|
||||
end
|
||||
if (state == S_WAITING && bus.ack) begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
picorv32 #(
|
||||
.ENABLE_COUNTERS(0),
|
||||
.ENABLE_COUNTERS64(0),
|
||||
.CATCH_MISALIGN(0),
|
||||
.CATCH_ILLINSN(0),
|
||||
.PROGADDR_RESET(sc64::CPU_RESET_VECTOR)
|
||||
) cpu_inst (
|
||||
.clk(sys.clk),
|
||||
.resetn(~sys.reset),
|
||||
.mem_addr(bus.address),
|
||||
.mem_wdata(bus.wdata),
|
||||
.mem_wstrb(bus.wmask),
|
||||
.mem_ready(bus.ack),
|
||||
.mem_rdata(bus.rdata),
|
||||
.mem_la_read(mem_la_read),
|
||||
.mem_la_write(mem_la_write)
|
||||
);
|
||||
|
||||
endmodule
|
37
fw/rtl/fifo/fifo_bus.sv
Normal file
37
fw/rtl/fifo/fifo_bus.sv
Normal file
@ -0,0 +1,37 @@
|
||||
interface fifo_bus ();
|
||||
|
||||
logic rx_empty;
|
||||
logic rx_almost_empty;
|
||||
logic rx_read;
|
||||
logic [7:0] rx_rdata;
|
||||
|
||||
logic tx_full;
|
||||
logic tx_almost_full;
|
||||
logic tx_write;
|
||||
logic [7:0] tx_wdata;
|
||||
|
||||
modport controller (
|
||||
input rx_empty,
|
||||
input rx_almost_empty,
|
||||
output rx_read,
|
||||
input rx_rdata,
|
||||
|
||||
input tx_full,
|
||||
input tx_almost_full,
|
||||
output tx_write,
|
||||
output tx_wdata
|
||||
);
|
||||
|
||||
modport fifo (
|
||||
output rx_empty,
|
||||
output rx_almost_empty,
|
||||
input rx_read,
|
||||
output rx_rdata,
|
||||
|
||||
output tx_full,
|
||||
output tx_almost_full,
|
||||
input tx_write,
|
||||
input tx_wdata
|
||||
);
|
||||
|
||||
endinterface
|
26
fw/rtl/fifo/fifo_junction.sv
Normal file
26
fw/rtl/fifo/fifo_junction.sv
Normal file
@ -0,0 +1,26 @@
|
||||
module fifo_junction (
|
||||
fifo_bus.controller dev_bus,
|
||||
|
||||
fifo_bus.fifo cfg_bus,
|
||||
fifo_bus.fifo dma_bus
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
dev_bus.rx_read = cfg_bus.rx_read || dma_bus.rx_read;
|
||||
dev_bus.tx_write = cfg_bus.tx_write || dma_bus.tx_write;
|
||||
dev_bus.tx_wdata = cfg_bus.tx_write ? cfg_bus.tx_wdata : dma_bus.tx_wdata;
|
||||
|
||||
cfg_bus.rx_empty = dev_bus.rx_empty;
|
||||
cfg_bus.rx_almost_empty = dev_bus.rx_almost_empty;
|
||||
cfg_bus.rx_rdata = dev_bus.rx_rdata;
|
||||
cfg_bus.tx_full = dev_bus.tx_full;
|
||||
cfg_bus.tx_almost_full = dev_bus.tx_almost_full;
|
||||
|
||||
dma_bus.rx_empty = dev_bus.rx_empty;
|
||||
dma_bus.rx_almost_empty = dev_bus.rx_almost_empty;
|
||||
dma_bus.rx_rdata = dev_bus.rx_rdata;
|
||||
dma_bus.tx_full = dev_bus.tx_full;
|
||||
dma_bus.tx_almost_full = dev_bus.tx_almost_full;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,4 +0,0 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "FIFO"
|
||||
set_global_assignment -name IP_TOOL_VERSION "21.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "intel_fifo_8.v"]
|
@ -1,162 +0,0 @@
|
||||
// megafunction wizard: %FIFO%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: scfifo
|
||||
|
||||
// ============================================================
|
||||
// File Name: intel_fifo_8.v
|
||||
// Megafunction Name(s):
|
||||
// scfifo
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
//
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
//Your use of Intel Corporation's design tools, logic functions
|
||||
//and other software and tools, and any partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Intel Program License
|
||||
//Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
//the Intel FPGA IP License Agreement, or other applicable license
|
||||
//agreement, including, without limitation, that your use is for
|
||||
//the sole purpose of programming logic devices manufactured by
|
||||
//Intel and sold by Intel or its authorized distributors. Please
|
||||
//refer to the applicable agreement for further details, at
|
||||
//https://fpgasoftware.intel.com/eula.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module intel_fifo_8 (
|
||||
clock,
|
||||
data,
|
||||
rdreq,
|
||||
sclr,
|
||||
wrreq,
|
||||
empty,
|
||||
full,
|
||||
q);
|
||||
|
||||
input clock;
|
||||
input [7:0] data;
|
||||
input rdreq;
|
||||
input sclr;
|
||||
input wrreq;
|
||||
output empty;
|
||||
output full;
|
||||
output [7:0] q;
|
||||
|
||||
wire sub_wire0;
|
||||
wire sub_wire1;
|
||||
wire [7:0] sub_wire2;
|
||||
wire empty = sub_wire0;
|
||||
wire full = sub_wire1;
|
||||
wire [7:0] q = sub_wire2[7:0];
|
||||
|
||||
scfifo scfifo_component (
|
||||
.clock (clock),
|
||||
.data (data),
|
||||
.rdreq (rdreq),
|
||||
.sclr (sclr),
|
||||
.wrreq (wrreq),
|
||||
.empty (sub_wire0),
|
||||
.full (sub_wire1),
|
||||
.q (sub_wire2),
|
||||
.aclr (),
|
||||
.almost_empty (),
|
||||
.almost_full (),
|
||||
.eccstatus (),
|
||||
.usedw ());
|
||||
defparam
|
||||
scfifo_component.add_ram_output_register = "ON",
|
||||
scfifo_component.intended_device_family = "MAX 10",
|
||||
scfifo_component.lpm_numwords = 1024,
|
||||
scfifo_component.lpm_showahead = "ON",
|
||||
scfifo_component.lpm_type = "scfifo",
|
||||
scfifo_component.lpm_width = 8,
|
||||
scfifo_component.lpm_widthu = 10,
|
||||
scfifo_component.overflow_checking = "ON",
|
||||
scfifo_component.underflow_checking = "ON",
|
||||
scfifo_component.use_eab = "ON";
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
|
||||
// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
|
||||
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Depth NUMERIC "1024"
|
||||
// Retrieval info: PRIVATE: Empty NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: Full NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Optimize NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: UsedW NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Width NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: diff_widths NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: output_width NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: rsFull NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: sc_sclr NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: wsFull NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "ON"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"
|
||||
// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "10"
|
||||
// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
|
||||
// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
|
||||
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
|
||||
// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
|
||||
// Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty"
|
||||
// Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full"
|
||||
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
|
||||
// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
|
||||
// Retrieval info: USED_PORT: sclr 0 0 0 0 INPUT NODEFVAL "sclr"
|
||||
// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
|
||||
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
|
||||
// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
|
||||
// Retrieval info: CONNECT: @sclr 0 0 0 0 sclr 0 0 0 0
|
||||
// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
|
||||
// Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0
|
||||
// Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_fifo_8.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_fifo_8.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_fifo_8.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_fifo_8.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_fifo_8_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_fifo_8_bb.v FALSE
|
@ -1,90 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<system name="$${FILENAME}">
|
||||
<component
|
||||
name="$${FILENAME}"
|
||||
displayName="$${FILENAME}"
|
||||
version="1.0"
|
||||
description=""
|
||||
tags="INTERNAL_COMPONENT=true"
|
||||
categories="System" />
|
||||
<parameter name="bonusData"><![CDATA[bonusData
|
||||
{
|
||||
element onchip_flash_0
|
||||
{
|
||||
datum _sortIndex
|
||||
{
|
||||
value = "0";
|
||||
type = "int";
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></parameter>
|
||||
<parameter name="clockCrossingAdapter" value="HANDSHAKE" />
|
||||
<parameter name="device" value="10M08SCE144C8G" />
|
||||
<parameter name="deviceFamily" value="MAX 10" />
|
||||
<parameter name="deviceSpeedGrade" value="8" />
|
||||
<parameter name="fabricMode" value="QSYS" />
|
||||
<parameter name="generateLegacySim" value="false" />
|
||||
<parameter name="generationId" value="0" />
|
||||
<parameter name="globalResetBus" value="false" />
|
||||
<parameter name="hdlLanguage" value="VERILOG" />
|
||||
<parameter name="hideFromIPCatalog" value="true" />
|
||||
<parameter name="lockedInterfaceDefinition" value="" />
|
||||
<parameter name="maxAdditionalLatency" value="1" />
|
||||
<parameter name="projectName" value="" />
|
||||
<parameter name="sopcBorderPoints" value="false" />
|
||||
<parameter name="systemHash" value="0" />
|
||||
<parameter name="testBenchDutName" value="" />
|
||||
<parameter name="timeStamp" value="0" />
|
||||
<parameter name="useTestBenchNamingPattern" value="false" />
|
||||
<instanceScript></instanceScript>
|
||||
<interface name="clk" internal="onchip_flash_0.clk" type="clock" dir="end">
|
||||
<port name="clock" internal="clock" />
|
||||
</interface>
|
||||
<interface name="csr" internal="onchip_flash_0.csr" type="avalon" dir="end">
|
||||
<port name="avmm_csr_addr" internal="avmm_csr_addr" />
|
||||
<port name="avmm_csr_read" internal="avmm_csr_read" />
|
||||
<port name="avmm_csr_writedata" internal="avmm_csr_writedata" />
|
||||
<port name="avmm_csr_write" internal="avmm_csr_write" />
|
||||
<port name="avmm_csr_readdata" internal="avmm_csr_readdata" />
|
||||
</interface>
|
||||
<interface name="data" internal="onchip_flash_0.data" type="avalon" dir="end">
|
||||
<port name="avmm_data_addr" internal="avmm_data_addr" />
|
||||
<port name="avmm_data_read" internal="avmm_data_read" />
|
||||
<port name="avmm_data_writedata" internal="avmm_data_writedata" />
|
||||
<port name="avmm_data_write" internal="avmm_data_write" />
|
||||
<port name="avmm_data_readdata" internal="avmm_data_readdata" />
|
||||
<port name="avmm_data_waitrequest" internal="avmm_data_waitrequest" />
|
||||
<port name="avmm_data_readdatavalid" internal="avmm_data_readdatavalid" />
|
||||
<port name="avmm_data_burstcount" internal="avmm_data_burstcount" />
|
||||
</interface>
|
||||
<interface name="nreset" internal="onchip_flash_0.nreset" type="reset" dir="end">
|
||||
<port name="reset_n" internal="reset_n" />
|
||||
</interface>
|
||||
<module
|
||||
name="onchip_flash_0"
|
||||
kind="altera_onchip_flash"
|
||||
version="21.1"
|
||||
enabled="1"
|
||||
autoexport="1">
|
||||
<parameter name="AUTO_CLOCK_RATE" value="0" />
|
||||
<parameter name="CLOCK_FREQUENCY" value="100.0" />
|
||||
<parameter name="CONFIGURATION_MODE">Single Compressed Image</parameter>
|
||||
<parameter name="CONFIGURATION_SCHEME">Internal Configuration</parameter>
|
||||
<parameter name="DATA_INTERFACE" value="Parallel" />
|
||||
<parameter name="DEVICE_FAMILY" value="MAX 10" />
|
||||
<parameter name="PART_NAME" value="10M08SCE144C8G" />
|
||||
<parameter name="READ_BURST_COUNT" value="2" />
|
||||
<parameter name="READ_BURST_MODE" value="Incrementing" />
|
||||
<parameter name="SECTOR_ACCESS_MODE">Read and write,Read and write,Hidden,Read and write,Read and write</parameter>
|
||||
<parameter name="autoInitializationFileName">$${FILENAME}_onchip_flash_0</parameter>
|
||||
<parameter name="initFlashContent" value="false" />
|
||||
<parameter name="initializationFileName"></parameter>
|
||||
<parameter name="initializationFileNameForSim"></parameter>
|
||||
<parameter name="useNonDefaultInitFile" value="false" />
|
||||
</module>
|
||||
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
|
||||
<interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" />
|
||||
<interconnectRequirement for="$system" name="qsys_mm.insertDefaultSlave" value="FALSE" />
|
||||
<interconnectRequirement for="$system" name="qsys_mm.maxAdditionalLatency" value="1" />
|
||||
</system>
|
@ -1,77 +0,0 @@
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TOOL_NAME "altera_gpio_lite"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TOOL_VERSION "21.1"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TOOL_ENV "mwpim"
|
||||
set_global_assignment -library "intel_gpio_ddro" -name MISC_FILE [file join $::quartus(qip_path) "intel_gpio_ddro.cmp"]
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_TARGETED_DEVICE_FAMILY "MAX 10"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_QSYS_MODE "UNKNOWN"
|
||||
set_global_assignment -name SYNTHESIS_ONLY_QIP ON
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_NAME "aW50ZWxfZ3Bpb19kZHJv"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_DISPLAY_NAME "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_REPORT_HIERARCHY "Off"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_INTERNAL "Off"
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24="
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_VERSION "MjEuMQ=="
|
||||
set_global_assignment -entity "intel_gpio_ddro" -library "intel_gpio_ddro" -name IP_COMPONENT_DESCRIPTION "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_NAME "YWx0ZXJhX2dwaW9fbGl0ZQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_DISPLAY_NAME "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_REPORT_HIERARCHY "Off"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_INTERNAL "Off"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_VERSION "MjEuMQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_DESCRIPTION "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "REVWSUNFX0ZBTUlMWQ==::TUFYIDEw::RGV2aWNlIGZhbWlseQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "UElOX1RZUEU=::b3V0cHV0::RGF0YSBkaXJlY3Rpb24="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "U0laRQ==::MQ==::RGF0YSB3aWR0aA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3RydWVfZGlmZl9idWY=::ZmFsc2U=::VXNlIHRydWUgZGlmZmVyZW50aWFsIGJ1ZmZlcg=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3BzZXVkb19kaWZmX2J1Zg==::ZmFsc2U=::VXNlIHBzZXVkbyBkaWZmZXJlbnRpYWwgYnVmZmVy"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2J1c19ob2xk::ZmFsc2U=::VXNlIGJ1cy1ob2xkIGNpcmN1aXRyeQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX29wZW5fZHJhaW4=::ZmFsc2U=::VXNlIG9wZW4gZHJhaW4gb3V0cHV0"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9vZV9wb3J0::ZmFsc2U=::RW5hYmxlIG9lIHBvcnQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2lvX3JlZ19tb2Rl::ZGRy::UmVnaXN0ZXIgbW9kZQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9hY2xyX3BvcnQ=::ZmFsc2U=::RW5hYmxlIGFjbHIgcG9ydA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9hc2V0X3BvcnQ=::ZmFsc2U=::RW5hYmxlIGFzZXQgcG9ydA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9zY2xyX3BvcnQ=::ZmFsc2U=::RW5hYmxlIHNjbHIgcG9ydA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3NldF9yZWdpc3RlcnNfdG9fcG93ZXJfdXBfaGlnaA==::ZmFsc2U=::U2V0IHJlZ2lzdGVycyB0byBwb3dlciB1cCBoaWdoICh3aGVuIGFjbHIsIHNjbHIgYW5kIGFzZXQgcG9ydHMgYXJlIG5vdCB1c2VkKQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2Nsb2NrX2VuYWJsZQ==::ZmFsc2U=::RW5hYmxlIGluY2xvY2tlbi9vdXRjbG9ja2VuIHBvcnRz"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vdXRwdXQ=::ZmFsc2U=::SW52ZXJ0IGRpbg=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9yZWdpc3Rlcl90b19kcml2ZV9vYnVmX29l::ZmFsc2U=::VXNlIGEgc2luZ2xlIHJlZ2lzdGVyIHRvIGRyaXZlIHRoZSBvdXRwdXQgZW5hYmxlIChvZSkgc2lnbmFsIGF0IHRoZSBJL08gYnVmZmVy"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9kZGlvX3JlZ190b19kcml2ZV9vZQ==::ZmFsc2U=::VXNlIERESU8gcmVnaXN0ZXJzIHRvIGRyaXZlIHRoZSBvdXRwdXQgZW5hYmxlIChvZSkgc2lnbmFsIGF0IHRoZSBJL08gYnVmZmVy"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9hZHZhbmNlZF9kZHJfZmVhdHVyZXM=::ZmFsc2U=::RW5hYmxlIGFkdmFuY2VkIEREUiBmZWF0dXJlcw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9waGFzZV9kZXRlY3Rvcl9mb3JfY2s=::ZmFsc2U=::RW5hYmxlIFBoYXNlIERldGVjdG9yIGZyb20gQ0sgbG9vcGJhY2sgc2lnbmFs"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9vZV9oYWxmX2N5Y2xlX2RlbGF5::dHJ1ZQ==::QWRkIGhhbGYtY3ljbGUgZGVsYXkgdG8gT0Ugc2lnbmFs"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9ocl9jbG9jaw==::ZmFsc2U=::RW5hYmxlIGhhbGYtcmF0ZSBjbG9jayBwb3J0"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9pbnZlcnRfaHJfY2xvY2tfcG9ydA==::ZmFsc2U=::RW5hYmxlIGludmVydF9ocl9jbG9jayBwb3J0"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9jbGtkaXZfaW5wdXRfY2xvY2s=::ZmFsc2U=::SW52ZXJ0IGNsb2NrIGRpdmlkZXIgaW5wdXQgY2xvY2s="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vdXRwdXRfY2xvY2s=::ZmFsc2U=::SW52ZXJ0IERESU8gb3V0Y2xvY2s="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vZV9pbmNsb2Nr::ZmFsc2U=::SW52ZXJ0IG91dHB1dCBlbmFibGUgKG9lKSByZWdpc3RlciBpbmNsb2Nr"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "UkVHSVNURVJfTU9ERQ==::ZGRy::UkVHSVNURVJfTU9ERQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "QlVGRkVSX1RZUEU=::c2luZ2xlLWVuZGVk::QlVGRkVSX1RZUEU="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "QVNZTkNfTU9ERQ==::bm9uZQ==::QVNZTkNfTU9ERQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "U1lOQ19NT0RF::bm9uZQ==::U1lOQ19NT0RF"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "QlVTX0hPTEQ=::ZmFsc2U=::QlVTX0hPTEQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "T1BFTl9EUkFJTl9PVVRQVVQ=::ZmFsc2U=::T1BFTl9EUkFJTl9PVVRQVVQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX09FX1BPUlQ=::ZmFsc2U=::RU5BQkxFX09FX1BPUlQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX05TTEVFUF9QT1JU::ZmFsc2U=::RU5BQkxFX05TTEVFUF9QT1JU"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0NMT0NLX0VOQV9QT1JU::ZmFsc2U=::RU5BQkxFX0NMT0NLX0VOQV9QT1JU"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "U0VUX1JFR0lTVEVSX09VVFBVVFNfSElHSA==::ZmFsc2U=::U0VUX1JFR0lTVEVSX09VVFBVVFNfSElHSA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09VVFBVVA==::ZmFsc2U=::SU5WRVJUX09VVFBVVA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX0lOUFVUX0NMT0NL::ZmFsc2U=::SU5WRVJUX0lOUFVUX0NMT0NL"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX09ORV9SRUdfVE9fRFJJVkVfT0U=::ZmFsc2U=::VVNFX09ORV9SRUdfVE9fRFJJVkVfT0U="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0RESU9fUkVHX1RPX0RSSVZFX09F::ZmFsc2U=::VVNFX0RESU9fUkVHX1RPX0RSSVZFX09F"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFUw==::ZmFsc2U=::VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFUw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFU19GT1JfSU5QVVRfT05MWQ==::ZmFsc2U=::VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFU19GT1JfSU5QVVRfT05MWQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX09FX0hBTEZfQ1lDTEVfREVMQVk=::dHJ1ZQ==::RU5BQkxFX09FX0hBTEZfQ1lDTEVfREVMQVk="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX0NMS0RJVl9JTlBVVF9DTE9DSw==::ZmFsc2U=::SU5WRVJUX0NMS0RJVl9JTlBVVF9DTE9DSw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX1BIQVNFX0lOVkVSVF9DVFJMX1BPUlQ=::ZmFsc2U=::RU5BQkxFX1BIQVNFX0lOVkVSVF9DVFJMX1BPUlQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0hSX0NMT0NL::ZmFsc2U=::RU5BQkxFX0hSX0NMT0NL"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09VVFBVVF9DTE9DSw==::ZmFsc2U=::SU5WRVJUX09VVFBVVF9DTE9DSw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09FX0lOQ0xPQ0s=::ZmFsc2U=::SU5WRVJUX09FX0lOQ0xPQ0s="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX1BIQVNFX0RFVEVDVE9SX0ZPUl9DSw==::ZmFsc2U=::RU5BQkxFX1BIQVNFX0RFVEVDVE9SX0ZPUl9DSw=="
|
||||
|
||||
set_global_assignment -library "intel_gpio_ddro" -name VERILOG_FILE [file join $::quartus(qip_path) "intel_gpio_ddro.v"]
|
||||
set_global_assignment -library "intel_gpio_ddro" -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "intel_gpio_ddro/altera_gpio_lite.sv"]
|
||||
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_NAME "altera_gpio_lite"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_VERSION "21.1"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_ENV "mwpim"
|
@ -1,123 +0,0 @@
|
||||
// megafunction wizard: %GPIO Lite Intel FPGA IP v21.1%
|
||||
// GENERATION: XML
|
||||
// intel_gpio_ddro.v
|
||||
|
||||
// Generated using ACDS version 21.1 842
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
module intel_gpio_ddro (
|
||||
input wire outclock, // outclock.export
|
||||
input wire [1:0] din, // din.export
|
||||
output wire [0:0] pad_out // pad_out.export
|
||||
);
|
||||
|
||||
altera_gpio_lite #(
|
||||
.PIN_TYPE ("output"),
|
||||
.SIZE (1),
|
||||
.REGISTER_MODE ("ddr"),
|
||||
.BUFFER_TYPE ("single-ended"),
|
||||
.ASYNC_MODE ("none"),
|
||||
.SYNC_MODE ("none"),
|
||||
.BUS_HOLD ("false"),
|
||||
.OPEN_DRAIN_OUTPUT ("false"),
|
||||
.ENABLE_OE_PORT ("false"),
|
||||
.ENABLE_NSLEEP_PORT ("false"),
|
||||
.ENABLE_CLOCK_ENA_PORT ("false"),
|
||||
.SET_REGISTER_OUTPUTS_HIGH ("false"),
|
||||
.INVERT_OUTPUT ("false"),
|
||||
.INVERT_INPUT_CLOCK ("false"),
|
||||
.USE_ONE_REG_TO_DRIVE_OE ("false"),
|
||||
.USE_DDIO_REG_TO_DRIVE_OE ("false"),
|
||||
.USE_ADVANCED_DDR_FEATURES ("false"),
|
||||
.USE_ADVANCED_DDR_FEATURES_FOR_INPUT_ONLY ("false"),
|
||||
.ENABLE_OE_HALF_CYCLE_DELAY ("true"),
|
||||
.INVERT_CLKDIV_INPUT_CLOCK ("false"),
|
||||
.ENABLE_PHASE_INVERT_CTRL_PORT ("false"),
|
||||
.ENABLE_HR_CLOCK ("false"),
|
||||
.INVERT_OUTPUT_CLOCK ("false"),
|
||||
.INVERT_OE_INCLOCK ("false"),
|
||||
.ENABLE_PHASE_DETECTOR_FOR_CK ("false")
|
||||
) intel_gpio_ddro_inst (
|
||||
.outclock (outclock), // outclock.export
|
||||
.din (din), // din.export
|
||||
.pad_out (pad_out), // pad_out.export
|
||||
.outclocken (1'b1), // (terminated)
|
||||
.inclock (1'b0), // (terminated)
|
||||
.inclocken (1'b0), // (terminated)
|
||||
.fr_clock (), // (terminated)
|
||||
.hr_clock (), // (terminated)
|
||||
.invert_hr_clock (1'b0), // (terminated)
|
||||
.phy_mem_clock (1'b0), // (terminated)
|
||||
.mimic_clock (), // (terminated)
|
||||
.dout (), // (terminated)
|
||||
.pad_io (), // (terminated)
|
||||
.pad_io_b (), // (terminated)
|
||||
.pad_in (1'b0), // (terminated)
|
||||
.pad_in_b (1'b0), // (terminated)
|
||||
.pad_out_b (), // (terminated)
|
||||
.aset (1'b0), // (terminated)
|
||||
.aclr (1'b0), // (terminated)
|
||||
.sclr (1'b0), // (terminated)
|
||||
.nsleep (1'b0), // (terminated)
|
||||
.oe (1'b0) // (terminated)
|
||||
);
|
||||
|
||||
endmodule
|
||||
// Retrieval info: <?xml version="1.0"?>
|
||||
//<!--
|
||||
// Generated by Altera MegaWizard Launcher Utility version 1.0
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
// ************************************************************
|
||||
// Copyright (C) 1991-2021 Altera Corporation
|
||||
// Any megafunction design, and related net list (encrypted or decrypted),
|
||||
// support information, device programming or simulation file, and any other
|
||||
// associated documentation or information provided by Altera or a partner
|
||||
// under Altera's Megafunction Partnership Program may be used only to
|
||||
// program PLD devices (but not masked PLD devices) from Altera. Any other
|
||||
// use of such megafunction design, net list, support information, device
|
||||
// programming or simulation file, or any other related documentation or
|
||||
// information is prohibited for any other purpose, including, but not
|
||||
// limited to modification, reverse engineering, de-compiling, or use with
|
||||
// any other silicon devices, unless such use is explicitly licensed under
|
||||
// a separate agreement with Altera or a megafunction partner. Title to
|
||||
// the intellectual property, including patents, copyrights, trademarks,
|
||||
// trade secrets, or maskworks, embodied in any such megafunction design,
|
||||
// net list, support information, device programming or simulation file, or
|
||||
// any other related documentation or information provided by Altera or a
|
||||
// megafunction partner, remains with Altera, the megafunction partner, or
|
||||
// their respective licensors. No other licenses, including any licenses
|
||||
// needed under any third party's intellectual property, are provided herein.
|
||||
//-->
|
||||
// Retrieval info: <instance entity-name="altera_gpio_lite" version="21.1" >
|
||||
// Retrieval info: <generic name="DEVICE_FAMILY" value="MAX 10" />
|
||||
// Retrieval info: <generic name="PIN_TYPE" value="output" />
|
||||
// Retrieval info: <generic name="SIZE" value="1" />
|
||||
// Retrieval info: <generic name="gui_true_diff_buf" value="false" />
|
||||
// Retrieval info: <generic name="gui_pseudo_diff_buf" value="false" />
|
||||
// Retrieval info: <generic name="gui_bus_hold" value="false" />
|
||||
// Retrieval info: <generic name="gui_open_drain" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_oe_port" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_nsleep_port" value="false" />
|
||||
// Retrieval info: <generic name="gui_io_reg_mode" value="ddr" />
|
||||
// Retrieval info: <generic name="gui_enable_aclr_port" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_aset_port" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_sclr_port" value="false" />
|
||||
// Retrieval info: <generic name="gui_set_registers_to_power_up_high" value="false" />
|
||||
// Retrieval info: <generic name="gui_clock_enable" value="false" />
|
||||
// Retrieval info: <generic name="gui_invert_output" value="false" />
|
||||
// Retrieval info: <generic name="gui_invert_input_clock" value="false" />
|
||||
// Retrieval info: <generic name="gui_use_register_to_drive_obuf_oe" value="false" />
|
||||
// Retrieval info: <generic name="gui_use_ddio_reg_to_drive_oe" value="false" />
|
||||
// Retrieval info: <generic name="gui_use_advanced_ddr_features" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_phase_detector_for_ck" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_oe_half_cycle_delay" value="true" />
|
||||
// Retrieval info: <generic name="gui_enable_hr_clock" value="false" />
|
||||
// Retrieval info: <generic name="gui_enable_invert_hr_clock_port" value="false" />
|
||||
// Retrieval info: <generic name="gui_invert_clkdiv_input_clock" value="false" />
|
||||
// Retrieval info: <generic name="gui_invert_output_clock" value="false" />
|
||||
// Retrieval info: <generic name="gui_invert_oe_inclock" value="false" />
|
||||
// Retrieval info: <generic name="gui_use_hardened_ddio_input_registers" value="false" />
|
||||
// Retrieval info: </instance>
|
||||
// IPFS_FILES : intel_gpio_ddro.vo
|
||||
// RELATED_FILES: intel_gpio_ddro.v, altera_gpio_lite.sv
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE pinplan>
|
||||
<pinplan intended_family="MAX 10" variation_name="intel_pll" megafunction_name="ALTPLL" specifies="all_ports">
|
||||
<global>
|
||||
<pin name="inclk0" direction="input" scope="external" source="clock" />
|
||||
<pin name="c0" direction="output" scope="external" source="clock" />
|
||||
<pin name="c1" direction="output" scope="external" source="clock" />
|
||||
<pin name="locked" direction="output" scope="external" />
|
||||
|
||||
</global>
|
||||
</pinplan>
|
@ -1,5 +0,0 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "21.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "intel_pll.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "intel_pll.ppf"]
|
@ -1,340 +0,0 @@
|
||||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: intel_pll.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
//
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
//Your use of Intel Corporation's design tools, logic functions
|
||||
//and other software and tools, and any partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Intel Program License
|
||||
//Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
//the Intel FPGA IP License Agreement, or other applicable license
|
||||
//agreement, including, without limitation, that your use is for
|
||||
//the sole purpose of programming logic devices manufactured by
|
||||
//Intel and sold by Intel or its authorized distributors. Please
|
||||
//refer to the applicable agreement for further details, at
|
||||
//https://fpgasoftware.intel.com/eula.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module intel_pll (
|
||||
inclk0,
|
||||
c0,
|
||||
c1,
|
||||
locked);
|
||||
|
||||
input inclk0;
|
||||
output c0;
|
||||
output c1;
|
||||
output locked;
|
||||
|
||||
wire [0:0] sub_wire2 = 1'h0;
|
||||
wire [4:0] sub_wire3;
|
||||
wire sub_wire6;
|
||||
wire sub_wire0 = inclk0;
|
||||
wire [1:0] sub_wire1 = {sub_wire2, sub_wire0};
|
||||
wire [1:1] sub_wire5 = sub_wire3[1:1];
|
||||
wire [0:0] sub_wire4 = sub_wire3[0:0];
|
||||
wire c0 = sub_wire4;
|
||||
wire c1 = sub_wire5;
|
||||
wire locked = sub_wire6;
|
||||
|
||||
altpll altpll_component (
|
||||
.inclk (sub_wire1),
|
||||
.clk (sub_wire3),
|
||||
.locked (sub_wire6),
|
||||
.activeclock (),
|
||||
.areset (1'b0),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "AUTO",
|
||||
altpll_component.clk0_divide_by = 1,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 2,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.clk1_divide_by = 1,
|
||||
altpll_component.clk1_duty_cycle = 50,
|
||||
altpll_component.clk1_multiply_by = 2,
|
||||
altpll_component.clk1_phase_shift = "-1500",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 20000,
|
||||
altpll_component.intended_device_family = "MAX 10",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=intel_pll",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "NORMAL",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_USED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "ON",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "100.000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "100.000000"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "100.00000000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "-54.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "intel_pll.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "1"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK2 STRING "0"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK3 STRING "0"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK4 STRING "0"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "2"
|
||||
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "-1500"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "ON"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL intel_pll_bb.v FALSE
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
92
fw/rtl/mcu/mcu_spi.sv
Normal file
92
fw/rtl/mcu/mcu_spi.sv
Normal file
@ -0,0 +1,92 @@
|
||||
module mcu_spi (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
output logic frame_start,
|
||||
output logic data_ready,
|
||||
output logic [7:0] rx_data,
|
||||
input [7:0] tx_data,
|
||||
|
||||
input mcu_clk,
|
||||
input mcu_cs,
|
||||
input mcu_mosi,
|
||||
output logic mcu_miso
|
||||
);
|
||||
|
||||
logic [2:0] mcu_clk_ff;
|
||||
logic [2:0] mcu_cs_ff;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
mcu_clk_ff <= {mcu_clk_ff[1:0], mcu_clk};
|
||||
mcu_cs_ff <= {mcu_cs_ff[1:0], mcu_cs};
|
||||
end
|
||||
|
||||
logic mcu_clk_falling;
|
||||
logic mcu_clk_rising;
|
||||
logic mcu_cs_falling;
|
||||
logic mcu_cs_rising;
|
||||
|
||||
always_comb begin
|
||||
mcu_clk_falling = mcu_clk_ff[2] && !mcu_clk_ff[1];
|
||||
mcu_clk_rising = !mcu_clk_ff[2] && mcu_clk_ff[1];
|
||||
mcu_cs_falling = mcu_cs_ff[2] && !mcu_cs_ff[1];
|
||||
mcu_cs_rising = !mcu_cs_ff[2] && mcu_cs_ff[1];
|
||||
end
|
||||
|
||||
logic mcu_dq_in;
|
||||
logic mcu_dq_out;
|
||||
logic mcu_miso_out;
|
||||
|
||||
assign mcu_miso = mcu_cs_ff[1] ? 1'bZ : mcu_miso_out;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
mcu_dq_in <= mcu_mosi;
|
||||
mcu_miso_out <= mcu_dq_out;
|
||||
end
|
||||
|
||||
logic [7:0] spi_tx_shift;
|
||||
|
||||
assign mcu_dq_out = spi_tx_shift[7];
|
||||
|
||||
logic spi_enabled;
|
||||
logic [2:0] spi_bit_counter;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
frame_start <= 1'b0;
|
||||
data_ready <= 1'b0;
|
||||
|
||||
if (reset) begin
|
||||
spi_enabled <= 1'b0;
|
||||
spi_bit_counter <= 3'd0;
|
||||
end else begin
|
||||
if (mcu_cs_falling) begin
|
||||
spi_enabled <= 1'b1;
|
||||
spi_bit_counter <= 3'd0;
|
||||
frame_start <= 1'b1;
|
||||
end
|
||||
|
||||
if (mcu_cs_rising) begin
|
||||
spi_enabled <= 1'b0;
|
||||
end
|
||||
|
||||
if (spi_enabled) begin
|
||||
if (mcu_clk_rising) begin
|
||||
if (spi_bit_counter == 3'd0) begin
|
||||
spi_tx_shift <= tx_data;
|
||||
end else begin
|
||||
spi_tx_shift <= {spi_tx_shift[6:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
if (mcu_clk_falling) begin
|
||||
spi_bit_counter <= spi_bit_counter + 1'd1;
|
||||
rx_data <= {rx_data[6:0], mcu_dq_in};
|
||||
if (spi_bit_counter == 3'd7) begin
|
||||
data_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
901
fw/rtl/mcu/mcu_top.sv
Normal file
901
fw/rtl/mcu/mcu_top.sv
Normal file
@ -0,0 +1,901 @@
|
||||
module mcu_top (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_scb.controller n64_scb,
|
||||
dd_scb.controller dd_scb,
|
||||
usb_scb.controller usb_scb,
|
||||
dma_scb.controller usb_dma_scb,
|
||||
sd_scb.controller sd_scb,
|
||||
dma_scb.controller sd_dma_scb,
|
||||
flash_scb.controller flash_scb,
|
||||
vendor_scb.controller vendor_scb,
|
||||
|
||||
fifo_bus.controller fifo_bus,
|
||||
mem_bus.controller mem_bus,
|
||||
|
||||
input sd_det,
|
||||
input button,
|
||||
|
||||
output logic mcu_int,
|
||||
input mcu_clk,
|
||||
input mcu_cs,
|
||||
input mcu_mosi,
|
||||
output mcu_miso
|
||||
);
|
||||
|
||||
// Button input synchronization
|
||||
|
||||
logic [2:0] sd_det_ff;
|
||||
logic [2:0] button_ff;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
sd_det_ff <= {sd_det_ff[1:0], sd_det};
|
||||
button_ff <= {button_ff[1:0], button};
|
||||
end
|
||||
|
||||
|
||||
// MCU <-> FPGA transport
|
||||
|
||||
logic frame_start;
|
||||
logic data_ready;
|
||||
logic [7:0] rdata;
|
||||
logic [7:0] wdata;
|
||||
|
||||
mcu_spi mcu_spi_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.frame_start(frame_start),
|
||||
.data_ready(data_ready),
|
||||
.rx_data(rdata),
|
||||
.tx_data(wdata),
|
||||
|
||||
.mcu_clk(mcu_clk),
|
||||
.mcu_cs(mcu_cs),
|
||||
.mcu_mosi(mcu_mosi),
|
||||
.mcu_miso(mcu_miso)
|
||||
);
|
||||
|
||||
|
||||
// Protocol controller
|
||||
|
||||
const bit [7:0] FPGA_ID = 8'h64;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
PHASE_CMD,
|
||||
PHASE_ADDRESS,
|
||||
PHASE_DATA,
|
||||
PHASE_NOP
|
||||
} phase_e;
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
CMD_IDENTIFY,
|
||||
CMD_REG_READ,
|
||||
CMD_REG_WRITE,
|
||||
CMD_MEM_READ,
|
||||
CMD_MEM_WRITE,
|
||||
CMD_USB_STATUS,
|
||||
CMD_USB_READ,
|
||||
CMD_USB_WRITE
|
||||
} cmd_e;
|
||||
|
||||
phase_e phase;
|
||||
cmd_e cmd;
|
||||
|
||||
logic [1:0] counter;
|
||||
logic [7:0] address;
|
||||
|
||||
logic reg_read;
|
||||
logic reg_write;
|
||||
logic [31:0] reg_rdata;
|
||||
logic [31:0] reg_wdata;
|
||||
|
||||
logic mem_read;
|
||||
logic mem_write;
|
||||
logic [15:0] mem_rdata;
|
||||
logic [15:0] mem_wdata;
|
||||
logic mem_word_select;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
fifo_bus.rx_read <= 1'b0;
|
||||
fifo_bus.tx_write <= 1'b0;
|
||||
|
||||
reg_read <= 1'b0;
|
||||
reg_write <= 1'b0;
|
||||
|
||||
mem_read <= 1'b0;
|
||||
mem_write <= 1'b0;
|
||||
|
||||
if (reset) begin
|
||||
end else begin
|
||||
if (frame_start) begin
|
||||
counter <= 2'd0;
|
||||
phase <= PHASE_CMD;
|
||||
end
|
||||
|
||||
if (reg_read || reg_write || (mem_word_select && (mem_read || mem_write))) begin
|
||||
address <= address + 1'd1;
|
||||
end
|
||||
|
||||
if (data_ready) begin
|
||||
case (phase)
|
||||
PHASE_CMD: begin
|
||||
cmd <= cmd_e'(rdata);
|
||||
phase <= PHASE_ADDRESS;
|
||||
|
||||
if (rdata == CMD_USB_STATUS) begin
|
||||
phase <= PHASE_NOP;
|
||||
end
|
||||
|
||||
if (rdata == CMD_USB_READ) begin
|
||||
fifo_bus.rx_read <= 1'b1;
|
||||
phase <= PHASE_DATA;
|
||||
end
|
||||
|
||||
if (rdata == CMD_USB_WRITE) begin
|
||||
phase <= PHASE_DATA;
|
||||
end
|
||||
end
|
||||
|
||||
PHASE_ADDRESS: begin
|
||||
address <= rdata;
|
||||
phase <= PHASE_DATA;
|
||||
|
||||
if (cmd == CMD_REG_READ) begin
|
||||
reg_read <= 1'b1;
|
||||
end
|
||||
|
||||
if (cmd == CMD_MEM_READ) begin
|
||||
mem_read <= 1'b1;
|
||||
mem_word_select <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
PHASE_DATA: begin
|
||||
counter <= counter + 1'd1;
|
||||
|
||||
if (cmd == CMD_REG_READ) begin
|
||||
if (counter == 2'd3) begin
|
||||
reg_read <= 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
if (cmd == CMD_REG_WRITE) begin
|
||||
case (counter)
|
||||
2'd0: reg_wdata[7:0] <= rdata;
|
||||
2'd1: reg_wdata[15:8] <= rdata;
|
||||
2'd2: reg_wdata[23:16] <= rdata;
|
||||
2'd3: reg_wdata[31:24] <= rdata;
|
||||
endcase
|
||||
if (counter == 2'd3) begin
|
||||
reg_write <= 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
if (cmd == CMD_MEM_READ) begin
|
||||
if (counter[0]) begin
|
||||
mem_read <= 1'b1;
|
||||
mem_word_select <= ~mem_word_select;
|
||||
end
|
||||
end
|
||||
|
||||
if (cmd == CMD_MEM_WRITE) begin
|
||||
case (counter[0])
|
||||
1'd0: mem_wdata[15:8] <= rdata;
|
||||
1'd1: mem_wdata[7:0] <= rdata;
|
||||
endcase
|
||||
if (counter[0]) begin
|
||||
mem_write <= 1'b1;
|
||||
mem_word_select <= counter[1];
|
||||
end
|
||||
end
|
||||
|
||||
if (cmd == CMD_USB_READ) begin
|
||||
phase <= PHASE_NOP;
|
||||
end
|
||||
|
||||
if (cmd == CMD_USB_WRITE) begin
|
||||
fifo_bus.tx_write <= 1'b1;
|
||||
fifo_bus.tx_wdata <= rdata;
|
||||
phase <= PHASE_NOP;
|
||||
end
|
||||
end
|
||||
|
||||
PHASE_NOP: begin end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
wdata = 8'h00;
|
||||
|
||||
case (cmd)
|
||||
CMD_IDENTIFY: begin
|
||||
wdata = FPGA_ID;
|
||||
end
|
||||
|
||||
CMD_REG_READ: begin
|
||||
case (counter)
|
||||
2'd0: wdata = reg_rdata[7:0];
|
||||
2'd1: wdata = reg_rdata[15:8];
|
||||
2'd2: wdata = reg_rdata[23:16];
|
||||
2'd3: wdata = reg_rdata[31:24];
|
||||
endcase
|
||||
end
|
||||
|
||||
CMD_REG_WRITE: begin
|
||||
wdata = 8'h00;
|
||||
end
|
||||
|
||||
CMD_MEM_READ: begin
|
||||
case (counter[0])
|
||||
1'd0: wdata = mem_rdata[15:8];
|
||||
1'd1: wdata = mem_rdata[7:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
CMD_MEM_WRITE: begin
|
||||
wdata = 8'h00;
|
||||
end
|
||||
|
||||
CMD_USB_STATUS: begin
|
||||
wdata = {6'd0, ~fifo_bus.tx_full, ~fifo_bus.rx_empty};
|
||||
end
|
||||
|
||||
CMD_USB_READ: begin
|
||||
wdata = fifo_bus.rx_rdata;
|
||||
end
|
||||
|
||||
CMD_USB_WRITE: begin
|
||||
wdata = 8'h00;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Mem bus controller
|
||||
|
||||
logic [15:0] mem_buffer [0:511];
|
||||
|
||||
logic mem_start;
|
||||
logic mem_stop;
|
||||
logic mem_direction;
|
||||
logic [8:0] mem_length;
|
||||
logic [31:0] mem_address;
|
||||
|
||||
logic mem_busy;
|
||||
logic mem_stop_pending;
|
||||
logic [8:0] mem_counter;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
mem_busy <= 1'b0;
|
||||
mem_stop_pending <= 1'b0;
|
||||
mem_bus.request <= 1'b0;
|
||||
end else begin
|
||||
if (mem_read) begin
|
||||
mem_rdata <= mem_buffer[{address, mem_word_select}];
|
||||
end
|
||||
|
||||
if (mem_write) begin
|
||||
mem_buffer[{address, mem_word_select}] <= mem_wdata;
|
||||
end
|
||||
|
||||
if (mem_stop) begin
|
||||
mem_stop_pending <= mem_busy;
|
||||
end else if (mem_start && !mem_busy) begin
|
||||
mem_bus.write <= mem_direction;
|
||||
mem_bus.address <= mem_address;
|
||||
mem_busy <= 1'b1;
|
||||
mem_counter <= 9'd0;
|
||||
end
|
||||
|
||||
if (mem_busy) begin
|
||||
if (!mem_bus.request) begin
|
||||
mem_bus.request <= 1'b1;
|
||||
mem_bus.wdata <= mem_buffer[mem_counter];
|
||||
end
|
||||
|
||||
if (mem_bus.ack) begin
|
||||
mem_bus.request <= 1'b0;
|
||||
mem_bus.address <= mem_bus.address + 2'd2;
|
||||
mem_counter <= mem_counter + 1'd1;
|
||||
if (!mem_bus.write) begin
|
||||
mem_buffer[mem_counter] <= mem_bus.rdata;
|
||||
end
|
||||
if ((mem_counter == mem_length) || mem_stop_pending) begin
|
||||
mem_busy <= 1'b0;
|
||||
mem_stop_pending <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
mem_bus.wmask = 2'b11;
|
||||
end
|
||||
|
||||
|
||||
// Register list
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
REG_MEM_ADDRESS,
|
||||
REG_MEM_SCR,
|
||||
REG_USB_SCR,
|
||||
REG_USB_DMA_ADDRESS,
|
||||
REG_USB_DMA_LENGTH,
|
||||
REG_USB_DMA_SCR,
|
||||
REG_CFG_SCR,
|
||||
REG_CFG_DATA_0,
|
||||
REG_CFG_DATA_1,
|
||||
REG_CFG_CMD,
|
||||
REG_CFG_VERSION,
|
||||
REG_FLASHRAM_SCR,
|
||||
REG_FLASH_SCR,
|
||||
REG_RTC_SCR,
|
||||
REG_RTC_TIME_0,
|
||||
REG_RTC_TIME_1,
|
||||
REG_SD_SCR,
|
||||
REG_SD_ARG,
|
||||
REG_SD_CMD,
|
||||
REG_SD_RSP_0,
|
||||
REG_SD_RSP_1,
|
||||
REG_SD_RSP_2,
|
||||
REG_SD_RSP_3,
|
||||
REG_SD_DAT,
|
||||
REG_SD_DMA_ADDRESS,
|
||||
REG_SD_DMA_LENGTH,
|
||||
REG_SD_DMA_SCR,
|
||||
REG_DD_SCR,
|
||||
REG_DD_CMD_DATA,
|
||||
REG_DD_HEAD_TRACK,
|
||||
REG_DD_SECTOR_INFO,
|
||||
REG_DD_DRIVE_ID,
|
||||
REG_VENDOR_SCR,
|
||||
REG_VENDOR_DATA,
|
||||
REG_DEBUG_0,
|
||||
REG_DEBUG_1
|
||||
} reg_address_e;
|
||||
|
||||
logic bootloader_skip;
|
||||
|
||||
assign n64_scb.cfg_version = 32'h53437632;
|
||||
|
||||
logic dd_bm_ack;
|
||||
|
||||
|
||||
// Register read logic
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reg_read) begin
|
||||
reg_rdata <= 32'd0;
|
||||
|
||||
case (address)
|
||||
REG_MEM_ADDRESS: begin
|
||||
reg_rdata <= mem_address;
|
||||
end
|
||||
|
||||
REG_MEM_SCR: begin
|
||||
reg_rdata <= {
|
||||
28'd0,
|
||||
mem_busy,
|
||||
3'b000
|
||||
};
|
||||
end
|
||||
|
||||
REG_USB_SCR: begin
|
||||
reg_rdata <= {
|
||||
2'd0,
|
||||
usb_scb.pwrsav,
|
||||
usb_scb.reset_state,
|
||||
usb_scb.tx_count,
|
||||
usb_scb.rx_count,
|
||||
2'b00,
|
||||
usb_scb.reset_pending,
|
||||
~fifo_bus.tx_full,
|
||||
~fifo_bus.rx_empty,
|
||||
1'b0
|
||||
};
|
||||
end
|
||||
|
||||
REG_USB_DMA_ADDRESS: begin
|
||||
reg_rdata <= {
|
||||
5'd0,
|
||||
usb_dma_scb.starting_address
|
||||
};
|
||||
end
|
||||
|
||||
REG_USB_DMA_LENGTH: begin
|
||||
reg_rdata <= {
|
||||
5'd0,
|
||||
usb_dma_scb.transfer_length
|
||||
};
|
||||
end
|
||||
|
||||
REG_USB_DMA_SCR: begin
|
||||
reg_rdata <= {
|
||||
28'd0,
|
||||
usb_dma_scb.busy,
|
||||
usb_dma_scb.direction,
|
||||
2'b00
|
||||
};
|
||||
end
|
||||
|
||||
REG_CFG_SCR: begin
|
||||
reg_rdata <= {
|
||||
~button_ff[2],
|
||||
19'd0,
|
||||
n64_scb.rom_extended_enabled,
|
||||
n64_scb.eeprom_16k_mode,
|
||||
n64_scb.eeprom_enabled,
|
||||
n64_scb.ddipl_enabled,
|
||||
n64_scb.dd_enabled,
|
||||
n64_scb.flashram_enabled,
|
||||
n64_scb.sram_banked,
|
||||
n64_scb.sram_enabled,
|
||||
n64_scb.rom_shadow_enabled,
|
||||
n64_scb.rom_write_enabled,
|
||||
bootloader_skip,
|
||||
n64_scb.bootloader_enabled
|
||||
};
|
||||
end
|
||||
|
||||
REG_CFG_DATA_0: begin
|
||||
reg_rdata <= n64_scb.cfg_rdata[0];
|
||||
end
|
||||
|
||||
REG_CFG_DATA_1: begin
|
||||
reg_rdata <= n64_scb.cfg_rdata[1];
|
||||
end
|
||||
|
||||
REG_CFG_CMD: begin
|
||||
reg_rdata <= {
|
||||
23'd0,
|
||||
n64_scb.cfg_pending,
|
||||
n64_scb.cfg_cmd
|
||||
};
|
||||
end
|
||||
|
||||
REG_CFG_VERSION: begin
|
||||
reg_rdata <= n64_scb.cfg_version;
|
||||
end
|
||||
|
||||
REG_FLASHRAM_SCR: begin
|
||||
reg_rdata <= {
|
||||
18'd0,
|
||||
n64_scb.flashram_write_or_erase,
|
||||
n64_scb.flashram_sector_or_all,
|
||||
n64_scb.flashram_sector,
|
||||
n64_scb.flashram_pending,
|
||||
1'b0
|
||||
};
|
||||
end
|
||||
|
||||
REG_FLASH_SCR: begin
|
||||
reg_rdata <= {
|
||||
31'd0,
|
||||
flash_scb.erase_pending
|
||||
};
|
||||
end
|
||||
|
||||
REG_RTC_SCR: begin
|
||||
reg_rdata <= {
|
||||
24'h525443,
|
||||
7'd0,
|
||||
n64_scb.rtc_pending
|
||||
};
|
||||
end
|
||||
|
||||
REG_RTC_TIME_0: begin
|
||||
reg_rdata <= {
|
||||
5'd0, n64_scb.rtc_rdata[28:26],
|
||||
2'd0, n64_scb.rtc_rdata[19:14],
|
||||
1'd0, n64_scb.rtc_rdata[13:7],
|
||||
1'd0, n64_scb.rtc_rdata[6:0]
|
||||
};
|
||||
end
|
||||
|
||||
REG_RTC_TIME_1: begin
|
||||
reg_rdata <= {
|
||||
8'd0,
|
||||
n64_scb.rtc_rdata[41:34],
|
||||
3'd0, n64_scb.rtc_rdata[33:29],
|
||||
2'd0, n64_scb.rtc_rdata[25:20]
|
||||
};
|
||||
end
|
||||
|
||||
REG_SD_SCR: begin
|
||||
reg_rdata <= {
|
||||
4'd0,
|
||||
sd_scb.tx_count,
|
||||
sd_scb.rx_count,
|
||||
~sd_det_ff[2],
|
||||
sd_scb.card_busy,
|
||||
sd_scb.cmd_error,
|
||||
sd_scb.cmd_busy,
|
||||
sd_scb.clock_mode
|
||||
};
|
||||
end
|
||||
|
||||
REG_SD_ARG: begin
|
||||
reg_rdata <= sd_scb.cmd_arg;
|
||||
end
|
||||
|
||||
REG_SD_CMD: begin
|
||||
reg_rdata <= {
|
||||
22'd0,
|
||||
sd_scb.cmd_ignore_crc,
|
||||
sd_scb.cmd_long_response,
|
||||
sd_scb.cmd_reserved_response,
|
||||
sd_scb.cmd_skip_response,
|
||||
sd_scb.cmd_index
|
||||
};
|
||||
end
|
||||
|
||||
REG_SD_RSP_0: begin
|
||||
reg_rdata <= sd_scb.cmd_rsp[31:0];
|
||||
end
|
||||
|
||||
REG_SD_RSP_1: begin
|
||||
reg_rdata <= sd_scb.cmd_rsp[63:32];
|
||||
end
|
||||
|
||||
REG_SD_RSP_2: begin
|
||||
reg_rdata <= sd_scb.cmd_rsp[95:64];
|
||||
end
|
||||
|
||||
REG_SD_RSP_3: begin
|
||||
reg_rdata <= sd_scb.cmd_rsp[127:96];
|
||||
end
|
||||
|
||||
REG_SD_DAT: begin
|
||||
reg_rdata <= {
|
||||
18'd0,
|
||||
sd_scb.dat_error,
|
||||
sd_scb.dat_busy,
|
||||
12'd0
|
||||
};
|
||||
end
|
||||
|
||||
REG_SD_DMA_ADDRESS: begin
|
||||
reg_rdata <= {
|
||||
5'd0,
|
||||
sd_dma_scb.starting_address
|
||||
};
|
||||
end
|
||||
|
||||
REG_SD_DMA_LENGTH: begin
|
||||
reg_rdata <= {
|
||||
5'd0,
|
||||
sd_dma_scb.transfer_length
|
||||
};
|
||||
end
|
||||
|
||||
REG_SD_DMA_SCR: begin
|
||||
reg_rdata <= {
|
||||
28'd0,
|
||||
sd_dma_scb.busy,
|
||||
sd_dma_scb.direction,
|
||||
2'b00
|
||||
};
|
||||
end
|
||||
|
||||
REG_DD_SCR: begin
|
||||
reg_rdata <= {
|
||||
14'd0,
|
||||
dd_bm_ack,
|
||||
dd_scb.bm_micro_error,
|
||||
dd_scb.bm_transfer_c2,
|
||||
dd_scb.bm_transfer_data,
|
||||
dd_scb.bm_transfer_blocks,
|
||||
dd_scb.bm_transfer_mode,
|
||||
1'b0,
|
||||
dd_scb.bm_stop_pending,
|
||||
1'b0,
|
||||
dd_scb.bm_start_pending,
|
||||
dd_scb.disk_changed,
|
||||
dd_scb.disk_inserted,
|
||||
1'b0,
|
||||
dd_scb.bm_pending,
|
||||
1'b0,
|
||||
dd_scb.cmd_pending,
|
||||
1'b0,
|
||||
dd_scb.hard_reset
|
||||
};
|
||||
end
|
||||
|
||||
REG_DD_CMD_DATA: begin
|
||||
reg_rdata <= {8'd0, dd_scb.cmd, dd_scb.data};
|
||||
end
|
||||
|
||||
REG_DD_HEAD_TRACK: begin
|
||||
reg_rdata <= {18'd0, dd_scb.index_lock, dd_scb.head_track};
|
||||
end
|
||||
|
||||
REG_DD_SECTOR_INFO: begin
|
||||
reg_rdata <= {
|
||||
dd_scb.sectors_in_block,
|
||||
dd_scb.sector_size_full,
|
||||
dd_scb.sector_size,
|
||||
dd_scb.sector_num
|
||||
};
|
||||
end
|
||||
|
||||
REG_VENDOR_SCR: begin
|
||||
reg_rdata <= vendor_scb.control_rdata;
|
||||
end
|
||||
|
||||
REG_VENDOR_DATA: begin
|
||||
reg_rdata <= vendor_scb.data_rdata;
|
||||
end
|
||||
|
||||
REG_DEBUG_0: begin
|
||||
reg_rdata <= n64_scb.pi_debug[31:0];
|
||||
end
|
||||
|
||||
REG_DEBUG_1: begin
|
||||
reg_rdata <= {
|
||||
28'd0,
|
||||
n64_scb.pi_debug[35:32]
|
||||
};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Register write logic
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
mem_start <= 1'b0;
|
||||
mem_stop <= 1'b0;
|
||||
|
||||
usb_scb.write_buffer_flush <= 1'b0;
|
||||
usb_scb.reset_ack <= 1'b0;
|
||||
usb_scb.fifo_flush <= 1'b0;
|
||||
|
||||
usb_dma_scb.start <= 1'b0;
|
||||
usb_dma_scb.stop <= 1'b0;
|
||||
|
||||
sd_scb.cmd_start <= 1'b0;
|
||||
sd_scb.dat_fifo_flush <= 1'b0;
|
||||
sd_scb.dat_start_write <= 1'b0;
|
||||
sd_scb.dat_start_read <= 1'b0;
|
||||
sd_scb.dat_stop <= 1'b0;
|
||||
|
||||
sd_dma_scb.start <= 1'b0;
|
||||
sd_dma_scb.stop <= 1'b0;
|
||||
|
||||
n64_scb.cfg_done <= 1'b0;
|
||||
n64_scb.cfg_error <= 1'b0;
|
||||
n64_scb.cfg_irq <= 1'b0;
|
||||
|
||||
n64_scb.flashram_done <= 1'b0;
|
||||
|
||||
n64_scb.rtc_done <= 1'b0;
|
||||
|
||||
dd_scb.hard_reset_clear <= 1'b0;
|
||||
dd_scb.cmd_ready <= 1'b0;
|
||||
dd_scb.bm_start_clear <= 1'b0;
|
||||
dd_scb.bm_stop_clear <= 1'b0;
|
||||
dd_scb.bm_clear <= 1'b0;
|
||||
dd_scb.bm_ready <= 1'b0;
|
||||
|
||||
vendor_scb.control_valid <= 1'b0;
|
||||
|
||||
if (n64_scb.n64_nmi) begin
|
||||
n64_scb.bootloader_enabled <= !bootloader_skip;
|
||||
end
|
||||
|
||||
if (flash_scb.erase_done) begin
|
||||
flash_scb.erase_pending <= 1'b0;
|
||||
end
|
||||
|
||||
if (dd_scb.bm_interrupt_ack) begin
|
||||
dd_bm_ack <= 1'b1;
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
mcu_int <= 1'b0;
|
||||
sd_scb.clock_mode <= 2'd0;
|
||||
n64_scb.rom_extended_enabled <= 1'b0;
|
||||
n64_scb.eeprom_16k_mode <= 1'b0;
|
||||
n64_scb.eeprom_enabled <= 1'b0;
|
||||
n64_scb.dd_enabled <= 1'b0;
|
||||
n64_scb.ddipl_enabled <= 1'b0;
|
||||
n64_scb.flashram_enabled <= 1'b0;
|
||||
n64_scb.sram_banked <= 1'b0;
|
||||
n64_scb.sram_enabled <= 1'b0;
|
||||
n64_scb.rom_shadow_enabled <= 1'b0;
|
||||
n64_scb.rom_write_enabled <= 1'b0;
|
||||
bootloader_skip <= 1'b0;
|
||||
n64_scb.bootloader_enabled <= 1'b1;
|
||||
flash_scb.erase_pending <= 1'b0;
|
||||
dd_bm_ack <= 1'b0;
|
||||
n64_scb.rtc_wdata_valid <= 1'b0;
|
||||
end else if (reg_write) begin
|
||||
case (address)
|
||||
REG_MEM_ADDRESS: begin
|
||||
mem_address <= reg_wdata;
|
||||
end
|
||||
|
||||
REG_MEM_SCR: begin
|
||||
{
|
||||
mem_length,
|
||||
mem_direction,
|
||||
mem_stop,
|
||||
mem_start
|
||||
} <= {(reg_wdata[14:5] - 1'd1), reg_wdata[2:0]};
|
||||
end
|
||||
|
||||
REG_USB_SCR: begin
|
||||
{
|
||||
usb_scb.write_buffer_flush,
|
||||
usb_scb.reset_ack,
|
||||
usb_scb.fifo_flush
|
||||
} <= {reg_wdata[5:4], reg_wdata[0]};
|
||||
end
|
||||
|
||||
REG_USB_DMA_ADDRESS: begin
|
||||
usb_dma_scb.starting_address <= reg_wdata[26:0];
|
||||
end
|
||||
|
||||
REG_USB_DMA_LENGTH: begin
|
||||
usb_dma_scb.transfer_length <= reg_wdata[26:0];
|
||||
end
|
||||
|
||||
REG_USB_DMA_SCR: begin
|
||||
{
|
||||
usb_dma_scb.direction,
|
||||
usb_dma_scb.stop,
|
||||
usb_dma_scb.start
|
||||
} <= reg_wdata[2:0];
|
||||
end
|
||||
|
||||
REG_CFG_SCR: begin
|
||||
{
|
||||
n64_scb.rom_extended_enabled,
|
||||
n64_scb.eeprom_16k_mode,
|
||||
n64_scb.eeprom_enabled,
|
||||
n64_scb.ddipl_enabled,
|
||||
n64_scb.dd_enabled,
|
||||
n64_scb.flashram_enabled,
|
||||
n64_scb.sram_banked,
|
||||
n64_scb.sram_enabled,
|
||||
n64_scb.rom_shadow_enabled,
|
||||
n64_scb.rom_write_enabled,
|
||||
bootloader_skip,
|
||||
n64_scb.bootloader_enabled
|
||||
} <= reg_wdata[11:0];
|
||||
end
|
||||
|
||||
REG_CFG_DATA_0: begin
|
||||
n64_scb.cfg_wdata[0] <= reg_wdata;
|
||||
end
|
||||
|
||||
REG_CFG_DATA_1: begin
|
||||
n64_scb.cfg_wdata[1] <= reg_wdata;
|
||||
end
|
||||
|
||||
REG_CFG_CMD: begin
|
||||
{
|
||||
n64_scb.cfg_irq,
|
||||
n64_scb.cfg_error,
|
||||
n64_scb.cfg_done
|
||||
} <= reg_wdata[11:9];
|
||||
end
|
||||
|
||||
REG_FLASHRAM_SCR: begin
|
||||
n64_scb.flashram_done <= reg_wdata[0];
|
||||
end
|
||||
|
||||
REG_FLASH_SCR: begin
|
||||
flash_scb.erase_pending <= 1'b1;
|
||||
flash_scb.erase_block <= reg_wdata[23:16];
|
||||
end
|
||||
|
||||
REG_RTC_SCR: begin
|
||||
n64_scb.rtc_done <= reg_wdata[1];
|
||||
end
|
||||
|
||||
REG_RTC_TIME_0: begin
|
||||
n64_scb.rtc_wdata_valid <= 1'b0;
|
||||
n64_scb.rtc_wdata[28:26] <= reg_wdata[26:24];
|
||||
n64_scb.rtc_wdata[19:14] <= reg_wdata[21:16];
|
||||
n64_scb.rtc_wdata[13:7] <= reg_wdata[14:8];
|
||||
n64_scb.rtc_wdata[6:0] <= reg_wdata[6:0];
|
||||
end
|
||||
|
||||
REG_RTC_TIME_1: begin
|
||||
n64_scb.rtc_wdata_valid <= 1'b1;
|
||||
n64_scb.rtc_wdata[41:34] <= reg_wdata[23:16];
|
||||
n64_scb.rtc_wdata[33:29] <= reg_wdata[12:8];
|
||||
n64_scb.rtc_wdata[25:20] <= reg_wdata[5:0];
|
||||
end
|
||||
|
||||
REG_SD_SCR: begin
|
||||
sd_scb.clock_mode <= reg_wdata[1:0];
|
||||
end
|
||||
|
||||
REG_SD_ARG: begin
|
||||
sd_scb.cmd_arg <= reg_wdata;
|
||||
end
|
||||
|
||||
REG_SD_CMD: begin
|
||||
sd_scb.cmd_start <= 1'b1;
|
||||
sd_scb.cmd_ignore_crc <= reg_wdata[9];
|
||||
sd_scb.cmd_long_response <= reg_wdata[8];
|
||||
sd_scb.cmd_reserved_response <= reg_wdata[7];
|
||||
sd_scb.cmd_skip_response <= reg_wdata[6];
|
||||
sd_scb.cmd_index <= reg_wdata[5:0];
|
||||
end
|
||||
|
||||
REG_SD_DAT: begin
|
||||
sd_scb.dat_blocks <= reg_wdata[11:4];
|
||||
sd_scb.dat_stop <= reg_wdata[3];
|
||||
sd_scb.dat_start_read <= reg_wdata[2];
|
||||
sd_scb.dat_start_write <= reg_wdata[1];
|
||||
sd_scb.dat_fifo_flush <= reg_wdata[0];
|
||||
end
|
||||
|
||||
REG_SD_DMA_ADDRESS: begin
|
||||
sd_dma_scb.starting_address <= reg_wdata[26:0];
|
||||
end
|
||||
|
||||
REG_SD_DMA_LENGTH: begin
|
||||
sd_dma_scb.transfer_length <= reg_wdata[26:0];
|
||||
end
|
||||
|
||||
REG_SD_DMA_SCR: begin
|
||||
{
|
||||
sd_dma_scb.direction,
|
||||
sd_dma_scb.stop,
|
||||
sd_dma_scb.start
|
||||
} <= reg_wdata[2:0];
|
||||
end
|
||||
|
||||
REG_DD_SCR: begin
|
||||
dd_scb.bm_clear <= reg_wdata[19];
|
||||
if (reg_wdata[18]) begin
|
||||
dd_bm_ack <= 1'b0;
|
||||
end
|
||||
dd_scb.bm_micro_error <= reg_wdata[16];
|
||||
dd_scb.bm_transfer_c2 <= reg_wdata[15];
|
||||
dd_scb.bm_transfer_data <= reg_wdata[14];
|
||||
dd_scb.bm_stop_clear <= reg_wdata[11];
|
||||
dd_scb.bm_start_clear <= reg_wdata[9];
|
||||
dd_scb.disk_changed <= reg_wdata[7];
|
||||
dd_scb.disk_inserted <= reg_wdata[6];
|
||||
dd_scb.bm_ready <= reg_wdata[5];
|
||||
dd_scb.cmd_ready <= reg_wdata[3];
|
||||
dd_scb.hard_reset_clear <= reg_wdata[1];
|
||||
end
|
||||
|
||||
REG_DD_CMD_DATA: begin
|
||||
dd_scb.cmd_data <= reg_wdata[15:0];
|
||||
end
|
||||
|
||||
REG_DD_HEAD_TRACK: begin
|
||||
{dd_scb.index_lock, dd_scb.head_track} <= reg_wdata[13:0];
|
||||
end
|
||||
|
||||
REG_DD_DRIVE_ID: begin
|
||||
dd_scb.drive_id <= reg_wdata[15:0];
|
||||
end
|
||||
|
||||
REG_VENDOR_SCR: begin
|
||||
vendor_scb.control_valid <= 1'b1;
|
||||
vendor_scb.control_wdata <= reg_wdata;
|
||||
end
|
||||
|
||||
REG_VENDOR_DATA: begin
|
||||
vendor_scb.data_wdata <= reg_wdata;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
31
fw/rtl/memory/mem_bus.sv
Normal file
31
fw/rtl/memory/mem_bus.sv
Normal file
@ -0,0 +1,31 @@
|
||||
interface mem_bus ();
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic write;
|
||||
logic [1:0] wmask;
|
||||
logic [26:0] address;
|
||||
logic [15:0] rdata;
|
||||
logic [15:0] wdata;
|
||||
|
||||
modport controller (
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output wmask,
|
||||
output address,
|
||||
input rdata,
|
||||
output wdata
|
||||
);
|
||||
|
||||
modport memory (
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input wmask,
|
||||
input address,
|
||||
output rdata,
|
||||
input wdata
|
||||
);
|
||||
|
||||
endinterface
|
231
fw/rtl/memory/memory_arbiter.sv
Normal file
231
fw/rtl/memory/memory_arbiter.sv
Normal file
@ -0,0 +1,231 @@
|
||||
module memory_arbiter (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_scb.arbiter n64_scb,
|
||||
|
||||
mem_bus.memory n64_bus,
|
||||
mem_bus.memory cfg_bus,
|
||||
mem_bus.memory usb_dma_bus,
|
||||
mem_bus.memory sd_dma_bus,
|
||||
|
||||
mem_bus.controller sdram_mem_bus,
|
||||
mem_bus.controller flash_mem_bus,
|
||||
mem_bus.controller bram_mem_bus
|
||||
);
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
SOURCE_N64,
|
||||
SOURCE_CFG,
|
||||
SOURCE_USB_DMA,
|
||||
SOURCE_SD_DMA
|
||||
} e_source_request;
|
||||
|
||||
logic n64_sdram_request;
|
||||
logic cfg_sdram_request;
|
||||
logic usb_dma_sdram_request;
|
||||
logic sd_dma_sdram_request;
|
||||
|
||||
logic n64_flash_request;
|
||||
logic cfg_flash_request;
|
||||
logic usb_dma_flash_request;
|
||||
logic sd_dma_flash_request;
|
||||
|
||||
logic n64_bram_request;
|
||||
logic cfg_bram_request;
|
||||
logic usb_dma_bram_request;
|
||||
logic sd_dma_bram_request;
|
||||
|
||||
assign n64_sdram_request = n64_bus.request && !n64_bus.address[26];
|
||||
assign cfg_sdram_request = !n64_scb.pi_sdram_active && cfg_bus.request && !cfg_bus.address[26];
|
||||
assign usb_dma_sdram_request = !n64_scb.pi_sdram_active && usb_dma_bus.request && !usb_dma_bus.address[26];
|
||||
assign sd_dma_sdram_request = !n64_scb.pi_sdram_active && sd_dma_bus.request && !sd_dma_bus.address[26];
|
||||
|
||||
assign n64_flash_request = n64_bus.request && (n64_bus.address[26:24] == 3'b100);
|
||||
assign cfg_flash_request = !n64_scb.pi_flash_active && cfg_bus.request && (cfg_bus.address[26:24] == 3'b100);
|
||||
assign usb_dma_flash_request = !n64_scb.pi_flash_active && usb_dma_bus.request && (usb_dma_bus.address[26:24] == 3'b100);
|
||||
assign sd_dma_flash_request = !n64_scb.pi_flash_active && sd_dma_bus.request && (sd_dma_bus.address[26:24] == 3'b100);
|
||||
|
||||
assign n64_bram_request = n64_bus.request && (n64_bus.address[26:24] >= 3'b101);
|
||||
assign cfg_bram_request = cfg_bus.request && (cfg_bus.address[26:24] >= 3'b101);
|
||||
assign usb_dma_bram_request = usb_dma_bus.request && (usb_dma_bus.address[26:24] >= 3'b101);
|
||||
assign sd_dma_bram_request = sd_dma_bus.request && (sd_dma_bus.address[26:24] >= 3'b101);
|
||||
|
||||
e_source_request sdram_source_request;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
sdram_mem_bus.request <= 1'b0;
|
||||
end else begin
|
||||
if (!sdram_mem_bus.request) begin
|
||||
sdram_mem_bus.request <= (
|
||||
n64_sdram_request ||
|
||||
cfg_sdram_request ||
|
||||
usb_dma_sdram_request ||
|
||||
sd_dma_sdram_request
|
||||
);
|
||||
|
||||
if (n64_sdram_request) begin
|
||||
sdram_mem_bus.write <= n64_bus.write;
|
||||
sdram_mem_bus.wmask <= n64_bus.wmask;
|
||||
sdram_mem_bus.address <= n64_bus.address;
|
||||
sdram_mem_bus.wdata <= n64_bus.wdata;
|
||||
sdram_source_request <= SOURCE_N64;
|
||||
end else if (cfg_sdram_request) begin
|
||||
sdram_mem_bus.write <= cfg_bus.write;
|
||||
sdram_mem_bus.wmask <= cfg_bus.wmask;
|
||||
sdram_mem_bus.address <= cfg_bus.address;
|
||||
sdram_mem_bus.wdata <= cfg_bus.wdata;
|
||||
sdram_source_request <= SOURCE_CFG;
|
||||
end else if (usb_dma_sdram_request) begin
|
||||
sdram_mem_bus.write <= usb_dma_bus.write;
|
||||
sdram_mem_bus.wmask <= usb_dma_bus.wmask;
|
||||
sdram_mem_bus.address <= usb_dma_bus.address;
|
||||
sdram_mem_bus.wdata <= usb_dma_bus.wdata;
|
||||
sdram_source_request <= SOURCE_USB_DMA;
|
||||
end else if (sd_dma_sdram_request) begin
|
||||
sdram_mem_bus.write <= sd_dma_bus.write;
|
||||
sdram_mem_bus.wmask <= sd_dma_bus.wmask;
|
||||
sdram_mem_bus.address <= sd_dma_bus.address;
|
||||
sdram_mem_bus.wdata <= sd_dma_bus.wdata;
|
||||
sdram_source_request <= SOURCE_SD_DMA;
|
||||
end
|
||||
end
|
||||
|
||||
if (sdram_mem_bus.ack) begin
|
||||
sdram_mem_bus.request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
e_source_request flash_source_request;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
flash_mem_bus.request <= 1'b0;
|
||||
end else begin
|
||||
if (!flash_mem_bus.request) begin
|
||||
flash_mem_bus.request <= (
|
||||
n64_flash_request ||
|
||||
cfg_flash_request ||
|
||||
usb_dma_flash_request ||
|
||||
sd_dma_flash_request
|
||||
);
|
||||
|
||||
if (n64_flash_request) begin
|
||||
flash_mem_bus.write <= n64_bus.write;
|
||||
flash_mem_bus.wmask <= n64_bus.wmask;
|
||||
flash_mem_bus.address <= n64_bus.address;
|
||||
flash_mem_bus.wdata <= n64_bus.wdata;
|
||||
flash_source_request <= SOURCE_N64;
|
||||
end else if (cfg_flash_request) begin
|
||||
flash_mem_bus.write <= cfg_bus.write;
|
||||
flash_mem_bus.wmask <= cfg_bus.wmask;
|
||||
flash_mem_bus.address <= cfg_bus.address;
|
||||
flash_mem_bus.wdata <= cfg_bus.wdata;
|
||||
flash_source_request <= SOURCE_CFG;
|
||||
end else if (usb_dma_flash_request) begin
|
||||
flash_mem_bus.write <= usb_dma_bus.write;
|
||||
flash_mem_bus.wmask <= usb_dma_bus.wmask;
|
||||
flash_mem_bus.address <= usb_dma_bus.address;
|
||||
flash_mem_bus.wdata <= usb_dma_bus.wdata;
|
||||
flash_source_request <= SOURCE_USB_DMA;
|
||||
end else if (sd_dma_flash_request) begin
|
||||
flash_mem_bus.write <= sd_dma_bus.write;
|
||||
flash_mem_bus.wmask <= sd_dma_bus.wmask;
|
||||
flash_mem_bus.address <= sd_dma_bus.address;
|
||||
flash_mem_bus.wdata <= sd_dma_bus.wdata;
|
||||
flash_source_request <= SOURCE_SD_DMA;
|
||||
end
|
||||
end
|
||||
|
||||
if (flash_mem_bus.ack) begin
|
||||
flash_mem_bus.request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
e_source_request bram_source_request;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
bram_mem_bus.request <= 1'b0;
|
||||
end else begin
|
||||
if (!bram_mem_bus.request) begin
|
||||
bram_mem_bus.request <= (
|
||||
n64_bram_request ||
|
||||
cfg_bram_request ||
|
||||
usb_dma_bram_request ||
|
||||
sd_dma_bram_request
|
||||
);
|
||||
|
||||
if (n64_bram_request) begin
|
||||
bram_mem_bus.write <= n64_bus.write;
|
||||
bram_mem_bus.wmask <= n64_bus.wmask;
|
||||
bram_mem_bus.address <= n64_bus.address;
|
||||
bram_mem_bus.wdata <= n64_bus.wdata;
|
||||
bram_source_request <= SOURCE_N64;
|
||||
end else if (cfg_bram_request) begin
|
||||
bram_mem_bus.write <= cfg_bus.write;
|
||||
bram_mem_bus.wmask <= cfg_bus.wmask;
|
||||
bram_mem_bus.address <= cfg_bus.address;
|
||||
bram_mem_bus.wdata <= cfg_bus.wdata;
|
||||
bram_source_request <= SOURCE_CFG;
|
||||
end else if (usb_dma_bram_request) begin
|
||||
bram_mem_bus.write <= usb_dma_bus.write;
|
||||
bram_mem_bus.wmask <= usb_dma_bus.wmask;
|
||||
bram_mem_bus.address <= usb_dma_bus.address;
|
||||
bram_mem_bus.wdata <= usb_dma_bus.wdata;
|
||||
bram_source_request <= SOURCE_USB_DMA;
|
||||
end else if (sd_dma_bram_request) begin
|
||||
bram_mem_bus.write <= sd_dma_bus.write;
|
||||
bram_mem_bus.wmask <= sd_dma_bus.wmask;
|
||||
bram_mem_bus.address <= sd_dma_bus.address;
|
||||
bram_mem_bus.wdata <= sd_dma_bus.wdata;
|
||||
bram_source_request <= SOURCE_SD_DMA;
|
||||
end
|
||||
end
|
||||
|
||||
if (bram_mem_bus.ack) begin
|
||||
bram_mem_bus.request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
n64_bus.ack = (
|
||||
((sdram_source_request == SOURCE_N64) && sdram_mem_bus.ack) ||
|
||||
((flash_source_request == SOURCE_N64) && flash_mem_bus.ack) ||
|
||||
((bram_source_request == SOURCE_N64) && bram_mem_bus.ack)
|
||||
);
|
||||
cfg_bus.ack = (
|
||||
((sdram_source_request == SOURCE_CFG) && sdram_mem_bus.ack) ||
|
||||
((flash_source_request == SOURCE_CFG) && flash_mem_bus.ack) ||
|
||||
((bram_source_request == SOURCE_CFG) && bram_mem_bus.ack)
|
||||
);
|
||||
usb_dma_bus.ack = (
|
||||
((sdram_source_request == SOURCE_USB_DMA) && sdram_mem_bus.ack) ||
|
||||
((flash_source_request == SOURCE_USB_DMA) && flash_mem_bus.ack) ||
|
||||
((bram_source_request == SOURCE_USB_DMA) && bram_mem_bus.ack)
|
||||
);
|
||||
sd_dma_bus.ack = (
|
||||
((sdram_source_request == SOURCE_SD_DMA) && sdram_mem_bus.ack) ||
|
||||
((flash_source_request == SOURCE_SD_DMA) && flash_mem_bus.ack) ||
|
||||
((bram_source_request == SOURCE_SD_DMA) && bram_mem_bus.ack)
|
||||
);
|
||||
|
||||
n64_bus.rdata = n64_bram_request ? bram_mem_bus.rdata :
|
||||
n64_flash_request ? flash_mem_bus.rdata :
|
||||
sdram_mem_bus.rdata;
|
||||
cfg_bus.rdata = cfg_bram_request ? bram_mem_bus.rdata :
|
||||
cfg_flash_request ? flash_mem_bus.rdata :
|
||||
sdram_mem_bus.rdata;
|
||||
usb_dma_bus.rdata = usb_dma_bram_request ? bram_mem_bus.rdata :
|
||||
usb_dma_flash_request ? flash_mem_bus.rdata :
|
||||
sdram_mem_bus.rdata;
|
||||
sd_dma_bus.rdata = sd_dma_bram_request ? bram_mem_bus.rdata :
|
||||
sd_dma_flash_request ? flash_mem_bus.rdata :
|
||||
sdram_mem_bus.rdata;
|
||||
end
|
||||
|
||||
endmodule
|
164
fw/rtl/memory/memory_bram.sv
Normal file
164
fw/rtl/memory/memory_bram.sv
Normal file
@ -0,0 +1,164 @@
|
||||
module memory_bram (
|
||||
input clk,
|
||||
|
||||
n64_scb.bram n64_scb,
|
||||
|
||||
mem_bus.memory mem_bus
|
||||
);
|
||||
|
||||
// Request logic
|
||||
|
||||
logic [1:0] last_request;
|
||||
logic write;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
last_request <= {last_request[0], mem_bus.request};
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
mem_bus.ack <= mem_bus.request && last_request[0] && !last_request[1];
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
write = mem_bus.request && !last_request[0] && mem_bus.write;
|
||||
end
|
||||
|
||||
|
||||
// Address decoding
|
||||
|
||||
logic buffer_selected;
|
||||
logic eeprom_selected;
|
||||
logic dd_selected;
|
||||
logic flashram_selected;
|
||||
|
||||
always_comb begin
|
||||
buffer_selected = 1'b0;
|
||||
eeprom_selected = 1'b0;
|
||||
dd_selected = 1'b0;
|
||||
flashram_selected = 1'b0;
|
||||
if (mem_bus.address[25:24] == 2'b01 && mem_bus.address[23:14] == 10'd0) begin
|
||||
buffer_selected = mem_bus.address[13] == 1'b0;
|
||||
eeprom_selected = mem_bus.address[13:11] == 3'b100;
|
||||
dd_selected = mem_bus.address[13:8] == 6'b101000;
|
||||
flashram_selected = mem_bus.address[13:7] == 7'b1010010;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Buffer memory
|
||||
|
||||
logic [15:0] buffer_bram [0:4095];
|
||||
logic [15:0] buffer_bram_rdata;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (write && buffer_selected) begin
|
||||
if (mem_bus.wmask[1]) buffer_bram[mem_bus.address[12:1]][15:8] <= mem_bus.wdata[15:8];
|
||||
if (mem_bus.wmask[0]) buffer_bram[mem_bus.address[12:1]][7:0] <= mem_bus.wdata[7:0];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
buffer_bram_rdata <= buffer_bram[mem_bus.address[12:1]];
|
||||
end
|
||||
|
||||
|
||||
// EEPROM memory
|
||||
|
||||
logic [7:0] eeprom_bram_high [0:1023];
|
||||
logic [7:0] eeprom_bram_low [0:1023];
|
||||
logic [7:0] eeprom_bram_high_rdata;
|
||||
logic [7:0] eeprom_bram_low_rdata;
|
||||
logic [7:0] eeprom_bram_high_n64_rdata;
|
||||
logic [7:0] eeprom_bram_low_n64_rdata;
|
||||
logic [15:0] eeprom_bram_rdata;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (write && mem_bus.wmask[1] && eeprom_selected) begin
|
||||
eeprom_bram_high[mem_bus.address[10:1]] <= mem_bus.wdata[15:8];
|
||||
end
|
||||
if (n64_scb.eeprom_write && !n64_scb.eeprom_address[0]) begin
|
||||
eeprom_bram_high[n64_scb.eeprom_address[10:1]] <= n64_scb.eeprom_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (write && mem_bus.wmask[0] && eeprom_selected) begin
|
||||
eeprom_bram_low[mem_bus.address[10:1]] <= mem_bus.wdata[7:0];
|
||||
end
|
||||
if (n64_scb.eeprom_write && n64_scb.eeprom_address[0]) begin
|
||||
eeprom_bram_low[n64_scb.eeprom_address[10:1]] <= n64_scb.eeprom_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
eeprom_bram_high_rdata <= eeprom_bram_high[mem_bus.address[10:1]];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
eeprom_bram_low_rdata <= eeprom_bram_low[mem_bus.address[10:1]];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
eeprom_bram_high_n64_rdata <= eeprom_bram_high[n64_scb.eeprom_address[10:1]];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
eeprom_bram_low_n64_rdata <= eeprom_bram_low[n64_scb.eeprom_address[10:1]];
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
eeprom_bram_rdata = {eeprom_bram_high_rdata, eeprom_bram_low_rdata};
|
||||
n64_scb.eeprom_rdata = n64_scb.eeprom_address[0] ? eeprom_bram_low_n64_rdata : eeprom_bram_high_n64_rdata;
|
||||
end
|
||||
|
||||
|
||||
// DD memory
|
||||
|
||||
logic [15:0] dd_bram [0:127];
|
||||
logic [15:0] dd_bram_rdata;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (write && dd_selected) begin
|
||||
dd_bram[mem_bus.address[7:1]] <= mem_bus.wdata;
|
||||
end
|
||||
if (n64_scb.dd_write) begin
|
||||
dd_bram[n64_scb.dd_address] <= n64_scb.dd_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
dd_bram_rdata <= dd_bram[mem_bus.address[7:1]];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
n64_scb.dd_rdata <= dd_bram[n64_scb.dd_address];
|
||||
end
|
||||
|
||||
|
||||
// FlashRAM memory
|
||||
|
||||
logic [15:0] flashram_bram [0:63];
|
||||
logic [15:0] flashram_bram_rdata;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (n64_scb.flashram_write) begin
|
||||
flashram_bram[n64_scb.flashram_address] <= n64_scb.flashram_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
flashram_bram_rdata <= flashram_bram[mem_bus.address[6:1]];
|
||||
end
|
||||
|
||||
|
||||
// Output data mux
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
mem_bus.rdata <= 16'd0;
|
||||
if (buffer_selected) mem_bus.rdata <= buffer_bram_rdata;
|
||||
if (eeprom_selected) mem_bus.rdata <= eeprom_bram_rdata;
|
||||
if (dd_selected) mem_bus.rdata <= dd_bram_rdata;
|
||||
if (flashram_selected) mem_bus.rdata <= flashram_bram_rdata;
|
||||
end
|
||||
|
||||
endmodule
|
243
fw/rtl/memory/memory_dma.sv
Normal file
243
fw/rtl/memory/memory_dma.sv
Normal file
@ -0,0 +1,243 @@
|
||||
interface dma_scb ();
|
||||
|
||||
logic start;
|
||||
logic stop;
|
||||
logic busy;
|
||||
logic direction;
|
||||
logic [26:0] starting_address;
|
||||
logic [26:0] transfer_length;
|
||||
|
||||
modport controller (
|
||||
output start,
|
||||
output stop,
|
||||
input busy,
|
||||
output direction,
|
||||
output starting_address,
|
||||
output transfer_length
|
||||
);
|
||||
|
||||
modport dma (
|
||||
input start,
|
||||
input stop,
|
||||
output busy,
|
||||
input direction,
|
||||
input starting_address,
|
||||
input transfer_length
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module memory_dma (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
dma_scb.dma dma_scb,
|
||||
|
||||
fifo_bus.controller fifo_bus,
|
||||
mem_bus.controller mem_bus
|
||||
);
|
||||
|
||||
// DMA start/stop control
|
||||
|
||||
logic dma_start;
|
||||
logic dma_stop;
|
||||
|
||||
always_comb begin
|
||||
dma_start = dma_scb.start && !dma_scb.stop && !dma_scb.busy;
|
||||
dma_stop = dma_scb.stop;
|
||||
end
|
||||
|
||||
|
||||
// Remaining counter and FIFO enable
|
||||
|
||||
logic [26:0] remaining;
|
||||
logic trx_enabled;
|
||||
|
||||
always_comb begin
|
||||
trx_enabled = remaining > 27'd0;
|
||||
end
|
||||
|
||||
|
||||
// RX FIFO controller
|
||||
|
||||
logic rx_rdata_pop;
|
||||
logic rx_rdata_shift;
|
||||
logic rx_rdata_valid;
|
||||
logic [15:0] rx_buffer;
|
||||
logic rx_buffer_valid;
|
||||
logic [1:0] rx_buffer_counter;
|
||||
logic [1:0] rx_buffer_valid_counter;
|
||||
|
||||
always_comb begin
|
||||
rx_buffer_valid = rx_buffer_valid_counter == 2'd2;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
rx_rdata_pop <= (
|
||||
!rx_rdata_pop &&
|
||||
!fifo_bus.rx_read &&
|
||||
trx_enabled &&
|
||||
rx_buffer_counter < 2'd2 &&
|
||||
!fifo_bus.rx_empty &&
|
||||
mem_bus.write
|
||||
);
|
||||
rx_rdata_shift <= 1'b0;
|
||||
fifo_bus.rx_read <= rx_rdata_pop;
|
||||
rx_rdata_valid <= fifo_bus.rx_read;
|
||||
|
||||
if (dma_start) begin
|
||||
if (dma_scb.starting_address[0]) begin
|
||||
mem_bus.wmask <= 2'b01;
|
||||
rx_buffer_counter <= 2'd1;
|
||||
rx_buffer_valid_counter <= 2'd1;
|
||||
end else begin
|
||||
mem_bus.wmask <= 2'b11;
|
||||
rx_buffer_counter <= 2'd0;
|
||||
rx_buffer_valid_counter <= 2'd0;
|
||||
end
|
||||
end
|
||||
|
||||
if (rx_rdata_pop) begin
|
||||
rx_buffer_counter <= rx_buffer_counter + 1'd1;
|
||||
end
|
||||
|
||||
if (rx_rdata_shift || rx_rdata_valid) begin
|
||||
rx_buffer <= {rx_buffer[7:0], fifo_bus.rx_rdata};
|
||||
rx_buffer_valid_counter <= rx_buffer_valid_counter + 1'd1;
|
||||
if (remaining == 27'd0 && rx_buffer_counter == 2'd1) begin
|
||||
mem_bus.wmask <= 2'b10;
|
||||
rx_rdata_shift <= 1'b1;
|
||||
rx_buffer_counter <= rx_buffer_counter + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
if (rx_buffer_valid && !mem_bus.request) begin
|
||||
rx_buffer_counter <= 2'd0;
|
||||
rx_buffer_valid_counter <= 2'd0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// TX FIFO controller
|
||||
|
||||
logic tx_wdata_push;
|
||||
logic tx_wdata_first_push;
|
||||
logic [7:0] tx_buffer;
|
||||
logic tx_buffer_counter;
|
||||
logic tx_buffer_ready;
|
||||
logic tx_buffer_valid;
|
||||
|
||||
always_comb begin
|
||||
fifo_bus.tx_write = tx_wdata_push;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
tx_wdata_push <= (
|
||||
!tx_wdata_push &&
|
||||
trx_enabled &&
|
||||
tx_buffer_valid &&
|
||||
!fifo_bus.tx_full &&
|
||||
!mem_bus.write
|
||||
);
|
||||
|
||||
if (reset || dma_stop) begin
|
||||
tx_buffer_ready <= 1'b0;
|
||||
tx_buffer_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (dma_start) begin
|
||||
tx_wdata_first_push <= 1'b1;
|
||||
tx_buffer_ready <= 1'b1;
|
||||
tx_buffer_valid <= 1'b0;
|
||||
end
|
||||
|
||||
if (tx_buffer_ready && mem_bus.request) begin
|
||||
tx_buffer_ready <= 1'b0;
|
||||
end
|
||||
|
||||
if (mem_bus.ack) begin
|
||||
tx_wdata_first_push <= 1'b0;
|
||||
tx_buffer_counter <= 1'd1;
|
||||
tx_buffer_valid <= 1'b1;
|
||||
{fifo_bus.tx_wdata, tx_buffer} <= mem_bus.rdata;
|
||||
if (tx_wdata_first_push && dma_scb.starting_address[0]) begin
|
||||
fifo_bus.tx_wdata <= mem_bus.rdata[7:0];
|
||||
tx_buffer_counter <= 1'd0;
|
||||
end
|
||||
end
|
||||
|
||||
if (tx_wdata_push) begin
|
||||
tx_buffer_counter <= tx_buffer_counter - 1'd1;
|
||||
fifo_bus.tx_wdata <= tx_buffer;
|
||||
if (tx_buffer_counter == 1'd0) begin
|
||||
tx_buffer_ready <= 1'b1;
|
||||
tx_buffer_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Remaining counter controller
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset || dma_stop) begin
|
||||
remaining <= 27'd0;
|
||||
end else begin
|
||||
if (dma_start) begin
|
||||
remaining <= dma_scb.transfer_length;
|
||||
end
|
||||
|
||||
if ((mem_bus.write && rx_rdata_pop) || (!mem_bus.write && tx_wdata_push)) begin
|
||||
remaining <= remaining - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Mem bus controller
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
dma_scb.busy <= mem_bus.request || trx_enabled;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
mem_bus.request <= 1'b0;
|
||||
end else begin
|
||||
if (!mem_bus.request) begin
|
||||
if (mem_bus.write) begin
|
||||
if (rx_buffer_valid) begin
|
||||
mem_bus.request <= 1'b1;
|
||||
mem_bus.wdata <= rx_buffer;
|
||||
end
|
||||
end else begin
|
||||
if (tx_buffer_ready) begin
|
||||
mem_bus.request <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (mem_bus.ack) begin
|
||||
mem_bus.request <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (dma_start) begin
|
||||
mem_bus.write <= dma_scb.direction;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (dma_start) begin
|
||||
mem_bus.address <= {dma_scb.starting_address[26:1], 1'b0};
|
||||
end
|
||||
|
||||
if (mem_bus.ack) begin
|
||||
mem_bus.address <= mem_bus.address + 2'd2;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
492
fw/rtl/memory/memory_flash.sv
Normal file
492
fw/rtl/memory/memory_flash.sv
Normal file
@ -0,0 +1,492 @@
|
||||
interface flash_scb ();
|
||||
|
||||
logic erase_pending;
|
||||
logic erase_done;
|
||||
logic [7:0] erase_block;
|
||||
|
||||
modport controller (
|
||||
output erase_pending,
|
||||
input erase_done,
|
||||
output erase_block
|
||||
);
|
||||
|
||||
modport flash (
|
||||
input erase_pending,
|
||||
output erase_done,
|
||||
input erase_block
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module flash_qspi (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input start,
|
||||
input finish,
|
||||
output logic busy,
|
||||
output logic valid,
|
||||
input output_enable,
|
||||
input quad_enable,
|
||||
output logic [7:0] rdata,
|
||||
input [7:0] wdata,
|
||||
|
||||
output logic flash_clk,
|
||||
output logic flash_cs,
|
||||
inout [3:0] flash_dq
|
||||
);
|
||||
|
||||
logic flash_dq_oe_s;
|
||||
logic flash_dq_oe_q;
|
||||
logic [3:0] flash_dq_out;
|
||||
|
||||
assign flash_dq[0] = flash_dq_oe_s ? flash_dq_out[0] : 1'bZ;
|
||||
assign flash_dq[3:1] = flash_dq_oe_q ? flash_dq_out[3:1] : 3'bZZZ;
|
||||
|
||||
logic ff_clk;
|
||||
logic ff_cs;
|
||||
logic ff_dq_oe_s;
|
||||
logic ff_dq_oe_q;
|
||||
logic [3:0] ff_dq_out;
|
||||
logic [3:0] ff_dq_in;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
flash_clk <= ff_clk;
|
||||
flash_cs <= ff_cs;
|
||||
flash_dq_oe_s <= ff_dq_oe_s;
|
||||
flash_dq_oe_q <= ff_dq_oe_q;
|
||||
flash_dq_out <= ff_dq_out;
|
||||
ff_dq_in <= flash_dq;
|
||||
end
|
||||
|
||||
logic running;
|
||||
logic exit;
|
||||
logic valid_enable;
|
||||
logic quad_mode;
|
||||
logic [2:0] counter;
|
||||
logic [7:0] output_shift;
|
||||
logic [2:0] sample_s;
|
||||
logic [2:0] sample_q;
|
||||
logic [2:0] valid_ff;
|
||||
|
||||
assign ff_dq_out = quad_mode ? output_shift[7:4] : {3'bXXX, output_shift[7]};
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
sample_s <= {sample_s[1:0], 1'b0};
|
||||
sample_q <= {sample_q[1:0], 1'b0};
|
||||
valid_ff <= {valid_ff[1:0], 1'b0};
|
||||
if (reset) begin
|
||||
ff_clk <= 1'b0;
|
||||
ff_cs <= 1'b1;
|
||||
ff_dq_oe_s <= 1'b0;
|
||||
ff_dq_oe_q <= 1'b0;
|
||||
busy <= 1'b0;
|
||||
running <= 1'b0;
|
||||
end else begin
|
||||
if (running) begin
|
||||
ff_clk <= ~ff_clk;
|
||||
if (!ff_clk) begin
|
||||
if (counter == 3'd0) begin
|
||||
busy <= 1'b0;
|
||||
valid_ff[0] <= valid_enable;
|
||||
end
|
||||
if (!quad_mode) begin
|
||||
sample_s[0] <= 1'b1;
|
||||
end else begin
|
||||
sample_q[0] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
counter <= counter - 1'd1;
|
||||
if (counter == 3'd0) begin
|
||||
running <= 1'b0;
|
||||
end
|
||||
if (!quad_mode) begin
|
||||
output_shift <= {output_shift[6:0], 1'bX};
|
||||
end else begin
|
||||
output_shift <= {output_shift[3:0], 4'bXXXX};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (exit) begin
|
||||
ff_cs <= 1'b1;
|
||||
counter <= counter - 1'd1;
|
||||
if (counter == 3'd0) begin
|
||||
busy <= 1'b0;
|
||||
exit <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (!busy) begin
|
||||
if (start) begin
|
||||
ff_clk <= 1'b0;
|
||||
ff_cs <= 1'b0;
|
||||
ff_dq_oe_s <= !quad_enable || (quad_enable && output_enable);
|
||||
ff_dq_oe_q <= quad_enable && output_enable;
|
||||
busy <= 1'b1;
|
||||
running <= 1'b1;
|
||||
valid_enable <= !output_enable;
|
||||
quad_mode <= quad_enable;
|
||||
counter <= quad_enable ? 3'd1 : 3'd7;
|
||||
output_shift <= wdata;
|
||||
end else if (finish) begin
|
||||
busy <= 1'b1;
|
||||
exit <= 1'b1;
|
||||
counter <= wdata[2:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
valid <= 1'b0;
|
||||
if (sample_s[2]) begin
|
||||
rdata <= {rdata[6:0], ff_dq_in[1]};
|
||||
end
|
||||
if (sample_q[2]) begin
|
||||
rdata <= {rdata[3:0], ff_dq_in};
|
||||
end
|
||||
if (valid_ff[2]) begin
|
||||
valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module memory_flash (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
flash_scb.flash flash_scb,
|
||||
|
||||
mem_bus.memory mem_bus,
|
||||
|
||||
output flash_clk,
|
||||
output flash_cs,
|
||||
inout [3:0] flash_dq
|
||||
);
|
||||
|
||||
logic start;
|
||||
logic finish;
|
||||
logic busy;
|
||||
logic valid;
|
||||
logic output_enable;
|
||||
logic quad_enable;
|
||||
logic [7:0] rdata;
|
||||
logic [7:0] wdata;
|
||||
|
||||
flash_qspi flash_qspi_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.start(start),
|
||||
.finish(finish),
|
||||
.busy(busy),
|
||||
.valid(valid),
|
||||
.output_enable(output_enable),
|
||||
.quad_enable(quad_enable),
|
||||
.rdata(rdata),
|
||||
.wdata(wdata),
|
||||
|
||||
.flash_clk(flash_clk),
|
||||
.flash_cs(flash_cs),
|
||||
.flash_dq(flash_dq)
|
||||
);
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
FLASH_CMD_PAGE_PROGRAM = 8'h02,
|
||||
FLASH_CMD_READ_STATUS_1 = 8'h05,
|
||||
FLASH_CMD_WRITE_ENABLE = 8'h06,
|
||||
FLASH_CMD_BLOCK_ERASE_64KB = 8'hD8,
|
||||
FLASH_CMD_FAST_READ_QUAD_IO = 8'hEB
|
||||
} e_flash_cmd;
|
||||
|
||||
typedef enum {
|
||||
FLASH_STATUS_1_BUSY = 0
|
||||
} e_flash_status_1;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
STATE_IDLE,
|
||||
STATE_WRITE_ENABLE,
|
||||
STATE_ERASE,
|
||||
STATE_PROGRAM_START,
|
||||
STATE_PROGRAM,
|
||||
STATE_PROGRAM_END,
|
||||
STATE_WAIT,
|
||||
STATE_READ_START,
|
||||
STATE_READ,
|
||||
STATE_READ_END
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
logic [2:0] counter;
|
||||
logic valid_counter;
|
||||
logic [23:0] current_address;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
start <= 1'b0;
|
||||
finish <= 1'b0;
|
||||
flash_scb.erase_done <= 1'b0;
|
||||
mem_bus.ack <= 1'b0;
|
||||
|
||||
if (reset) begin
|
||||
state <= STATE_IDLE;
|
||||
end else begin
|
||||
if (!busy && (start || finish)) begin
|
||||
counter <= counter + 1'd1;
|
||||
end
|
||||
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
output_enable <= 1'b1;
|
||||
quad_enable <= 1'b0;
|
||||
counter <= 3'd0;
|
||||
if (flash_scb.erase_pending) begin
|
||||
state <= STATE_WRITE_ENABLE;
|
||||
end else if (mem_bus.request) begin
|
||||
current_address <= {mem_bus.address[23:1], 1'b0};
|
||||
if (mem_bus.write) begin
|
||||
state <= STATE_WRITE_ENABLE;
|
||||
end else begin
|
||||
state <= STATE_READ_START;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_WRITE_ENABLE: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
wdata <= FLASH_CMD_WRITE_ENABLE;
|
||||
end
|
||||
3'd1: begin
|
||||
finish <= 1'b1;
|
||||
wdata <= 8'd4;
|
||||
if (!busy) begin
|
||||
counter <= 3'd0;
|
||||
if (flash_scb.erase_pending) begin
|
||||
state <= STATE_ERASE;
|
||||
end else begin
|
||||
state <= STATE_PROGRAM_START;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
STATE_ERASE: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
wdata <= FLASH_CMD_BLOCK_ERASE_64KB;
|
||||
end
|
||||
3'd1: begin
|
||||
start <= 1'b1;
|
||||
wdata <= flash_scb.erase_block;
|
||||
end
|
||||
3'd2: begin
|
||||
start <= 1'b1;
|
||||
wdata <= 8'd0;
|
||||
end
|
||||
3'd3: begin
|
||||
start <= 1'b1;
|
||||
wdata <= 8'd0;
|
||||
end
|
||||
3'd4: begin
|
||||
finish <= 1'b1;
|
||||
wdata <= 8'd4;
|
||||
if (!busy) begin
|
||||
flash_scb.erase_done <= 1'b1;
|
||||
counter <= 3'd0;
|
||||
state <= STATE_WAIT;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
STATE_PROGRAM_START: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
wdata <= FLASH_CMD_PAGE_PROGRAM;
|
||||
end
|
||||
3'd1: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.address[23:16];
|
||||
end
|
||||
3'd2: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.address[15:8];
|
||||
end
|
||||
3'd3: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.address[7:0];
|
||||
if (!busy) begin
|
||||
counter <= 3'd0;
|
||||
state <= STATE_PROGRAM;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
STATE_PROGRAM: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.wdata[15:8];
|
||||
end
|
||||
3'd1: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.wdata[7:0];
|
||||
if (!busy) begin
|
||||
mem_bus.ack <= 1'b1;
|
||||
current_address <= current_address + 2'd2;
|
||||
end
|
||||
end
|
||||
3'd2: begin
|
||||
if (current_address[7:0] == 8'h00) begin
|
||||
state <= STATE_PROGRAM_END;
|
||||
end else if (flash_scb.erase_pending) begin
|
||||
state <= STATE_PROGRAM_END;
|
||||
end else if (mem_bus.request && !mem_bus.ack) begin
|
||||
if (!mem_bus.write || (mem_bus.address[23:0] != current_address)) begin
|
||||
state <= STATE_PROGRAM_END;
|
||||
end else begin
|
||||
counter <= 3'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
STATE_PROGRAM_END: begin
|
||||
finish <= 1'b1;
|
||||
wdata <= 8'd4;
|
||||
if (!busy) begin
|
||||
counter <= 3'd0;
|
||||
state <= STATE_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_WAIT: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
output_enable <= 1'b1;
|
||||
wdata <= FLASH_CMD_READ_STATUS_1;
|
||||
end
|
||||
3'd1: begin
|
||||
start <= 1'b1;
|
||||
output_enable <= 1'b0;
|
||||
end
|
||||
3'd2: begin
|
||||
finish <= 1'b1;
|
||||
wdata <= 8'd0;
|
||||
end
|
||||
3'd3: begin
|
||||
counter <= counter;
|
||||
end
|
||||
endcase
|
||||
if (valid) begin
|
||||
if (rdata[FLASH_STATUS_1_BUSY]) begin
|
||||
counter <= 3'd0;
|
||||
end else begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_READ_START: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
wdata <= FLASH_CMD_FAST_READ_QUAD_IO;
|
||||
end
|
||||
3'd1: begin
|
||||
start <= 1'b1;
|
||||
quad_enable <= 1'b1;
|
||||
wdata <= mem_bus.address[23:16];
|
||||
end
|
||||
3'd2: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.address[15:8];
|
||||
end
|
||||
3'd3: begin
|
||||
start <= 1'b1;
|
||||
wdata <= mem_bus.address[7:0];
|
||||
end
|
||||
3'd4: begin
|
||||
start <= 1'b1;
|
||||
wdata <= 8'hFF;
|
||||
end
|
||||
3'd5: begin
|
||||
start <= 1'b1;
|
||||
end
|
||||
3'd6: begin
|
||||
start <= 1'b1;
|
||||
if (!busy) begin
|
||||
counter <= 3'd0;
|
||||
valid_counter <= 1'b0;
|
||||
state <= STATE_READ;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
STATE_READ: begin
|
||||
case (counter)
|
||||
3'd0: begin
|
||||
start <= 1'b1;
|
||||
output_enable <= 1'b0;
|
||||
end
|
||||
3'd1: begin
|
||||
start <= 1'b1;
|
||||
end
|
||||
3'd2: begin end
|
||||
3'd3: begin
|
||||
if (flash_scb.erase_pending) begin
|
||||
state <= STATE_READ_END;
|
||||
end else if (mem_bus.request && !mem_bus.ack) begin
|
||||
if (mem_bus.write || (mem_bus.address[23:0] != current_address)) begin
|
||||
state <= STATE_READ_END;
|
||||
end else begin
|
||||
start <= 1'b1;
|
||||
counter <= 3'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (valid) begin
|
||||
valid_counter <= ~valid_counter;
|
||||
if (valid_counter) begin
|
||||
mem_bus.ack <= 1'b1;
|
||||
counter <= counter + 1'd1;
|
||||
current_address <= current_address + 2'd2;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_READ_END: begin
|
||||
finish <= 1'b1;
|
||||
wdata <= 8'd0;
|
||||
if (!busy) begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state <= STATE_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (valid) begin
|
||||
mem_bus.rdata <= {mem_bus.rdata[7:0], rdata};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,48 +1,41 @@
|
||||
module memory_sdram (
|
||||
if_system sys,
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input [25:0] address,
|
||||
output [15:0] rdata,
|
||||
input [15:0] wdata,
|
||||
mem_bus.memory mem_bus,
|
||||
|
||||
output sdram_cs,
|
||||
output sdram_ras,
|
||||
output sdram_cas,
|
||||
output sdram_we,
|
||||
output [1:0] sdram_ba,
|
||||
output [12:0] sdram_a,
|
||||
output logic sdram_cs,
|
||||
output logic sdram_ras,
|
||||
output logic sdram_cas,
|
||||
output logic sdram_we,
|
||||
output logic [1:0] sdram_ba,
|
||||
output logic [12:0] sdram_a,
|
||||
output logic [1:0] sdram_dqm,
|
||||
inout [15:0] sdram_dq
|
||||
);
|
||||
|
||||
parameter [2:0] CAS_LATENCY = 3'd2;
|
||||
localparam [2:0] CAS_LATENCY = 3'd2;
|
||||
|
||||
parameter real T_INIT = 100_000.0;
|
||||
parameter real T_RC = 60.0;
|
||||
parameter real T_RP = 15.0;
|
||||
parameter real T_RCD = 15.0;
|
||||
// parameter real T_RAS = 37.0; //TODO: handle this timing
|
||||
// parameter real T_WR = T_RAS - T_RCD; //TODO: handle this timing
|
||||
parameter real T_MRD = 14.0;
|
||||
parameter real T_REF = 7_800.0;
|
||||
localparam real T_INIT = 100_000.0;
|
||||
localparam real T_RC = 60.0;
|
||||
localparam real T_RP = 15.0;
|
||||
localparam real T_RCD = 15.0;
|
||||
localparam real T_MRD = 14.0;
|
||||
localparam real T_REF = 7_800.0;
|
||||
|
||||
localparam real T_CLK = (1.0 / sc64::CLOCK_FREQUENCY) * 1_000_000_000.0;
|
||||
localparam real T_CLK = (1.0 / 100_000_000) * 1_000_000_000.0;
|
||||
localparam int C_INIT = int'((T_INIT + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RC = int'((T_RC + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RP = int'((T_RP + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RCD = int'((T_RCD + T_CLK - 1) / T_CLK);
|
||||
// localparam int C_RAS = int'((T_RAS + T_CLK - 1) / T_CLK);
|
||||
// localparam int C_WR = int'((T_WR + T_CLK - 1) / T_CLK);
|
||||
localparam int C_MRD = int'((T_MRD + T_CLK - 1) / T_CLK);
|
||||
localparam int C_REF = int'((T_REF + T_CLK - 1) / T_CLK);
|
||||
|
||||
localparam INIT_PRECHARGE = C_INIT;
|
||||
localparam INIT_REFRESH_1 = C_INIT + C_RP;
|
||||
localparam INIT_REFRESH_2 = C_INIT + C_RP + C_RC;
|
||||
localparam INIT_MODE_REG = C_INIT + C_RP + (2 * C_RC);
|
||||
localparam INIT_DONE = C_INIT + C_RP + (2 * C_RC) + C_MRD;
|
||||
localparam INIT_PRECHARGE = 4'd0;
|
||||
localparam INIT_REFRESH_1 = C_RP;
|
||||
localparam INIT_REFRESH_2 = C_RP + C_RC;
|
||||
localparam INIT_MODE_REG = C_RP + (2 * C_RC);
|
||||
localparam INIT_DONE = C_RP + (2 * C_RC) + C_MRD;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
CMD_DESL = 4'b1111,
|
||||
@ -63,37 +56,51 @@ module memory_sdram (
|
||||
logic [14:0] current_active_bank_row;
|
||||
logic request_in_current_active_bank_row;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
always_ff @(posedge clk) begin
|
||||
{sdram_cs, sdram_ras, sdram_cas, sdram_we} <= 4'(sdram_next_cmd);
|
||||
|
||||
{sdram_ba, sdram_a} <= 15'd0;
|
||||
sdram_dqm <= 2'b00;
|
||||
|
||||
sdram_dq_input <= sdram_dq;
|
||||
sdram_dq_output <= wdata;
|
||||
sdram_dq_output <= mem_bus.wdata;
|
||||
|
||||
sdram_dq_output_enable <= 1'b0;
|
||||
|
||||
case (sdram_next_cmd)
|
||||
CMD_READ, CMD_WRITE: begin
|
||||
{sdram_ba, sdram_a} <= {address[25:24], 3'b000, address[10:1]};
|
||||
sdram_dq_output_enable <= sdram_next_cmd == CMD_WRITE;
|
||||
{sdram_ba, sdram_a} <= {mem_bus.address[25:24], 3'b000, mem_bus.address[10:1]};
|
||||
sdram_dqm <= (sdram_next_cmd == CMD_WRITE) ? (~mem_bus.wmask) : 2'b00;
|
||||
sdram_dq_output_enable <= (sdram_next_cmd == CMD_WRITE);
|
||||
end
|
||||
|
||||
CMD_ACT: begin
|
||||
{sdram_ba, sdram_a} <= address[25:11];
|
||||
current_active_bank_row <= address[25:11];
|
||||
{sdram_ba, sdram_a} <= mem_bus.address[25:11];
|
||||
sdram_dqm <= 2'b00;
|
||||
current_active_bank_row <= mem_bus.address[25:11];
|
||||
end
|
||||
|
||||
CMD_PRE: begin
|
||||
{sdram_ba, sdram_a} <= {2'b00, 2'b00, 1'b1, 10'd0};
|
||||
sdram_dqm <= 2'b00;
|
||||
end
|
||||
|
||||
CMD_MRS: begin
|
||||
{sdram_ba, sdram_a} <= {2'b00, 1'b0, 1'b0, 2'b00, CAS_LATENCY, 1'b0, 3'b000};
|
||||
sdram_dqm <= 2'b00;
|
||||
end
|
||||
CMD_PRE: {sdram_ba, sdram_a} <= {2'b00, 2'b00, 1'b1, 10'd0};
|
||||
CMD_MRS: {sdram_ba, sdram_a} <= {2'b00, 1'b0, 1'b0, 2'b00, CAS_LATENCY, 1'b0, 3'b000};
|
||||
endcase
|
||||
end
|
||||
|
||||
assign sdram_dq = sdram_dq_output_enable ? sdram_dq_output : 16'hZZZZ;
|
||||
|
||||
always_comb begin
|
||||
rdata = sdram_dq_input;
|
||||
sdram_dq = sdram_dq_output_enable ? sdram_dq_output : 16'hZZZZ;
|
||||
request_in_current_active_bank_row = address[25:11] == current_active_bank_row;
|
||||
mem_bus.rdata = sdram_dq_input;
|
||||
request_in_current_active_bank_row = mem_bus.address[25:11] == current_active_bank_row;
|
||||
end
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
S_POWERUP,
|
||||
S_INIT,
|
||||
S_IDLE,
|
||||
S_ACTIVATING,
|
||||
@ -106,44 +113,54 @@ module memory_sdram (
|
||||
e_state state;
|
||||
e_state next_state;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
state <= S_INIT;
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
state <= S_POWERUP;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
logic [13:0] wait_counter;
|
||||
logic [13:0] powerup_coutner;
|
||||
logic powerup_done;
|
||||
logic [4:0] wait_counter;
|
||||
logic [9:0] refresh_counter;
|
||||
logic pending_refresh;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || state != next_state) begin
|
||||
wait_counter <= 14'd0;
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
powerup_coutner <= 14'd0;
|
||||
powerup_done <= 1'b0;
|
||||
end else if (powerup_coutner < C_INIT) begin
|
||||
powerup_coutner <= powerup_coutner + 1'd1;
|
||||
end else begin
|
||||
powerup_done <= 1'b1;
|
||||
end
|
||||
|
||||
if (reset || state != next_state) begin
|
||||
wait_counter <= 5'd0;
|
||||
end else begin
|
||||
wait_counter <= wait_counter + 1'd1;
|
||||
end
|
||||
|
||||
if (sdram_next_cmd == CMD_REF) begin
|
||||
refresh_counter <= 10'd0;
|
||||
end else if (refresh_counter < 10'h3FF) begin
|
||||
pending_refresh <= 1'b0;
|
||||
end else if (refresh_counter < C_REF) begin
|
||||
refresh_counter <= refresh_counter + 1'd1;
|
||||
end else begin
|
||||
pending_refresh <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
pending_refresh = refresh_counter >= C_REF;
|
||||
end
|
||||
|
||||
logic [(CAS_LATENCY):0] read_cmd_ack_delay;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
ack <= 1'b0;
|
||||
always_ff @(posedge clk) begin
|
||||
mem_bus.ack <= 1'b0;
|
||||
read_cmd_ack_delay <= {sdram_next_cmd == CMD_READ, read_cmd_ack_delay[(CAS_LATENCY):1]};
|
||||
|
||||
if (sdram_next_cmd == CMD_WRITE || read_cmd_ack_delay[0]) begin
|
||||
ack <= 1'b1;
|
||||
mem_bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
@ -152,10 +169,14 @@ module memory_sdram (
|
||||
next_state = state;
|
||||
|
||||
case (state)
|
||||
S_INIT: begin
|
||||
if (wait_counter < INIT_PRECHARGE) begin
|
||||
sdram_next_cmd = CMD_DESL;
|
||||
S_POWERUP: begin
|
||||
sdram_next_cmd = CMD_DESL;
|
||||
if (powerup_done) begin
|
||||
next_state = S_INIT;
|
||||
end
|
||||
end
|
||||
|
||||
S_INIT: begin
|
||||
if (wait_counter == INIT_PRECHARGE) begin
|
||||
sdram_next_cmd = CMD_PRE;
|
||||
end
|
||||
@ -174,7 +195,7 @@ module memory_sdram (
|
||||
if (pending_refresh) begin
|
||||
next_state = S_REFRESH;
|
||||
sdram_next_cmd = CMD_REF;
|
||||
end else if (request) begin
|
||||
end else if (mem_bus.request) begin
|
||||
next_state = S_ACTIVATING;
|
||||
sdram_next_cmd = CMD_ACT;
|
||||
end
|
||||
@ -190,10 +211,10 @@ module memory_sdram (
|
||||
if (pending_refresh) begin
|
||||
next_state = S_PRECHARGE;
|
||||
sdram_next_cmd = CMD_PRE;
|
||||
end else if (request) begin
|
||||
end else if (mem_bus.request) begin
|
||||
if (request_in_current_active_bank_row) begin
|
||||
next_state = S_BUSY;
|
||||
sdram_next_cmd = write ? CMD_WRITE : CMD_READ;
|
||||
sdram_next_cmd = mem_bus.write ? CMD_WRITE : CMD_READ;
|
||||
end else begin
|
||||
next_state = S_PRECHARGE;
|
||||
sdram_next_cmd = CMD_PRE;
|
||||
@ -202,7 +223,7 @@ module memory_sdram (
|
||||
end
|
||||
|
||||
S_BUSY: begin
|
||||
if (ack) begin
|
||||
if (mem_bus.ack) begin
|
||||
next_state = S_ACTIVE;
|
||||
end
|
||||
end
|
||||
|
@ -1,124 +0,0 @@
|
||||
module n64_bootloader (
|
||||
if_system.sys sys,
|
||||
if_n64_bus bus,
|
||||
if_flash.memory flash
|
||||
);
|
||||
|
||||
logic mem_request;
|
||||
logic csr_ack;
|
||||
logic data_ack;
|
||||
logic write_ack;
|
||||
logic data_busy;
|
||||
logic mem_write;
|
||||
logic [31:0] mem_address;
|
||||
logic [31:0] csr_rdata;
|
||||
logic [31:0] data_rdata;
|
||||
logic [31:0] mem_wdata;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
T_N64,
|
||||
T_CPU
|
||||
} e_source_request;
|
||||
|
||||
e_state state;
|
||||
e_source_request source_request;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
csr_ack <= 1'b0;
|
||||
write_ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
mem_request <= 1'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request || flash.request) begin
|
||||
state <= S_WAIT;
|
||||
mem_request <= 1'b1;
|
||||
if (bus.request) begin
|
||||
mem_write <= 1'b0;
|
||||
mem_address <= bus.address;
|
||||
mem_wdata <= bus.wdata;
|
||||
source_request <= T_N64;
|
||||
end else if (flash.request) begin
|
||||
mem_write <= flash.write;
|
||||
mem_address <= flash.address;
|
||||
mem_wdata <= flash.wdata;
|
||||
source_request <= T_CPU;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
if (mem_address[27] && source_request != T_N64 && !csr_ack) begin
|
||||
mem_request <= 1'b0;
|
||||
csr_ack <= 1'b1;
|
||||
end
|
||||
if ((!mem_address[27] || source_request == T_N64) && !data_busy) begin
|
||||
mem_request <= 1'b0;
|
||||
end
|
||||
if (!mem_address[27] && mem_write && !data_busy && !write_ack) begin
|
||||
write_ack <= 1'b1;
|
||||
end
|
||||
if (csr_ack || data_ack || write_ack) begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
logic csr_or_data;
|
||||
logic csr_read;
|
||||
logic csr_write;
|
||||
logic data_read;
|
||||
logic data_write;
|
||||
|
||||
always_comb begin
|
||||
csr_or_data = mem_address[27] && source_request == T_CPU;
|
||||
csr_read = csr_or_data && mem_request && !mem_write;
|
||||
csr_write = csr_or_data && mem_request && mem_write;
|
||||
data_read = !csr_or_data && mem_request && !mem_write;
|
||||
data_write = !csr_or_data && mem_request && mem_write;
|
||||
|
||||
bus.ack = source_request == T_N64 && data_ack;
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack && bus.address >= 32'h10000000 && bus.address < 32'h10016800) begin
|
||||
if (bus.address[1]) bus.rdata = {data_rdata[23:16], data_rdata[31:24]};
|
||||
else bus.rdata = {data_rdata[7:0], data_rdata[15:8]};
|
||||
end
|
||||
|
||||
flash.ack = source_request == T_CPU && (csr_ack || data_ack || write_ack);
|
||||
flash.rdata = 32'd0;
|
||||
if (flash.ack) begin
|
||||
flash.rdata = csr_or_data ? csr_rdata : data_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
intel_flash intel_flash_inst (
|
||||
.clock(sys.clk),
|
||||
.reset_n(~sys.reset),
|
||||
|
||||
.avmm_csr_addr(mem_address[2]),
|
||||
.avmm_csr_read(csr_read),
|
||||
.avmm_csr_writedata(mem_wdata),
|
||||
.avmm_csr_write(csr_write),
|
||||
.avmm_csr_readdata(csr_rdata),
|
||||
|
||||
.avmm_data_addr(mem_address[31:2]),
|
||||
.avmm_data_read(data_read),
|
||||
.avmm_data_writedata(mem_wdata),
|
||||
.avmm_data_write(data_write),
|
||||
.avmm_data_readdata(data_rdata),
|
||||
.avmm_data_waitrequest(data_busy),
|
||||
.avmm_data_readdatavalid(data_ack),
|
||||
.avmm_data_burstcount(2'd1)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,67 +0,0 @@
|
||||
interface if_n64_bus ();
|
||||
|
||||
localparam sc64::e_n64_id NUM_DEVICES = sc64::__ID_N64_END;
|
||||
|
||||
sc64::e_n64_id id;
|
||||
logic request;
|
||||
logic ack;
|
||||
logic write;
|
||||
logic [31:0] address;
|
||||
logic [15:0] wdata;
|
||||
logic [15:0] rdata;
|
||||
logic [31:0] real_address;
|
||||
logic read_op;
|
||||
logic write_op;
|
||||
|
||||
logic device_ack [(NUM_DEVICES - 1):0];
|
||||
logic [15:0] device_rdata [(NUM_DEVICES - 1):0];
|
||||
|
||||
always_comb begin
|
||||
ack = 1'b0;
|
||||
rdata = 16'd0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
ack = ack | device_ack[i];
|
||||
rdata = rdata | device_rdata[i];
|
||||
end
|
||||
end
|
||||
|
||||
modport n64 (
|
||||
output id,
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output address,
|
||||
output wdata,
|
||||
input rdata,
|
||||
|
||||
output real_address,
|
||||
output read_op,
|
||||
output write_op
|
||||
);
|
||||
|
||||
genvar n;
|
||||
generate
|
||||
for (n = 0; n < NUM_DEVICES; n++) begin : at
|
||||
logic device_request;
|
||||
|
||||
always_comb begin
|
||||
device_request = request && id == sc64::e_n64_id'(n);
|
||||
end
|
||||
|
||||
modport device (
|
||||
input .request(device_request),
|
||||
output .ack(device_ack[n]),
|
||||
input .write(write),
|
||||
input .address(address),
|
||||
input .wdata(wdata),
|
||||
output .rdata(device_rdata[n]),
|
||||
|
||||
input .real_address(real_address),
|
||||
input .read_op(read_op),
|
||||
input .write_op(write_op)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endinterface
|
@ -1,83 +1,137 @@
|
||||
module n64_cfg (
|
||||
if_system sys,
|
||||
if_n64_bus bus,
|
||||
if_config.n64 cfg
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_reg_bus.cfg reg_bus,
|
||||
|
||||
n64_scb.cfg n64_scb,
|
||||
|
||||
output logic irq
|
||||
);
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
R_SR,
|
||||
R_COMMAND,
|
||||
R_DATA_0_H,
|
||||
R_DATA_0_L,
|
||||
R_DATA_1_H,
|
||||
R_DATA_1_L,
|
||||
R_VERSION_H,
|
||||
R_VERSION_L
|
||||
} e_reg_id;
|
||||
REG_STATUS,
|
||||
REG_COMMAND,
|
||||
REG_DATA_0_H,
|
||||
REG_DATA_0_L,
|
||||
REG_DATA_1_H,
|
||||
REG_DATA_1_L,
|
||||
REG_VERSION_H,
|
||||
REG_VERSION_L,
|
||||
REG_KEY_H,
|
||||
REG_KEY_L
|
||||
} e_reg;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
logic cfg_error;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[3:1])
|
||||
R_SR: bus.rdata = {
|
||||
cfg.cpu_ready,
|
||||
cfg.cpu_busy,
|
||||
1'b0,
|
||||
cfg.cmd_error,
|
||||
12'd0
|
||||
reg_bus.rdata = 16'd0;
|
||||
if (reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin
|
||||
case (reg_bus.address[4:1])
|
||||
REG_STATUS: reg_bus.rdata = {
|
||||
n64_scb.cfg_pending,
|
||||
cfg_error,
|
||||
irq,
|
||||
13'd0
|
||||
};
|
||||
R_COMMAND: bus.rdata = {8'd0, cfg.cmd};
|
||||
R_DATA_0_H: bus.rdata = cfg.data[0][31:16];
|
||||
R_DATA_0_L: bus.rdata = cfg.data[0][15:0];
|
||||
R_DATA_1_H: bus.rdata = cfg.data[1][31:16];
|
||||
R_DATA_1_L: bus.rdata = cfg.data[1][15:0];
|
||||
R_VERSION_H: bus.rdata = sc64::SC64_VER[31:16];
|
||||
R_VERSION_L: bus.rdata = sc64::SC64_VER[15:0];
|
||||
REG_COMMAND: reg_bus.rdata = {8'd0, n64_scb.cfg_cmd};
|
||||
REG_DATA_0_H: reg_bus.rdata = n64_scb.cfg_wdata[0][31:16];
|
||||
REG_DATA_0_L: reg_bus.rdata = n64_scb.cfg_wdata[0][15:0];
|
||||
REG_DATA_1_H: reg_bus.rdata = n64_scb.cfg_wdata[1][31:16];
|
||||
REG_DATA_1_L: reg_bus.rdata = n64_scb.cfg_wdata[1][15:0];
|
||||
REG_VERSION_H: reg_bus.rdata = n64_scb.cfg_version[31:16];
|
||||
REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0];
|
||||
REG_KEY_H: reg_bus.rdata = 16'd0;
|
||||
REG_KEY_L: reg_bus.rdata = 16'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
cfg.cmd_request <= 1'b0;
|
||||
logic unlock_flag;
|
||||
logic lock_sequence_counter;
|
||||
|
||||
if (cfg.data_write[0]) cfg.data[0] <= cfg.wdata;
|
||||
if (cfg.data_write[1]) cfg.data[1] <= cfg.wdata;
|
||||
always_ff @(posedge clk) begin
|
||||
if (n64_scb.cfg_done) begin
|
||||
n64_scb.cfg_pending <= 1'b0;
|
||||
cfg_error <= n64_scb.cfg_error;
|
||||
end
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
if (bus.write) begin
|
||||
case (bus.address[3:1])
|
||||
R_COMMAND: begin
|
||||
cfg.cmd <= bus.wdata[7:0];
|
||||
cfg.cmd_request <= 1'b1;
|
||||
end
|
||||
R_DATA_0_H: cfg.data[0][31:16] <= bus.wdata;
|
||||
R_DATA_0_L: cfg.data[0][15:0] <= bus.wdata;
|
||||
R_DATA_1_H: cfg.data[1][31:16] <= bus.wdata;
|
||||
R_DATA_1_L: cfg.data[1][15:0] <= bus.wdata;
|
||||
endcase
|
||||
if (n64_scb.cfg_irq) begin
|
||||
irq <= 1'b1;
|
||||
end
|
||||
|
||||
if (unlock_flag) begin
|
||||
n64_scb.cfg_unlock <= 1'b1;
|
||||
end
|
||||
|
||||
if (reset || n64_scb.n64_reset || n64_scb.n64_nmi) begin
|
||||
n64_scb.cfg_unlock <= 1'b0;
|
||||
n64_scb.cfg_pending <= 1'b0;
|
||||
n64_scb.cfg_cmd <= 8'h00;
|
||||
irq <= 1'b0;
|
||||
cfg_error <= 1'b0;
|
||||
lock_sequence_counter <= 1'd0;
|
||||
end else if (n64_scb.cfg_unlock) begin
|
||||
if (reg_bus.write && reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin
|
||||
case (reg_bus.address[4:1])
|
||||
REG_COMMAND: begin
|
||||
n64_scb.cfg_pending <= 1'b1;
|
||||
n64_scb.cfg_cmd <= reg_bus.wdata[7:0];
|
||||
cfg_error <= 1'b0;
|
||||
end
|
||||
REG_DATA_0_H: n64_scb.cfg_rdata[0][31:16] <= reg_bus.wdata;
|
||||
REG_DATA_0_L: n64_scb.cfg_rdata[0][15:0] <= reg_bus.wdata;
|
||||
REG_DATA_1_H: n64_scb.cfg_rdata[1][31:16] <= reg_bus.wdata;
|
||||
REG_DATA_1_L: n64_scb.cfg_rdata[1][15:0] <= reg_bus.wdata;
|
||||
REG_VERSION_H: irq <= 1'b0;
|
||||
REG_KEY_H, REG_KEY_L: begin
|
||||
lock_sequence_counter <= lock_sequence_counter + 1'd1;
|
||||
if (reg_bus.wdata != 16'hFFFF) begin
|
||||
lock_sequence_counter <= 1'd0;
|
||||
end
|
||||
if (lock_sequence_counter == 1'd1) begin
|
||||
n64_scb.cfg_unlock <= (reg_bus.wdata != 16'hFFFF);
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
const bit [15:0] UNLOCK_SEQUENCE [4] = {
|
||||
16'h5F55,
|
||||
16'h4E4C,
|
||||
16'h4F43,
|
||||
16'h4B5F
|
||||
};
|
||||
|
||||
logic [1:0] unlock_sequence_counter;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
unlock_flag <= 1'b0;
|
||||
|
||||
if (reset || n64_scb.n64_reset || n64_scb.n64_nmi) begin
|
||||
unlock_sequence_counter <= 2'd0;
|
||||
end else if (!n64_scb.cfg_unlock) begin
|
||||
if (reg_bus.write && reg_bus.address[16] && (reg_bus.address[15:5] == 11'd0)) begin
|
||||
case (reg_bus.address[4:1])
|
||||
REG_KEY_H, REG_KEY_L: begin
|
||||
for (int index = 0; index < $size(UNLOCK_SEQUENCE); index++) begin
|
||||
if (index == unlock_sequence_counter) begin
|
||||
if (reg_bus.wdata == UNLOCK_SEQUENCE[index]) begin
|
||||
unlock_sequence_counter <= unlock_sequence_counter + 1'd1;
|
||||
if (index == ($size(UNLOCK_SEQUENCE) - 1'd1)) begin
|
||||
unlock_flag <= 1'b1;
|
||||
unlock_sequence_counter <= 2'd0;
|
||||
end
|
||||
end else begin
|
||||
unlock_sequence_counter <= 2'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,21 +1,4 @@
|
||||
interface if_dd (
|
||||
output dd_interrupt
|
||||
);
|
||||
|
||||
// Sector buffer regs
|
||||
|
||||
logic [6:0] n64_sector_address;
|
||||
logic n64_sector_address_valid;
|
||||
logic n64_sector_write;
|
||||
logic [15:0] n64_sector_wdata;
|
||||
|
||||
logic [5:0] cpu_sector_address;
|
||||
logic cpu_sector_address_valid;
|
||||
logic cpu_sector_write;
|
||||
logic [31:0] cpu_sector_wdata;
|
||||
|
||||
logic [31:0] sector_rdata;
|
||||
|
||||
interface dd_scb ();
|
||||
|
||||
// N64 controlled regs
|
||||
|
||||
@ -55,11 +38,38 @@ interface if_dd (
|
||||
logic [12:0] head_track;
|
||||
logic [15:0] drive_id;
|
||||
|
||||
modport controller (
|
||||
input hard_reset,
|
||||
input data,
|
||||
input cmd,
|
||||
input cmd_pending,
|
||||
input bm_start_pending,
|
||||
input bm_stop_pending,
|
||||
input bm_transfer_mode,
|
||||
input bm_transfer_blocks,
|
||||
input bm_pending,
|
||||
input bm_interrupt_ack,
|
||||
input sector_num,
|
||||
input sector_size,
|
||||
input sector_size_full,
|
||||
input sectors_in_block,
|
||||
|
||||
always_comb begin
|
||||
dd_interrupt = cmd_interrupt || bm_interrupt;
|
||||
end
|
||||
|
||||
output hard_reset_clear,
|
||||
output cmd_data,
|
||||
output cmd_ready,
|
||||
output bm_start_clear,
|
||||
output bm_stop_clear,
|
||||
output bm_transfer_c2,
|
||||
output bm_transfer_data,
|
||||
output bm_micro_error,
|
||||
output bm_ready,
|
||||
output bm_clear,
|
||||
output disk_inserted,
|
||||
output disk_changed,
|
||||
output index_lock,
|
||||
output head_track,
|
||||
output drive_id
|
||||
);
|
||||
|
||||
modport dd (
|
||||
output hard_reset,
|
||||
@ -93,90 +103,36 @@ interface if_dd (
|
||||
input disk_changed,
|
||||
input index_lock,
|
||||
input head_track,
|
||||
input drive_id,
|
||||
|
||||
output .sector_address(n64_sector_address),
|
||||
output .sector_address_valid(n64_sector_address_valid),
|
||||
output .sector_write(n64_sector_write),
|
||||
output .sector_wdata(n64_sector_wdata),
|
||||
input sector_rdata
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
input hard_reset,
|
||||
input data,
|
||||
input cmd,
|
||||
input cmd_pending,
|
||||
input bm_start_pending,
|
||||
input bm_stop_pending,
|
||||
input bm_transfer_mode,
|
||||
input bm_transfer_blocks,
|
||||
input bm_pending,
|
||||
input bm_interrupt_ack,
|
||||
input sector_num,
|
||||
input sector_size,
|
||||
input sector_size_full,
|
||||
input sectors_in_block,
|
||||
|
||||
output hard_reset_clear,
|
||||
output cmd_data,
|
||||
output cmd_ready,
|
||||
output bm_start_clear,
|
||||
output bm_stop_clear,
|
||||
output bm_transfer_c2,
|
||||
output bm_transfer_data,
|
||||
output bm_micro_error,
|
||||
output bm_ready,
|
||||
output bm_clear,
|
||||
output disk_inserted,
|
||||
output disk_changed,
|
||||
output index_lock,
|
||||
output head_track,
|
||||
output drive_id,
|
||||
|
||||
output .sector_address(cpu_sector_address),
|
||||
output .sector_address_valid(cpu_sector_address_valid),
|
||||
output .sector_write(cpu_sector_write),
|
||||
output .sector_wdata(cpu_sector_wdata),
|
||||
input sector_rdata
|
||||
);
|
||||
|
||||
modport sector_buffer (
|
||||
input n64_sector_address,
|
||||
input n64_sector_address_valid,
|
||||
input n64_sector_write,
|
||||
input n64_sector_wdata,
|
||||
|
||||
input cpu_sector_address,
|
||||
input cpu_sector_address_valid,
|
||||
input cpu_sector_write,
|
||||
input cpu_sector_wdata,
|
||||
|
||||
output sector_rdata
|
||||
input drive_id
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module n64_dd (
|
||||
if_system.sys sys,
|
||||
if_n64_bus bus,
|
||||
if_dd.dd dd
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_reg_bus.dd reg_bus,
|
||||
|
||||
n64_scb.dd n64_scb,
|
||||
dd_scb.dd dd_scb,
|
||||
|
||||
output logic irq
|
||||
);
|
||||
|
||||
const bit [31:0] M_BASE = 32'h0500_0000;
|
||||
const bit [31:0] M_C2_BUFFER = M_BASE + 11'h000;
|
||||
const bit [31:0] M_SECTOR_BUFFER = M_BASE + 11'h400;
|
||||
const bit [10:0] MEM_C2_BUFFER = 11'h000;
|
||||
const bit [10:0] MEM_SECTOR_BUFFER = 11'h400;
|
||||
|
||||
typedef enum bit [10:0] {
|
||||
R_DATA = 11'h500,
|
||||
R_CMD_SR = 11'h508,
|
||||
R_TRK_CUR = 11'h50C,
|
||||
R_BM_SCR = 11'h510,
|
||||
R_RESET = 11'h520,
|
||||
R_SEC_SIZ = 11'h528,
|
||||
R_SEC_INFO = 11'h530,
|
||||
R_ID = 11'h540
|
||||
REG_DATA = 11'h500,
|
||||
REG_CMD_SR = 11'h508,
|
||||
REG_TRK_CUR = 11'h50C,
|
||||
REG_BM_SCR = 11'h510,
|
||||
REG_RESET = 11'h520,
|
||||
REG_SEC_SIZ = 11'h528,
|
||||
REG_SEC_INFO = 11'h530,
|
||||
REG_ID = 11'h540
|
||||
} e_reg_id;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
@ -187,218 +143,144 @@ module n64_dd (
|
||||
BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8
|
||||
} e_bm_control_id;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
|
||||
always_comb begin
|
||||
dd.sector_address = bus.address[7:1];
|
||||
dd.sector_address_valid = bus.request && bus.address[11:8] == M_SECTOR_BUFFER[11:8];
|
||||
dd.sector_write = bus.write && dd.sector_address_valid;
|
||||
dd.sector_wdata = bus.wdata;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack) begin
|
||||
if (bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin
|
||||
if (bus.address[1]) begin
|
||||
bus.rdata = dd.sector_rdata[15:0];
|
||||
end else begin
|
||||
bus.rdata = dd.sector_rdata[31:16];
|
||||
end
|
||||
end else begin
|
||||
case (bus.address[10:0])
|
||||
R_DATA: bus.rdata = dd.data;
|
||||
R_CMD_SR: bus.rdata = {
|
||||
1'b0,
|
||||
dd.bm_transfer_data,
|
||||
1'b0,
|
||||
dd.bm_transfer_c2,
|
||||
1'b0,
|
||||
dd.bm_interrupt,
|
||||
dd.cmd_interrupt,
|
||||
dd.disk_inserted,
|
||||
dd.cmd_pending,
|
||||
dd.hard_reset,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
dd.disk_changed
|
||||
};
|
||||
R_TRK_CUR: bus.rdata = {1'd0, {2{dd.index_lock}}, dd.head_track};
|
||||
R_BM_SCR: bus.rdata = {6'd0, dd.bm_micro_error, 9'd0};
|
||||
R_ID: bus.rdata = {dd.drive_id};
|
||||
default: bus.rdata = 16'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
dd.bm_interrupt_ack <= 1'b0;
|
||||
|
||||
if (dd.hard_reset_clear) begin
|
||||
dd.hard_reset <= 1'b0;
|
||||
end
|
||||
if (dd.cmd_ready) begin
|
||||
dd.data <= dd.cmd_data;
|
||||
dd.cmd_pending <= 1'b0;
|
||||
dd.cmd_interrupt <= 1'b1;
|
||||
end
|
||||
if (dd.bm_start_clear) begin
|
||||
dd.bm_start_pending <= 1'b0;
|
||||
end
|
||||
if (dd.bm_stop_clear) begin
|
||||
dd.bm_stop_pending <= 1'b0;
|
||||
end
|
||||
if (dd.bm_clear) begin
|
||||
dd.bm_pending <= 1'b0;
|
||||
end
|
||||
if (dd.bm_ready) begin
|
||||
dd.bm_interrupt <= 1'b1;
|
||||
end
|
||||
if (bus.real_address == (M_C2_BUFFER + ({dd.sector_size[7:1], 1'b0} * 3'd4)) && bus.read_op) begin
|
||||
dd.bm_pending <= 1'b1;
|
||||
end
|
||||
if (bus.real_address == (M_SECTOR_BUFFER + {dd.sector_size[7:1], 1'b0}) && (bus.read_op || bus.write_op)) begin
|
||||
dd.bm_pending <= 1'b1;
|
||||
end
|
||||
if (bus.real_address == (M_BASE + R_CMD_SR) && bus.read_op) begin
|
||||
dd.bm_interrupt <= 1'b0;
|
||||
dd.bm_interrupt_ack <= 1'b1;
|
||||
end
|
||||
|
||||
if (sys.reset || sys.n64_hard_reset) begin
|
||||
dd.hard_reset <= 1'b1;
|
||||
dd.cmd_pending <= 1'b0;
|
||||
dd.cmd_interrupt <= 1'b0;
|
||||
dd.bm_start_pending <= 1'b0;
|
||||
dd.bm_stop_pending <= 1'b0;
|
||||
dd.bm_pending <= 1'b0;
|
||||
dd.bm_interrupt <= 1'b0;
|
||||
state <= S_IDLE;
|
||||
reg_bus.rdata = 16'd0;
|
||||
if (reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8]) begin
|
||||
reg_bus.rdata = n64_scb.dd_rdata;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
if (bus.write) begin
|
||||
case (bus.address[10:0])
|
||||
R_DATA: begin
|
||||
dd.data <= bus.wdata;
|
||||
end
|
||||
case (reg_bus.address[10:0])
|
||||
REG_DATA: reg_bus.rdata = dd_scb.data;
|
||||
REG_CMD_SR: reg_bus.rdata = {
|
||||
1'b0,
|
||||
dd_scb.bm_transfer_data,
|
||||
1'b0,
|
||||
dd_scb.bm_transfer_c2,
|
||||
1'b0,
|
||||
dd_scb.bm_interrupt,
|
||||
dd_scb.cmd_interrupt,
|
||||
dd_scb.disk_inserted,
|
||||
dd_scb.cmd_pending,
|
||||
dd_scb.hard_reset,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
dd_scb.disk_changed
|
||||
};
|
||||
REG_TRK_CUR: reg_bus.rdata = {1'd0, {2{dd_scb.index_lock}}, dd_scb.head_track};
|
||||
REG_BM_SCR: reg_bus.rdata = {6'd0, dd_scb.bm_micro_error, 9'd0};
|
||||
REG_ID: reg_bus.rdata = dd_scb.drive_id;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
R_CMD_SR: begin
|
||||
dd.cmd <= bus.wdata[7:0];
|
||||
dd.cmd_pending <= 1'b1;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
dd_scb.bm_interrupt_ack <= 1'b0;
|
||||
|
||||
R_BM_SCR: begin
|
||||
dd.sector_num <= bus.wdata[7:0];
|
||||
if (bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin
|
||||
dd.bm_start_pending <= 1'b1;
|
||||
dd.bm_stop_pending <= 1'b0;
|
||||
dd.bm_transfer_mode <= bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE];
|
||||
dd.bm_transfer_blocks <= bus.wdata[BM_CONTROL_BLOCK_TRANSFER];
|
||||
end
|
||||
if (bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin
|
||||
dd.bm_start_pending <= 1'b0;
|
||||
dd.bm_stop_pending <= 1'b1;
|
||||
dd.bm_transfer_mode <= 1'b0;
|
||||
dd.bm_transfer_blocks <= 1'b0;
|
||||
dd.bm_pending <= 1'b0;
|
||||
dd.bm_interrupt <= 1'b0;
|
||||
end
|
||||
if (bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin
|
||||
dd.cmd_interrupt <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (dd_scb.hard_reset_clear) begin
|
||||
dd_scb.hard_reset <= 1'b0;
|
||||
end
|
||||
if (dd_scb.cmd_ready) begin
|
||||
dd_scb.data <= dd_scb.cmd_data;
|
||||
dd_scb.cmd_pending <= 1'b0;
|
||||
dd_scb.cmd_interrupt <= 1'b1;
|
||||
end
|
||||
if (dd_scb.bm_start_clear) begin
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
end
|
||||
if (dd_scb.bm_stop_clear) begin
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
end
|
||||
if (dd_scb.bm_clear) begin
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
end
|
||||
if (dd_scb.bm_ready) begin
|
||||
dd_scb.bm_interrupt <= 1'b1;
|
||||
end
|
||||
if (reg_bus.address[10:0] == (MEM_C2_BUFFER + ({dd_scb.sector_size[7:1], 1'b0} * 3'd4)) && reg_bus.read) begin
|
||||
dd_scb.bm_pending <= 1'b1;
|
||||
end
|
||||
if (reg_bus.address[10:0] == (MEM_SECTOR_BUFFER + {dd_scb.sector_size[7:1], 1'b0}) && (reg_bus.read || reg_bus.write)) begin
|
||||
dd_scb.bm_pending <= 1'b1;
|
||||
end
|
||||
if (reg_bus.address[10:0] == REG_CMD_SR && reg_bus.read) begin
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
dd_scb.bm_interrupt_ack <= 1'b1;
|
||||
end
|
||||
|
||||
R_RESET: begin
|
||||
if (bus.wdata == 16'hAAAA) begin
|
||||
dd.hard_reset <= 1'b1;
|
||||
dd.cmd_pending <= 1'b0;
|
||||
dd.cmd_interrupt <= 1'b0;
|
||||
dd.bm_start_pending <= 1'b0;
|
||||
dd.bm_stop_pending <= 1'b0;
|
||||
dd.bm_pending <= 1'b0;
|
||||
dd.bm_interrupt <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (reset || n64_scb.n64_reset) begin
|
||||
dd_scb.hard_reset <= 1'b1;
|
||||
dd_scb.cmd_pending <= 1'b0;
|
||||
dd_scb.cmd_interrupt <= 1'b0;
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
end else if (reg_bus.write) begin
|
||||
case (reg_bus.address[10:0])
|
||||
REG_DATA: begin
|
||||
dd_scb.data <= reg_bus.wdata;
|
||||
end
|
||||
|
||||
R_SEC_SIZ: begin
|
||||
dd.sector_size <= bus.wdata[7:0];
|
||||
end
|
||||
REG_CMD_SR: begin
|
||||
dd_scb.cmd <= reg_bus.wdata[7:0];
|
||||
dd_scb.cmd_pending <= 1'b1;
|
||||
end
|
||||
|
||||
R_SEC_INFO: begin
|
||||
dd.sectors_in_block <= bus.wdata[15:8];
|
||||
dd.sector_size_full <= bus.wdata[7:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
REG_BM_SCR: begin
|
||||
dd_scb.sector_num <= reg_bus.wdata[7:0];
|
||||
if (reg_bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin
|
||||
dd_scb.bm_start_pending <= 1'b1;
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
dd_scb.bm_transfer_mode <= reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE];
|
||||
dd_scb.bm_transfer_blocks <= reg_bus.wdata[BM_CONTROL_BLOCK_TRANSFER];
|
||||
end
|
||||
if (reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
dd_scb.bm_stop_pending <= 1'b1;
|
||||
dd_scb.bm_transfer_mode <= 1'b0;
|
||||
dd_scb.bm_transfer_blocks <= 1'b0;
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
end
|
||||
if (reg_bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin
|
||||
dd_scb.cmd_interrupt <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
state <= S_IDLE;
|
||||
REG_RESET: begin
|
||||
if (reg_bus.wdata == 16'hAAAA) begin
|
||||
dd_scb.hard_reset <= 1'b1;
|
||||
dd_scb.cmd_pending <= 1'b0;
|
||||
dd_scb.cmd_interrupt <= 1'b0;
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
REG_SEC_SIZ: begin
|
||||
dd_scb.sector_size <= reg_bus.wdata[7:0];
|
||||
end
|
||||
|
||||
REG_SEC_INFO: begin
|
||||
dd_scb.sectors_in_block <= reg_bus.wdata[15:8];
|
||||
dd_scb.sector_size_full <= reg_bus.wdata[7:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module n64_dd_sector_buffer (
|
||||
if_system.sys sys,
|
||||
if_dd.sector_buffer dd
|
||||
);
|
||||
|
||||
logic [5:0] sector_address;
|
||||
logic [31:0] sector_buffer [0:63];
|
||||
logic [15:0] sector_high_buffer;
|
||||
logic sector_write;
|
||||
logic [31:0] sector_wdata;
|
||||
always_comb begin
|
||||
irq = dd_scb.cmd_interrupt || dd_scb.bm_interrupt;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
sector_address = 6'd0;
|
||||
sector_write = 1'b0;
|
||||
sector_wdata = 32'd0;
|
||||
|
||||
if (dd.n64_sector_address_valid) begin
|
||||
sector_address = dd.n64_sector_address[6:1];
|
||||
end else if (dd.cpu_sector_address_valid) begin
|
||||
sector_address = dd.cpu_sector_address;
|
||||
end
|
||||
|
||||
if (dd.n64_sector_write && dd.n64_sector_address[0]) begin
|
||||
sector_write = 1'b1;
|
||||
sector_wdata = {sector_high_buffer, dd.n64_sector_wdata};
|
||||
end else if (dd.cpu_sector_write) begin
|
||||
sector_write = 1'b1;
|
||||
sector_wdata = dd.cpu_sector_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (dd.n64_sector_write && !dd.n64_sector_address[0]) begin
|
||||
sector_high_buffer <= dd.n64_sector_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
dd.sector_rdata <= sector_buffer[sector_address];
|
||||
if (sector_write) begin
|
||||
sector_buffer[sector_address] <= sector_wdata;
|
||||
end
|
||||
n64_scb.dd_write = reg_bus.write && reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8];
|
||||
n64_scb.dd_address = reg_bus.address[7:1];
|
||||
n64_scb.dd_wdata = reg_bus.wdata;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -1,189 +1,152 @@
|
||||
module n64_flashram (
|
||||
if_system.sys sys,
|
||||
if_n64_bus bus,
|
||||
if_config.flashram cfg,
|
||||
if_flashram.flashram flashram
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_reg_bus.flashram reg_bus,
|
||||
|
||||
n64_scb.flashram n64_scb
|
||||
);
|
||||
|
||||
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
|
||||
localparam [31:0] FLASH_MODEL_ID = 32'h00C2_001D;
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
CMD_STATUS_MODE = 8'hD2,
|
||||
CMD_READID_MODE = 8'hE1,
|
||||
CMD_READ_MODE = 8'hF0,
|
||||
CMD_ERASE_SECTOR = 8'h4B,
|
||||
CMD_ERASE_CHIP = 8'h3C,
|
||||
CMD_BUFFER_MODE = 8'hB4,
|
||||
CMD_ERASE_START = 8'h78,
|
||||
CMD_WRITE_START = 8'hA5
|
||||
CMD_STATUS_MODE = 8'hD2,
|
||||
CMD_READID_MODE = 8'hE1,
|
||||
CMD_READ_MODE = 8'hF0,
|
||||
CMD_ERASE_SECTOR = 8'h4B,
|
||||
CMD_ERASE_CHIP = 8'h3C,
|
||||
CMD_BUFFER_MODE = 8'hB4,
|
||||
CMD_ERASE_START = 8'h78,
|
||||
CMD_WRITE_START = 8'hA5
|
||||
} e_cmd;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_bus_state;
|
||||
typedef enum bit [1:0] {
|
||||
STATE_STATUS,
|
||||
STATE_ID,
|
||||
STATE_READ,
|
||||
STATE_BUFFER
|
||||
} e_state;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
FS_STATUS,
|
||||
FS_ID,
|
||||
FS_READ,
|
||||
FS_BUFFER
|
||||
} e_flashram_state;
|
||||
WRITE_BUSY,
|
||||
ERASE_BUSY,
|
||||
WRITE_DONE,
|
||||
ERASE_DONE
|
||||
} e_status_bits;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
B_WRITE_BUSY,
|
||||
B_ERASE_BUSY,
|
||||
B_WRITE_DONE,
|
||||
B_ERASE_DONE
|
||||
} e_flashram_status;
|
||||
|
||||
e_bus_state bus_state;
|
||||
e_flashram_state flashram_state;
|
||||
logic [3:0] flashram_status;
|
||||
logic [7:0] flashram_command;
|
||||
logic flashram_erase_enabled;
|
||||
|
||||
logic [31:0] write_buffer [0:31];
|
||||
logic [1:0] write_buffer_wmask;
|
||||
logic [15:0] high_buffer;
|
||||
e_state state;
|
||||
logic [3:0] status;
|
||||
logic [7:0] cmd;
|
||||
logic erase_enabled;
|
||||
|
||||
always_comb begin
|
||||
write_buffer_wmask = 2'b00;
|
||||
if (bus.request && bus.write && !bus.address[16] && flashram_state == FS_BUFFER) begin
|
||||
write_buffer_wmask[0] = !bus.address[1];
|
||||
write_buffer_wmask[1] = bus.address[1];
|
||||
n64_scb.flashram_read_mode = (state == STATE_READ);
|
||||
|
||||
reg_bus.rdata = 16'd0;
|
||||
if (state == STATE_ID) begin
|
||||
case (reg_bus.address[2:1])
|
||||
0: reg_bus.rdata = FLASH_TYPE_ID[31:16];
|
||||
1: reg_bus.rdata = FLASH_TYPE_ID[15:0];
|
||||
2: reg_bus.rdata = FLASH_MODEL_ID[31:16];
|
||||
3: reg_bus.rdata = FLASH_MODEL_ID[15:0];
|
||||
endcase
|
||||
end else if (reg_bus.address[1]) begin
|
||||
reg_bus.rdata = {12'd0, status};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (write_buffer_wmask[0]) high_buffer <= bus.wdata;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
flashram.rdata <= write_buffer[flashram.address];
|
||||
if (write_buffer_wmask[1]) write_buffer[bus.address[6:2]] <= {high_buffer, bus.wdata};
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack) begin
|
||||
if (bus.address[1]) begin
|
||||
bus.rdata = {12'd0, flashram_status};
|
||||
end
|
||||
if (flashram_state == FS_ID) begin
|
||||
case (bus.address[2:1])
|
||||
0: bus.rdata = FLASH_TYPE_ID[31:16];
|
||||
1: bus.rdata = FLASH_TYPE_ID[15:0];
|
||||
2: bus.rdata = FLASH_MODEL_ID[31:16];
|
||||
3: bus.rdata = FLASH_MODEL_ID[15:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
cfg.flashram_read_mode = flashram_state == FS_READ;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
bus_state <= S_IDLE;
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_status <= 4'b0000;
|
||||
flashram_erase_enabled <= 1'b0;
|
||||
flashram.operation_pending <= 1'b0;
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
state <= STATE_STATUS;
|
||||
status <= 4'b0000;
|
||||
erase_enabled <= 1'b0;
|
||||
n64_scb.flashram_pending <= 1'b0;
|
||||
end else begin
|
||||
if (flashram.operation_done) begin
|
||||
flashram.operation_pending <= 1'b0;
|
||||
if (flashram.write_or_erase) begin
|
||||
flashram_status[B_ERASE_BUSY] <= 1'b0;
|
||||
flashram_status[B_ERASE_DONE] <= 1'b1;
|
||||
if (n64_scb.flashram_done) begin
|
||||
n64_scb.flashram_pending <= 1'b0;
|
||||
if (n64_scb.flashram_write_or_erase) begin
|
||||
status[ERASE_BUSY] <= 1'b0;
|
||||
status[ERASE_DONE] <= 1'b1;
|
||||
end else begin
|
||||
flashram_status[B_WRITE_BUSY] <= 1'b0;
|
||||
flashram_status[B_WRITE_DONE] <= 1'b1;
|
||||
status[WRITE_BUSY] <= 1'b0;
|
||||
status[WRITE_DONE] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
case (bus_state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
bus_state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
if (bus.write && !flashram.operation_pending) begin
|
||||
if (bus.address[16]) begin
|
||||
if (!bus.address[1]) begin
|
||||
flashram_command <= bus.wdata[15:8];
|
||||
end else begin
|
||||
flashram_erase_enabled <= 1'b0;
|
||||
if (reg_bus.write && !n64_scb.flashram_pending) begin
|
||||
if (reg_bus.address[16]) begin
|
||||
if (!reg_bus.address[1]) begin
|
||||
cmd <= reg_bus.wdata[15:8];
|
||||
end else begin
|
||||
erase_enabled <= 1'b0;
|
||||
|
||||
case (flashram_command)
|
||||
CMD_STATUS_MODE: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
end
|
||||
case (cmd)
|
||||
CMD_STATUS_MODE: begin
|
||||
state <= STATE_STATUS;
|
||||
end
|
||||
|
||||
CMD_READID_MODE: begin
|
||||
flashram_state <= FS_ID;
|
||||
end
|
||||
CMD_READID_MODE: begin
|
||||
state <= STATE_ID;
|
||||
end
|
||||
|
||||
CMD_READ_MODE: begin
|
||||
flashram_state <= FS_READ;
|
||||
end
|
||||
CMD_READ_MODE: begin
|
||||
state <= STATE_READ;
|
||||
end
|
||||
|
||||
CMD_ERASE_SECTOR: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_erase_enabled <= 1'b1;
|
||||
flashram.sector <= bus.wdata[9:0];
|
||||
flashram.sector_or_all <= 1'b0;
|
||||
end
|
||||
CMD_ERASE_SECTOR: begin
|
||||
state <= STATE_STATUS;
|
||||
erase_enabled <= 1'b1;
|
||||
n64_scb.flashram_sector <= reg_bus.wdata[9:0];
|
||||
n64_scb.flashram_sector_or_all <= 1'b0;
|
||||
end
|
||||
|
||||
CMD_ERASE_CHIP: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_erase_enabled <= 1'b1;
|
||||
flashram.sector <= 10'd0;
|
||||
flashram.sector_or_all <= 1'b1;
|
||||
end
|
||||
CMD_ERASE_CHIP: begin
|
||||
state <= STATE_STATUS;
|
||||
erase_enabled <= 1'b1;
|
||||
n64_scb.flashram_sector <= 10'd0;
|
||||
n64_scb.flashram_sector_or_all <= 1'b1;
|
||||
end
|
||||
|
||||
CMD_BUFFER_MODE: begin
|
||||
flashram_state <= FS_BUFFER;
|
||||
end
|
||||
CMD_BUFFER_MODE: begin
|
||||
state <= STATE_BUFFER;
|
||||
end
|
||||
|
||||
CMD_ERASE_START: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
if (flashram_erase_enabled) begin
|
||||
flashram_status[B_ERASE_BUSY] <= 1'b1;
|
||||
flashram_status[B_ERASE_DONE] <= 1'b0;
|
||||
flashram.operation_pending <= 1'b1;
|
||||
flashram.write_or_erase <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
CMD_WRITE_START: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_status[B_WRITE_BUSY] <= 1'b1;
|
||||
flashram_status[B_WRITE_DONE] <= 1'b0;
|
||||
flashram.sector <= bus.wdata[9:0];
|
||||
flashram.operation_pending <= 1'b1;
|
||||
flashram.write_or_erase <= 1'b0;
|
||||
flashram.sector_or_all <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin
|
||||
if (bus.address[1] && flashram_state == FS_STATUS) begin
|
||||
flashram_status[B_ERASE_BUSY] <= bus.wdata[B_ERASE_BUSY];
|
||||
flashram_status[B_WRITE_BUSY] <= bus.wdata[B_WRITE_BUSY];
|
||||
CMD_ERASE_START: begin
|
||||
state <= STATE_STATUS;
|
||||
if (erase_enabled) begin
|
||||
status[ERASE_BUSY] <= 1'b1;
|
||||
status[ERASE_DONE] <= 1'b0;
|
||||
n64_scb.flashram_pending <= 1'b1;
|
||||
n64_scb.flashram_write_or_erase <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
CMD_WRITE_START: begin
|
||||
state <= STATE_STATUS;
|
||||
status[WRITE_BUSY] <= 1'b1;
|
||||
status[WRITE_DONE] <= 1'b0;
|
||||
n64_scb.flashram_sector <= reg_bus.wdata[9:0];
|
||||
n64_scb.flashram_pending <= 1'b1;
|
||||
n64_scb.flashram_write_or_erase <= 1'b0;
|
||||
n64_scb.flashram_sector_or_all <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin
|
||||
if (reg_bus.address[1] && state != STATE_BUFFER) begin
|
||||
status[ERASE_BUSY] <= reg_bus.wdata[ERASE_BUSY];
|
||||
status[WRITE_BUSY] <= reg_bus.wdata[WRITE_BUSY];
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
bus_state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
n64_scb.flashram_write = reg_bus.write && !reg_bus.address[16] && state == STATE_BUFFER;
|
||||
n64_scb.flashram_address = reg_bus.address[6:1];
|
||||
n64_scb.flashram_wdata = reg_bus.wdata;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -1,8 +1,14 @@
|
||||
module n64_pi (
|
||||
if_system.sys sys,
|
||||
if_config.pi cfg,
|
||||
if_n64_bus.n64 bus,
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
mem_bus.controller mem_bus,
|
||||
n64_reg_bus.controller reg_bus,
|
||||
|
||||
n64_scb.pi n64_scb,
|
||||
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
input n64_pi_alel,
|
||||
input n64_pi_aleh,
|
||||
input n64_pi_read,
|
||||
@ -10,81 +16,36 @@ module n64_pi (
|
||||
inout [15:0] n64_pi_ad
|
||||
);
|
||||
|
||||
// FIFOs
|
||||
|
||||
logic read_fifo_flush;
|
||||
|
||||
logic read_fifo_full;
|
||||
logic read_fifo_write;
|
||||
logic [15:0] read_fifo_wdata;
|
||||
|
||||
logic read_fifo_empty;
|
||||
logic read_fifo_read;
|
||||
logic [15:0] read_fifo_rdata;
|
||||
|
||||
n64_pi_fifo read_fifo_inst (
|
||||
.sys(sys),
|
||||
|
||||
.flush(read_fifo_flush),
|
||||
|
||||
.full(read_fifo_full),
|
||||
.write(read_fifo_write),
|
||||
.wdata(read_fifo_wdata),
|
||||
|
||||
.empty(read_fifo_empty),
|
||||
.read(read_fifo_read),
|
||||
.rdata(read_fifo_rdata)
|
||||
);
|
||||
|
||||
logic write_fifo_flush;
|
||||
|
||||
logic write_fifo_full;
|
||||
logic write_fifo_write;
|
||||
logic [15:0] write_fifo_wdata;
|
||||
|
||||
logic write_fifo_empty;
|
||||
logic write_fifo_read;
|
||||
logic [15:0] write_fifo_rdata;
|
||||
|
||||
n64_pi_fifo write_fifo_inst (
|
||||
.sys(sys),
|
||||
|
||||
.flush(write_fifo_flush),
|
||||
|
||||
.full(write_fifo_full),
|
||||
.write(write_fifo_write),
|
||||
.wdata(write_fifo_wdata),
|
||||
|
||||
.empty(write_fifo_empty),
|
||||
.read(write_fifo_read),
|
||||
.rdata(write_fifo_rdata)
|
||||
);
|
||||
|
||||
|
||||
// Control signals and input synchronization
|
||||
|
||||
logic [2:0] n64_pi_alel_ff;
|
||||
logic [2:0] n64_pi_aleh_ff;
|
||||
logic [2:0] n64_pi_read_ff;
|
||||
logic [1:0] n64_reset_ff;
|
||||
logic [1:0] n64_nmi_ff;
|
||||
logic [3:0] n64_pi_alel_ff;
|
||||
logic [3:0] n64_pi_aleh_ff;
|
||||
logic [1:0] n64_pi_read_ff;
|
||||
logic [2:0] n64_pi_write_ff;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_pi_aleh_ff <= {n64_pi_aleh_ff[1:0], n64_pi_aleh};
|
||||
n64_pi_alel_ff <= {n64_pi_alel_ff[1:0], n64_pi_alel};
|
||||
n64_pi_read_ff <= {n64_pi_read_ff[1:0], n64_pi_read};
|
||||
always_ff @(posedge clk) begin
|
||||
n64_reset_ff <= {n64_reset_ff[0], n64_reset};
|
||||
n64_nmi_ff <= {n64_nmi_ff[0], n64_nmi};
|
||||
n64_pi_aleh_ff <= {n64_pi_aleh_ff[2:0], n64_pi_aleh};
|
||||
n64_pi_alel_ff <= {n64_pi_alel_ff[2:0], n64_pi_alel};
|
||||
n64_pi_read_ff <= {n64_pi_read_ff[0], n64_pi_read};
|
||||
n64_pi_write_ff <= {n64_pi_write_ff[1:0], n64_pi_write};
|
||||
end
|
||||
|
||||
logic pi_reset;
|
||||
logic pi_nmi;
|
||||
logic pi_aleh;
|
||||
logic pi_alel;
|
||||
logic pi_read;
|
||||
logic pi_write;
|
||||
|
||||
always_comb begin
|
||||
pi_reset = sys.n64_hard_reset;
|
||||
pi_aleh = n64_pi_aleh_ff[2];
|
||||
pi_alel = n64_pi_alel_ff[2];
|
||||
pi_reset = n64_reset_ff[1];
|
||||
pi_nmi = n64_nmi_ff[1];
|
||||
pi_aleh = n64_pi_aleh_ff[3];
|
||||
pi_alel = n64_pi_alel_ff[3];
|
||||
pi_read = n64_pi_read_ff[1];
|
||||
pi_write = n64_pi_write_ff[2];
|
||||
end
|
||||
@ -99,16 +60,30 @@ module n64_pi (
|
||||
PI_MODE_VALID = 2'b00
|
||||
} e_pi_mode;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
PORT_NONE,
|
||||
PORT_MEM,
|
||||
PORT_REG
|
||||
} e_port;
|
||||
|
||||
e_pi_mode pi_mode;
|
||||
e_pi_mode last_pi_mode;
|
||||
logic last_read;
|
||||
logic last_write;
|
||||
|
||||
e_port read_port;
|
||||
e_port write_port;
|
||||
|
||||
always_comb begin
|
||||
pi_mode = e_pi_mode'({pi_aleh, pi_alel});
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
logic last_reset;
|
||||
logic last_nmi;
|
||||
e_pi_mode last_pi_mode;
|
||||
logic last_read;
|
||||
logic last_write;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
last_reset <= pi_reset;
|
||||
last_nmi <= pi_nmi;
|
||||
last_pi_mode <= pi_mode;
|
||||
last_read <= pi_read;
|
||||
last_write <= pi_write;
|
||||
@ -121,250 +96,394 @@ module n64_pi (
|
||||
logic end_op;
|
||||
|
||||
always_comb begin
|
||||
aleh_op = !pi_reset && last_pi_mode != PI_MODE_HIGH && pi_mode == PI_MODE_HIGH;
|
||||
alel_op = !pi_reset && last_pi_mode == PI_MODE_HIGH && pi_mode == PI_MODE_LOW;
|
||||
read_op = !pi_reset && pi_mode == PI_MODE_VALID && last_read && !pi_read;
|
||||
write_op = !pi_reset && pi_mode == PI_MODE_VALID && last_write && !pi_write;
|
||||
end_op = !pi_reset && last_pi_mode == PI_MODE_VALID && pi_mode != PI_MODE_VALID;
|
||||
n64_scb.n64_reset = !last_reset && pi_reset;
|
||||
n64_scb.n64_nmi = !last_nmi && pi_nmi;
|
||||
aleh_op = pi_reset && (last_pi_mode != PI_MODE_HIGH) && (pi_mode == PI_MODE_HIGH);
|
||||
alel_op = pi_reset && (last_pi_mode == PI_MODE_HIGH) && (pi_mode == PI_MODE_LOW);
|
||||
read_op = pi_reset && (pi_mode == PI_MODE_VALID) && (read_port != PORT_NONE) && (last_read && !pi_read);
|
||||
write_op = pi_reset && (pi_mode == PI_MODE_VALID) && (write_port != PORT_NONE) && (last_write && !pi_write);
|
||||
end_op = pi_reset && (last_pi_mode == PI_MODE_VALID) && (pi_mode != PI_MODE_VALID);
|
||||
end
|
||||
|
||||
|
||||
// Input and output data sampling
|
||||
|
||||
logic [15:0] n64_pi_ad_input;
|
||||
logic [15:0] n64_pi_ad_output;
|
||||
logic [15:0] n64_pi_ad_output_data;
|
||||
logic n64_pi_ad_output_enable;
|
||||
logic n64_pi_ad_output_enable_data;
|
||||
|
||||
logic n64_pi_address_valid;
|
||||
logic pending_operation;
|
||||
logic pending_write;
|
||||
logic n64_pi_ad_oe;
|
||||
logic [15:0] n64_pi_ad_out;
|
||||
logic [15:0] n64_pi_dq_in;
|
||||
logic [15:0] n64_pi_dq_out;
|
||||
|
||||
always_comb begin
|
||||
n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ;
|
||||
n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !n64_pi_read_ff[2];
|
||||
assign n64_pi_ad = n64_pi_ad_oe ? n64_pi_ad_out : 16'hZZZZ;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
n64_pi_ad_oe <= pi_reset && (pi_mode == PI_MODE_VALID) && !last_read && (read_port != PORT_NONE);
|
||||
n64_pi_ad_out <= n64_pi_dq_out;
|
||||
n64_pi_dq_in <= n64_pi_ad;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_pi_ad_input <= n64_pi_ad;
|
||||
n64_pi_ad_output <= n64_pi_ad_output_data;
|
||||
n64_pi_ad_output_enable <= n64_pi_ad_output_enable_data;
|
||||
end
|
||||
|
||||
logic wait_for_read_fifo;
|
||||
logic wait_for_write_fifo;
|
||||
|
||||
always_comb begin
|
||||
read_fifo_write = bus.ack && !bus.write;
|
||||
read_fifo_wdata = bus.rdata;
|
||||
|
||||
write_fifo_wdata = n64_pi_ad_input;
|
||||
end
|
||||
// Debug: last accessed PI address
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
read_fifo_read <= 1'b0;
|
||||
write_fifo_write <= 1'b0;
|
||||
|
||||
if (sys.reset || sys.n64_hard_reset) begin
|
||||
wait_for_read_fifo <= 1'b0;
|
||||
wait_for_write_fifo <= 1'b0;
|
||||
end else if (n64_pi_address_valid) begin
|
||||
if (read_op || wait_for_read_fifo) begin
|
||||
if (read_fifo_empty) begin
|
||||
wait_for_read_fifo <= 1'b1;
|
||||
end else begin
|
||||
n64_pi_ad_output_data <= read_fifo_rdata;
|
||||
read_fifo_read <= 1'b1;
|
||||
wait_for_read_fifo <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (write_op || wait_for_write_fifo) begin
|
||||
if (write_fifo_full) begin
|
||||
wait_for_write_fifo <= 1'b1;
|
||||
end else begin
|
||||
write_fifo_write <= 1'b1;
|
||||
wait_for_write_fifo <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.read_op = read_op;
|
||||
bus.write_op = write_op;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
always_ff @(posedge clk) begin
|
||||
if (aleh_op) begin
|
||||
bus.real_address[31:16] <= n64_pi_ad_input;
|
||||
n64_scb.pi_debug[31:16] <= n64_pi_dq_in;
|
||||
end
|
||||
if (alel_op) begin
|
||||
bus.real_address[15:0] <= {n64_pi_ad_input[15:1], 1'b0};
|
||||
end
|
||||
if (read_op || write_op) begin
|
||||
bus.real_address <= bus.real_address + 2'd2;
|
||||
n64_scb.pi_debug[15:0] <= n64_pi_dq_in;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Address decoding
|
||||
|
||||
sc64::e_n64_id next_id;
|
||||
logic [31:0] next_offset;
|
||||
logic sram_selected;
|
||||
logic cfg_selected;
|
||||
const bit [31:0] DDIPL_OFFSET = 32'h03BC_0000;
|
||||
const bit [31:0] SAVE_OFFSET = 32'h03FE_0000;
|
||||
const bit [31:0] FLASH_OFFSET = 32'h0400_0000;
|
||||
const bit [31:0] BOOTLOADER_OFFSET = 32'h04E0_0000;
|
||||
const bit [31:0] SHADOW_OFFSET = 32'h04FE_0000;
|
||||
const bit [31:0] BUFFER_OFFSET = 32'h0500_0000;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (aleh_op) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
next_offset <= 32'd0;
|
||||
sram_selected <= 1'b0;
|
||||
cfg_selected <= 1'b0;
|
||||
if (cfg.dd_enabled) begin
|
||||
if (n64_pi_ad_input == 16'h0500) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_DD;
|
||||
end
|
||||
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.ddipl_offset + 32'h0A00_0000;
|
||||
logic [31:0] mem_offset;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset || !pi_reset || end_op) begin
|
||||
n64_scb.pi_sdram_active <= 1'b0;
|
||||
n64_scb.pi_flash_active <= 1'b0;
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
read_port <= PORT_NONE;
|
||||
write_port <= PORT_NONE;
|
||||
reg_bus.dd_select <= 1'b0;
|
||||
reg_bus.flashram_select <= 1'b0;
|
||||
reg_bus.cfg_select <= 1'b0;
|
||||
end else if (aleh_op) begin
|
||||
read_port <= PORT_NONE;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= 32'd0;
|
||||
reg_bus.dd_select <= 1'b0;
|
||||
reg_bus.flashram_select <= 1'b0;
|
||||
reg_bus.cfg_select <= 1'b0;
|
||||
|
||||
if (n64_scb.dd_enabled) begin
|
||||
if (n64_pi_dq_in == 16'h0500) begin
|
||||
read_port <= PORT_REG;
|
||||
write_port <= PORT_REG;
|
||||
reg_bus.dd_select <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (cfg.flashram_enabled) begin
|
||||
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_FLASHRAM;
|
||||
if (cfg.flashram_read_mode) begin
|
||||
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||
|
||||
if (n64_scb.ddipl_enabled) begin
|
||||
if (n64_pi_dq_in >= 16'h0600 && n64_pi_dq_in < 16'h0640) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h0600_0000) + DDIPL_OFFSET;
|
||||
n64_scb.pi_sdram_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (n64_scb.flashram_enabled) begin
|
||||
if (n64_pi_dq_in >= 16'h0800 && n64_pi_dq_in < 16'h0802) begin
|
||||
read_port <= PORT_REG;
|
||||
write_port <= PORT_REG;
|
||||
mem_offset <= (-32'h0800_0000) + SAVE_OFFSET;
|
||||
reg_bus.flashram_select <= 1'b1;
|
||||
if (n64_scb.flashram_read_mode) begin
|
||||
read_port <= PORT_MEM;
|
||||
n64_scb.pi_sdram_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else if (cfg.sram_enabled) begin
|
||||
if (cfg.sram_banked) begin
|
||||
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0810) begin
|
||||
if (n64_pi_ad_input[3:2] != 2'b11 && n64_pi_ad_input[1:0] == 2'b00) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.save_offset - {n64_pi_ad_input[3:2], 18'd0} + {n64_pi_ad_input[3:2], 15'd0} + 32'h0800_0000;
|
||||
sram_selected <= 1'b1;
|
||||
end else if (n64_scb.sram_enabled) begin
|
||||
if (n64_scb.sram_banked) begin
|
||||
if (n64_pi_dq_in >= 16'h0800 && n64_pi_dq_in < 16'h0810) begin
|
||||
if (n64_pi_dq_in[3:2] != 2'b11 && n64_pi_dq_in[1:0] == 2'b00) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_MEM;
|
||||
mem_offset <= (-32'h0800_0000) - {n64_pi_dq_in[3:2], 18'd0} + {n64_pi_dq_in[3:2], 15'd0} + SAVE_OFFSET;
|
||||
n64_scb.pi_sdram_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (n64_pi_ad_input == 16'h0800) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||
sram_selected <= 1'b1;
|
||||
if (n64_pi_dq_in >= 16'h0800 && n64_pi_dq_in < 16'h0802) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_MEM;
|
||||
mem_offset <= (-32'h0800_0000) + SAVE_OFFSET;
|
||||
n64_scb.pi_sdram_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if (n64_pi_ad_input >= 16'h1000 && n64_pi_ad_input < 16'h1400) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= cfg.sdram_switch ? sc64::ID_N64_SDRAM : sc64::ID_N64_BOOTLOADER;
|
||||
end
|
||||
if (n64_pi_ad_input == 16'h1FFF) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_CFG;
|
||||
cfg_selected <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (alel_op) begin
|
||||
if (next_id == sc64::ID_N64_DD) begin
|
||||
if (|n64_pi_ad_input[15:11]) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
|
||||
if (n64_scb.bootloader_enabled) begin
|
||||
if (n64_pi_dq_in >= 16'h1000 && n64_pi_dq_in < 16'h101C) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h1000_0000) + BOOTLOADER_OFFSET;
|
||||
n64_scb.pi_flash_active <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
if (n64_pi_dq_in >= 16'h1000 && n64_pi_dq_in < 16'h1400) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= n64_scb.rom_write_enabled ? PORT_MEM : PORT_NONE;
|
||||
mem_offset <= (-32'h1000_0000);
|
||||
n64_scb.pi_sdram_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (sram_selected) begin
|
||||
if (n64_pi_ad_input[15]) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
|
||||
if (n64_scb.rom_shadow_enabled) begin
|
||||
if (n64_pi_dq_in >= 16'h13FE && n64_pi_dq_in < 16'h1400) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h13FE_0000) + SHADOW_OFFSET;
|
||||
n64_scb.pi_flash_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (cfg_selected) begin
|
||||
if (|n64_pi_ad_input[15:4]) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
|
||||
if (n64_scb.rom_extended_enabled) begin
|
||||
if (n64_pi_dq_in >= 16'h1400 && n64_pi_dq_in < 16'h14E0) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
||||
n64_scb.pi_flash_active <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (n64_scb.cfg_unlock) begin
|
||||
if (n64_pi_dq_in >= 16'h1FFC && n64_pi_dq_in < 16'h1FFE) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h1FFC_0000) + SHADOW_OFFSET;
|
||||
n64_scb.pi_flash_active <= 1'b1;
|
||||
end
|
||||
|
||||
if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h1FFF) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_MEM;
|
||||
mem_offset <= (-32'h1FFE_0000) + BUFFER_OFFSET;
|
||||
end
|
||||
end
|
||||
|
||||
if (n64_pi_dq_in >= 16'h1FFF && n64_pi_dq_in < 16'h2000) begin
|
||||
read_port <= n64_scb.cfg_unlock ? PORT_REG : PORT_NONE;
|
||||
write_port <= PORT_REG;
|
||||
reg_bus.cfg_select <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Bus controller
|
||||
// Mem bus read FIFO controller
|
||||
|
||||
logic read_fifo_full;
|
||||
logic read_fifo_write;
|
||||
logic [15:0] read_fifo_wdata;
|
||||
|
||||
logic read_fifo_empty;
|
||||
logic read_fifo_read;
|
||||
logic [15:0] read_fifo_rdata;
|
||||
|
||||
logic read_fifo_wait;
|
||||
|
||||
n64_pi_fifo read_fifo_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.flush(reset || !pi_reset || alel_op),
|
||||
|
||||
.full(read_fifo_full),
|
||||
.write(read_fifo_write),
|
||||
.wdata(read_fifo_wdata),
|
||||
|
||||
.empty(read_fifo_empty),
|
||||
.read(read_fifo_read),
|
||||
.rdata(read_fifo_rdata)
|
||||
);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
read_fifo_read <= 1'b0;
|
||||
|
||||
if (!pi_reset) begin
|
||||
n64_scb.pi_debug[33:32] <= 2'b00;
|
||||
end
|
||||
|
||||
if (reset || !pi_reset || alel_op) begin
|
||||
read_fifo_wait <= 1'b0;
|
||||
end
|
||||
|
||||
if (read_port == PORT_MEM) begin
|
||||
if (read_op) begin
|
||||
if (read_fifo_empty) begin
|
||||
read_fifo_wait <= 1'b1;
|
||||
n64_scb.pi_debug[32] <= 1'b1;
|
||||
if (read_fifo_wait) begin
|
||||
n64_scb.pi_debug[33] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
read_fifo_read <= 1'b1;
|
||||
n64_pi_dq_out <= read_fifo_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
if (!read_fifo_empty && read_fifo_wait) begin
|
||||
read_fifo_read <= 1'b1;
|
||||
read_fifo_wait <= 1'b0;
|
||||
n64_pi_dq_out <= read_fifo_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
if (read_port == PORT_REG) begin
|
||||
if (read_op) begin
|
||||
n64_pi_dq_out <= reg_bus.rdata;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Mem bus write FIFO controller
|
||||
|
||||
logic write_fifo_full;
|
||||
logic write_fifo_write;
|
||||
logic [15:0] write_fifo_wdata;
|
||||
|
||||
logic write_fifo_empty;
|
||||
logic write_fifo_read;
|
||||
logic [15:0] write_fifo_rdata;
|
||||
|
||||
logic write_fifo_wait;
|
||||
|
||||
n64_pi_fifo write_fifo_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.flush(reset),
|
||||
|
||||
.full(write_fifo_full),
|
||||
.write(write_fifo_write),
|
||||
.wdata(write_fifo_wdata),
|
||||
|
||||
.empty(write_fifo_empty),
|
||||
.read(write_fifo_read),
|
||||
.rdata(write_fifo_rdata)
|
||||
);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
write_fifo_write <= 1'b0;
|
||||
|
||||
if (!pi_reset) begin
|
||||
n64_scb.pi_debug[35:34] <= 2'b00;
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
write_fifo_wait <= 1'b0;
|
||||
end
|
||||
|
||||
if (write_port == PORT_MEM) begin
|
||||
if (write_op) begin
|
||||
if (write_fifo_full) begin
|
||||
write_fifo_wait <= 1'b1;
|
||||
n64_scb.pi_debug[34] <= 1'b1;
|
||||
if (write_fifo_wait) begin
|
||||
n64_scb.pi_debug[35] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
write_fifo_write <= 1'b1;
|
||||
write_fifo_wdata <= n64_pi_dq_in;
|
||||
end
|
||||
end
|
||||
|
||||
if (!write_fifo_full && write_fifo_wait) begin
|
||||
write_fifo_write <= 1'b1;
|
||||
write_fifo_wait <= 1'b0;
|
||||
write_fifo_wdata <= n64_pi_dq_in;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Mem bus controller
|
||||
|
||||
logic can_read;
|
||||
logic first_write_op;
|
||||
logic load_starting_address;
|
||||
sc64::e_n64_id starting_id;
|
||||
logic [31:0] starting_address;
|
||||
logic load_starting_address;
|
||||
logic read_enabled;
|
||||
logic first_write_op;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
read_fifo_flush <= 1'b0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
write_fifo_read <= 1'b0;
|
||||
load_starting_address <= 1'b0;
|
||||
|
||||
if (sys.reset || sys.n64_hard_reset) begin
|
||||
bus.request <= 1'b0;
|
||||
read_fifo_flush <= 1'b1;
|
||||
write_fifo_flush <= 1'b1;
|
||||
if (reset || !pi_reset) begin
|
||||
mem_bus.request <= 1'b0;
|
||||
read_enabled <= 1'b0;
|
||||
end else begin
|
||||
write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected;
|
||||
|
||||
if (aleh_op) begin
|
||||
starting_address[31:16] <= n64_pi_ad_input;
|
||||
starting_address[31:16] <= n64_pi_dq_in;
|
||||
end
|
||||
|
||||
if (alel_op) begin
|
||||
read_fifo_flush <= 1'b1;
|
||||
can_read <= 1'b1;
|
||||
first_write_op <= 1'b1;
|
||||
starting_address <= {starting_address[31:16], n64_pi_dq_in} + mem_offset;
|
||||
load_starting_address <= 1'b1;
|
||||
starting_id <= next_id;
|
||||
starting_address <= {starting_address[31:16], n64_pi_ad_input[15:1], 1'b0};
|
||||
read_enabled <= 1'b1;
|
||||
first_write_op <= 1'b1;
|
||||
end
|
||||
|
||||
if (write_op) begin
|
||||
can_read <= 1'b0;
|
||||
if (first_write_op) begin
|
||||
first_write_op <= 1'b0;
|
||||
load_starting_address <= 1'b1;
|
||||
end
|
||||
if (load_starting_address) begin
|
||||
mem_bus.address <= starting_address;
|
||||
end
|
||||
|
||||
if (!bus.request) begin
|
||||
if (!write_fifo_empty) begin
|
||||
bus.request <= 1'b1;
|
||||
bus.write <= 1'b1;
|
||||
if (load_starting_address) begin
|
||||
bus.id <= starting_id;
|
||||
bus.address <= starting_address + next_offset;
|
||||
if (starting_id == sc64::ID_N64_FLASHRAM) begin
|
||||
bus.address <= starting_address;
|
||||
end
|
||||
load_starting_address <= 1'b0;
|
||||
end
|
||||
bus.wdata <= write_fifo_rdata;
|
||||
if (!mem_bus.request) begin
|
||||
if ((write_port == PORT_MEM) && !write_fifo_empty) begin
|
||||
mem_bus.request <= 1'b1;
|
||||
mem_bus.write <= 1'b1;
|
||||
mem_bus.wdata <= write_fifo_rdata;
|
||||
write_fifo_read <= 1'b1;
|
||||
end else if (!read_fifo_full && can_read) begin
|
||||
bus.request <= 1'b1;
|
||||
bus.write <= 1'b0;
|
||||
if (load_starting_address) begin
|
||||
bus.id <= starting_id;
|
||||
bus.address <= starting_address + next_offset;
|
||||
if (starting_id == sc64::ID_N64_FLASHRAM && cfg.flashram_read_mode) begin
|
||||
bus.id <= sc64::ID_N64_SDRAM;
|
||||
end
|
||||
load_starting_address <= 1'b0;
|
||||
read_enabled <= 1'b0;
|
||||
if (first_write_op) begin
|
||||
mem_bus.address <= starting_address;
|
||||
first_write_op <= 1'b0;
|
||||
end
|
||||
end else if ((read_port == PORT_MEM) && !read_fifo_full && read_enabled) begin
|
||||
mem_bus.request <= 1'b1;
|
||||
mem_bus.write <= 1'b0;
|
||||
end
|
||||
end else if (bus.ack) begin
|
||||
bus.request <= 1'b0;
|
||||
bus.address <= bus.address + 2'd2;
|
||||
end
|
||||
|
||||
if (mem_bus.ack) begin
|
||||
mem_bus.request <= 1'b0;
|
||||
mem_bus.address[16:0] <= mem_bus.address[16:0] + 2'd2;
|
||||
end
|
||||
|
||||
if (end_op) begin
|
||||
can_read <= 1'b0;
|
||||
read_enabled <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
read_fifo_write = !mem_bus.write && mem_bus.ack;
|
||||
read_fifo_wdata = mem_bus.rdata;
|
||||
mem_bus.wmask = 2'b11;
|
||||
end
|
||||
|
||||
|
||||
// Reg bus controller
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (aleh_op) begin
|
||||
reg_bus.address[16] <= n64_pi_dq_in[0];
|
||||
end
|
||||
|
||||
if (alel_op) begin
|
||||
reg_bus.address[15:0] <= n64_pi_dq_in;
|
||||
end
|
||||
|
||||
if (read_op || write_op) begin
|
||||
reg_bus.address <= reg_bus.address + 2'd2;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
reg_bus.read = read_op && (read_port == PORT_REG);
|
||||
reg_bus.write = write_op && (write_port == PORT_REG);
|
||||
reg_bus.wdata = n64_pi_dq_in;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -1,5 +1,6 @@
|
||||
module n64_pi_fifo (
|
||||
if_system.sys sys,
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input flush,
|
||||
|
||||
@ -18,15 +19,13 @@ module n64_pi_fifo (
|
||||
|
||||
logic empty_or_full;
|
||||
|
||||
always_comb begin
|
||||
rdata = fifo_mem[fifo_rd_ptr[1:0]];
|
||||
empty_or_full = fifo_wr_ptr[1:0] == fifo_rd_ptr[1:0];
|
||||
empty = empty_or_full && fifo_wr_ptr[2] == fifo_rd_ptr[2];
|
||||
full = empty_or_full && fifo_wr_ptr[2] != fifo_rd_ptr[2];
|
||||
end
|
||||
assign rdata = fifo_mem[fifo_rd_ptr[1:0]];
|
||||
assign empty_or_full = fifo_wr_ptr[1:0] == fifo_rd_ptr[1:0];
|
||||
assign empty = empty_or_full && fifo_wr_ptr[2] == fifo_rd_ptr[2];
|
||||
assign full = empty_or_full && fifo_wr_ptr[2] != fifo_rd_ptr[2];
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || flush) begin
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset || flush) begin
|
||||
fifo_wr_ptr <= 3'd0;
|
||||
fifo_rd_ptr <= 3'd0;
|
||||
end else begin
|
||||
|
66
fw/rtl/n64/n64_reg_bus.sv
Normal file
66
fw/rtl/n64/n64_reg_bus.sv
Normal file
@ -0,0 +1,66 @@
|
||||
interface n64_reg_bus ();
|
||||
|
||||
logic flashram_select;
|
||||
logic dd_select;
|
||||
logic cfg_select;
|
||||
|
||||
logic read;
|
||||
logic write;
|
||||
logic [16:0] address;
|
||||
logic [15:0] rdata;
|
||||
logic [15:0] wdata;
|
||||
|
||||
logic [15:0] flashram_rdata;
|
||||
logic [15:0] dd_rdata;
|
||||
logic [15:0] cfg_rdata;
|
||||
|
||||
modport controller (
|
||||
output flashram_select,
|
||||
output dd_select,
|
||||
output cfg_select,
|
||||
|
||||
output read,
|
||||
output write,
|
||||
output address,
|
||||
input rdata,
|
||||
output wdata
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
rdata = 16'd0;
|
||||
if (flashram_select) begin
|
||||
rdata = flashram_rdata;
|
||||
end
|
||||
if (dd_select) begin
|
||||
rdata = dd_rdata;
|
||||
end
|
||||
if (cfg_select) begin
|
||||
rdata = cfg_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
modport flashram (
|
||||
input .read(read && flashram_select),
|
||||
input .write(write && flashram_select),
|
||||
input address,
|
||||
output .rdata(flashram_rdata),
|
||||
input wdata
|
||||
);
|
||||
|
||||
modport dd (
|
||||
input .read(read && dd_select),
|
||||
input .write(write && dd_select),
|
||||
input address,
|
||||
output .rdata(dd_rdata),
|
||||
input wdata
|
||||
);
|
||||
|
||||
modport cfg (
|
||||
input .read(read && cfg_select),
|
||||
input .write(write && cfg_select),
|
||||
input address,
|
||||
output .rdata(cfg_rdata),
|
||||
input wdata
|
||||
);
|
||||
|
||||
endinterface
|
197
fw/rtl/n64/n64_scb.sv
Normal file
197
fw/rtl/n64/n64_scb.sv
Normal file
@ -0,0 +1,197 @@
|
||||
interface n64_scb ();
|
||||
|
||||
logic n64_reset;
|
||||
logic n64_nmi;
|
||||
|
||||
logic bootloader_enabled;
|
||||
logic rom_write_enabled;
|
||||
logic rom_shadow_enabled;
|
||||
logic rom_extended_enabled;
|
||||
logic sram_enabled;
|
||||
logic sram_banked;
|
||||
logic flashram_enabled;
|
||||
logic dd_enabled;
|
||||
logic ddipl_enabled;
|
||||
logic eeprom_enabled;
|
||||
logic eeprom_16k_mode;
|
||||
|
||||
logic dd_write;
|
||||
logic [6:0] dd_address;
|
||||
logic [15:0] dd_rdata;
|
||||
logic [15:0] dd_wdata;
|
||||
|
||||
logic flashram_pending;
|
||||
logic flashram_done;
|
||||
logic [9:0] flashram_sector;
|
||||
logic flashram_sector_or_all;
|
||||
logic flashram_write_or_erase;
|
||||
logic flashram_read_mode;
|
||||
logic flashram_write;
|
||||
logic [5:0] flashram_address;
|
||||
logic [15:0] flashram_wdata;
|
||||
|
||||
logic eeprom_write;
|
||||
logic [10:0] eeprom_address;
|
||||
logic [7:0] eeprom_rdata;
|
||||
logic [7:0] eeprom_wdata;
|
||||
|
||||
logic rtc_pending;
|
||||
logic rtc_done;
|
||||
logic rtc_wdata_valid;
|
||||
logic [41:0] rtc_rdata;
|
||||
logic [41:0] rtc_wdata;
|
||||
|
||||
logic cfg_unlock;
|
||||
logic cfg_pending;
|
||||
logic cfg_done;
|
||||
logic cfg_error;
|
||||
logic cfg_irq;
|
||||
logic [7:0] cfg_cmd;
|
||||
logic [31:0] cfg_rdata [0:1];
|
||||
logic [31:0] cfg_wdata [0:1];
|
||||
logic [31:0] cfg_version;
|
||||
|
||||
logic pi_sdram_active;
|
||||
logic pi_flash_active;
|
||||
logic [35:0] pi_debug;
|
||||
|
||||
modport controller (
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
|
||||
output bootloader_enabled,
|
||||
output rom_write_enabled,
|
||||
output rom_shadow_enabled,
|
||||
output rom_extended_enabled,
|
||||
output sram_enabled,
|
||||
output sram_banked,
|
||||
output flashram_enabled,
|
||||
output dd_enabled,
|
||||
output ddipl_enabled,
|
||||
output eeprom_enabled,
|
||||
output eeprom_16k_mode,
|
||||
|
||||
input flashram_pending,
|
||||
output flashram_done,
|
||||
input flashram_sector,
|
||||
input flashram_sector_or_all,
|
||||
input flashram_write_or_erase,
|
||||
|
||||
input rtc_pending,
|
||||
output rtc_done,
|
||||
output rtc_wdata_valid,
|
||||
input rtc_rdata,
|
||||
output rtc_wdata,
|
||||
|
||||
input cfg_pending,
|
||||
output cfg_done,
|
||||
output cfg_error,
|
||||
output cfg_irq,
|
||||
input cfg_cmd,
|
||||
input cfg_rdata,
|
||||
output cfg_wdata,
|
||||
output cfg_version,
|
||||
|
||||
input pi_debug
|
||||
);
|
||||
|
||||
modport pi (
|
||||
output n64_reset,
|
||||
output n64_nmi,
|
||||
|
||||
input bootloader_enabled,
|
||||
input rom_write_enabled,
|
||||
input rom_shadow_enabled,
|
||||
input rom_extended_enabled,
|
||||
input sram_enabled,
|
||||
input sram_banked,
|
||||
input flashram_enabled,
|
||||
input dd_enabled,
|
||||
input ddipl_enabled,
|
||||
|
||||
input flashram_read_mode,
|
||||
|
||||
input cfg_unlock,
|
||||
|
||||
output pi_sdram_active,
|
||||
output pi_flash_active,
|
||||
output pi_debug
|
||||
);
|
||||
|
||||
modport flashram (
|
||||
output flashram_pending,
|
||||
input flashram_done,
|
||||
output flashram_sector,
|
||||
output flashram_sector_or_all,
|
||||
output flashram_write_or_erase,
|
||||
|
||||
output flashram_read_mode,
|
||||
|
||||
output flashram_write,
|
||||
output flashram_address,
|
||||
output flashram_wdata
|
||||
);
|
||||
|
||||
modport si (
|
||||
input eeprom_enabled,
|
||||
input eeprom_16k_mode,
|
||||
|
||||
output eeprom_write,
|
||||
output eeprom_address,
|
||||
input eeprom_rdata,
|
||||
output eeprom_wdata,
|
||||
|
||||
output rtc_pending,
|
||||
input rtc_done,
|
||||
input rtc_wdata_valid,
|
||||
output rtc_rdata,
|
||||
input rtc_wdata
|
||||
);
|
||||
|
||||
modport dd (
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
|
||||
output dd_write,
|
||||
output dd_address,
|
||||
input dd_rdata,
|
||||
output dd_wdata
|
||||
);
|
||||
|
||||
modport bram (
|
||||
input flashram_write,
|
||||
input flashram_address,
|
||||
input flashram_wdata,
|
||||
|
||||
input eeprom_write,
|
||||
input eeprom_address,
|
||||
output eeprom_rdata,
|
||||
input eeprom_wdata,
|
||||
|
||||
input dd_write,
|
||||
input dd_address,
|
||||
output dd_rdata,
|
||||
input dd_wdata
|
||||
);
|
||||
|
||||
modport cfg (
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
|
||||
output cfg_unlock,
|
||||
output cfg_pending,
|
||||
input cfg_done,
|
||||
input cfg_error,
|
||||
input cfg_irq,
|
||||
output cfg_cmd,
|
||||
output cfg_rdata,
|
||||
input cfg_wdata,
|
||||
input cfg_version
|
||||
);
|
||||
|
||||
modport arbiter (
|
||||
input pi_sdram_active,
|
||||
input pi_flash_active
|
||||
);
|
||||
|
||||
endinterface
|
@ -1,106 +0,0 @@
|
||||
module n64_sdram (
|
||||
if_system sys,
|
||||
if_n64_bus bus,
|
||||
if_dma.memory dma,
|
||||
if_sdram.memory sdram,
|
||||
|
||||
output sdram_cs,
|
||||
output sdram_ras,
|
||||
output sdram_cas,
|
||||
output sdram_we,
|
||||
output [1:0] sdram_ba,
|
||||
output [12:0] sdram_a,
|
||||
inout [15:0] sdram_dq
|
||||
);
|
||||
|
||||
logic mem_request;
|
||||
logic mem_ack;
|
||||
logic mem_write;
|
||||
logic [31:0] mem_address;
|
||||
logic [15:0] mem_rdata;
|
||||
logic [15:0] mem_wdata;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
T_BUS,
|
||||
T_DMA,
|
||||
T_SDRAM
|
||||
} e_source_request;
|
||||
|
||||
e_state state;
|
||||
e_source_request source_request;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
mem_request <= 1'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request || sdram.request || dma.request) begin
|
||||
state <= S_WAIT;
|
||||
mem_request <= 1'b1;
|
||||
if (bus.request) begin
|
||||
mem_write <= bus.write;
|
||||
mem_address <= bus.address;
|
||||
mem_wdata <= bus.wdata;
|
||||
source_request <= T_BUS;
|
||||
end else if (sdram.request) begin
|
||||
mem_write <= sdram.write;
|
||||
mem_address <= sdram.address;
|
||||
mem_wdata <= sdram.wdata;
|
||||
source_request <= T_SDRAM;
|
||||
end else if (dma.request) begin
|
||||
mem_write <= dma.write;
|
||||
mem_address <= dma.address;
|
||||
mem_wdata <= dma.wdata;
|
||||
source_request <= T_DMA;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
if (mem_ack) begin
|
||||
state <= S_IDLE;
|
||||
mem_request <= 1'b0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.ack = source_request == T_BUS && mem_ack;
|
||||
bus.rdata = bus.ack ? mem_rdata : 16'd0;
|
||||
|
||||
dma.ack = source_request == T_DMA && mem_ack;
|
||||
dma.rdata = mem_rdata;
|
||||
|
||||
sdram.ack = source_request == T_SDRAM && mem_ack;
|
||||
sdram.rdata = mem_rdata;
|
||||
end
|
||||
|
||||
memory_sdram memory_sdram_inst (
|
||||
.sys(sys),
|
||||
|
||||
.request(mem_request),
|
||||
.ack(mem_ack),
|
||||
.write(mem_write),
|
||||
.address(mem_address[25:0]),
|
||||
.rdata(mem_rdata),
|
||||
.wdata(mem_wdata),
|
||||
|
||||
.sdram_cs(sdram_cs),
|
||||
.sdram_ras(sdram_ras),
|
||||
.sdram_cas(sdram_cas),
|
||||
.sdram_we(sdram_we),
|
||||
.sdram_ba(sdram_ba),
|
||||
.sdram_a(sdram_a),
|
||||
.sdram_dq(sdram_dq)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,164 +1,253 @@
|
||||
interface if_si ();
|
||||
|
||||
logic rx_reset;
|
||||
logic rx_ready;
|
||||
logic [6:0] rx_length;
|
||||
logic [80:0] rx_data;
|
||||
|
||||
logic tx_reset;
|
||||
logic tx_start;
|
||||
logic tx_busy;
|
||||
logic [2:0] tx_wmask;
|
||||
logic [6:0] tx_length;
|
||||
logic [31:0] tx_data;
|
||||
|
||||
modport si (
|
||||
input rx_reset,
|
||||
output rx_ready,
|
||||
output rx_length,
|
||||
output rx_data,
|
||||
input tx_reset,
|
||||
input tx_start,
|
||||
output tx_busy,
|
||||
input tx_wmask,
|
||||
input tx_length,
|
||||
input tx_data
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
output rx_reset,
|
||||
input rx_ready,
|
||||
input rx_length,
|
||||
input rx_data,
|
||||
output tx_reset,
|
||||
output tx_start,
|
||||
input tx_busy,
|
||||
output tx_wmask,
|
||||
output tx_length,
|
||||
output tx_data
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
module n64_si (
|
||||
if_system.sys sys,
|
||||
if_si.si si,
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_scb.si n64_scb,
|
||||
|
||||
input n64_reset,
|
||||
input n64_si_clk,
|
||||
inout n64_si_dq
|
||||
);
|
||||
|
||||
// Control signals and input synchronization
|
||||
// Input/output synchronization
|
||||
|
||||
logic [1:0] n64_reset_ff;
|
||||
logic [1:0] n64_si_clk_ff;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
always_ff @(posedge clk) begin
|
||||
n64_reset_ff <= {n64_reset_ff[0], n64_reset};
|
||||
n64_si_clk_ff <= {n64_si_clk_ff[0], n64_si_clk};
|
||||
end
|
||||
|
||||
logic si_reset;
|
||||
logic si_clk;
|
||||
logic si_dq;
|
||||
|
||||
always_comb begin
|
||||
si_reset = sys.n64_hard_reset;
|
||||
si_reset = n64_reset_ff[1];
|
||||
si_clk = n64_si_clk_ff[1];
|
||||
si_dq = n64_si_dq;
|
||||
end
|
||||
|
||||
logic si_dq_oe;
|
||||
logic si_dq_out;
|
||||
logic si_dq_in;
|
||||
|
||||
assign n64_si_dq = si_dq_oe ? 1'b0 : 1'bZ;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
si_dq_oe <= ~si_dq_out;
|
||||
si_dq_in <= n64_si_dq;
|
||||
end
|
||||
|
||||
|
||||
// Clock falling/rising event generator
|
||||
|
||||
logic last_si_clk;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
always_ff @(posedge clk) begin
|
||||
last_si_clk <= si_clk;
|
||||
end
|
||||
|
||||
logic si_clk_rising_edge;
|
||||
logic si_clk_falling_edge;
|
||||
logic si_clk_rising_edge;
|
||||
|
||||
always_comb begin
|
||||
si_clk_rising_edge = !si_reset && !last_si_clk && si_clk;
|
||||
si_clk_falling_edge = !si_reset && last_si_clk && !si_clk;
|
||||
end
|
||||
|
||||
logic si_dq_output_enable;
|
||||
logic si_dq_output_enable_data;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
si_dq_output_enable <= si_dq_output_enable_data;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
n64_si_dq = si_dq_output_enable ? 1'b0 : 1'bZ;
|
||||
si_clk_falling_edge = si_reset && last_si_clk && !si_clk;
|
||||
si_clk_rising_edge = si_reset && !last_si_clk && si_clk;
|
||||
end
|
||||
|
||||
|
||||
// Data register and shifter
|
||||
// Data falling/rising event generator
|
||||
|
||||
logic [80:0] trx_data;
|
||||
logic rx_shift;
|
||||
logic tx_shift;
|
||||
logic last_si_dq_in;
|
||||
|
||||
always_comb begin
|
||||
si.rx_data = trx_data;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (si.tx_wmask[0]) trx_data[80:49] <= si.tx_data;
|
||||
if (si.tx_wmask[1]) trx_data[48:17] <= si.tx_data;
|
||||
if (si.tx_wmask[2]) trx_data[16:0] <= si.tx_data[16:0];
|
||||
|
||||
if (rx_shift || tx_shift) begin
|
||||
trx_data <= {trx_data[79:0], rx_sub_bit_counter < 2'd2};
|
||||
always_ff @(posedge clk) begin
|
||||
if (si_clk_rising_edge) begin
|
||||
last_si_dq_in <= si_dq_in;
|
||||
end
|
||||
end
|
||||
|
||||
logic si_dq_falling_edge;
|
||||
logic si_dq_rising_edge;
|
||||
|
||||
always_comb begin
|
||||
si_dq_falling_edge = si_clk_rising_edge && last_si_dq_in && !si_dq_in;
|
||||
si_dq_rising_edge = si_clk_rising_edge && !last_si_dq_in && si_dq_in;
|
||||
end
|
||||
|
||||
|
||||
// RX bit generator
|
||||
|
||||
logic [3:0] rx_sub_bit_counter;
|
||||
logic rx_timeout;
|
||||
logic rx_bit_valid;
|
||||
logic rx_bit_data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (si_clk_rising_edge && !(&rx_sub_bit_counter)) begin
|
||||
rx_sub_bit_counter <= rx_sub_bit_counter + 1'd1;
|
||||
end
|
||||
if (si_dq_falling_edge) begin
|
||||
rx_sub_bit_counter <= 4'd0;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
rx_timeout = si_clk_rising_edge && si_dq_in && (&rx_sub_bit_counter);
|
||||
rx_bit_valid = si_dq_rising_edge;
|
||||
rx_bit_data = (rx_sub_bit_counter >= 4'd3) ? 1'b0 : 1'b1;
|
||||
end
|
||||
|
||||
|
||||
// RX byte generator
|
||||
|
||||
logic [2:0] rx_bit_counter;
|
||||
logic rx_byte_valid;
|
||||
logic [7:0] rx_byte_data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
rx_byte_valid <= 1'b0;
|
||||
if (rx_timeout) begin
|
||||
rx_bit_counter <= 3'd0;
|
||||
end
|
||||
if (rx_bit_valid) begin
|
||||
rx_bit_counter <= rx_bit_counter + 1'd1;
|
||||
rx_byte_data <= {rx_byte_data[6:0], rx_bit_data};
|
||||
if (&rx_bit_counter) begin
|
||||
rx_byte_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// RX stop generator
|
||||
|
||||
logic rx_stop;
|
||||
|
||||
always_comb begin
|
||||
rx_stop = si_clk_rising_edge && si_dq_in && (rx_sub_bit_counter == 4'd7) && (rx_bit_counter == 3'd1);
|
||||
end
|
||||
|
||||
|
||||
// TX byte/stop generator
|
||||
|
||||
logic tx_busy;
|
||||
logic [2:0] tx_sub_bit_counter;
|
||||
logic [2:0] tx_bit_counter;
|
||||
logic [7:0] tx_shift;
|
||||
logic tx_start;
|
||||
logic tx_stop;
|
||||
logic tx_byte_valid;
|
||||
logic [7:0] tx_byte_data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
si_dq_out <= 1'b1;
|
||||
tx_busy <= 1'b0;
|
||||
end else begin
|
||||
if (tx_busy) begin
|
||||
if (si_clk_falling_edge) begin
|
||||
tx_sub_bit_counter <= tx_sub_bit_counter + 1'd1;
|
||||
if (&tx_sub_bit_counter) begin
|
||||
tx_bit_counter <= tx_bit_counter + 1'd1;
|
||||
tx_shift <= {tx_shift[6:0], 1'bX};
|
||||
if (&tx_bit_counter) begin
|
||||
tx_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (tx_shift[7]) begin
|
||||
si_dq_out <= !(tx_sub_bit_counter < 3'd2);
|
||||
end else begin
|
||||
si_dq_out <= !(tx_sub_bit_counter < 3'd6);
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (tx_byte_valid) begin
|
||||
tx_busy <= 1'b1;
|
||||
tx_sub_bit_counter <= 3'd0;
|
||||
tx_bit_counter <= 3'd0;
|
||||
tx_shift <= tx_byte_data;
|
||||
end else if (tx_stop) begin
|
||||
tx_busy <= 1'b1;
|
||||
tx_sub_bit_counter <= 3'd0;
|
||||
tx_bit_counter <= 3'd7;
|
||||
tx_shift <= 8'hFF;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Joybus CMDs
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
CMD_EEPROM_STATUS = 8'h00,
|
||||
CMD_EEPROM_READ = 8'h04,
|
||||
CMD_EEPROM_WRITE = 8'h05,
|
||||
CMD_RTC_STATUS = 8'h06,
|
||||
CMD_RTC_READ = 8'h07,
|
||||
CMD_RTC_WRITE = 8'h08
|
||||
} e_cmd;
|
||||
|
||||
e_cmd cmd;
|
||||
|
||||
|
||||
// RX path
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_RX_IDLE,
|
||||
S_RX_WAITING
|
||||
typedef enum bit [1:0] {
|
||||
RX_STATE_IDLE,
|
||||
RX_STATE_DATA,
|
||||
RX_STATE_IGNORE
|
||||
} e_rx_state;
|
||||
|
||||
e_rx_state rx_state;
|
||||
logic [3:0] rx_byte_counter;
|
||||
logic rx_data_valid;
|
||||
|
||||
logic [1:0] rx_sub_bit_counter;
|
||||
logic [3:0] rx_timeout_counter;
|
||||
always_comb begin
|
||||
rx_data_valid = rx_byte_valid && (rx_state == RX_STATE_DATA);
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
rx_shift <= 1'b0;
|
||||
always_ff @(posedge clk) begin
|
||||
tx_start <= 1'b0;
|
||||
|
||||
if (si_clk_rising_edge) begin
|
||||
if (rx_timeout_counter < 4'd8) begin
|
||||
rx_timeout_counter <= rx_timeout_counter + 1'd1;
|
||||
end else if (si.rx_length > 7'd0) begin
|
||||
si.rx_ready <= 1'b1;
|
||||
end
|
||||
if (rx_byte_valid) begin
|
||||
rx_byte_counter <= rx_byte_counter + 1'd1;
|
||||
end
|
||||
|
||||
if (sys.reset || si.rx_reset) begin
|
||||
rx_state <= S_RX_IDLE;
|
||||
si.rx_ready <= 1'b0;
|
||||
si.rx_length <= 7'd0;
|
||||
end else if (!si.tx_busy) begin
|
||||
if (reset || rx_timeout) begin
|
||||
rx_state <= RX_STATE_IDLE;
|
||||
end else begin
|
||||
case (rx_state)
|
||||
S_RX_IDLE: begin
|
||||
if (si_clk_rising_edge && !si_dq) begin
|
||||
rx_state <= S_RX_WAITING;
|
||||
rx_sub_bit_counter <= 2'd0;
|
||||
rx_timeout_counter <= 3'd0;
|
||||
RX_STATE_IDLE: begin
|
||||
if (rx_byte_valid) begin
|
||||
cmd <= e_cmd'(rx_byte_data);
|
||||
rx_byte_counter <= 4'd0;
|
||||
rx_state <= RX_STATE_IGNORE;
|
||||
case (rx_byte_data)
|
||||
CMD_EEPROM_STATUS,
|
||||
CMD_EEPROM_READ,
|
||||
CMD_EEPROM_WRITE: begin
|
||||
rx_state <= n64_scb.eeprom_enabled ? RX_STATE_DATA : RX_STATE_IGNORE;
|
||||
end
|
||||
CMD_RTC_STATUS,
|
||||
CMD_RTC_READ,
|
||||
CMD_RTC_WRITE: begin
|
||||
rx_state <= RX_STATE_DATA;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
S_RX_WAITING: begin
|
||||
if (si_clk_rising_edge) begin
|
||||
if (si_dq) begin
|
||||
rx_state <= S_RX_IDLE;
|
||||
rx_shift <= 1'b1;
|
||||
si.rx_length <= si.rx_length + 1'd1;
|
||||
end else if (rx_sub_bit_counter < 2'd3) begin
|
||||
rx_sub_bit_counter <= rx_sub_bit_counter + 1'd1;
|
||||
end
|
||||
RX_STATE_DATA: begin
|
||||
if (rx_stop) begin
|
||||
tx_start <= 1'b1;
|
||||
rx_state <= RX_STATE_IGNORE;
|
||||
end
|
||||
end
|
||||
|
||||
RX_STATE_IGNORE: begin
|
||||
if (rx_stop) begin
|
||||
rx_state <= RX_STATE_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
@ -168,57 +257,217 @@ module n64_si (
|
||||
|
||||
// TX path
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_TX_IDLE,
|
||||
S_TX_SENDING
|
||||
typedef enum bit [1:0] {
|
||||
TX_STATE_IDLE,
|
||||
TX_STATE_DATA,
|
||||
TX_STATE_STOP
|
||||
} e_tx_state;
|
||||
|
||||
e_tx_state tx_state;
|
||||
|
||||
logic [2:0] tx_sub_bit_counter;
|
||||
logic [6:0] tx_bit_counter;
|
||||
logic [3:0] tx_byte_counter;
|
||||
logic [3:0] tx_length;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
tx_shift <= 1'b0;
|
||||
always_ff @(posedge clk) begin
|
||||
tx_byte_valid <= 1'b0;
|
||||
tx_stop <= 1'b0;
|
||||
|
||||
if (sys.reset || si.tx_reset) begin
|
||||
tx_state <= S_TX_IDLE;
|
||||
si_dq_output_enable_data <= 1'b0;
|
||||
si.tx_busy <= 1'b0;
|
||||
if (!tx_busy && tx_byte_valid) begin
|
||||
tx_byte_counter <= tx_byte_counter + 1'd1;
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
tx_state <= TX_STATE_IDLE;
|
||||
end else begin
|
||||
case (tx_state)
|
||||
S_TX_IDLE: begin
|
||||
if (si.tx_start) begin
|
||||
tx_state <= S_TX_SENDING;
|
||||
tx_sub_bit_counter <= 3'd0;
|
||||
tx_bit_counter <= si.tx_length;
|
||||
si.tx_busy <= 1'b1;
|
||||
TX_STATE_IDLE: begin
|
||||
if (tx_start) begin
|
||||
tx_byte_counter <= 4'd0;
|
||||
tx_state <= TX_STATE_DATA;
|
||||
end
|
||||
end
|
||||
|
||||
S_TX_SENDING: begin
|
||||
if (si_clk_falling_edge) begin
|
||||
tx_sub_bit_counter <= tx_sub_bit_counter + 1'd1;
|
||||
if (tx_sub_bit_counter == 3'd7) begin
|
||||
tx_shift <= 1'b1;
|
||||
if (tx_bit_counter >= 7'd1) begin
|
||||
tx_bit_counter <= tx_bit_counter - 1'd1;
|
||||
end else begin
|
||||
tx_state <= S_TX_IDLE;
|
||||
si.tx_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (tx_bit_counter == 7'd0) begin
|
||||
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd4;
|
||||
end else if (trx_data[80]) begin
|
||||
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd2;
|
||||
end else begin
|
||||
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd6;
|
||||
TX_STATE_DATA: begin
|
||||
tx_byte_valid <= 1'b1;
|
||||
if (!tx_busy && tx_byte_valid) begin
|
||||
if (tx_byte_counter == tx_length) begin
|
||||
tx_state <= TX_STATE_STOP;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TX_STATE_STOP: begin
|
||||
tx_stop <= 1'b1;
|
||||
if (!tx_busy && tx_stop) begin
|
||||
tx_state <= TX_STATE_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Joybus address latching
|
||||
|
||||
logic [7:0] joybus_address;
|
||||
logic [2:0] joybus_subaddress;
|
||||
logic [10:0] joybus_full_address;
|
||||
|
||||
always_comb begin
|
||||
joybus_full_address = {joybus_address, joybus_subaddress};
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rx_data_valid || (!tx_busy && tx_byte_valid)) begin
|
||||
joybus_subaddress <= joybus_subaddress + 1'd1;
|
||||
end
|
||||
if (rx_data_valid) begin
|
||||
if (rx_byte_counter == 4'd0) begin
|
||||
joybus_address <= rx_byte_data;
|
||||
joybus_subaddress <= 3'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// EEPROM controller
|
||||
|
||||
always_comb begin
|
||||
n64_scb.eeprom_write = rx_data_valid && (cmd == CMD_EEPROM_WRITE) && rx_byte_counter > 4'd0;
|
||||
n64_scb.eeprom_address = joybus_full_address;
|
||||
n64_scb.eeprom_wdata = rx_byte_data;
|
||||
end
|
||||
|
||||
|
||||
// RTC controller
|
||||
|
||||
logic rtc_backup_wp;
|
||||
logic rtc_time_wp;
|
||||
logic [1:0] rtc_stopped;
|
||||
logic [6:0] rtc_time_second;
|
||||
logic [6:0] rtc_time_minute;
|
||||
logic [5:0] rtc_time_hour;
|
||||
logic [5:0] rtc_time_day;
|
||||
logic [2:0] rtc_time_weekday;
|
||||
logic [4:0] rtc_time_month;
|
||||
logic [7:0] rtc_time_year;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
rtc_backup_wp <= 1'b1;
|
||||
rtc_time_wp <= 1'b1;
|
||||
rtc_stopped <= 2'b00;
|
||||
n64_scb.rtc_pending <= 1'b0;
|
||||
end
|
||||
|
||||
if (n64_scb.rtc_done) begin
|
||||
n64_scb.rtc_pending <= 1'b0;
|
||||
end
|
||||
|
||||
if (!(|rtc_stopped) && !n64_scb.rtc_pending && n64_scb.rtc_wdata_valid && (tx_state != TX_STATE_DATA)) begin
|
||||
{
|
||||
rtc_time_year,
|
||||
rtc_time_month,
|
||||
rtc_time_weekday,
|
||||
rtc_time_day,
|
||||
rtc_time_hour,
|
||||
rtc_time_minute,
|
||||
rtc_time_second
|
||||
} <= n64_scb.rtc_wdata;
|
||||
end
|
||||
|
||||
if (rx_data_valid && (cmd == CMD_RTC_WRITE)) begin
|
||||
if (joybus_address[1:0] == 2'd0) begin
|
||||
case (rx_byte_counter)
|
||||
4'd1: {rtc_time_wp, rtc_backup_wp} <= rx_byte_data[1:0];
|
||||
4'd2: begin
|
||||
rtc_stopped <= rx_byte_data[2:1];
|
||||
if (rx_byte_data[2:1] == 2'b00) begin
|
||||
n64_scb.rtc_pending <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
if ((joybus_address[1:0] == 2'd2) && !rtc_time_wp) begin
|
||||
case (rx_byte_counter)
|
||||
4'd1: rtc_time_second <= rx_byte_data[6:0];
|
||||
4'd2: rtc_time_minute <= rx_byte_data[6:0];
|
||||
4'd3: rtc_time_hour <= rx_byte_data[5:0];
|
||||
4'd4: rtc_time_day <= rx_byte_data[5:0];
|
||||
4'd5: rtc_time_weekday <= rx_byte_data[2:0];
|
||||
4'd6: rtc_time_month <= rx_byte_data[4:0];
|
||||
4'd7: rtc_time_year <= rx_byte_data;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
n64_scb.rtc_rdata = {
|
||||
rtc_time_year,
|
||||
rtc_time_month,
|
||||
rtc_time_weekday,
|
||||
rtc_time_day,
|
||||
rtc_time_hour,
|
||||
rtc_time_minute,
|
||||
rtc_time_second
|
||||
};
|
||||
end
|
||||
|
||||
|
||||
// TX data multiplexer
|
||||
|
||||
always_comb begin
|
||||
tx_length = 4'd0;
|
||||
tx_byte_data = 8'h00;
|
||||
case (cmd)
|
||||
CMD_EEPROM_STATUS: begin
|
||||
tx_length = 4'd2;
|
||||
case (tx_byte_counter)
|
||||
4'd1: tx_byte_data = {1'b1, n64_scb.eeprom_16k_mode, 6'd0};
|
||||
endcase
|
||||
end
|
||||
CMD_EEPROM_READ: begin
|
||||
tx_length = 4'd7;
|
||||
tx_byte_data = n64_scb.eeprom_rdata;
|
||||
end
|
||||
CMD_EEPROM_WRITE: begin
|
||||
tx_length = 4'd0;
|
||||
end
|
||||
CMD_RTC_STATUS: begin
|
||||
tx_length = 4'd2;
|
||||
case (tx_byte_counter)
|
||||
4'd1: tx_byte_data = 8'h10;
|
||||
4'd2: tx_byte_data = {(|rtc_stopped), 7'd0};
|
||||
endcase
|
||||
end
|
||||
CMD_RTC_READ: begin
|
||||
tx_length = 4'd8;
|
||||
if (joybus_address[1:0] == 2'd0) begin
|
||||
case (tx_byte_counter)
|
||||
4'd0: tx_byte_data = {6'd0, rtc_time_wp, rtc_backup_wp};
|
||||
4'd1: tx_byte_data = {5'd0, rtc_stopped, 1'b0};
|
||||
4'd8: tx_byte_data = {(|rtc_stopped), 7'd0};
|
||||
endcase
|
||||
end else if (joybus_address[1:0] == 2'd2) begin
|
||||
case (tx_byte_counter)
|
||||
4'd0: tx_byte_data = {1'd0, rtc_time_second};
|
||||
4'd1: tx_byte_data = {1'd0, rtc_time_minute};
|
||||
4'd2: tx_byte_data = {2'b10, rtc_time_hour};
|
||||
4'd3: tx_byte_data = {2'd0, rtc_time_day};
|
||||
4'd4: tx_byte_data = {5'd0, rtc_time_weekday};
|
||||
4'd5: tx_byte_data = {3'd0, rtc_time_month};
|
||||
4'd6: tx_byte_data = rtc_time_year;
|
||||
4'd7: tx_byte_data = 8'h01;
|
||||
4'd8: tx_byte_data = {(|rtc_stopped), 7'd0};
|
||||
endcase
|
||||
end
|
||||
end
|
||||
CMD_RTC_WRITE: begin
|
||||
tx_length = 4'd0;
|
||||
tx_byte_data = {(|rtc_stopped), 7'd0};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -1,96 +0,0 @@
|
||||
module n64_soc (
|
||||
if_system sys,
|
||||
if_config cfg,
|
||||
if_dma.memory dma,
|
||||
if_sdram.memory sdram,
|
||||
if_flashram.flashram flashram,
|
||||
if_si.si si,
|
||||
if_flash.memory flash,
|
||||
if_dd dd,
|
||||
|
||||
input n64_pi_alel,
|
||||
input n64_pi_aleh,
|
||||
input n64_pi_read,
|
||||
input n64_pi_write,
|
||||
inout [15:0] n64_pi_ad,
|
||||
|
||||
input n64_si_clk,
|
||||
inout n64_si_dq,
|
||||
|
||||
output sdram_cs,
|
||||
output sdram_ras,
|
||||
output sdram_cas,
|
||||
output sdram_we,
|
||||
output [1:0] sdram_ba,
|
||||
output [12:0] sdram_a,
|
||||
inout [15:0] sdram_dq
|
||||
);
|
||||
|
||||
if_n64_bus bus ();
|
||||
|
||||
n64_pi n64_pi_inst (
|
||||
.sys(sys),
|
||||
.cfg(cfg),
|
||||
.bus(bus),
|
||||
|
||||
.n64_pi_alel(n64_pi_alel),
|
||||
.n64_pi_aleh(n64_pi_aleh),
|
||||
.n64_pi_read(n64_pi_read),
|
||||
.n64_pi_write(n64_pi_write),
|
||||
.n64_pi_ad(n64_pi_ad)
|
||||
);
|
||||
|
||||
n64_si n64_si_inst (
|
||||
.sys(sys),
|
||||
.si(si),
|
||||
|
||||
.n64_si_clk(n64_si_clk),
|
||||
.n64_si_dq(n64_si_dq)
|
||||
);
|
||||
|
||||
n64_sdram n64_sdram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_SDRAM].device),
|
||||
.dma(dma),
|
||||
.sdram(sdram),
|
||||
|
||||
.sdram_cs(sdram_cs),
|
||||
.sdram_ras(sdram_ras),
|
||||
.sdram_cas(sdram_cas),
|
||||
.sdram_we(sdram_we),
|
||||
.sdram_ba(sdram_ba),
|
||||
.sdram_a(sdram_a),
|
||||
.sdram_dq(sdram_dq)
|
||||
);
|
||||
|
||||
n64_bootloader n64_bootloader_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device),
|
||||
.flash(flash)
|
||||
);
|
||||
|
||||
n64_flashram n64_flashram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_FLASHRAM].device),
|
||||
.cfg(cfg),
|
||||
.flashram(flashram)
|
||||
);
|
||||
|
||||
n64_dd n64_dd_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_DD].device),
|
||||
.dd(dd)
|
||||
);
|
||||
|
||||
n64_dd_sector_buffer n64_dd_sector_buffer_inst (
|
||||
.sys(sys),
|
||||
.dd(dd)
|
||||
);
|
||||
|
||||
n64_cfg n64_cfg_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_CFG].device),
|
||||
.cfg(cfg)
|
||||
);
|
||||
|
||||
endmodule
|
97
fw/rtl/n64/n64_top.sv
Normal file
97
fw/rtl/n64/n64_top.sv
Normal file
@ -0,0 +1,97 @@
|
||||
module n64_top (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_scb n64_scb,
|
||||
dd_scb.dd dd_scb,
|
||||
|
||||
mem_bus.controller mem_bus,
|
||||
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
output n64_irq,
|
||||
|
||||
input n64_pi_alel,
|
||||
input n64_pi_aleh,
|
||||
input n64_pi_read,
|
||||
input n64_pi_write,
|
||||
inout [15:0] n64_pi_ad,
|
||||
|
||||
input n64_si_clk,
|
||||
inout n64_si_dq
|
||||
);
|
||||
|
||||
logic n64_dd_irq;
|
||||
logic n64_cfg_irq;
|
||||
logic n64_irq_oe;
|
||||
|
||||
always @(posedge clk) begin
|
||||
n64_irq_oe <= (n64_dd_irq || n64_cfg_irq);
|
||||
end
|
||||
|
||||
assign n64_irq = n64_irq_oe ? 1'b0 : 1'bZ;
|
||||
|
||||
n64_reg_bus reg_bus ();
|
||||
|
||||
n64_pi n64_pi_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.mem_bus(mem_bus),
|
||||
.reg_bus(reg_bus),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
|
||||
.n64_reset(n64_reset),
|
||||
.n64_nmi(n64_nmi),
|
||||
.n64_pi_alel(n64_pi_alel),
|
||||
.n64_pi_aleh(n64_pi_aleh),
|
||||
.n64_pi_read(n64_pi_read),
|
||||
.n64_pi_write(n64_pi_write),
|
||||
.n64_pi_ad(n64_pi_ad)
|
||||
);
|
||||
|
||||
n64_dd n64_dd_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.reg_bus(reg_bus),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
.dd_scb(dd_scb),
|
||||
|
||||
.irq(n64_dd_irq)
|
||||
);
|
||||
|
||||
n64_flashram n64_flashram_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.reg_bus(reg_bus),
|
||||
|
||||
.n64_scb(n64_scb)
|
||||
);
|
||||
|
||||
n64_cfg n64_cfg_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.reg_bus(reg_bus),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
|
||||
.irq(n64_cfg_irq)
|
||||
);
|
||||
|
||||
n64_si n64_si_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
|
||||
.n64_reset(n64_reset),
|
||||
.n64_si_clk(n64_si_clk),
|
||||
.n64_si_dq(n64_si_dq)
|
||||
);
|
||||
|
||||
endmodule
|
48
fw/rtl/sd/sd_clk.sv
Normal file
48
fw/rtl/sd/sd_clk.sv
Normal file
@ -0,0 +1,48 @@
|
||||
module sd_clk (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
sd_scb.clk sd_scb,
|
||||
|
||||
output logic sd_clk_rising,
|
||||
output logic sd_clk_falling,
|
||||
|
||||
output logic sd_clk
|
||||
);
|
||||
|
||||
logic [7:0] clock_divider;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!sd_scb.clock_stop) begin
|
||||
clock_divider <= clock_divider + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
logic selected_clock;
|
||||
|
||||
always_comb begin
|
||||
selected_clock = 1'b0;
|
||||
case (sd_scb.clock_mode)
|
||||
2'd0: selected_clock = 1'b0;
|
||||
2'd1: selected_clock = clock_divider[7];
|
||||
2'd2: selected_clock = clock_divider[1];
|
||||
2'd3: selected_clock = clock_divider[0];
|
||||
endcase
|
||||
end
|
||||
|
||||
logic last_selected_clock;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
last_selected_clock <= selected_clock;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
sd_clk_rising = !last_selected_clock && selected_clock;
|
||||
sd_clk_falling = last_selected_clock && !selected_clock;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
sd_clk <= last_selected_clock;
|
||||
end
|
||||
|
||||
endmodule
|
231
fw/rtl/sd/sd_cmd.sv
Normal file
231
fw/rtl/sd/sd_cmd.sv
Normal file
@ -0,0 +1,231 @@
|
||||
module sd_cmd (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
sd_scb.cmd sd_scb,
|
||||
|
||||
input sd_clk_rising,
|
||||
input sd_clk_falling,
|
||||
|
||||
inout sd_cmd
|
||||
);
|
||||
|
||||
// Input and output data sampling
|
||||
|
||||
logic sd_cmd_oe;
|
||||
logic sd_cmd_out;
|
||||
logic sd_cmd_in;
|
||||
logic sd_cmd_oe_data;
|
||||
logic sd_cmd_data;
|
||||
|
||||
assign sd_cmd = sd_cmd_oe ? sd_cmd_out : 1'bZ;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
sd_cmd_oe <= sd_cmd_oe_data;
|
||||
sd_cmd_out <= sd_cmd_data;
|
||||
sd_cmd_in <= sd_cmd;
|
||||
end
|
||||
|
||||
|
||||
// CMD state
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
STATE_IDLE,
|
||||
STATE_TX,
|
||||
STATE_WAIT,
|
||||
STATE_RX
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
e_state next_state;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
state <= STATE_IDLE;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
assign sd_scb.cmd_busy = (state != STATE_IDLE);
|
||||
|
||||
logic [7:0] counter;
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (sd_scb.cmd_start) begin
|
||||
next_state = STATE_TX;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX: begin
|
||||
if (sd_clk_falling) begin
|
||||
if (counter == 8'd48) begin
|
||||
if (sd_scb.cmd_skip_response) begin
|
||||
next_state = STATE_IDLE;
|
||||
end else begin
|
||||
next_state = STATE_WAIT;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_WAIT: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (counter == 8'd64) begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
if (!sd_cmd_in) begin
|
||||
next_state = STATE_RX;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_RX: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (sd_scb.cmd_long_response) begin
|
||||
if (counter == 8'd136) begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
end else begin
|
||||
if (counter == 8'd48) begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// CRC7 unit
|
||||
|
||||
logic crc_reset;
|
||||
logic crc_enable;
|
||||
logic crc_data;
|
||||
logic [6:0] crc_result;
|
||||
|
||||
sd_crc_7 sd_crc_7_inst (
|
||||
.clk(clk),
|
||||
.reset(crc_reset),
|
||||
.enable(crc_enable),
|
||||
.data(crc_data),
|
||||
.result(crc_result)
|
||||
);
|
||||
|
||||
|
||||
// Data shifting
|
||||
|
||||
logic [7:0] data_shift;
|
||||
|
||||
assign crc_data = (state == STATE_RX) ? data_shift[0] : data_shift[7];
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
crc_reset <= 1'b0;
|
||||
crc_enable <= 1'b0;
|
||||
|
||||
if (reset) begin
|
||||
sd_cmd_oe_data <= 1'b0;
|
||||
sd_cmd_data <= 1'b1;
|
||||
end else begin
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (sd_scb.cmd_start) begin
|
||||
sd_scb.cmd_error <= 1'b0;
|
||||
crc_reset <= 1'b1;
|
||||
data_shift <= {2'b01, sd_scb.cmd_index};
|
||||
counter <= 8'd0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX: begin
|
||||
if (sd_clk_falling) begin
|
||||
sd_cmd_oe_data <= 1'b1;
|
||||
sd_cmd_data <= data_shift[7];
|
||||
counter <= counter + 1'd1;
|
||||
crc_enable <= 1'b1;
|
||||
data_shift <= {data_shift[6:0], 1'bX};
|
||||
if (counter == 8'd7) begin
|
||||
data_shift <= sd_scb.cmd_arg[31:24];
|
||||
end
|
||||
if (counter == 8'd15) begin
|
||||
data_shift <= sd_scb.cmd_arg[23:16];
|
||||
end
|
||||
if (counter == 8'd23) begin
|
||||
data_shift <= sd_scb.cmd_arg[15:8];
|
||||
end
|
||||
if (counter == 8'd31) begin
|
||||
data_shift <= sd_scb.cmd_arg[7:0];
|
||||
end
|
||||
if (counter == 8'd39) begin
|
||||
data_shift <= {crc_result, 1'b1};
|
||||
end
|
||||
if (counter == 8'd48) begin
|
||||
sd_cmd_oe_data <= 1'b0;
|
||||
counter <= 8'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_WAIT: begin
|
||||
if (sd_clk_rising) begin
|
||||
counter <= counter + 1'd1;
|
||||
if (counter == 8'd64) begin
|
||||
sd_scb.cmd_error <= 1'b1;
|
||||
end
|
||||
if (!sd_cmd_in) begin
|
||||
counter <= 8'd1;
|
||||
crc_reset <= 1'b1;
|
||||
data_shift <= 8'h00;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_RX: begin
|
||||
if (sd_clk_rising) begin
|
||||
counter <= counter + 1'd1;
|
||||
data_shift <= {data_shift[6:0], sd_cmd_in};
|
||||
if (counter == 8'd8) begin
|
||||
if (data_shift[6:0] != (sd_scb.cmd_reserved_response ? 7'h3F : {1'b0, sd_scb.cmd_index})) begin
|
||||
sd_scb.cmd_error <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (sd_scb.cmd_long_response) begin
|
||||
if (counter >= 8'd8 && counter < 8'd128) begin
|
||||
crc_enable <= 1'b1;
|
||||
end
|
||||
if (counter[2:0] == 3'd0) begin
|
||||
sd_scb.cmd_rsp <= {sd_scb.cmd_rsp[119:0], data_shift};
|
||||
end
|
||||
if (!sd_scb.cmd_ignore_crc && counter == 8'd136) begin
|
||||
if (data_shift[7:1] != crc_result) begin
|
||||
sd_scb.cmd_error <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (counter < 8'd40) begin
|
||||
crc_enable <= 1'b1;
|
||||
end
|
||||
if (counter <= 8'd40 && counter[2:0] == 3'd0) begin
|
||||
sd_scb.cmd_rsp <= {sd_scb.cmd_rsp[119:0], data_shift};
|
||||
end
|
||||
if (!sd_scb.cmd_ignore_crc && counter == 8'd48) begin
|
||||
if (data_shift[7:1] != crc_result) begin
|
||||
sd_scb.cmd_error <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
33
fw/rtl/sd/sd_crc_16.sv
Normal file
33
fw/rtl/sd/sd_crc_16.sv
Normal file
@ -0,0 +1,33 @@
|
||||
module sd_crc_16 (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input enable,
|
||||
input shift,
|
||||
input data,
|
||||
|
||||
output logic [15:0] result
|
||||
);
|
||||
|
||||
logic crc_inv;
|
||||
|
||||
assign crc_inv = result[15] ^ data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
result <= 16'd0;
|
||||
end else if (enable) begin
|
||||
result <= {
|
||||
result[14:12],
|
||||
result[11] ^ crc_inv,
|
||||
result[10:5],
|
||||
result[4] ^ crc_inv,
|
||||
result[3:0],
|
||||
crc_inv
|
||||
};
|
||||
end else if (shift) begin
|
||||
result <= {result[14:0], 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
28
fw/rtl/sd/sd_crc_7.sv
Normal file
28
fw/rtl/sd/sd_crc_7.sv
Normal file
@ -0,0 +1,28 @@
|
||||
module sd_crc_7 (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input enable,
|
||||
input data,
|
||||
|
||||
output logic [6:0] result
|
||||
);
|
||||
|
||||
logic crc_inv;
|
||||
|
||||
assign crc_inv = result[6] ^ data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
result <= 7'd0;
|
||||
end else if (enable) begin
|
||||
result <= {
|
||||
result[5:3],
|
||||
result[2] ^ crc_inv,
|
||||
result[1:0],
|
||||
crc_inv
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
373
fw/rtl/sd/sd_dat.sv
Normal file
373
fw/rtl/sd/sd_dat.sv
Normal file
@ -0,0 +1,373 @@
|
||||
module sd_dat (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
sd_scb.dat sd_scb,
|
||||
|
||||
fifo_bus.fifo fifo_bus,
|
||||
|
||||
input sd_clk_rising,
|
||||
input sd_clk_falling,
|
||||
|
||||
inout [3:0] sd_dat
|
||||
);
|
||||
|
||||
// Input and output data sampling
|
||||
|
||||
logic sd_dat_oe;
|
||||
logic [3:0] sd_dat_out;
|
||||
logic [3:0] sd_dat_in;
|
||||
logic sd_dat_oe_data;
|
||||
logic [3:0] sd_dat_data;
|
||||
|
||||
assign sd_dat = sd_dat_oe ? sd_dat_out : 4'hZ;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
sd_dat_oe <= sd_dat_oe_data;
|
||||
sd_dat_out <= sd_dat_data;
|
||||
sd_dat_in <= sd_dat;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
sd_scb.card_busy <= !sd_dat_in[0];
|
||||
end
|
||||
|
||||
|
||||
// FIFO
|
||||
|
||||
logic rx_full;
|
||||
logic rx_almost_full;
|
||||
logic rx_write;
|
||||
logic [7:0] rx_wdata;
|
||||
|
||||
logic tx_empty;
|
||||
logic tx_almost_empty;
|
||||
logic tx_read;
|
||||
logic [7:0] tx_rdata;
|
||||
|
||||
fifo_8kb fifo_8kb_rx_inst (
|
||||
.clk(clk),
|
||||
.reset(reset || sd_scb.dat_fifo_flush),
|
||||
|
||||
.empty(fifo_bus.rx_empty),
|
||||
.almost_empty(fifo_bus.rx_almost_empty),
|
||||
.read(fifo_bus.rx_read),
|
||||
.rdata(fifo_bus.rx_rdata),
|
||||
|
||||
.full(rx_full),
|
||||
.almost_full(rx_almost_full),
|
||||
.write(rx_write),
|
||||
.wdata(rx_wdata),
|
||||
|
||||
.count(sd_scb.rx_count)
|
||||
);
|
||||
|
||||
fifo_8kb fifo_8kb_tx_inst (
|
||||
.clk(clk),
|
||||
.reset(reset || sd_scb.dat_fifo_flush),
|
||||
|
||||
.empty(tx_empty),
|
||||
.almost_empty(tx_almost_empty),
|
||||
.read(tx_read),
|
||||
.rdata(tx_rdata),
|
||||
|
||||
.full(fifo_bus.tx_full),
|
||||
.almost_full(fifo_bus.tx_almost_full),
|
||||
.write(fifo_bus.tx_write),
|
||||
.wdata(fifo_bus.tx_wdata),
|
||||
|
||||
.count(sd_scb.tx_count)
|
||||
);
|
||||
|
||||
|
||||
// DAT state
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
STATE_IDLE,
|
||||
STATE_RX_WAIT,
|
||||
STATE_RX,
|
||||
STATE_TX_WAIT,
|
||||
STATE_TX,
|
||||
STATE_TX_STATUS_WAIT,
|
||||
STATE_TX_STATUS
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
e_state next_state;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset || sd_scb.dat_stop) begin
|
||||
state <= STATE_IDLE;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
assign sd_scb.dat_busy = (state != STATE_IDLE);
|
||||
|
||||
logic [10:0] counter;
|
||||
logic [7:0] blocks_remaining;
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (sd_scb.dat_start_read) begin
|
||||
next_state = STATE_RX_WAIT;
|
||||
end
|
||||
if (sd_scb.dat_start_write) begin
|
||||
next_state = STATE_TX_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_RX_WAIT: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (!sd_dat_in[0]) begin
|
||||
next_state = STATE_RX;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_RX: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (counter == 11'd1041) begin
|
||||
if (blocks_remaining == 8'd0) begin
|
||||
next_state = STATE_IDLE;
|
||||
end else begin
|
||||
next_state = STATE_RX_WAIT;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX_WAIT: begin
|
||||
if (sd_clk_falling) begin
|
||||
if (sd_scb.tx_count >= 11'd512) begin
|
||||
next_state = STATE_TX;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX: begin
|
||||
if (sd_clk_falling) begin
|
||||
if (counter == 11'd1042) begin
|
||||
next_state = STATE_TX_STATUS_WAIT;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX_STATUS_WAIT: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (counter == 11'd8) begin
|
||||
next_state = STATE_IDLE;
|
||||
end else if (!sd_dat_in[0]) begin
|
||||
next_state = STATE_TX_STATUS;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX_STATUS: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (counter == 11'd5) begin
|
||||
if (sd_dat_in[0]) begin
|
||||
if (blocks_remaining == 8'd0) begin
|
||||
next_state = STATE_IDLE;
|
||||
end else begin
|
||||
next_state = STATE_TX_WAIT;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// CRC16 units
|
||||
|
||||
logic crc_reset;
|
||||
logic crc_enable;
|
||||
logic crc_shift;
|
||||
logic [3:0] crc_data;
|
||||
logic [15:0] crc_result [0:3];
|
||||
|
||||
sd_crc_16 sd_crc_16_inst_0 (
|
||||
.clk(clk),
|
||||
.reset(crc_reset),
|
||||
.enable(crc_enable),
|
||||
.shift(crc_shift),
|
||||
.data(crc_data[0]),
|
||||
.result(crc_result[0])
|
||||
);
|
||||
|
||||
sd_crc_16 sd_crc_16_inst_1 (
|
||||
.clk(clk),
|
||||
.reset(crc_reset),
|
||||
.enable(crc_enable),
|
||||
.shift(crc_shift),
|
||||
.data(crc_data[1]),
|
||||
.result(crc_result[1])
|
||||
);
|
||||
|
||||
sd_crc_16 sd_crc_16_inst_2 (
|
||||
.clk(clk),
|
||||
.reset(crc_reset),
|
||||
.enable(crc_enable),
|
||||
.shift(crc_shift),
|
||||
.data(crc_data[2]),
|
||||
.result(crc_result[2])
|
||||
);
|
||||
|
||||
sd_crc_16 sd_crc_16_inst_3 (
|
||||
.clk(clk),
|
||||
.reset(crc_reset),
|
||||
.enable(crc_enable),
|
||||
.shift(crc_shift),
|
||||
.data(crc_data[3]),
|
||||
.result(crc_result[3])
|
||||
);
|
||||
|
||||
|
||||
// Data shifting
|
||||
|
||||
logic [7:0] data_shift;
|
||||
logic tx_rdata_valid;
|
||||
|
||||
assign crc_data = (state == STATE_RX) ? rx_wdata[3:0] : sd_dat_data;
|
||||
|
||||
always_comb begin
|
||||
tx_read = (state == STATE_TX) && sd_clk_falling && (counter < 11'd1024) && (!counter[0]);
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
rx_write <= 1'b0;
|
||||
tx_rdata_valid <= tx_read;
|
||||
crc_reset <= 1'b0;
|
||||
crc_enable <= 1'b0;
|
||||
crc_shift <= 1'b0;
|
||||
|
||||
if (reset || sd_scb.dat_stop) begin
|
||||
sd_scb.clock_stop <= 1'b0;
|
||||
sd_dat_oe_data <= 1'b0;
|
||||
sd_dat_data <= 4'hF;
|
||||
end else begin
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (sd_scb.dat_start_read || sd_scb.dat_start_write) begin
|
||||
sd_scb.dat_error <= 1'b0;
|
||||
blocks_remaining <= sd_scb.dat_blocks;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_RX_WAIT: begin
|
||||
if (sd_scb.rx_count <= 11'd512) begin
|
||||
sd_scb.clock_stop <= 1'b0;
|
||||
end
|
||||
if (sd_clk_rising) begin
|
||||
if (!sd_dat_in[0]) begin
|
||||
counter <= 11'd1;
|
||||
crc_reset <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_RX: begin
|
||||
if (sd_clk_rising) begin
|
||||
counter <= counter + 1'd1;
|
||||
rx_wdata <= {rx_wdata[3:0], sd_dat_in};
|
||||
if (counter <= 11'd1024) begin
|
||||
crc_enable <= 1'b1;
|
||||
if (!counter[0]) begin
|
||||
if (rx_full) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end else begin
|
||||
rx_write <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
crc_shift <= 1'b1;
|
||||
if ({crc_result[3][15], crc_result[2][15], crc_result[1][15], crc_result[0][15]} != sd_dat_in) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (counter == 11'd1041) begin
|
||||
if ((blocks_remaining > 8'd0) && (sd_scb.rx_count > 11'd512)) begin
|
||||
sd_scb.clock_stop <= 1'b1;
|
||||
end
|
||||
blocks_remaining <= blocks_remaining - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX_WAIT: begin
|
||||
if (sd_clk_falling) begin
|
||||
if (sd_scb.tx_count >= 11'd512) begin
|
||||
counter <= 11'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX: begin
|
||||
if (sd_clk_falling) begin
|
||||
counter <= counter + 1'd1;
|
||||
if (counter == 11'd0) begin
|
||||
crc_reset <= 1'b1;
|
||||
sd_dat_oe_data <= 1'b1;
|
||||
sd_dat_data <= 4'h0;
|
||||
end else if (counter <= 11'd1024) begin
|
||||
crc_enable <= 1'b1;
|
||||
{sd_dat_data, data_shift} <= {data_shift, 4'h0};
|
||||
end else begin
|
||||
crc_shift <= 1'b1;
|
||||
sd_dat_data <= {crc_result[3][15], crc_result[2][15], crc_result[1][15], crc_result[0][15]};
|
||||
end
|
||||
if (counter == 11'd1042) begin
|
||||
sd_dat_oe_data <= 1'b0;
|
||||
counter <= 11'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX_STATUS_WAIT: begin
|
||||
if (sd_clk_rising) begin
|
||||
counter <= counter + 1'd1;
|
||||
if (counter == 11'd8) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end else if (!sd_dat_in[0]) begin
|
||||
counter <= 11'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_TX_STATUS: begin
|
||||
if (sd_clk_rising) begin
|
||||
if (counter < 11'd5) begin
|
||||
counter <= counter + 1'd1;
|
||||
end
|
||||
if ((counter == 11'd1) && (sd_dat_in[0] != 1'b0)) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end
|
||||
if ((counter == 11'd2) && (sd_dat_in[0] != 1'b1)) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end
|
||||
if ((counter == 11'd3) && (sd_dat_in[0] != 1'b0)) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end
|
||||
if ((counter == 11'd4) && (sd_dat_in[0] != 1'b1)) begin
|
||||
sd_scb.dat_error <= 1'b1;
|
||||
end
|
||||
if ((counter == 11'd5) && (sd_dat_in[0] == 1'b1)) begin
|
||||
blocks_remaining <= blocks_remaining - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (tx_rdata_valid) begin
|
||||
data_shift <= tx_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
93
fw/rtl/sd/sd_scb.sv
Normal file
93
fw/rtl/sd/sd_scb.sv
Normal file
@ -0,0 +1,93 @@
|
||||
interface sd_scb ();
|
||||
|
||||
logic [1:0] clock_mode;
|
||||
logic clock_stop;
|
||||
|
||||
logic card_busy;
|
||||
|
||||
logic [10:0] rx_count;
|
||||
logic [10:0] tx_count;
|
||||
|
||||
logic [5:0] cmd_index;
|
||||
logic [31:0] cmd_arg;
|
||||
logic [127:0] cmd_rsp;
|
||||
logic cmd_start;
|
||||
logic cmd_skip_response;
|
||||
logic cmd_reserved_response;
|
||||
logic cmd_long_response;
|
||||
logic cmd_ignore_crc;
|
||||
logic cmd_busy;
|
||||
logic cmd_error;
|
||||
|
||||
logic dat_fifo_flush;
|
||||
logic dat_start_write;
|
||||
logic dat_start_read;
|
||||
logic dat_stop;
|
||||
logic [7:0] dat_blocks;
|
||||
logic dat_busy;
|
||||
logic dat_error;
|
||||
|
||||
modport controller (
|
||||
output clock_mode,
|
||||
|
||||
input card_busy,
|
||||
|
||||
input rx_count,
|
||||
input tx_count,
|
||||
|
||||
output cmd_index,
|
||||
output cmd_arg,
|
||||
input cmd_rsp,
|
||||
output cmd_start,
|
||||
output cmd_skip_response,
|
||||
output cmd_reserved_response,
|
||||
output cmd_long_response,
|
||||
output cmd_ignore_crc,
|
||||
input cmd_busy,
|
||||
input cmd_error,
|
||||
|
||||
output dat_fifo_flush,
|
||||
output dat_start_write,
|
||||
output dat_start_read,
|
||||
output dat_stop,
|
||||
output dat_blocks,
|
||||
input dat_busy,
|
||||
input dat_error
|
||||
);
|
||||
|
||||
modport clk (
|
||||
input clock_mode,
|
||||
input clock_stop
|
||||
);
|
||||
|
||||
modport cmd (
|
||||
input cmd_index,
|
||||
input cmd_arg,
|
||||
output cmd_rsp,
|
||||
input cmd_start,
|
||||
input cmd_skip_response,
|
||||
input cmd_reserved_response,
|
||||
input cmd_long_response,
|
||||
input cmd_ignore_crc,
|
||||
output cmd_busy,
|
||||
output cmd_error
|
||||
);
|
||||
|
||||
modport dat (
|
||||
output clock_stop,
|
||||
|
||||
output card_busy,
|
||||
|
||||
output rx_count,
|
||||
output tx_count,
|
||||
|
||||
input dat_fifo_flush,
|
||||
input dat_start_write,
|
||||
input dat_start_read,
|
||||
input dat_stop,
|
||||
input dat_blocks,
|
||||
output dat_busy,
|
||||
output dat_error
|
||||
);
|
||||
|
||||
endinterface
|
55
fw/rtl/sd/sd_top.sv
Normal file
55
fw/rtl/sd/sd_top.sv
Normal file
@ -0,0 +1,55 @@
|
||||
module sd_top (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
sd_scb sd_scb,
|
||||
|
||||
fifo_bus.fifo fifo_bus,
|
||||
|
||||
output sd_clk,
|
||||
inout sd_cmd,
|
||||
inout [3:0] sd_dat
|
||||
);
|
||||
|
||||
logic sd_clk_rising;
|
||||
logic sd_clk_falling;
|
||||
|
||||
sd_clk sd_clk_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.sd_scb(sd_scb),
|
||||
|
||||
.sd_clk_rising(sd_clk_rising),
|
||||
.sd_clk_falling(sd_clk_falling),
|
||||
|
||||
.sd_clk(sd_clk)
|
||||
);
|
||||
|
||||
sd_cmd sd_cmd_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.sd_scb(sd_scb),
|
||||
|
||||
.sd_clk_rising(sd_clk_rising),
|
||||
.sd_clk_falling(sd_clk_falling),
|
||||
|
||||
.sd_cmd(sd_cmd)
|
||||
);
|
||||
|
||||
sd_dat sd_dat_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.sd_scb(sd_scb),
|
||||
|
||||
.fifo_bus(fifo_bus),
|
||||
|
||||
.sd_clk_rising(sd_clk_rising),
|
||||
.sd_clk_falling(sd_clk_falling),
|
||||
|
||||
.sd_dat(sd_dat)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,67 +0,0 @@
|
||||
interface if_config ();
|
||||
|
||||
logic cpu_ready;
|
||||
logic cpu_busy;
|
||||
logic cmd_error;
|
||||
logic cmd_request;
|
||||
logic [7:0] cmd;
|
||||
logic [31:0] data [0:1];
|
||||
logic [1:0] data_write;
|
||||
logic [31:0] wdata;
|
||||
logic sdram_switch;
|
||||
logic sdram_writable;
|
||||
logic dd_enabled;
|
||||
logic sram_enabled;
|
||||
logic sram_banked;
|
||||
logic flashram_enabled;
|
||||
logic flashram_read_mode;
|
||||
logic [25:0] ddipl_offset;
|
||||
logic [25:0] save_offset;
|
||||
|
||||
modport pi (
|
||||
input sdram_switch,
|
||||
input sdram_writable,
|
||||
input dd_enabled,
|
||||
input sram_enabled,
|
||||
input sram_banked,
|
||||
input flashram_enabled,
|
||||
input flashram_read_mode,
|
||||
input ddipl_offset,
|
||||
input save_offset
|
||||
);
|
||||
|
||||
modport flashram (
|
||||
output flashram_read_mode
|
||||
);
|
||||
|
||||
modport n64 (
|
||||
input cpu_ready,
|
||||
input cpu_busy,
|
||||
input cmd_error,
|
||||
output cmd_request,
|
||||
output cmd,
|
||||
output data,
|
||||
input data_write,
|
||||
input wdata
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
output cpu_ready,
|
||||
output cpu_busy,
|
||||
output cmd_error,
|
||||
input cmd_request,
|
||||
input cmd,
|
||||
input data,
|
||||
output data_write,
|
||||
output wdata,
|
||||
output sdram_switch,
|
||||
output sdram_writable,
|
||||
output dd_enabled,
|
||||
output sram_enabled,
|
||||
output sram_banked,
|
||||
output flashram_enabled,
|
||||
output ddipl_offset,
|
||||
output save_offset
|
||||
);
|
||||
|
||||
endinterface
|
@ -1,45 +0,0 @@
|
||||
package sc64;
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
ID_N64_SDRAM,
|
||||
ID_N64_BOOTLOADER,
|
||||
ID_N64_FLASHRAM,
|
||||
ID_N64_DD,
|
||||
ID_N64_CFG,
|
||||
__ID_N64_END
|
||||
} e_n64_id;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
ID_CPU_RAM,
|
||||
ID_CPU_FLASH,
|
||||
ID_CPU_GPIO,
|
||||
ID_CPU_I2C,
|
||||
ID_CPU_USB,
|
||||
ID_CPU_UART,
|
||||
ID_CPU_DMA,
|
||||
ID_CPU_CFG,
|
||||
ID_CPU_SDRAM,
|
||||
ID_CPU_FLASHRAM,
|
||||
ID_CPU_SI,
|
||||
ID_CPU_DD,
|
||||
__ID_CPU_END
|
||||
} e_cpu_id;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
ID_DMA_USB,
|
||||
ID_DMA_SD,
|
||||
__ID_DMA_END
|
||||
} e_dma_id;
|
||||
|
||||
parameter bit [31:0] SC64_VER = 32'h53437632;
|
||||
parameter int CLOCK_FREQUENCY = 32'd100_000_000;
|
||||
parameter bit [31:0] CPU_RESET_VECTOR = {4'(ID_CPU_FLASH), 28'h0035800};
|
||||
parameter int UART_BAUD_RATE = 32'd1_000_000;
|
||||
|
||||
`ifdef DEBUG
|
||||
parameter bit CPU_HAS_UART = 1'b1;
|
||||
`else
|
||||
parameter bit CPU_HAS_UART = 1'b0;
|
||||
`endif
|
||||
|
||||
endpackage
|
@ -1,62 +0,0 @@
|
||||
interface if_system (
|
||||
input in_clk,
|
||||
input n64_reset,
|
||||
input n64_nmi
|
||||
);
|
||||
|
||||
logic clk;
|
||||
logic sdram_clk;
|
||||
logic reset;
|
||||
logic n64_soft_reset;
|
||||
logic n64_hard_reset;
|
||||
|
||||
modport internal (
|
||||
input in_clk,
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
output clk,
|
||||
output sdram_clk,
|
||||
output reset,
|
||||
output n64_soft_reset,
|
||||
output n64_hard_reset
|
||||
);
|
||||
|
||||
modport sys (
|
||||
input clk,
|
||||
input reset,
|
||||
input n64_soft_reset,
|
||||
input n64_hard_reset
|
||||
);
|
||||
|
||||
modport sdram (
|
||||
input sdram_clk
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module system (if_system.internal sys);
|
||||
|
||||
logic locked;
|
||||
logic [1:0] n64_reset_ff;
|
||||
logic [1:0] n64_nmi_ff;
|
||||
|
||||
intel_pll intel_pll_inst (
|
||||
.inclk0(sys.in_clk),
|
||||
.c0(sys.clk),
|
||||
.c1(sys.sdram_clk),
|
||||
.locked(locked)
|
||||
);
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_reset_ff <= {n64_reset_ff[0], sys.n64_reset};
|
||||
n64_nmi_ff <= {n64_nmi_ff[0], sys.n64_nmi};
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
sys.reset = ~locked;
|
||||
sys.n64_hard_reset = ~n64_reset_ff[1];
|
||||
sys.n64_soft_reset = ~n64_nmi_ff[1];
|
||||
end
|
||||
|
||||
endmodule
|
267
fw/rtl/top.sv
Normal file
267
fw/rtl/top.sv
Normal file
@ -0,0 +1,267 @@
|
||||
module top (
|
||||
input inclk,
|
||||
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
output n64_irq,
|
||||
|
||||
input n64_pi_alel,
|
||||
input n64_pi_aleh,
|
||||
input n64_pi_read,
|
||||
input n64_pi_write,
|
||||
inout [15:0] n64_pi_ad,
|
||||
|
||||
input n64_si_clk,
|
||||
inout n64_si_dq,
|
||||
|
||||
input usb_pwrsav,
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
input usb_miso,
|
||||
inout [7:0] usb_miosi,
|
||||
|
||||
input sd_det,
|
||||
output sd_clk,
|
||||
inout sd_cmd,
|
||||
inout [3:0] sd_dat,
|
||||
|
||||
output sdram_clk,
|
||||
output sdram_cs,
|
||||
output sdram_ras,
|
||||
output sdram_cas,
|
||||
output sdram_we,
|
||||
output [1:0] sdram_ba,
|
||||
output [12:0] sdram_a,
|
||||
output [1:0] sdram_dqm,
|
||||
inout [15:0] sdram_dq,
|
||||
|
||||
output flash_clk,
|
||||
output flash_cs,
|
||||
inout [3:0] flash_dq,
|
||||
|
||||
input button,
|
||||
|
||||
output mcu_int,
|
||||
input mcu_clk,
|
||||
input mcu_cs,
|
||||
input mcu_mosi,
|
||||
output mcu_miso
|
||||
);
|
||||
|
||||
logic clk;
|
||||
logic reset;
|
||||
|
||||
n64_scb n64_scb ();
|
||||
dd_scb dd_scb ();
|
||||
usb_scb usb_scb ();
|
||||
dma_scb usb_dma_scb ();
|
||||
sd_scb sd_scb ();
|
||||
dma_scb sd_dma_scb ();
|
||||
flash_scb flash_scb ();
|
||||
vendor_scb vendor_scb ();
|
||||
|
||||
fifo_bus usb_cfg_fifo_bus ();
|
||||
fifo_bus usb_dma_fifo_bus ();
|
||||
fifo_bus usb_fifo_bus ();
|
||||
fifo_bus sd_fifo_bus ();
|
||||
|
||||
mem_bus n64_mem_bus ();
|
||||
mem_bus cfg_mem_bus ();
|
||||
mem_bus usb_dma_mem_bus ();
|
||||
mem_bus sd_dma_mem_bus ();
|
||||
mem_bus sdram_mem_bus ();
|
||||
mem_bus flash_mem_bus ();
|
||||
mem_bus bram_mem_bus ();
|
||||
|
||||
pll pll_inst (
|
||||
.inclk(inclk),
|
||||
.clk(clk),
|
||||
.sdram_clk(sdram_clk),
|
||||
.reset(reset)
|
||||
);
|
||||
|
||||
|
||||
// MCU controller
|
||||
|
||||
mcu_top mcu_top_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
.dd_scb(dd_scb),
|
||||
.usb_scb(usb_scb),
|
||||
.usb_dma_scb(usb_dma_scb),
|
||||
.sd_scb(sd_scb),
|
||||
.sd_dma_scb(sd_dma_scb),
|
||||
.flash_scb(flash_scb),
|
||||
.vendor_scb(vendor_scb),
|
||||
|
||||
.fifo_bus(usb_cfg_fifo_bus),
|
||||
.mem_bus(cfg_mem_bus),
|
||||
|
||||
.sd_det(sd_det),
|
||||
.button(button),
|
||||
|
||||
.mcu_int(mcu_int),
|
||||
.mcu_clk(mcu_clk),
|
||||
.mcu_cs(mcu_cs),
|
||||
.mcu_mosi(mcu_mosi),
|
||||
.mcu_miso(mcu_miso)
|
||||
);
|
||||
|
||||
|
||||
// N64 controller
|
||||
|
||||
n64_top n64_top_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
.dd_scb(dd_scb),
|
||||
|
||||
.mem_bus(n64_mem_bus),
|
||||
|
||||
.n64_reset(n64_reset),
|
||||
.n64_nmi(n64_nmi),
|
||||
.n64_irq(n64_irq),
|
||||
|
||||
.n64_pi_alel(n64_pi_alel),
|
||||
.n64_pi_aleh(n64_pi_aleh),
|
||||
.n64_pi_read(n64_pi_read),
|
||||
.n64_pi_write(n64_pi_write),
|
||||
.n64_pi_ad(n64_pi_ad),
|
||||
|
||||
.n64_si_clk(n64_si_clk),
|
||||
.n64_si_dq(n64_si_dq)
|
||||
);
|
||||
|
||||
|
||||
// USB
|
||||
|
||||
usb_ft1248 usb_ft1248_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.usb_scb(usb_scb),
|
||||
|
||||
.fifo_bus(usb_fifo_bus),
|
||||
|
||||
.usb_pwrsav(usb_pwrsav),
|
||||
.usb_clk(usb_clk),
|
||||
.usb_cs(usb_cs),
|
||||
.usb_miso(usb_miso),
|
||||
.usb_miosi(usb_miosi)
|
||||
);
|
||||
|
||||
memory_dma memory_usb_dma_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.dma_scb(usb_dma_scb),
|
||||
|
||||
.fifo_bus(usb_dma_fifo_bus),
|
||||
.mem_bus(usb_dma_mem_bus)
|
||||
);
|
||||
|
||||
fifo_junction usb_fifo_junction_inst (
|
||||
.cfg_bus(usb_cfg_fifo_bus),
|
||||
.dma_bus(usb_dma_fifo_bus),
|
||||
.dev_bus(usb_fifo_bus)
|
||||
);
|
||||
|
||||
|
||||
// SD card
|
||||
|
||||
sd_top sd_top_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.sd_scb(sd_scb),
|
||||
|
||||
.fifo_bus(sd_fifo_bus),
|
||||
|
||||
.sd_clk(sd_clk),
|
||||
.sd_cmd(sd_cmd),
|
||||
.sd_dat(sd_dat)
|
||||
);
|
||||
|
||||
memory_dma memory_sd_dma_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.dma_scb(sd_dma_scb),
|
||||
|
||||
.fifo_bus(sd_fifo_bus),
|
||||
.mem_bus(sd_dma_mem_bus)
|
||||
);
|
||||
|
||||
|
||||
// Memory bus arbiter
|
||||
|
||||
memory_arbiter memory_arbiter_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
|
||||
.n64_bus(n64_mem_bus),
|
||||
.cfg_bus(cfg_mem_bus),
|
||||
.usb_dma_bus(usb_dma_mem_bus),
|
||||
.sd_dma_bus(sd_dma_mem_bus),
|
||||
|
||||
.sdram_mem_bus(sdram_mem_bus),
|
||||
.flash_mem_bus(flash_mem_bus),
|
||||
.bram_mem_bus(bram_mem_bus)
|
||||
);
|
||||
|
||||
|
||||
// Memory controllers
|
||||
|
||||
memory_sdram memory_sdram_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.mem_bus(sdram_mem_bus),
|
||||
|
||||
.sdram_cs(sdram_cs),
|
||||
.sdram_ras(sdram_ras),
|
||||
.sdram_cas(sdram_cas),
|
||||
.sdram_we(sdram_we),
|
||||
.sdram_ba(sdram_ba),
|
||||
.sdram_a(sdram_a),
|
||||
.sdram_dqm(sdram_dqm),
|
||||
.sdram_dq(sdram_dq)
|
||||
);
|
||||
|
||||
memory_flash memory_flash_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.flash_scb(flash_scb),
|
||||
|
||||
.mem_bus(flash_mem_bus),
|
||||
|
||||
.flash_clk(flash_clk),
|
||||
.flash_cs(flash_cs),
|
||||
.flash_dq(flash_dq)
|
||||
);
|
||||
|
||||
memory_bram memory_bram_inst (
|
||||
.clk(clk),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
|
||||
.mem_bus(bram_mem_bus)
|
||||
);
|
||||
|
||||
|
||||
// Vendor specific control
|
||||
|
||||
vendor vendor_inst (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.vendor_scb(vendor_scb)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,261 +1,356 @@
|
||||
interface usb_scb ();
|
||||
|
||||
logic fifo_flush;
|
||||
logic reset_pending;
|
||||
logic reset_ack;
|
||||
logic write_buffer_flush;
|
||||
logic [10:0] rx_count;
|
||||
logic [10:0] tx_count;
|
||||
logic pwrsav;
|
||||
logic reset_state;
|
||||
|
||||
modport controller (
|
||||
output fifo_flush,
|
||||
input reset_pending,
|
||||
output reset_ack,
|
||||
output write_buffer_flush,
|
||||
input rx_count,
|
||||
input tx_count,
|
||||
input pwrsav,
|
||||
input reset_state
|
||||
);
|
||||
|
||||
modport usb (
|
||||
input fifo_flush,
|
||||
output reset_pending,
|
||||
input reset_ack,
|
||||
input write_buffer_flush,
|
||||
output rx_count,
|
||||
output tx_count,
|
||||
output pwrsav,
|
||||
output reset_state
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module usb_ft1248 (
|
||||
if_system.sys sys,
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input usb_enabled,
|
||||
usb_scb.usb usb_scb,
|
||||
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
fifo_bus.fifo fifo_bus,
|
||||
|
||||
input usb_pwrsav,
|
||||
output logic usb_clk,
|
||||
output logic usb_cs,
|
||||
input usb_miso,
|
||||
inout [3:0] usb_miosi,
|
||||
|
||||
input rx_flush,
|
||||
output rx_empty,
|
||||
input rx_read,
|
||||
output [7:0] rx_rdata,
|
||||
|
||||
input tx_flush,
|
||||
output tx_full,
|
||||
input tx_write,
|
||||
input [7:0] tx_wdata,
|
||||
|
||||
output rx_escape_valid,
|
||||
input rx_escape_ack,
|
||||
output [7:0] rx_escape
|
||||
inout [7:0] usb_miosi
|
||||
);
|
||||
|
||||
parameter bit [7:0] ESCAPE_CHARACTER = 8'h1B;
|
||||
|
||||
// FIFOs
|
||||
|
||||
logic rx_full;
|
||||
logic rx_almost_full;
|
||||
logic rx_write;
|
||||
logic [7:0] rx_wdata;
|
||||
|
||||
logic tx_empty;
|
||||
logic tx_almost_empty;
|
||||
logic tx_read;
|
||||
logic [7:0] tx_rdata;
|
||||
|
||||
logic rx_wdata_valid;
|
||||
logic rx_escape_active;
|
||||
fifo_8kb fifo_8kb_rx_inst (
|
||||
.clk(clk),
|
||||
.reset(reset || usb_scb.fifo_flush),
|
||||
|
||||
intel_fifo_8 fifo_8_rx_inst (
|
||||
.clock(sys.clk),
|
||||
.sclr(rx_flush || !usb_enabled),
|
||||
|
||||
.empty(rx_empty),
|
||||
.rdreq(rx_read),
|
||||
.q(rx_rdata),
|
||||
.empty(fifo_bus.rx_empty),
|
||||
.almost_empty(fifo_bus.rx_almost_empty),
|
||||
.read(fifo_bus.rx_read),
|
||||
.rdata(fifo_bus.rx_rdata),
|
||||
|
||||
.full(rx_full),
|
||||
.wrreq(rx_write),
|
||||
.data(rx_wdata)
|
||||
.almost_full(rx_almost_full),
|
||||
.write(rx_write),
|
||||
.wdata(rx_wdata),
|
||||
|
||||
.count(usb_scb.rx_count)
|
||||
);
|
||||
|
||||
intel_fifo_8 fifo_8_tx_inst (
|
||||
.clock(sys.clk),
|
||||
.sclr(tx_flush || !usb_enabled),
|
||||
fifo_8kb fifo_8kb_tx_inst (
|
||||
.clk(clk),
|
||||
.reset(reset || usb_scb.fifo_flush),
|
||||
|
||||
.empty(tx_empty),
|
||||
.rdreq(tx_read),
|
||||
.q(tx_rdata),
|
||||
.almost_empty(tx_almost_empty),
|
||||
.read(tx_read),
|
||||
.rdata(tx_rdata),
|
||||
|
||||
.full(tx_full),
|
||||
.wrreq(tx_write),
|
||||
.data(tx_wdata)
|
||||
.full(fifo_bus.tx_full),
|
||||
.almost_full(fifo_bus.tx_almost_full),
|
||||
.write(fifo_bus.tx_write),
|
||||
.wdata(fifo_bus.tx_wdata),
|
||||
|
||||
.count(usb_scb.tx_count)
|
||||
);
|
||||
|
||||
logic [1:0] usb_pwrsav_ff;
|
||||
logic [7:0] usb_miosi_out;
|
||||
logic usb_oe;
|
||||
|
||||
// Escape character detection
|
||||
logic ft_pwrsav;
|
||||
logic ft_clk;
|
||||
logic ft_cs;
|
||||
logic ft_miso;
|
||||
logic [7:0] ft_miosi_in;
|
||||
logic [7:0] ft_miosi_out;
|
||||
logic ft_oe;
|
||||
|
||||
always_comb begin
|
||||
rx_write = 1'b0;
|
||||
if (rx_wdata_valid) begin
|
||||
rx_write = rx_escape_active ? rx_wdata == ESCAPE_CHARACTER : rx_wdata != ESCAPE_CHARACTER;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
usb_pwrsav_ff <= {usb_pwrsav_ff[0], usb_pwrsav};
|
||||
ft_pwrsav <= usb_pwrsav_ff[1];
|
||||
usb_clk <= ft_clk;
|
||||
usb_cs <= ft_cs;
|
||||
ft_miso <= usb_miso;
|
||||
ft_miosi_in <= usb_miosi;
|
||||
usb_miosi_out <= ft_miosi_out;
|
||||
usb_oe <= ft_oe;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || !usb_enabled) begin
|
||||
rx_escape_valid <= 1'b0;
|
||||
rx_escape_active <= 1'b0;
|
||||
end else begin
|
||||
if (rx_escape_ack) begin
|
||||
rx_escape_valid <= 1'b0;
|
||||
end
|
||||
assign usb_miosi = usb_oe ? usb_miosi_out : 8'hZZ;
|
||||
|
||||
if (rx_wdata_valid) begin
|
||||
if (!rx_escape_active) begin
|
||||
if (rx_wdata == ESCAPE_CHARACTER) begin
|
||||
rx_escape_active <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
rx_escape_active <= 1'b0;
|
||||
rx_escape <= rx_wdata;
|
||||
if (rx_wdata != ESCAPE_CHARACTER) begin
|
||||
rx_escape_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// FT1248 interface controller
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
S_TRY_RX,
|
||||
S_TRY_TX,
|
||||
S_COMMAND,
|
||||
S_DATA
|
||||
typedef enum bit [2:0] {
|
||||
STATE_IDLE,
|
||||
STATE_SELECT,
|
||||
STATE_COMMAND,
|
||||
STATE_STATUS,
|
||||
STATE_DATA,
|
||||
STATE_DESELECT
|
||||
} e_state;
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
C_WRITE = 8'h00,
|
||||
C_READ = 8'h04
|
||||
} e_command;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
P_PRE_RISING,
|
||||
P_RISING,
|
||||
P_PRE_FALLING,
|
||||
P_FALLING
|
||||
} e_clock_phase;
|
||||
CMD_WRITE = 8'h00,
|
||||
CMD_READ = 8'h40,
|
||||
CMD_READ_MODEM_STATUS = 8'h20,
|
||||
CMD_WRITE_MODEM_STATUS = 8'h60,
|
||||
CMD_WRITE_BUFFER_FLUSH = 8'h08
|
||||
} e_cmd;
|
||||
|
||||
e_state state;
|
||||
e_state next_state;
|
||||
e_cmd cmd;
|
||||
e_cmd next_cmd;
|
||||
logic [3:0] phase;
|
||||
logic last_tx_failed;
|
||||
logic reset_reply;
|
||||
logic last_reset_status;
|
||||
logic [4:0] modem_status_counter;
|
||||
logic write_modem_status_pending;
|
||||
logic write_buffer_flush_pending;
|
||||
|
||||
logic [3:0] clock_phase;
|
||||
always_ff @(posedge clk) begin
|
||||
state <= next_state;
|
||||
cmd <= next_cmd;
|
||||
|
||||
logic usb_clk_output;
|
||||
logic usb_cs_output;
|
||||
logic [3:0] usb_miosi_input;
|
||||
logic [3:0] usb_miosi_output;
|
||||
logic [3:0] usb_miosi_output_data;
|
||||
logic usb_miosi_output_enable;
|
||||
logic usb_miosi_output_enable_data;
|
||||
logic usb_miso_input;
|
||||
usb_scb.pwrsav <= !ft_pwrsav;
|
||||
usb_scb.reset_state <= last_reset_status;
|
||||
|
||||
logic is_cmd_write;
|
||||
logic [1:0] nibble_counter;
|
||||
logic [7:0] tx_buffer;
|
||||
phase <= {phase[2:0], phase[3]};
|
||||
if (state == STATE_IDLE) begin
|
||||
phase <= 4'b0100;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || state == S_TRY_RX || state == S_TRY_TX) begin
|
||||
clock_phase <= 4'b0001;
|
||||
if (reset) begin
|
||||
last_tx_failed <= 1'b0;
|
||||
usb_scb.reset_pending <= 1'b0;
|
||||
last_reset_status <= 1'b0;
|
||||
modem_status_counter <= 5'd0;
|
||||
write_modem_status_pending <= 1'b0;
|
||||
write_buffer_flush_pending <= 1'b0;
|
||||
end else begin
|
||||
clock_phase <= {clock_phase[2:0], clock_phase[3]};
|
||||
end
|
||||
end
|
||||
if (usb_scb.reset_ack) begin
|
||||
usb_scb.reset_pending <= 1'b0;
|
||||
reset_reply <= 1'b1;
|
||||
write_modem_status_pending <= 1'b1;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
usb_clk <= usb_clk_output;
|
||||
usb_cs <= usb_cs_output;
|
||||
if (usb_scb.write_buffer_flush) begin
|
||||
write_buffer_flush_pending <= 1'b1;
|
||||
end
|
||||
|
||||
usb_miosi_input <= usb_miosi;
|
||||
usb_miosi_output <= usb_miosi_output_data;
|
||||
usb_miosi_output_enable <= usb_miosi_output_enable_data;
|
||||
|
||||
usb_miso_input <= usb_miso;
|
||||
if (state == STATE_IDLE) begin
|
||||
modem_status_counter <= modem_status_counter + 1'd1;
|
||||
end
|
||||
|
||||
tx_buffer <= tx_rdata;
|
||||
end
|
||||
if ((state == STATE_DATA) && (cmd == CMD_WRITE) && phase[3]) begin
|
||||
last_tx_failed <= ft_miso;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
usb_miosi = usb_miosi_output_enable ? usb_miosi_output : 4'bZZZZ;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (state)
|
||||
S_COMMAND: begin
|
||||
usb_clk_output = clock_phase[P_PRE_FALLING] || clock_phase[P_FALLING];
|
||||
usb_cs_output = 1'b0;
|
||||
if (is_cmd_write) begin
|
||||
usb_miosi_output_data = nibble_counter[0] ? C_WRITE[3:0] : C_WRITE[7:4];
|
||||
end else begin
|
||||
usb_miosi_output_data = nibble_counter[0] ? C_READ[3:0] : C_READ[7:4];
|
||||
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
|
||||
if (cmd == CMD_READ_MODEM_STATUS) begin
|
||||
last_reset_status <= ft_miosi_in[0];
|
||||
if (!last_reset_status && ft_miosi_in[0]) begin
|
||||
usb_scb.reset_pending <= 1'b1;
|
||||
end
|
||||
if (last_reset_status && !ft_miosi_in[0]) begin
|
||||
reset_reply <= 1'b0;
|
||||
write_modem_status_pending <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (cmd == CMD_WRITE_MODEM_STATUS) begin
|
||||
write_modem_status_pending <= 1'b0;
|
||||
end
|
||||
if (cmd == CMD_WRITE_BUFFER_FLUSH) begin
|
||||
write_buffer_flush_pending <= 1'b0;
|
||||
end
|
||||
usb_miosi_output_enable_data = nibble_counter < 2'd2;
|
||||
end
|
||||
|
||||
S_DATA: begin
|
||||
usb_clk_output = clock_phase[P_PRE_FALLING] || clock_phase[P_FALLING];
|
||||
usb_cs_output = 1'b0;
|
||||
usb_miosi_output_data = nibble_counter[0] ? tx_buffer[7:4] : tx_buffer[3:0];
|
||||
usb_miosi_output_enable_data = is_cmd_write;
|
||||
end
|
||||
|
||||
default: begin
|
||||
usb_clk_output = 1'b0;
|
||||
usb_cs_output = 1'b1;
|
||||
usb_miosi_output_data = 4'hF;
|
||||
usb_miosi_output_enable_data = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
rx_wdata_valid <= 1'b0;
|
||||
tx_read <= 1'b0;
|
||||
always_comb begin
|
||||
ft_clk = 1'b0;
|
||||
ft_cs = 1'b1;
|
||||
ft_miosi_out = 8'hFF;
|
||||
ft_oe = 1'b0;
|
||||
|
||||
if (clock_phase[P_RISING]) begin
|
||||
nibble_counter <= nibble_counter + 1'd1;
|
||||
if (state == STATE_SELECT) begin
|
||||
ft_cs = 1'b0;
|
||||
end
|
||||
|
||||
if (sys.reset || !usb_enabled) begin
|
||||
state <= S_TRY_RX;
|
||||
if (state == STATE_COMMAND) begin
|
||||
if (phase[0] || phase[1]) begin
|
||||
ft_clk = 1'b1;
|
||||
end
|
||||
ft_cs = 1'b0;
|
||||
ft_miosi_out = cmd;
|
||||
ft_oe = 1'b1;
|
||||
end
|
||||
|
||||
if (state == STATE_STATUS) begin
|
||||
if (phase[0] || phase[1]) begin
|
||||
ft_clk = 1'b1;
|
||||
end
|
||||
ft_cs = 1'b0;
|
||||
end
|
||||
|
||||
if (state == STATE_DATA) begin
|
||||
if (phase[0] || phase[1]) begin
|
||||
ft_clk = 1'b1;
|
||||
end
|
||||
ft_cs = 1'b0;
|
||||
if (cmd == CMD_WRITE) begin
|
||||
ft_miosi_out = tx_rdata;
|
||||
ft_oe = 1'b1;
|
||||
end
|
||||
if (cmd == CMD_WRITE_MODEM_STATUS) begin
|
||||
ft_miosi_out = {2'b00, reset_reply, 5'b00000};
|
||||
ft_oe = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
rx_write = 1'b0;
|
||||
tx_read = 1'b0;
|
||||
|
||||
rx_wdata = ft_miosi_in;
|
||||
|
||||
if (!ft_miso && phase[3]) begin
|
||||
case (state)
|
||||
STATE_STATUS: begin
|
||||
if (cmd == CMD_WRITE && !last_tx_failed) begin
|
||||
tx_read = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_DATA: begin
|
||||
if (cmd == CMD_READ) begin
|
||||
rx_write = 1'b1;
|
||||
end
|
||||
if (cmd == CMD_WRITE && !tx_empty) begin
|
||||
tx_read = 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
next_cmd = cmd;
|
||||
|
||||
if (reset) begin
|
||||
next_state = STATE_IDLE;
|
||||
end else begin
|
||||
case (state)
|
||||
S_TRY_RX: begin
|
||||
if (!rx_full && !rx_escape_valid) begin
|
||||
state <= S_COMMAND;
|
||||
is_cmd_write <= 1'b0;
|
||||
nibble_counter <= 2'b11;
|
||||
end else begin
|
||||
state <= S_TRY_TX;
|
||||
STATE_IDLE: begin
|
||||
if (ft_pwrsav) begin
|
||||
if (write_modem_status_pending) begin
|
||||
next_state = STATE_SELECT;
|
||||
next_cmd = CMD_WRITE_MODEM_STATUS;
|
||||
end else if (&modem_status_counter) begin
|
||||
next_state = STATE_SELECT;
|
||||
next_cmd = CMD_READ_MODEM_STATUS;
|
||||
end else if (!tx_empty || last_tx_failed) begin
|
||||
next_state = STATE_SELECT;
|
||||
next_cmd = CMD_WRITE;
|
||||
end else if (write_buffer_flush_pending) begin
|
||||
next_state = STATE_SELECT;
|
||||
next_cmd = CMD_WRITE_BUFFER_FLUSH;
|
||||
end else if (!rx_full) begin
|
||||
next_state = STATE_SELECT;
|
||||
next_cmd = CMD_READ;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_TRY_TX: begin
|
||||
if (!tx_empty) begin
|
||||
state <= S_COMMAND;
|
||||
is_cmd_write <= 1'b1;
|
||||
nibble_counter <= 2'b11;
|
||||
end else begin
|
||||
state <= S_TRY_RX;
|
||||
STATE_SELECT: begin
|
||||
if (phase[3]) begin
|
||||
next_state = STATE_COMMAND;
|
||||
end
|
||||
end
|
||||
|
||||
S_COMMAND: begin
|
||||
if (clock_phase[P_RISING]) begin
|
||||
if (nibble_counter == 2'd2) begin
|
||||
if (usb_miso_input) begin
|
||||
state <= is_cmd_write ? S_TRY_RX : S_TRY_TX;
|
||||
end else begin
|
||||
state <= S_DATA;
|
||||
nibble_counter <= 2'd0;
|
||||
STATE_COMMAND: begin
|
||||
if (phase[3]) begin
|
||||
next_state = STATE_STATUS;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_STATUS: begin
|
||||
if (phase[3]) begin
|
||||
if (ft_miso) begin
|
||||
next_state = STATE_DESELECT;
|
||||
end else begin
|
||||
next_state = STATE_DATA;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_DATA: begin
|
||||
if (phase[3]) begin
|
||||
if (ft_miso) begin
|
||||
next_state = STATE_DESELECT;
|
||||
end else if (cmd == CMD_READ) begin
|
||||
if (rx_almost_full) begin
|
||||
next_state = STATE_DESELECT;
|
||||
end
|
||||
end else if (cmd == CMD_WRITE) begin
|
||||
if (tx_empty) begin
|
||||
next_state = STATE_DESELECT;
|
||||
end
|
||||
end else begin
|
||||
next_state = STATE_DESELECT;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_DATA: begin
|
||||
if (clock_phase[P_FALLING]) begin
|
||||
if (nibble_counter[0]) begin
|
||||
tx_read <= is_cmd_write;
|
||||
end
|
||||
end
|
||||
if (clock_phase[P_RISING]) begin
|
||||
rx_wdata <= {usb_miosi_input, rx_wdata[7:4]};
|
||||
if (nibble_counter[0]) begin
|
||||
rx_wdata_valid <= !is_cmd_write;
|
||||
end
|
||||
if (usb_miso_input || (!is_cmd_write && (rx_full || rx_escape_valid)) || (is_cmd_write && tx_empty)) begin
|
||||
state <= is_cmd_write ? S_TRY_RX : S_TRY_TX;
|
||||
end
|
||||
STATE_DESELECT: begin
|
||||
if (phase[1]) begin
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state <= S_TRY_RX;
|
||||
next_state = STATE_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
47
fw/rtl/vendor/lcmxo2/fifo_8kb.sv
vendored
Normal file
47
fw/rtl/vendor/lcmxo2/fifo_8kb.sv
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
module fifo_8kb (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
output empty,
|
||||
output almost_empty,
|
||||
input read,
|
||||
output [7:0] rdata,
|
||||
|
||||
output full,
|
||||
output almost_full,
|
||||
input write,
|
||||
input [7:0] wdata,
|
||||
|
||||
output logic [10:0] count
|
||||
);
|
||||
|
||||
fifo_8kb_lattice_generated fifo_8kb_lattice_generated_inst (
|
||||
.Data(wdata),
|
||||
.WrClock(clk),
|
||||
.RdClock(clk),
|
||||
.WrEn(write),
|
||||
.RdEn(read),
|
||||
.Reset(reset),
|
||||
.RPReset(reset),
|
||||
.Q(rdata),
|
||||
.Empty(empty),
|
||||
.Full(full),
|
||||
.AlmostEmpty(almost_empty),
|
||||
.AlmostFull(almost_full)
|
||||
);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
count <= 11'd0;
|
||||
end else begin
|
||||
if (write && read) begin
|
||||
count <= count;
|
||||
end else if (write) begin
|
||||
count <= count + 1'd1;
|
||||
end else if (read) begin
|
||||
count <= count - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
113
fw/rtl/vendor/lcmxo2/generated/efb_lattice_generated.v
vendored
Normal file
113
fw/rtl/vendor/lcmxo2/generated/efb_lattice_generated.v
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/* Verilog netlist generated by SCUBA Diamond (64-bit) 3.12.1.454 */
|
||||
/* Module Version: 1.2 */
|
||||
/* C:\lscc\diamond\3.12\ispfpga\bin\nt64\scuba.exe -w -n efb_lattice_generated -lang verilog -synth synplify -bus_exp 7 -bb -type efb -arch xo2c00 -freq 100 -ufm -ufm_ebr 2038 -mem_size 8 -ufm_0 -wb -dev 7000 */
|
||||
/* Sun Jul 31 17:59:17 2022 */
|
||||
|
||||
|
||||
`timescale 1 ns / 1 ps
|
||||
module efb_lattice_generated (wb_clk_i, wb_rst_i, wb_cyc_i, wb_stb_i,
|
||||
wb_we_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_ack_o, wbc_ufm_irq)/* synthesis NGD_DRC_MASK=1 */;
|
||||
input wire wb_clk_i;
|
||||
input wire wb_rst_i;
|
||||
input wire wb_cyc_i;
|
||||
input wire wb_stb_i;
|
||||
input wire wb_we_i;
|
||||
input wire [7:0] wb_adr_i;
|
||||
input wire [7:0] wb_dat_i;
|
||||
output wire [7:0] wb_dat_o;
|
||||
output wire wb_ack_o;
|
||||
output wire wbc_ufm_irq;
|
||||
|
||||
wire scuba_vhi;
|
||||
wire scuba_vlo;
|
||||
|
||||
VHI scuba_vhi_inst (.Z(scuba_vhi));
|
||||
|
||||
VLO scuba_vlo_inst (.Z(scuba_vlo));
|
||||
|
||||
defparam EFBInst_0.UFM_INIT_FILE_FORMAT = "HEX" ;
|
||||
defparam EFBInst_0.UFM_INIT_FILE_NAME = "NONE" ;
|
||||
defparam EFBInst_0.UFM_INIT_ALL_ZEROS = "ENABLED" ;
|
||||
defparam EFBInst_0.UFM_INIT_START_PAGE = 2038 ;
|
||||
defparam EFBInst_0.UFM_INIT_PAGES = 8 ;
|
||||
defparam EFBInst_0.DEV_DENSITY = "7000L" ;
|
||||
defparam EFBInst_0.EFB_UFM = "ENABLED" ;
|
||||
defparam EFBInst_0.TC_ICAPTURE = "DISABLED" ;
|
||||
defparam EFBInst_0.TC_OVERFLOW = "DISABLED" ;
|
||||
defparam EFBInst_0.TC_ICR_INT = "OFF" ;
|
||||
defparam EFBInst_0.TC_OCR_INT = "OFF" ;
|
||||
defparam EFBInst_0.TC_OV_INT = "OFF" ;
|
||||
defparam EFBInst_0.TC_TOP_SEL = "OFF" ;
|
||||
defparam EFBInst_0.TC_RESETN = "ENABLED" ;
|
||||
defparam EFBInst_0.TC_OC_MODE = "TOGGLE" ;
|
||||
defparam EFBInst_0.TC_OCR_SET = 32767 ;
|
||||
defparam EFBInst_0.TC_TOP_SET = 65535 ;
|
||||
defparam EFBInst_0.GSR = "ENABLED" ;
|
||||
defparam EFBInst_0.TC_CCLK_SEL = 1 ;
|
||||
defparam EFBInst_0.TC_MODE = "CTCM" ;
|
||||
defparam EFBInst_0.TC_SCLK_SEL = "PCLOCK" ;
|
||||
defparam EFBInst_0.EFB_TC_PORTMODE = "WB" ;
|
||||
defparam EFBInst_0.EFB_TC = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_WAKEUP = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_INTR_RXOVR = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_INTR_TXOVR = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_INTR_RXRDY = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_INTR_TXRDY = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_SLAVE_HANDSHAKE = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_PHASE_ADJ = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_CLK_INV = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_LSB_FIRST = "DISABLED" ;
|
||||
defparam EFBInst_0.SPI_CLK_DIVIDER = 2 ;
|
||||
defparam EFBInst_0.SPI_MODE = "MASTER" ;
|
||||
defparam EFBInst_0.EFB_SPI = "DISABLED" ;
|
||||
defparam EFBInst_0.I2C2_WAKEUP = "DISABLED" ;
|
||||
defparam EFBInst_0.I2C2_GEN_CALL = "DISABLED" ;
|
||||
defparam EFBInst_0.I2C2_CLK_DIVIDER = 1 ;
|
||||
defparam EFBInst_0.I2C2_BUS_PERF = "100kHz" ;
|
||||
defparam EFBInst_0.I2C2_SLAVE_ADDR = "0b1000010" ;
|
||||
defparam EFBInst_0.I2C2_ADDRESSING = "7BIT" ;
|
||||
defparam EFBInst_0.EFB_I2C2 = "DISABLED" ;
|
||||
defparam EFBInst_0.I2C1_WAKEUP = "DISABLED" ;
|
||||
defparam EFBInst_0.I2C1_GEN_CALL = "DISABLED" ;
|
||||
defparam EFBInst_0.I2C1_CLK_DIVIDER = 1 ;
|
||||
defparam EFBInst_0.I2C1_BUS_PERF = "100kHz" ;
|
||||
defparam EFBInst_0.I2C1_SLAVE_ADDR = "0b1000001" ;
|
||||
defparam EFBInst_0.I2C1_ADDRESSING = "7BIT" ;
|
||||
defparam EFBInst_0.EFB_I2C1 = "DISABLED" ;
|
||||
defparam EFBInst_0.EFB_WB_CLK_FREQ = "100.0" ;
|
||||
EFB EFBInst_0 (.WBCLKI(wb_clk_i), .WBRSTI(wb_rst_i), .WBCYCI(wb_cyc_i),
|
||||
.WBSTBI(wb_stb_i), .WBWEI(wb_we_i), .WBADRI7(wb_adr_i[7]), .WBADRI6(wb_adr_i[6]),
|
||||
.WBADRI5(wb_adr_i[5]), .WBADRI4(wb_adr_i[4]), .WBADRI3(wb_adr_i[3]),
|
||||
.WBADRI2(wb_adr_i[2]), .WBADRI1(wb_adr_i[1]), .WBADRI0(wb_adr_i[0]),
|
||||
.WBDATI7(wb_dat_i[7]), .WBDATI6(wb_dat_i[6]), .WBDATI5(wb_dat_i[5]),
|
||||
.WBDATI4(wb_dat_i[4]), .WBDATI3(wb_dat_i[3]), .WBDATI2(wb_dat_i[2]),
|
||||
.WBDATI1(wb_dat_i[1]), .WBDATI0(wb_dat_i[0]), .PLL0DATI7(scuba_vlo),
|
||||
.PLL0DATI6(scuba_vlo), .PLL0DATI5(scuba_vlo), .PLL0DATI4(scuba_vlo),
|
||||
.PLL0DATI3(scuba_vlo), .PLL0DATI2(scuba_vlo), .PLL0DATI1(scuba_vlo),
|
||||
.PLL0DATI0(scuba_vlo), .PLL0ACKI(scuba_vlo), .PLL1DATI7(scuba_vlo),
|
||||
.PLL1DATI6(scuba_vlo), .PLL1DATI5(scuba_vlo), .PLL1DATI4(scuba_vlo),
|
||||
.PLL1DATI3(scuba_vlo), .PLL1DATI2(scuba_vlo), .PLL1DATI1(scuba_vlo),
|
||||
.PLL1DATI0(scuba_vlo), .PLL1ACKI(scuba_vlo), .I2C1SCLI(scuba_vlo),
|
||||
.I2C1SDAI(scuba_vlo), .I2C2SCLI(scuba_vlo), .I2C2SDAI(scuba_vlo),
|
||||
.SPISCKI(scuba_vlo), .SPIMISOI(scuba_vlo), .SPIMOSII(scuba_vlo),
|
||||
.SPISCSN(scuba_vlo), .TCCLKI(scuba_vlo), .TCRSTN(scuba_vlo), .TCIC(scuba_vlo),
|
||||
.UFMSN(scuba_vhi), .WBDATO7(wb_dat_o[7]), .WBDATO6(wb_dat_o[6]),
|
||||
.WBDATO5(wb_dat_o[5]), .WBDATO4(wb_dat_o[4]), .WBDATO3(wb_dat_o[3]),
|
||||
.WBDATO2(wb_dat_o[2]), .WBDATO1(wb_dat_o[1]), .WBDATO0(wb_dat_o[0]),
|
||||
.WBACKO(wb_ack_o), .PLLCLKO(), .PLLRSTO(), .PLL0STBO(), .PLL1STBO(),
|
||||
.PLLWEO(), .PLLADRO4(), .PLLADRO3(), .PLLADRO2(), .PLLADRO1(), .PLLADRO0(),
|
||||
.PLLDATO7(), .PLLDATO6(), .PLLDATO5(), .PLLDATO4(), .PLLDATO3(),
|
||||
.PLLDATO2(), .PLLDATO1(), .PLLDATO0(), .I2C1SCLO(), .I2C1SCLOEN(),
|
||||
.I2C1SDAO(), .I2C1SDAOEN(), .I2C2SCLO(), .I2C2SCLOEN(), .I2C2SDAO(),
|
||||
.I2C2SDAOEN(), .I2C1IRQO(), .I2C2IRQO(), .SPISCKO(), .SPISCKEN(),
|
||||
.SPIMISOO(), .SPIMISOEN(), .SPIMOSIO(), .SPIMOSIEN(), .SPIMCSN7(),
|
||||
.SPIMCSN6(), .SPIMCSN5(), .SPIMCSN4(), .SPIMCSN3(), .SPIMCSN2(),
|
||||
.SPIMCSN1(), .SPIMCSN0(), .SPICSNEN(), .SPIIRQO(), .TCINT(), .TCOC(),
|
||||
.WBCUFMIRQ(wbc_ufm_irq), .CFGWAKE(), .CFGSTDBY());
|
||||
|
||||
|
||||
|
||||
// exemplar begin
|
||||
// exemplar end
|
||||
|
||||
endmodule
|
66
fw/rtl/vendor/lcmxo2/generated/fifo_8kb_lattice_generated.v
vendored
Normal file
66
fw/rtl/vendor/lcmxo2/generated/fifo_8kb_lattice_generated.v
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/* Verilog netlist generated by SCUBA Diamond (64-bit) 3.12.1.454 */
|
||||
/* Module Version: 5.8 */
|
||||
/* C:\lscc\diamond\3.12\ispfpga\bin\nt64\scuba.exe -w -n fifo_8kb_lattice_generated -lang verilog -synth synplify -bus_exp 7 -bb -arch xo2c00 -type ebfifo -depth 1024 -width 8 -rwidth 8 -no_enable -pe 1 -pf 1023 */
|
||||
/* Sat Mar 19 13:53:20 2022 */
|
||||
|
||||
|
||||
`timescale 1 ns / 1 ps
|
||||
module fifo_8kb_lattice_generated (Data, WrClock, RdClock, WrEn, RdEn,
|
||||
Reset, RPReset, Q, Empty, Full, AlmostEmpty, AlmostFull)/* synthesis NGD_DRC_MASK=1 */;
|
||||
input wire [7:0] Data;
|
||||
input wire WrClock;
|
||||
input wire RdClock;
|
||||
input wire WrEn;
|
||||
input wire RdEn;
|
||||
input wire Reset;
|
||||
input wire RPReset;
|
||||
output wire [7:0] Q;
|
||||
output wire Empty;
|
||||
output wire Full;
|
||||
output wire AlmostEmpty;
|
||||
output wire AlmostFull;
|
||||
|
||||
wire scuba_vhi;
|
||||
wire Empty_int;
|
||||
wire Full_int;
|
||||
wire scuba_vlo;
|
||||
|
||||
VHI scuba_vhi_inst (.Z(scuba_vhi));
|
||||
|
||||
VLO scuba_vlo_inst (.Z(scuba_vlo));
|
||||
|
||||
defparam fifo_8kb_lattice_generated_0_0.FULLPOINTER1 = "0b01111111111000" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.FULLPOINTER = "0b10000000000000" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.AFPOINTER1 = "0b01111111110000" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.AFPOINTER = "0b01111111111000" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.AEPOINTER1 = "0b00000000010000" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.AEPOINTER = "0b00000000001000" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.ASYNC_RESET_RELEASE = "SYNC" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.GSR = "DISABLED" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.RESETMODE = "ASYNC" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.REGMODE = "NOREG" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.CSDECODE_R = "0b11" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.CSDECODE_W = "0b11" ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.DATA_WIDTH_R = 9 ;
|
||||
defparam fifo_8kb_lattice_generated_0_0.DATA_WIDTH_W = 9 ;
|
||||
FIFO8KB fifo_8kb_lattice_generated_0_0 (.DI0(Data[0]), .DI1(Data[1]),
|
||||
.DI2(Data[2]), .DI3(Data[3]), .DI4(Data[4]), .DI5(Data[5]), .DI6(Data[6]),
|
||||
.DI7(Data[7]), .DI8(scuba_vlo), .DI9(scuba_vlo), .DI10(scuba_vlo),
|
||||
.DI11(scuba_vlo), .DI12(scuba_vlo), .DI13(scuba_vlo), .DI14(scuba_vlo),
|
||||
.DI15(scuba_vlo), .DI16(scuba_vlo), .DI17(scuba_vlo), .CSW0(scuba_vhi),
|
||||
.CSW1(scuba_vhi), .CSR0(scuba_vhi), .CSR1(scuba_vhi), .FULLI(Full_int),
|
||||
.EMPTYI(Empty_int), .WE(WrEn), .RE(RdEn), .ORE(RdEn), .CLKW(WrClock),
|
||||
.CLKR(RdClock), .RST(Reset), .RPRST(RPReset), .DO0(Q[0]), .DO1(Q[1]),
|
||||
.DO2(Q[2]), .DO3(Q[3]), .DO4(Q[4]), .DO5(Q[5]), .DO6(Q[6]), .DO7(Q[7]),
|
||||
.DO8(), .DO9(), .DO10(), .DO11(), .DO12(), .DO13(), .DO14(), .DO15(),
|
||||
.DO16(), .DO17(), .EF(Empty_int), .AEF(AlmostEmpty), .AFF(AlmostFull),
|
||||
.FF(Full_int));
|
||||
|
||||
assign Empty = Empty_int;
|
||||
assign Full = Full_int;
|
||||
|
||||
|
||||
// exemplar begin
|
||||
// exemplar end
|
||||
|
||||
endmodule
|
98
fw/rtl/vendor/lcmxo2/generated/pll_lattice_generated.v
vendored
Normal file
98
fw/rtl/vendor/lcmxo2/generated/pll_lattice_generated.v
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/* Verilog netlist generated by SCUBA Diamond (64-bit) 3.12.1.454 */
|
||||
/* Module Version: 5.7 */
|
||||
/* C:\lscc\diamond\3.12\ispfpga\bin\nt64\scuba.exe -w -n pll_lattice_generated -lang verilog -synth synplify -arch xo2c00 -type pll -fin 50 -fclkop 100 -fclkop_tol 0.0 -fclkos 100 -fclkos_tol 0.0 -trimp 0 -phasep 0 -trimp_r -trims 0 -phases 90 -trims_r -phase_cntl STATIC -fb_mode 1 -lock */
|
||||
/* Sat Mar 19 17:10:12 2022 */
|
||||
|
||||
|
||||
`timescale 1 ns / 1 ps
|
||||
module pll_lattice_generated (CLKI, CLKOP, CLKOS, LOCK)/* synthesis NGD_DRC_MASK=1 */;
|
||||
input wire CLKI;
|
||||
output wire CLKOP;
|
||||
output wire CLKOS;
|
||||
output wire LOCK;
|
||||
|
||||
wire CLKOS_t;
|
||||
wire CLKOP_t;
|
||||
wire scuba_vlo;
|
||||
|
||||
VLO scuba_vlo_inst (.Z(scuba_vlo));
|
||||
|
||||
defparam PLLInst_0.DDRST_ENA = "DISABLED" ;
|
||||
defparam PLLInst_0.DCRST_ENA = "DISABLED" ;
|
||||
defparam PLLInst_0.MRST_ENA = "DISABLED" ;
|
||||
defparam PLLInst_0.PLLRST_ENA = "DISABLED" ;
|
||||
defparam PLLInst_0.INTFB_WAKE = "DISABLED" ;
|
||||
defparam PLLInst_0.STDBY_ENABLE = "DISABLED" ;
|
||||
defparam PLLInst_0.DPHASE_SOURCE = "DISABLED" ;
|
||||
defparam PLLInst_0.PLL_USE_WB = "DISABLED" ;
|
||||
defparam PLLInst_0.CLKOS3_FPHASE = 0 ;
|
||||
defparam PLLInst_0.CLKOS3_CPHASE = 0 ;
|
||||
defparam PLLInst_0.CLKOS2_FPHASE = 0 ;
|
||||
defparam PLLInst_0.CLKOS2_CPHASE = 0 ;
|
||||
defparam PLLInst_0.CLKOS_FPHASE = 2 ;
|
||||
defparam PLLInst_0.CLKOS_CPHASE = 5 ;
|
||||
defparam PLLInst_0.CLKOP_FPHASE = 0 ;
|
||||
defparam PLLInst_0.CLKOP_CPHASE = 4 ;
|
||||
defparam PLLInst_0.PLL_LOCK_MODE = 0 ;
|
||||
defparam PLLInst_0.CLKOS_TRIM_DELAY = 0 ;
|
||||
defparam PLLInst_0.CLKOS_TRIM_POL = "RISING" ;
|
||||
defparam PLLInst_0.CLKOP_TRIM_DELAY = 0 ;
|
||||
defparam PLLInst_0.CLKOP_TRIM_POL = "RISING" ;
|
||||
defparam PLLInst_0.FRACN_DIV = 0 ;
|
||||
defparam PLLInst_0.FRACN_ENABLE = "DISABLED" ;
|
||||
defparam PLLInst_0.OUTDIVIDER_MUXD2 = "DIVD" ;
|
||||
defparam PLLInst_0.PREDIVIDER_MUXD1 = 0 ;
|
||||
defparam PLLInst_0.VCO_BYPASS_D0 = "DISABLED" ;
|
||||
defparam PLLInst_0.CLKOS3_ENABLE = "DISABLED" ;
|
||||
defparam PLLInst_0.OUTDIVIDER_MUXC2 = "DIVC" ;
|
||||
defparam PLLInst_0.PREDIVIDER_MUXC1 = 0 ;
|
||||
defparam PLLInst_0.VCO_BYPASS_C0 = "DISABLED" ;
|
||||
defparam PLLInst_0.CLKOS2_ENABLE = "DISABLED" ;
|
||||
defparam PLLInst_0.OUTDIVIDER_MUXB2 = "DIVB" ;
|
||||
defparam PLLInst_0.PREDIVIDER_MUXB1 = 0 ;
|
||||
defparam PLLInst_0.VCO_BYPASS_B0 = "DISABLED" ;
|
||||
defparam PLLInst_0.CLKOS_ENABLE = "ENABLED" ;
|
||||
defparam PLLInst_0.OUTDIVIDER_MUXA2 = "DIVA" ;
|
||||
defparam PLLInst_0.PREDIVIDER_MUXA1 = 0 ;
|
||||
defparam PLLInst_0.VCO_BYPASS_A0 = "DISABLED" ;
|
||||
defparam PLLInst_0.CLKOP_ENABLE = "ENABLED" ;
|
||||
defparam PLLInst_0.CLKOS3_DIV = 1 ;
|
||||
defparam PLLInst_0.CLKOS2_DIV = 1 ;
|
||||
defparam PLLInst_0.CLKOS_DIV = 5 ;
|
||||
defparam PLLInst_0.CLKOP_DIV = 5 ;
|
||||
defparam PLLInst_0.CLKFB_DIV = 2 ;
|
||||
defparam PLLInst_0.CLKI_DIV = 1 ;
|
||||
defparam PLLInst_0.FEEDBK_PATH = "CLKOP" ;
|
||||
EHXPLLJ PLLInst_0 (.CLKI(CLKI), .CLKFB(CLKOP_t), .PHASESEL1(scuba_vlo),
|
||||
.PHASESEL0(scuba_vlo), .PHASEDIR(scuba_vlo), .PHASESTEP(scuba_vlo),
|
||||
.LOADREG(scuba_vlo), .STDBY(scuba_vlo), .PLLWAKESYNC(scuba_vlo),
|
||||
.RST(scuba_vlo), .RESETM(scuba_vlo), .RESETC(scuba_vlo), .RESETD(scuba_vlo),
|
||||
.ENCLKOP(scuba_vlo), .ENCLKOS(scuba_vlo), .ENCLKOS2(scuba_vlo),
|
||||
.ENCLKOS3(scuba_vlo), .PLLCLK(scuba_vlo), .PLLRST(scuba_vlo), .PLLSTB(scuba_vlo),
|
||||
.PLLWE(scuba_vlo), .PLLADDR4(scuba_vlo), .PLLADDR3(scuba_vlo), .PLLADDR2(scuba_vlo),
|
||||
.PLLADDR1(scuba_vlo), .PLLADDR0(scuba_vlo), .PLLDATI7(scuba_vlo),
|
||||
.PLLDATI6(scuba_vlo), .PLLDATI5(scuba_vlo), .PLLDATI4(scuba_vlo),
|
||||
.PLLDATI3(scuba_vlo), .PLLDATI2(scuba_vlo), .PLLDATI1(scuba_vlo),
|
||||
.PLLDATI0(scuba_vlo), .CLKOP(CLKOP_t), .CLKOS(CLKOS_t), .CLKOS2(),
|
||||
.CLKOS3(), .LOCK(LOCK), .INTLOCK(), .REFCLK(), .CLKINTFB(), .DPHSRC(),
|
||||
.PLLACK(), .PLLDATO7(), .PLLDATO6(), .PLLDATO5(), .PLLDATO4(), .PLLDATO3(),
|
||||
.PLLDATO2(), .PLLDATO1(), .PLLDATO0())
|
||||
/* synthesis FREQUENCY_PIN_CLKOS="100.000000" */
|
||||
/* synthesis FREQUENCY_PIN_CLKOP="100.000000" */
|
||||
/* synthesis FREQUENCY_PIN_CLKI="50.000000" */
|
||||
/* synthesis ICP_CURRENT="9" */
|
||||
/* synthesis LPF_RESISTOR="72" */;
|
||||
|
||||
assign CLKOS = CLKOS_t;
|
||||
assign CLKOP = CLKOP_t;
|
||||
|
||||
|
||||
// exemplar begin
|
||||
// exemplar attribute PLLInst_0 FREQUENCY_PIN_CLKOS 100.000000
|
||||
// exemplar attribute PLLInst_0 FREQUENCY_PIN_CLKOP 100.000000
|
||||
// exemplar attribute PLLInst_0 FREQUENCY_PIN_CLKI 50.000000
|
||||
// exemplar attribute PLLInst_0 ICP_CURRENT 9
|
||||
// exemplar attribute PLLInst_0 LPF_RESISTOR 72
|
||||
// exemplar end
|
||||
|
||||
endmodule
|
36
fw/rtl/vendor/lcmxo2/pll.sv
vendored
Normal file
36
fw/rtl/vendor/lcmxo2/pll.sv
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
module pll (
|
||||
input inclk,
|
||||
output logic reset,
|
||||
output clk,
|
||||
output sdram_clk
|
||||
);
|
||||
|
||||
logic pll_sdram_clk;
|
||||
logic buf_sdram_clk;
|
||||
logic pll_lock;
|
||||
|
||||
pll_lattice_generated pll_lattice_generated_inst (
|
||||
.CLKI(inclk),
|
||||
.CLKOP(clk),
|
||||
.CLKOS(pll_sdram_clk),
|
||||
.LOCK(pll_lock)
|
||||
);
|
||||
|
||||
ODDRXE oddrxe_sdram_clk_inst (
|
||||
.D0(1'b0),
|
||||
.D1(1'b1),
|
||||
.SCLK(pll_sdram_clk),
|
||||
.RST(1'b0),
|
||||
.Q(buf_sdram_clk)
|
||||
);
|
||||
|
||||
OB ob_sdram_clk_inst (
|
||||
.I(buf_sdram_clk),
|
||||
.O(sdram_clk)
|
||||
) /* synthesis IO_TYPE="LVCMOS33" */;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
reset <= ~pll_lock;
|
||||
end
|
||||
|
||||
endmodule
|
127
fw/rtl/vendor/lcmxo2/vendor.sv
vendored
Normal file
127
fw/rtl/vendor/lcmxo2/vendor.sv
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
module vendor (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
vendor_scb.vendor vendor_scb
|
||||
);
|
||||
|
||||
logic start;
|
||||
logic busy;
|
||||
logic [1:0] length;
|
||||
logic [5:0] delay;
|
||||
|
||||
logic request;
|
||||
logic write;
|
||||
logic ack;
|
||||
logic [7:0] address;
|
||||
logic [7:0] rdata;
|
||||
logic [7:0] wdata;
|
||||
|
||||
logic [23:0] wdata_buffer;
|
||||
|
||||
logic ufm_irq;
|
||||
|
||||
always_comb begin
|
||||
start = vendor_scb.control_valid && vendor_scb.control_wdata[0] && !busy;
|
||||
vendor_scb.control_rdata = {
|
||||
16'd0,
|
||||
address,
|
||||
4'b0000,
|
||||
length,
|
||||
write,
|
||||
busy
|
||||
};
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
busy <= 1'b0;
|
||||
end else begin
|
||||
if (start) begin
|
||||
busy <= 1'b1;
|
||||
end
|
||||
if (length == 2'd0 && ack) begin
|
||||
busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (start) begin
|
||||
length <= vendor_scb.control_wdata[3:2];
|
||||
end
|
||||
if (ack && length > 2'd0) begin
|
||||
length <= length - 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
delay <= 6'd0;
|
||||
end else begin
|
||||
if (start && vendor_scb.control_wdata[4]) begin
|
||||
delay <= 6'd35;
|
||||
end
|
||||
if (delay > 6'd0) begin
|
||||
delay <= delay - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
request <= 1'b0;
|
||||
end else begin
|
||||
if (start) begin
|
||||
request <= 1'b1;
|
||||
end
|
||||
if (busy && !request && delay == 6'd0) begin
|
||||
request <= 1'b1;
|
||||
end
|
||||
if (ack) begin
|
||||
request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (start) begin
|
||||
write <= vendor_scb.control_wdata[1];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (start) begin
|
||||
address <= vendor_scb.control_wdata[15:8];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (ack) begin
|
||||
vendor_scb.data_rdata <= {vendor_scb.data_rdata[23:0], rdata};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (start) begin
|
||||
{wdata, wdata_buffer} <= vendor_scb.data_wdata;
|
||||
end
|
||||
if (ack) begin
|
||||
{wdata, wdata_buffer} <= {wdata_buffer, 8'h00};
|
||||
end
|
||||
end
|
||||
|
||||
efb_lattice_generated efb_lattice_generated_inst (
|
||||
.wb_clk_i(clk),
|
||||
.wb_rst_i(reset),
|
||||
.wb_cyc_i(request),
|
||||
.wb_stb_i(request),
|
||||
.wb_we_i(write),
|
||||
.wb_adr_i(address),
|
||||
.wb_dat_i(wdata),
|
||||
.wb_dat_o(rdata),
|
||||
.wb_ack_o(ack),
|
||||
.wbc_ufm_irq(ufm_irq)
|
||||
);
|
||||
|
||||
endmodule
|
25
fw/rtl/vendor/vendor_scb.sv
vendored
Normal file
25
fw/rtl/vendor/vendor_scb.sv
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
interface vendor_scb ();
|
||||
|
||||
logic control_valid;
|
||||
logic [31:0] control_rdata;
|
||||
logic [31:0] control_wdata;
|
||||
logic [31:0] data_rdata;
|
||||
logic [31:0] data_wdata;
|
||||
|
||||
modport controller (
|
||||
output control_valid,
|
||||
input control_rdata,
|
||||
output control_wdata,
|
||||
input data_rdata,
|
||||
output data_wdata
|
||||
);
|
||||
|
||||
modport vendor (
|
||||
input control_valid,
|
||||
output control_rdata,
|
||||
input control_wdata,
|
||||
output data_rdata,
|
||||
input data_wdata
|
||||
);
|
||||
|
||||
endinterface
|
@ -1,6 +0,0 @@
|
||||
set flow [lindex $quartus(args) 0]
|
||||
|
||||
if [string match "quartus_asm" $flow] {
|
||||
post_message "Generating final programming file"
|
||||
qexec "quartus_cpf -c SummerCart64.cof"
|
||||
}
|
7
hw/.gitignore
vendored
7
hw/.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
/CAMOutputs
|
||||
*.b#*
|
||||
*.l#*
|
||||
*.s#*
|
||||
*.pdf
|
||||
*.zip
|
||||
eagle.epf
|
@ -1,7 +0,0 @@
|
||||
# SummerCart64 Hardware
|
||||
|
||||
Schematics and PCB design for SummerCart64 done in Autodesk Eagle software.
|
||||
|
||||
## TODO
|
||||
|
||||
- Expand documentation
|
5643
hw/SummerCart64.brd
5643
hw/SummerCart64.brd
File diff suppressed because it is too large
Load Diff
@ -1,276 +0,0 @@
|
||||
{
|
||||
"author": {
|
||||
"email": "sc@mateuszfaderewski.pl",
|
||||
"name": "Polprzewodnikowy"
|
||||
},
|
||||
"description": {
|
||||
"EN": "SummerCart64 CAM job."
|
||||
},
|
||||
"output_type": "zip",
|
||||
"outputs": [
|
||||
{
|
||||
"filename_prefix": "CAMOutputs/GerberFiles",
|
||||
"format_specifier": {
|
||||
"decimal": 4,
|
||||
"integer": 3
|
||||
},
|
||||
"generate_job_file": true,
|
||||
"output_type": "gerber",
|
||||
"outputs": [
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Copper",
|
||||
"layer": 1,
|
||||
"layer_details": "mixed",
|
||||
"layer_type": "top"
|
||||
},
|
||||
"filename_format": "%PREFIX/copper_top.gbr",
|
||||
"layers": [
|
||||
1,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"name": "Top Copper",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Copper",
|
||||
"layer": 2,
|
||||
"layer_details": "mixed",
|
||||
"layer_type": "bottom"
|
||||
},
|
||||
"filename_format": "%PREFIX/copper_bottom.gbr",
|
||||
"layers": [
|
||||
16,
|
||||
17,
|
||||
18
|
||||
],
|
||||
"name": "Bottom Copper",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": true,
|
||||
"config": {
|
||||
"file_function": "Profile",
|
||||
"plating": "non-plated"
|
||||
},
|
||||
"filename_format": "%PREFIX/profile.gbr",
|
||||
"layers": [
|
||||
],
|
||||
"milling": true,
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Soldermask",
|
||||
"index": 1,
|
||||
"layer_type": "top"
|
||||
},
|
||||
"filename_format": "%PREFIX/soldermask_top.gbr",
|
||||
"layers": [
|
||||
29
|
||||
],
|
||||
"name": "Soldermask Top",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Soldermask",
|
||||
"index": 1,
|
||||
"layer_type": "bottom"
|
||||
},
|
||||
"filename_format": "%PREFIX/soldermask_bottom.gbr",
|
||||
"layers": [
|
||||
30
|
||||
],
|
||||
"name": "Soldermask Bottom",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Paste",
|
||||
"layer_type": "top"
|
||||
},
|
||||
"filename_format": "%PREFIX/solderpaste_top.gbr",
|
||||
"layers": [
|
||||
31
|
||||
],
|
||||
"milling": false,
|
||||
"name": "Solderpaste Top",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Paste",
|
||||
"layer_type": "bottom"
|
||||
},
|
||||
"filename_format": "%PREFIX/solderpaste_bottom.gbr",
|
||||
"layers": [
|
||||
32
|
||||
],
|
||||
"milling": false,
|
||||
"name": "Solderpaste Bottom",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Legend",
|
||||
"index": 1,
|
||||
"layer_type": "top"
|
||||
},
|
||||
"filename_format": "%PREFIX/silkscreen_top.gbr",
|
||||
"layers": [
|
||||
21,
|
||||
25
|
||||
],
|
||||
"milling": false,
|
||||
"name": "Silkscreen Top",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
},
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"board_outline": false,
|
||||
"config": {
|
||||
"file_function": "Legend",
|
||||
"index": 1,
|
||||
"layer_type": "bottom"
|
||||
},
|
||||
"filename_format": "%PREFIX/silkscreen_bottom.gbr",
|
||||
"layers": [
|
||||
22,
|
||||
26
|
||||
],
|
||||
"milling": false,
|
||||
"name": "Silkscreen Bottom",
|
||||
"polarity": "positive",
|
||||
"type": "gerber_layer"
|
||||
}
|
||||
],
|
||||
"version": "RS274X"
|
||||
},
|
||||
{
|
||||
"filename_prefix": "CAMOutputs/DrillFiles",
|
||||
"format_specifier": {
|
||||
"decimal": 3,
|
||||
"integer": 3
|
||||
},
|
||||
"output_type": "drill",
|
||||
"outputs": [
|
||||
{
|
||||
"advanced_options": {
|
||||
"mirror": false,
|
||||
"offset_x": 0,
|
||||
"offset_y": 0,
|
||||
"rotate": false,
|
||||
"upside_down": false
|
||||
},
|
||||
"filename_format": "%DRILLPREFIX/drill_%FROM_%TO.xln",
|
||||
"name": "Auto Drill",
|
||||
"type": "autodrills"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"filename_prefix": "CAMOutputs/Assembly",
|
||||
"output_type": "assembly",
|
||||
"outputs": [
|
||||
{
|
||||
"filename_format": "%ASSEMBLYPREFIX/%N",
|
||||
"list_attribute": true,
|
||||
"list_type": "values",
|
||||
"name": "Bill of Material",
|
||||
"output_format": "txt",
|
||||
"type": "bom"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"filename_prefix": "CAMOutputs/DrawingFiles",
|
||||
"output_type": "drawing",
|
||||
"outputs": [
|
||||
]
|
||||
}
|
||||
],
|
||||
"timestamp": "2020-10-25T01:41:35",
|
||||
"type": "EAGLE CAM job",
|
||||
"units": "metric",
|
||||
"version": "9.2.0"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user