This commit is contained in:
Polprzewodnikowy 2022-05-15 15:47:12 +02:00
parent 89e84f10fb
commit ab9bd74e91
197 changed files with 93573 additions and 34145 deletions

View File

@ -21,7 +21,17 @@ jobs:
with: with:
submodules: true 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 - name: Build script
env:
MAC_ADDRESS: ${{ secrets.LATTICE_DIAMOND_MAC }}
run: ./docker_build.sh release --force-clean run: ./docker_build.sh release --force-clean
- name: Upload artifact - name: Upload artifact

6
.gitignore vendored
View File

@ -1,4 +1,8 @@
**/.DS_Store **/.DS_Store
**/.vscode/settings.json **/.vscode/
**/*.bak **/*.bak
**/*.zip **/*.zip
/flexlm
!**/.vscode/launch.json
!**/.vscode/tasks.json

8
.gitmodules vendored
View File

@ -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

51
.vscode/launch.json vendored
View File

@ -2,11 +2,58 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Build SW and Update", "cwd": "${workspaceRoot}/sw/controller",
"executable": "./build/controller.elf",
"name": "Load ARM",
"request": "launch",
"type": "cortex-debug",
"servertype": "stlink",
// "serverpath": "C:\\msys64\\mingw64\\bin\\openocd.exe",
"preLaunchTask": "build_controller",
"device": "STM32G030F6",
"svdFile": "./STM32G030.svd",
// "configFiles": ["interface/stlink.cfg", "target/stm32g0x.cfg"],
// "runToMain": true
"postRestartCommands": [
// "b Reset_Handler"
// "monitor reset halt",
// "load",
// "b main",
// "monitor reset",
]
},
{
"name": "Run ROM",
"type": "python", "type": "python",
"request": "launch", "request": "launch",
"program": "sw/pc/sc64.py", "program": "sw/pc/sc64.py",
"preLaunchTask": "build", // "preLaunchTask": "build",
"justMyCode": false,
"args": [
// "-u", "fw/output_files/SC64_update.bin",
// "-rtc",
// "-f", "\\\\.\\D:",
// "-d", "-df",
// "-i", "S:/n64/64dd/ipl/NDXJ0.n64",
// "-k", "S:/n64/64dd/dev/EZLJ_Expansion_DEV_v1.1.ndd",
// "-t", "1",
// "-b", "2",
// "-s", "1",
// "-q",
// "-v",
// "-e", "S:/n64/saves/majora_snowhead.fla",
// "S:/n64/roms/Legend of Zelda, The - Ocarina of Time (USA) (Rev B).z64",
// "S:/n64/roms/ZELOOTD.z64",
"S:/n64/roms/switchtome.z64",
// "D:/sc64menu.n64",
],
},
{
"name": "Build SW and Update",
"type": "python",
"request": "launch",
"program": "sw/pc/v2.py",
// "preLaunchTask": "build",
"args": [ "args": [
"-u", "fw/output_files/SC64_update.bin", "-u", "fw/output_files/SC64_update.bin",
] ]

68
.vscode/tasks.json vendored
View File

@ -2,15 +2,54 @@
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"label": "build", "label": "build_bootloader",
"type": "shell", "type": "shell",
"command": "./docker_build.sh update -s -c -d", "command": "./docker_build.sh bootloader",
"presentation": { "presentation": {
"showReuseMessage": false, "showReuseMessage": false,
"clear": true "clear": true
}, },
"windows":{ "windows": {
"command": "wsl -- ./docker_build.sh update -s -c -d" "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": { "group": {
"kind": "build", "kind": "build",
@ -18,30 +57,17 @@
} }
}, },
{ {
"label": "build_full", "label": "build_release",
"type": "shell", "type": "shell",
"command": "./docker_build.sh release -c -d", "command": "./docker_build.sh release --force-clean",
"presentation": { "presentation": {
"showReuseMessage": false, "showReuseMessage": false,
"clear": true "clear": true
}, },
"windows": { "windows":{
"command": "wsl -- ./docker_build.sh update -c -d" "command": "wsl -- ./docker_build.sh release --force-clean"
}, },
"group": "build" "group": "build"
}, },
{
"label": "build_n64",
"type": "shell",
"command": "./docker_build.sh n64 -d",
"presentation": {
"showReuseMessage": false,
"clear": true
},
"windows": {
"command": "wsl -- ./docker_build.sh n64 -d"
},
"group": "build"
}
] ]
} }

BIN
assets/sc64_logo.blend Normal file

Binary file not shown.

149
build.sh
View File

@ -2,99 +2,67 @@
set -e set -e
PACKAGE_FILE_NAME="SummerCart64" PACKAGE_FILE_NAME="SC64"
FILES=( FILES=(
"./fw/output_files/SC64_firmware.pof" "./fw/project/lcmxo2/impl1/sc64_impl1.bit"
"./fw/output_files/SC64_update.bin" "./fw/project/lcmxo2/impl1/sc64_impl1.jed"
"./hw/ftdi-template.xml" "./hw/ftdi-template.xml"
"./sw/cic/UltraCIC-III.hex" "./sw/bootloader/build/bootloader.bin"
"./sw/controller/build/controller.bin"
"./sw/controller/build/controller.elf"
"./sw/pc/helpers.py"
"./sw/pc/sc64.py"
"./LICENSE" "./LICENSE"
"./README.md"
) )
BUILT_CIC=false BUILT_BOOTLOADER=false
BUILT_N64=false BUILT_CONTROLLER=false
BUILT_RISCV=false
BUILT_SW=false
BUILT_FPGA=false BUILT_FPGA=false
BUILT_UPDATE=false BUILT_UPDATE=false
BUILT_RELEASE=false BUILT_RELEASE=false
FORCE_CLEAN=false FORCE_CLEAN=false
SKIP_FPGA_REBUILD=false
DEBUG_ENABLED=false
build_cic () { build_bootloader () {
if [ "$BUILT_CIC" = true ]; then return; fi if [ "$BUILT_BOOTLOADER" = true ]; then return; fi
pushd sw/cic > /dev/null pushd sw/bootloader > /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
if [ "$FORCE_CLEAN" = true ]; then if [ "$FORCE_CLEAN" = true ]; then
make clean make clean
fi fi
N64_FLAGS="$USER_FLAGS" FLAGS="$USER_FLAGS"
if [ ! -z "${GIT_BRANCH+x}" ]; then N64_FLAGS+=" -DGIT_BRANCH='\"$GIT_BRANCH\"'"; fi if [ ! -z "${GIT_BRANCH+x}" ]; then FLAGS+=" -DGIT_BRANCH='\"$GIT_BRANCH\"'"; fi
if [ ! -z "${GIT_TAG+x}" ]; then N64_FLAGS+=" -DGIT_TAG='\"$GIT_TAG\"'"; fi if [ ! -z "${GIT_TAG+x}" ]; then FLAGS+=" -DGIT_TAG='\"$GIT_TAG\"'"; fi
if [ ! -z "${GIT_SHA+x}" ]; then N64_FLAGS+=" -DGIT_SHA='\"$GIT_SHA\"'"; fi if [ ! -z "${GIT_SHA+x}" ]; then FLAGS+=" -DGIT_SHA='\"$GIT_SHA\"'"; fi
make all -j USER_FLAGS="$N64_FLAGS" make all -j USER_FLAGS="$FLAGS"
popd > /dev/null popd > /dev/null
BUILT_N64=true BUILT_BOOTLOADER=true
} }
build_riscv () { build_controller () {
if [ "$BUILT_RISCV" = true ]; then return; fi if [ "$BUILT_CONTROLLER" = true ]; then return; fi
pushd sw/riscv > /dev/null pushd sw/controller > /dev/null
if [ "$FORCE_CLEAN" = true ]; then if [ "$FORCE_CLEAN" = true ]; then
make clean make clean
fi fi
make all -j USER_FLAGS="$USER_FLAGS" make all -j USER_FLAGS="$USER_FLAGS"
popd > /dev/null popd > /dev/null
BUILT_RISCV=true BUILT_CONTROLLER=true
}
build_sw () {
if [ "$BUILT_SW" = true ]; then return; fi
build_n64
build_riscv
pushd fw > /dev/null
mkdir -p output_files > /dev/null
cat ../sw/n64/build/n64boot.bin ../sw/riscv/build/governor.bin > output_files/SC64_software.bin
objcopy -I binary -O ihex output_files/SC64_software.bin output_files/SC64_software.hex
popd
BUILT_SW=true
} }
build_fpga () { build_fpga () {
if [ "$BUILT_FPGA" = true ]; then return; fi if [ "$BUILT_FPGA" = true ]; then return; fi
build_sw pushd fw/project/lcmxo2 > /dev/null
if [ "$FORCE_CLEAN" = true ]; then
pushd fw > /dev/null rm -rf ./impl1/
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
else
quartus_sh --set -remove VERILOG_MACRO="DEBUG" ./SummerCart64.qpf
fi
quartus_sh --flow compile ./SummerCart64.qpf
fi fi
./build.sh
popd > /dev/null popd > /dev/null
BUILT_FPGA=true BUILT_FPGA=true
@ -103,20 +71,16 @@ build_fpga () {
build_update () { build_update () {
if [ "$BUILT_UPDATE" = true ]; then return; fi if [ "$BUILT_UPDATE" = true ]; then return; fi
build_bootloader
build_controller
build_fpga build_fpga
pushd fw/output_files > /dev/null
objcopy -I binary -O binary --reverse-bytes=4 sc64_firmware_cfm0_auto.rpd SC64_firmware.bin
cat SC64_software.bin SC64_firmware.bin > SC64_update.bin
popd > /dev/null
BUILT_UPDATE=true BUILT_UPDATE=true
} }
build_release () { build_release () {
if [ "$BUILT_RELEASE" = true ]; then return; fi if [ "$BUILT_RELEASE" = true ]; then return; fi
build_cic
build_update build_update
if [ -e "./${PACKAGE_FILE_NAME}.zip" ]; then if [ -e "./${PACKAGE_FILE_NAME}.zip" ]; then
@ -129,21 +93,15 @@ build_release () {
print_usage () { print_usage () {
echo "builder script for SummerCart64" echo "builder script for SummerCart64"
echo "usage: ./build.sh [cic] [n64] [riscv] [fpga] [update] [release] [-c] [-s] [-d] [--help]" echo "usage: ./build.sh [bootloader] [controller] [fpga] [update] [release] [-c] [--help]"
echo "parameters:" echo "parameters:"
echo " cic - assemble UltraCIC-III software" echo " bootloader - compile N64 bootloader software"
echo " n64 - compile N64 bootloader software" echo " controller - compile ARM controller software"
echo " riscv - compile cart governor software" echo " fpga - compile FPGA design"
echo " sw - compile all software (triggers 'n64' and 'riscv' build)" echo " update - compile all software and designs"
echo " fpga - compile FPGA design (triggers 'sw' build)" echo " release - collect and zip files for release (triggers 'update' 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 " -c | --force-clean" echo " -c | --force-clean"
echo " - clean software compilation result directories before build" echo " - clean 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 " --help - print this guide"
} }
@ -154,27 +112,19 @@ if test $# -eq 0; then
exit 1 exit 1
fi fi
TRIGGER_CIC=false TRIGGER_BOOTLOADER=false
TRIGGER_N64=false TRIGGER_CONTROLLER=false
TRIGGER_RISCV=false
TRIGGER_SW=false
TRIGGER_FPGA=false TRIGGER_FPGA=false
TRIGGER_UPDATE=false TRIGGER_UPDATE=false
TRIGGER_RELEASE=false TRIGGER_RELEASE=false
while test $# -gt 0; do while test $# -gt 0; do
case "$1" in case "$1" in
cic) bootloader)
TRIGGER_CIC=true TRIGGER_BOOTLOADER=true
;; ;;
n64) controller)
TRIGGER_N64=true TRIGGER_CONTROLLER=true
;;
riscv)
TRIGGER_RISCV=true
;;
sw)
TRIGGER_SW=true
;; ;;
fpga) fpga)
TRIGGER_FPGA=true TRIGGER_FPGA=true
@ -188,12 +138,6 @@ while test $# -gt 0; do
-c|--force-clean) -c|--force-clean)
FORCE_CLEAN=true FORCE_CLEAN=true
;; ;;
-s|--skip-fpga-rebuild)
SKIP_FPGA_REBUILD=true
;;
-d|--debug)
DEBUG_ENABLED=true
;;
--help) --help)
print_usage print_usage
exit 0 exit 0
@ -208,11 +152,8 @@ while test $# -gt 0; do
shift shift
done done
if [ "$DEBUG_ENABLED" = true ]; then USER_FLAGS+=" -DDEBUG"; fi if [ "$TRIGGER_BOOTLOADER" = true ]; then build_bootloader; fi
if [ "$TRIGGER_CIC" = true ]; then build_cic; fi if [ "$TRIGGER_CONTROLLER" = true ]; then build_controller; fi
if [ "$TRIGGER_N64" = true ]; then build_n64; fi
if [ "$TRIGGER_RISCV" = true ]; then build_riscv; fi
if [ "$TRIGGER_SW" = true ]; then build_sw; fi
if [ "$TRIGGER_FPGA" = true ]; then build_fpga; fi if [ "$TRIGGER_FPGA" = true ]; then build_fpga; fi
if [ "$TRIGGER_UPDATE" = true ]; then build_update; fi if [ "$TRIGGER_UPDATE" = true ]; then build_update; fi
if [ "$TRIGGER_RELEASE" = true ]; then build_release; fi if [ "$TRIGGER_RELEASE" = true ]; then build_release; fi

View File

@ -1,17 +1,8 @@
#!/bin/bash #!/bin/bash
CONTAINER_NAME="sc64builder" BUILDER_IMAGE="ghcr.io/polprzewodnikowy/sc64env:v1.4"
docker ps | grep $CONTAINER_NAME > /dev/null pushd $(dirname $0) > /dev/null
if [ $? -eq 1 ]; then
docker run \
-dt --rm \
--name $CONTAINER_NAME \
--user $(id -u):$(id -g) \
--mount type=bind,src="$(pwd)",target="/workdir" \
ghcr.io/polprzewodnikowy/sc64env:v1.2
fi
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
GIT_TAG=$(git describe --tags 2> /dev/null) GIT_TAG=$(git describe --tags 2> /dev/null)
@ -21,10 +12,18 @@ if [ -t 1 ]; then
DOCKER_OPTIONS="-it" DOCKER_OPTIONS="-it"
fi fi
docker exec \ docker run \
$DOCKER_OPTIONS \ $DOCKER_OPTIONS \
--rm \
--privileged \
--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 GIT_BRANCH="$GIT_BRANCH" \ -e GIT_BRANCH="$GIT_BRANCH" \
-e GIT_TAG="$GIT_TAG" \ -e GIT_TAG="$GIT_TAG" \
-e GIT_SHA="$GIT_SHA" \ -e GIT_SHA="$GIT_SHA" \
$CONTAINER_NAME \ $BUILDER_IMAGE \
./build.sh $@ ./build.sh $@
popd > /dev/null

13
fw/.gitignore vendored
View File

@ -1,13 +0,0 @@
/db
/greybox_tmp
/incremental_db
/output_files
**/.qsys_edit
**/*.bin
**/*.dat
**/*.elf
*.qws
*.rpt
*.sopcinfo
*.srf
*.txt

View File

@ -1,40 +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>output_files/SC64_software.hex</ufm_filepath>
</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>

View File

@ -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"

View File

@ -1,293 +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 = 19:19:14 February 04, 2022
#
# -------------------------------------------------------------------------- #
#
# 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 POST_MODULE_SCRIPT_FILE "quartus_sh:scripts/post_module.tcl"
set_global_assignment -name QSYS_FILE rtl/vendor/intel/generated/intel_flash.qsys
set_global_assignment -name QIP_FILE rtl/intel/fifo/intel_fifo_8.qip
set_global_assignment -name QIP_FILE rtl/vendor/intel/generated/intel_gpio_ddro.qip
set_global_assignment -name QIP_FILE rtl/vendor/intel/generated/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_flash.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_flashram.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_dma.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 SYSTEMVERILOG_FILE rtl/vendor/intel/vendor_flash.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/vendor/intel/vendor_reconfigure.sv
# Pin & Location Assignments
# ==========================
set_location_assignment PIN_6 -to o_usb_cs
set_location_assignment PIN_7 -to i_usb_miso
set_location_assignment PIN_8 -to o_usb_clk
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_124 -to io_usb_miosi[7]
set_location_assignment PIN_127 -to io_usb_miosi[6]
set_location_assignment PIN_130 -to io_usb_miosi[4]
set_location_assignment PIN_131 -to io_usb_miosi[5]
set_location_assignment PIN_134 -to io_usb_miosi[3]
set_location_assignment PIN_135 -to io_usb_miosi[2]
set_location_assignment PIN_140 -to io_usb_miosi[1]
set_location_assignment PIN_141 -to io_usb_miosi[0]
# 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
set_global_assignment -name VERILOG_MACRO DEBUG
# 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 i_n64_nmi
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_alel
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_reset
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_a[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ba[*]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cas
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_cs
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_ras
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_we
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs
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_usb_miosi[*]
# Fitter Assignments
# ==================
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_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)
# ------------------------

View File

@ -1,91 +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_clock -name usb_clk -period 40.0 [get_ports {o_usb_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]
set_multicycle_path -hold -end 1 -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_output_delay -clock [get_clocks {usb_clk}] -max 2.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_output_delay -clock [get_clocks {usb_clk}] -min -1.0 [get_ports {io_usb_miosi[*] o_usb_cs}]
set_input_delay -clock [get_clocks {usb_clk}] -max 5.0 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_input_delay -clock [get_clocks {usb_clk}] -min 2.5 [get_ports {io_usb_miosi[*] i_usb_miso}]
set_multicycle_path -setup -start 2 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}]
set_multicycle_path -hold -start 3 -from [get_clocks $sys_clk] -to [get_clocks {usb_clk}]
set_multicycle_path -setup -end 2 -from [get_clocks {usb_clk}] -to [get_clocks $sys_clk]
set_multicycle_path -hold -end 3 -from [get_clocks {usb_clk}] -to [get_clocks $sys_clk]
# 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}]

@ -1 +0,0 @@
Subproject commit f00a88c36eaab478b64ee27d8162e421049bcc66

15
fw/project/lcmxo2/.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
.recovery
*.dir/
*.html
*.ini
*.rva
*.rvl
*.rvs
*.svf
*.tcl
*.tpf
*.trc
*.xml
impl*/
!build.tcl

View File

@ -0,0 +1,5 @@
#!/bin/bash
source $bindir/diamond_env
diamondc build.tcl

View File

@ -0,0 +1,3 @@
prj_project open sc64.ldf
prj_run Export -impl impl1 -task Bitgen
prj_run Export -impl impl1 -task Jedecgen

104
fw/project/lcmxo2/sc64.ldf Normal file
View File

@ -0,0 +1,104 @@
<?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="Strategy">
<Options VerilogStandard="System Verilog" def_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_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_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" top_module="sd_crc_7"/>
</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/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/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">
<Options/>
</Source>
<Source name="si.rvl" type="Reveal" type_short="Reveal">
<Options/>
</Source>
</Implementation>
<Strategy name="Strategy" file="sc64.sty"/>
</BaliProject>

204
fw/project/lcmxo2/sc64.lpf Normal file
View File

@ -0,0 +1,204 @@
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;

205
fw/project/lcmxo2/sc64.sty Normal file
View File

@ -0,0 +1,205 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE strategy>
<Strategy version="1.0" predefined="0" description="" label="Strategy1">
<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="False" time="0"/>
<Property name="PROP_MAPSTA_FullName" value="False" 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="0" 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="False" time="0"/>
<Property name="PROP_PARSTA_FullName" value="False" 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="1" 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="False" 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="101" 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>

View File

@ -1,138 +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 [7:0] io_usb_miosi,
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 dd_interrupt;
if_system sys (
.in_clk(i_clk),
.n64_reset(i_n64_reset),
.n64_nmi(i_n64_nmi)
);
if_config cfg ();
if_memory_dma usb_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),
.usb_dma(usb_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),
.usb_dma(usb_dma),
.sdram(sdram),
.flashram(flashram),
.si(si),
.flash(flash),
.dd(dd),
.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),
.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;
o_led = 1'bZ;
end
endmodule

View File

@ -1,54 +0,0 @@
interface if_cpu_bus #(
parameter bit [3:0] NUM_DEVICES
) ();
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

View File

@ -1,142 +0,0 @@
module cpu_cfg (
if_system.sys sys,
if_cpu_bus bus,
if_config.cpu cfg
);
logic skip_bootloader;
logic enable_writes_on_reset;
logic trigger_reconfiguration;
typedef enum bit [2:0] {
R_SCR,
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,
2'd0,
cfg.flash_erase_busy,
1'd0,
16'd0,
enable_writes_on_reset,
skip_bootloader,
cfg.flashram_enabled,
cfg.sram_banked,
cfg.sram_enabled,
cfg.dd_enabled,
cfg.sdram_writable,
cfg.sdram_switch
};
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
cfg.flash_erase_start <= 1'b0;
cfg.flash_wp_enable <= 1'b0;
cfg.flash_wp_disable <= 1'b0;
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;
skip_bootloader <= 1'b0;
enable_writes_on_reset <= 1'b0;
trigger_reconfiguration <= 1'b0;
end else begin
if (sys.n64_soft_reset) begin
cfg.sdram_switch <= skip_bootloader;
cfg.sdram_writable <= enable_writes_on_reset;
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,
cfg.flash_wp_disable,
cfg.flash_wp_enable,
cfg.flash_erase_start
} <= {bus.wdata[31:30], bus.wdata[28:26], bus.wdata[24]};
end
if (bus.wmask[0]) begin
{
enable_writes_on_reset,
skip_bootloader,
cfg.flashram_enabled,
cfg.sram_banked,
cfg.sram_enabled,
cfg.dd_enabled,
cfg.sdram_writable,
cfg.sdram_switch
} <= bus.wdata[7:0];
end
end
R_RECONFIGURE: begin
if (&bus.wmask && bus.wdata == RECONFIGURE_MAGIC) begin
trigger_reconfiguration <= 1'b1;
end
end
endcase
end
end
end
vendor_reconfigure vendor_reconfigure_inst (
.clk(sys.clk),
.reset(sys.reset),
.trigger_reconfiguration(trigger_reconfiguration)
);
endmodule

View File

@ -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

View File

@ -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 flash (
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,123 +0,0 @@
module cpu_soc (
if_system.sys sys,
if_config.cpu cfg,
if_memory_dma usb_dma,
if_sdram.cpu sdram,
if_flashram.cpu flashram,
if_si.cpu si,
if_flash flash,
if_dd.cpu dd,
output i2c_scl,
inout i2c_sda,
output usb_clk,
output usb_cs,
input usb_miso,
inout [7:0] usb_miosi,
input uart_rxd,
output uart_txd,
output sd_clk,
inout sd_cmd,
inout [3:0] sd_dat
);
typedef enum bit [3:0] {
DEV_FLASH,
DEV_RAM,
DEV_CFG,
DEV_I2C,
DEV_USB,
DEV_UART,
DEV_DD,
DEV_SDRAM,
DEV_FLASHRAM,
DEV_SI,
__NUM_DEVICES
} e_bus_id;
if_cpu_bus #(
.NUM_DEVICES(__NUM_DEVICES)
) bus ();
cpu_wrapper cpu_wrapper_inst (
.sys(sys),
.bus(bus)
);
cpu_flash cpu_flash_inst (
.sys(sys),
.bus(bus.at[DEV_FLASH].device),
.flash(flash)
);
cpu_ram cpu_ram_inst (
.sys(sys),
.bus(bus.at[DEV_RAM].device)
);
cpu_cfg cpu_cfg_inst (
.sys(sys),
.bus(bus.at[DEV_CFG].device),
.cfg(cfg)
);
cpu_i2c cpu_i2c_inst (
.sys(sys),
.bus(bus.at[DEV_I2C].device),
.i2c_scl(i2c_scl),
.i2c_sda(i2c_sda)
);
cpu_usb cpu_usb_inst (
.sys(sys),
.bus(bus.at[DEV_USB].device),
.dma(usb_dma),
.usb_clk(usb_clk),
.usb_cs(usb_cs),
.usb_miso(usb_miso),
.usb_miosi(usb_miosi)
);
generate
if (sc64::CPU_HAS_UART) begin
cpu_uart cpu_uart_inst (
.sys(sys),
.bus(bus.at[DEV_UART].device),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd)
);
end
endgenerate
cpu_dd cpu_dd_inst (
.sys(sys),
.bus(bus.at[DEV_DD].device),
.dd(dd)
);
cpu_sdram cpu_sdram_inst (
.sys(sys),
.bus(bus.at[DEV_SDRAM].device),
.sdram(sdram)
);
cpu_flashram cpu_flashram_inst (
.sys(sys),
.bus(bus.at[DEV_FLASHRAM].device),
.flashram(flashram)
);
cpu_si cpu_si_inst (
.sys(sys),
.bus(bus.at[DEV_SI].device),
.si(si)
);
assign sd_clk = 1'bZ;
assign sd_cmd = 1'bZ;
assign sd_dat = 4'bZZZZ;
endmodule

View File

@ -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

View File

@ -1,126 +0,0 @@
module cpu_usb (
if_system sys,
if_cpu_bus bus,
if_memory_dma dma,
output usb_clk,
output usb_cs,
input usb_miso,
inout [7:0] usb_miosi
);
logic rx_flush;
logic tx_flush;
logic usb_enable;
logic reset_pending;
logic reset_ack;
logic write_buffer_flush;
typedef enum bit [1:0] {
R_SCR,
R_DATA,
R_ADDR,
R_LEN
} 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
case (bus.address[3:2])
R_SCR: bus.rdata = {
23'd0,
dma.busy,
1'b0,
reset_pending,
1'b0,
usb_enable,
2'b00,
~dma.tx_full,
~dma.rx_empty
};
R_DATA: bus.rdata = {24'd0, dma.rx_rdata};
default: bus.rdata = 32'd0;
endcase
end
end
always_ff @(posedge sys.clk) begin
dma.start <= 1'b0;
dma.stop <= 1'b0;
dma.cpu_rx_read <= 1'b0;
dma.cpu_tx_write <= 1'b0;
rx_flush <= 1'b0;
tx_flush <= 1'b0;
reset_ack <= 1'b0;
write_buffer_flush <= 1'b0;
if (sys.reset) begin
usb_enable <= 1'b0;
end else begin
if (bus.request) begin
case (bus.address[3:2])
R_SCR: if (&bus.wmask) begin
{dma.direction, dma.stop, dma.start} <= bus.wdata[11:9];
reset_ack <= bus.wdata[7];
{write_buffer_flush, usb_enable, tx_flush, rx_flush} <= bus.wdata[5:2];
end
R_DATA: if (bus.wmask == 4'b0000) begin
dma.cpu_rx_read <= 1'b1;
end else if (bus.wmask == 4'b0001) begin
dma.cpu_tx_write <= 1'b1;
dma.cpu_tx_wdata <= bus.wdata[7:0];
end
R_ADDR: if (&bus.wmask) begin
dma.starting_address <= bus.wdata;
end
R_LEN: if (&bus.wmask) begin
dma.transfer_length <= bus.wdata;
end
endcase
end
end
end
memory_dma usb_memory_dma_inst (
.clk(sys.clk),
.reset(~usb_enable),
.dma(dma)
);
usb_ft1248 usb_ft1248_inst (
.clk(sys.clk),
.reset(~usb_enable),
.usb_clk(usb_clk),
.usb_cs(usb_cs),
.usb_miso(usb_miso),
.usb_miosi(usb_miosi),
.reset_pending(reset_pending),
.reset_ack(reset_ack),
.write_buffer_flush(write_buffer_flush),
.rx_flush(rx_flush),
.rx_empty(dma.rx_empty),
.rx_almost_empty(dma.rx_almost_empty),
.rx_read(dma.rx_read),
.rx_rdata(dma.rx_rdata),
.tx_flush(tx_flush),
.tx_full(dma.tx_full),
.tx_almost_full(dma.tx_almost_full),
.tx_write(dma.tx_write),
.tx_wdata(dma.tx_wdata)
);
endmodule

View File

@ -1,85 +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
logic trap;
logic mem_valid;
logic mem_instr;
logic [31:0] mem_la_addr;
logic [31:0] mem_la_wdata;
logic [3:0] mem_la_wstrb;
logic pcpi_valid;
logic [31:0] pcpi_insn;
logic [31:0] pcpi_rs1;
logic [31:0] pcpi_rs2;
logic [31:0] eoi;
logic trace_valid;
logic [35:0] trace_data;
picorv32 #(
.ENABLE_COUNTERS(0),
.ENABLE_COUNTERS64(0),
.TWO_STAGE_SHIFT(0),
.TWO_CYCLE_COMPARE(1),
.TWO_CYCLE_ALU(1),
.CATCH_MISALIGN(0),
.CATCH_ILLINSN(0),
.PROGADDR_RESET(32'h0001_0000)
) 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),
.trap(trap),
.mem_valid(mem_valid),
.mem_instr(mem_instr),
.mem_la_addr(mem_la_addr),
.mem_la_wdata(mem_la_wdata),
.mem_la_wstrb(mem_la_wstrb),
.pcpi_valid(pcpi_valid),
.pcpi_insn(pcpi_insn),
.pcpi_rs1(pcpi_rs1),
.pcpi_rs2(pcpi_rs2),
.pcpi_wr(1'b0),
.pcpi_rd(32'd0),
.pcpi_wait(1'b0),
.pcpi_ready(1'b0),
.irq(32'd0),
.eoi(eoi),
.trace_valid(trace_valid),
.trace_data(trace_data)
);
endmodule

37
fw/rtl/fifo/fifo_bus.sv Normal file
View 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

View 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

View File

@ -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"]

View File

@ -1,179 +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):
// altera_mf
// ============================================================
// ************************************************************
// 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,
almost_empty,
almost_full,
empty,
full,
q);
input clock;
input [7:0] data;
input rdreq;
input sclr;
input wrreq;
output almost_empty;
output almost_full;
output empty;
output full;
output [7:0] q;
wire sub_wire0;
wire sub_wire1;
wire sub_wire2;
wire sub_wire3;
wire [7:0] sub_wire4;
wire almost_empty = sub_wire0;
wire almost_full = sub_wire1;
wire empty = sub_wire2;
wire full = sub_wire3;
wire [7:0] q = sub_wire4[7:0];
scfifo scfifo_component (
.clock (clock),
.data (data),
.rdreq (rdreq),
.sclr (sclr),
.wrreq (wrreq),
.almost_empty (sub_wire0),
.almost_full (sub_wire1),
.empty (sub_wire2),
.full (sub_wire3),
.q (sub_wire4),
.aclr (),
.eccstatus (),
.usedw ());
defparam
scfifo_component.add_ram_output_register = "OFF",
scfifo_component.almost_empty_value = 2,
scfifo_component.almost_full_value = 1023,
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 "1"
// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "2"
// Retrieval info: PRIVATE: AlmostFull NUMERIC "1"
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "1023"
// 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 "2"
// 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 "OFF"
// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "2"
// Retrieval info: CONSTANT: ALMOST_FULL_VALUE NUMERIC "1023"
// 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: almost_empty 0 0 0 0 OUTPUT NODEFVAL "almost_empty"
// Retrieval info: USED_PORT: almost_full 0 0 0 0 OUTPUT NODEFVAL "almost_full"
// 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: almost_empty 0 0 0 0 @almost_empty 0 0 0 0
// Retrieval info: CONNECT: almost_full 0 0 0 0 @almost_full 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
// Retrieval info: LIB_FILE: altera_mf

92
fw/rtl/mcu/mcu_spi.sv Normal file
View 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

753
fw/rtl/mcu/mcu_top.sv Normal file
View File

@ -0,0 +1,753 @@
module mcu_top (
input clk,
input reset,
usb_scb.controller usb_scb,
dma_scb.controller usb_dma_scb,
sd_scb.controller sd_scb,
dma_scb.controller sd_dma_scb,
n64_scb.controller n64_scb,
flash_scb.controller flash_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_FLASHRAM_READ,
CMD_EEPROM_READ,
CMD_EEPROM_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;
n64_scb.eeprom_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 (n64_scb.eeprom_write) begin
n64_scb.eeprom_address <= n64_scb.eeprom_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
if (cmd == CMD_FLASHRAM_READ) begin
n64_scb.flashram_buffer_address <= rdata[6:1];
counter <= {1'b0, rdata[0]};
end
if ((cmd == CMD_EEPROM_READ) || (cmd == CMD_EEPROM_WRITE)) begin
n64_scb.eeprom_address <= {rdata, 3'd0};
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
if (cmd == CMD_FLASHRAM_READ) begin
if (counter[0]) begin
n64_scb.flashram_buffer_address <= n64_scb.flashram_buffer_address + 1'd1;
end
end
if (cmd == CMD_EEPROM_READ) begin
n64_scb.eeprom_address <= n64_scb.eeprom_address + 1'd1;
end
if (cmd == CMD_EEPROM_WRITE) begin
n64_scb.eeprom_write <= 1'b1;
n64_scb.eeprom_wdata <= rdata;
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
CMD_FLASHRAM_READ: begin
case (counter[0])
1'd0: wdata = n64_scb.flashram_buffer_rdata[15:8];
1'd1: wdata = n64_scb.flashram_buffer_rdata[7:0];
endcase
end
CMD_EEPROM_READ: begin
wdata = n64_scb.eeprom_rdata;
end
CMD_EEPROM_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_STATUS,
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_address_e;
logic bootloader_skip;
assign n64_scb.cfg_version = 32'h53437632;
// Register read logic
always_ff @(posedge clk) begin
if (reg_read) begin
reg_rdata <= 32'd0;
case (address)
REG_STATUS: begin
reg_rdata <= {
24'd0,
sd_det_ff[2],
~fifo_bus.tx_full,
~fifo_bus.rx_empty,
n64_scb.flashram_pending,
n64_scb.cfg_pending,
usb_dma_scb.busy,
usb_scb.reset_pending,
button_ff[2]
};
end
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 <= {
28'd0,
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 <= {
22'd0,
n64_scb.eeprom_16k_mode,
n64_scb.eeprom_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 <= {
24'd0,
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 <= {
31'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 <= {
30'd0,
sd_scb.clock_mode
};
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
endcase
end
end
// Register write logic
logic [31:0] reg_buffer;
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_dma_scb.start <= 1'b0;
sd_dma_scb.stop <= 1'b0;
n64_scb.cfg_done <= 1'b0;
n64_scb.cfg_irq <= 1'b0;
n64_scb.flashram_done <= 1'b0;
n64_scb.rtc_done <= 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 (reset) begin
mcu_int <= 1'b0;
sd_scb.clock_mode <= 2'd0;
n64_scb.eeprom_16k_mode <= 1'b0;
n64_scb.eeprom_enabled <= 1'b0;
n64_scb.dd_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;
end else if (reg_write) begin
case (address)
REG_STATUS: begin end
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.eeprom_16k_mode,
n64_scb.eeprom_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[9: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[2:0];
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
reg_buffer <= reg_wdata;
end
REG_RTC_TIME_1: begin
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];
n64_scb.rtc_wdata[28:26] <= reg_buffer[26:24];
n64_scb.rtc_wdata[19:14] <= reg_buffer[21:16];
n64_scb.rtc_wdata[13:7] <= reg_buffer[14:8];
n64_scb.rtc_wdata[6:0] <= reg_buffer[6:0];
end
REG_SD_SCR: begin
sd_scb.clock_mode <= reg_wdata[1: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
endcase
end
end
endmodule

31
fw/rtl/memory/mem_bus.sv Normal file
View 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

View File

@ -0,0 +1,159 @@
module memory_arbiter (
input clk,
input reset,
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
);
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;
assign n64_sdram_request = n64_bus.request && !n64_bus.address[26];
assign cfg_sdram_request = cfg_bus.request && !cfg_bus.address[26];
assign usb_dma_sdram_request = usb_dma_bus.request && !usb_dma_bus.address[26];
assign sd_dma_sdram_request = sd_dma_bus.request && !sd_dma_bus.address[26];
assign n64_flash_request = n64_bus.request && n64_bus.address[26];
assign cfg_flash_request = cfg_bus.request && cfg_bus.address[26];
assign usb_dma_flash_request = usb_dma_bus.request && usb_dma_bus.address[26];
assign sd_dma_flash_request = sd_dma_bus.request && sd_dma_bus.address[26];
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
always_comb begin
n64_bus.ack = (
((sdram_source_request == SOURCE_N64) && sdram_mem_bus.ack) ||
((flash_source_request == SOURCE_N64) && flash_mem_bus.ack)
);
cfg_bus.ack = (
((sdram_source_request == SOURCE_CFG) && sdram_mem_bus.ack) ||
((flash_source_request == SOURCE_CFG) && flash_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)
);
sd_dma_bus.ack = (
((sdram_source_request == SOURCE_SD_DMA) && sdram_mem_bus.ack) ||
((flash_source_request == SOURCE_SD_DMA) && flash_mem_bus.ack)
);
n64_bus.rdata = n64_flash_request ? flash_mem_bus.rdata : sdram_mem_bus.rdata;
cfg_bus.rdata = cfg_flash_request ? flash_mem_bus.rdata : sdram_mem_bus.rdata;
usb_dma_bus.rdata = usb_dma_flash_request ? flash_mem_bus.rdata : sdram_mem_bus.rdata;
sd_dma_bus.rdata = sd_dma_flash_request ? flash_mem_bus.rdata : sdram_mem_bus.rdata;
end
endmodule

View File

@ -1,108 +1,28 @@
interface if_memory_dma (); interface dma_scb ();
logic request;
logic ack;
logic write;
logic [1:0] wmask;
logic [31:0] address;
logic [15:0] rdata;
logic [15:0] wdata;
logic start; logic start;
logic stop; logic stop;
logic busy; logic busy;
logic direction; logic direction;
logic [31:0] transfer_length; logic [26:0] starting_address;
logic [31:0] starting_address; logic [26:0] transfer_length;
logic dma_rx_read; modport controller (
logic dma_tx_write; output start,
logic [7:0] dma_tx_wdata; output stop,
input busy,
logic cpu_rx_read; output direction,
logic cpu_tx_write; output starting_address,
logic [7:0] cpu_tx_wdata; output transfer_length
);
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;
always_comb begin
rx_read = dma_rx_read || cpu_rx_read;
tx_write = dma_tx_write || cpu_tx_write;
tx_wdata = cpu_tx_write ? cpu_tx_wdata : dma_tx_wdata;
end
modport dma ( modport dma (
input start, input start,
input stop, input stop,
output busy, output busy,
input direction, input direction,
input transfer_length,
input starting_address, input starting_address,
input transfer_length
output request,
input ack,
output write,
output wmask,
output address,
input rdata,
output wdata,
input rx_empty,
input rx_almost_empty,
output dma_rx_read,
input rx_rdata,
input tx_full,
input tx_almost_full,
output dma_tx_write,
output dma_tx_wdata
);
modport cpu (
output start,
output stop,
input busy,
output direction,
output transfer_length,
output starting_address,
input rx_empty,
output cpu_rx_read,
input rx_rdata,
input tx_full,
output cpu_tx_write,
output cpu_tx_wdata
);
modport memory (
input request,
output ack,
input write,
input wmask,
input address,
output rdata,
input wdata
);
modport device (
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 endinterface
@ -111,7 +31,11 @@ endinterface
module memory_dma ( module memory_dma (
input clk, input clk,
input reset, input reset,
if_memory_dma.dma dma
dma_scb.dma dma_scb,
fifo_bus.controller fifo_bus,
mem_bus.controller mem_bus
); );
typedef enum bit [0:0] { typedef enum bit [0:0] {
@ -119,73 +43,79 @@ module memory_dma (
STATE_TRANSFER STATE_TRANSFER
} e_state; } e_state;
logic [31:0] remaining; // logic [31:0] remaining;
logic [26:0] end_address;
logic [15:0] data_buffer; logic [15:0] data_buffer;
logic byte_counter; logic byte_counter;
e_state state; e_state state;
logic rx_delay;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
dma.dma_rx_read <= 1'b0; fifo_bus.rx_read <= 1'b0;
dma.dma_tx_write <= 1'b0; fifo_bus.tx_write <= 1'b0;
rx_delay <= fifo_bus.rx_read;
if (dma.dma_rx_read) begin if (rx_delay) begin
if (dma.address[0] || (remaining == 32'd1)) begin // if (dma.address[0] || (remaining == 32'd1)) begin
dma.wdata <= {dma.rx_rdata, dma.rx_rdata}; // dma.wdata <= {dma.rx_rdata, dma.rx_rdata};
end else begin // end else begin
dma.wdata <= {dma.wdata[7:0], dma.rx_rdata}; mem_bus.wdata <= {mem_bus.wdata[7:0], fifo_bus.rx_rdata};
end // end
end end
if (reset) begin if (reset) begin
dma.busy <= 1'b0; dma_scb.busy <= 1'b0;
dma.request <= 1'b0; mem_bus.request <= 1'b0;
end else begin end else begin
if (!dma.busy) begin if (!dma_scb.busy) begin
if (dma.start) begin if (dma_scb.start) begin
dma.busy <= 1'b1; dma_scb.busy <= 1'b1;
dma.write <= dma.direction; mem_bus.write <= dma_scb.direction;
dma.address <= dma.starting_address; mem_bus.address <= dma_scb.starting_address;
remaining <= dma.transfer_length; end_address <= dma_scb.starting_address + dma_scb.transfer_length;
// remaining <= dma.transfer_length;
byte_counter <= 1'd0; byte_counter <= 1'd0;
state <= STATE_FETCH; state <= STATE_FETCH;
end end
end else begin end else begin
if (dma.stop) begin if (dma_scb.stop) begin
dma.busy <= 1'b0; dma_scb.busy <= 1'b0;
dma.request <= 1'b0; mem_bus.request <= 1'b0;
end else if (remaining != 32'd0) begin end else if (mem_bus.address != end_address/* remaining != 32'd0*/) begin
if (dma.write) begin if (mem_bus.write) begin
case (state) case (state)
STATE_FETCH: begin STATE_FETCH: begin
if (!dma.rx_empty && !(dma.dma_rx_read && dma.rx_almost_empty)) begin if (!fifo_bus.rx_empty && !(fifo_bus.rx_read && fifo_bus.rx_almost_empty)) begin
dma.dma_rx_read <= 1'b1; fifo_bus.rx_read <= 1'b1;
if (dma.address[0]) begin // if (dma.address[0]) begin
dma.wmask <= 2'b01; // dma.wmask <= 2'b01;
state <= STATE_TRANSFER; // state <= STATE_TRANSFER;
end else if (remaining == 32'd1) begin // end else if (dma.starting_address[0] remaining == 32'd1) begin
dma.wmask <= 2'b10; // dma.wmask <= 2'b10;
state <= STATE_TRANSFER; // state <= STATE_TRANSFER;
end else begin // end else begin
byte_counter <= byte_counter + 1'd1; byte_counter <= byte_counter + 1'd1;
if (byte_counter) begin if (byte_counter) begin
dma.wmask <= 2'b11; mem_bus.wmask <= 2'b11;
state <= STATE_TRANSFER; state <= STATE_TRANSFER;
end end
end // end
end end
end end
STATE_TRANSFER: begin STATE_TRANSFER: begin
dma.request <= 1'b1; if (!fifo_bus.rx_read) begin
if (dma.ack) begin mem_bus.request <= 1'b1;
dma.request <= 1'b0;
if (dma.wmask != 2'b11) begin
dma.address <= dma.address + 1'd1;
remaining <= remaining - 1'd1;
end else begin
dma.address <= dma.address + 2'd2;
remaining <= remaining - 2'd2;
end end
if (mem_bus.ack) begin
mem_bus.request <= 1'b0;
// if (dma.wmask != 2'b11) begin
// dma.address <= dma.address + 1'd1;
// remaining <= remaining - 1'd1;
// end else begin
mem_bus.address <= mem_bus.address + 2'd2;
// remaining <= remaining - 2'd2;
// end
state <= STATE_FETCH; state <= STATE_FETCH;
end end
end end
@ -193,42 +123,42 @@ module memory_dma (
end else begin end else begin
case (state) case (state)
STATE_FETCH: begin STATE_FETCH: begin
dma.request <= 1'b1; mem_bus.request <= 1'b1;
if (dma.ack) begin if (mem_bus.ack) begin
dma.request <= 1'b0; mem_bus.request <= 1'b0;
data_buffer <= dma.rdata; data_buffer <= mem_bus.rdata;
state <= STATE_TRANSFER; state <= STATE_TRANSFER;
end end
end end
STATE_TRANSFER: begin STATE_TRANSFER: begin
if (!dma.tx_full && !(dma.dma_tx_write && dma.tx_almost_full)) begin if (!fifo_bus.tx_full && !(fifo_bus.tx_write && fifo_bus.tx_almost_full)) begin
dma.dma_tx_write <= 1'b1; fifo_bus.tx_write <= 1'b1;
if (dma.address[0]) begin // if (dma.address[0]) begin
dma.address <= dma.address + 1'd1; // dma.address <= dma.address + 1'd1;
remaining <= remaining - 1'd1; // // remaining <= remaining - 1'd1;
dma.dma_tx_wdata <= data_buffer[7:0]; // dma.dma_tx_wdata <= data_buffer[7:0];
state <= STATE_FETCH; // state <= STATE_FETCH;
end else if (remaining == 32'd1) begin // end else if (remaining == 32'd1) begin
dma.address <= dma.address + 1'd1; // dma.address <= dma.address + 1'd1;
remaining <= remaining - 1'd1; // // remaining <= remaining - 1'd1;
dma.dma_tx_wdata <= data_buffer[15:8]; // dma.dma_tx_wdata <= data_buffer[15:8];
state <= STATE_FETCH; // state <= STATE_FETCH;
end else begin // end else begin
dma.dma_tx_wdata <= byte_counter ? data_buffer[7:0] : data_buffer[15:8]; fifo_bus.tx_wdata <= byte_counter ? data_buffer[7:0] : data_buffer[15:8];
byte_counter <= byte_counter + 1'd1; byte_counter <= byte_counter + 1'd1;
if (byte_counter) begin if (byte_counter) begin
dma.address <= dma.address + 2'd2; mem_bus.address <= mem_bus.address + 2'd2;
remaining <= remaining - 2'd2; // remaining <= remaining - 2'd2;
state <= STATE_FETCH; state <= STATE_FETCH;
end end
end // end
end end
end end
endcase endcase
end end
end else begin end else begin
dma.busy <= 1'b0; dma_scb.busy <= 1'b0;
end end
end end
end end

View File

@ -0,0 +1,493 @@
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;
e_state next_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

View File

@ -1,48 +1,41 @@
module memory_sdram ( module memory_sdram (
if_system sys, input clk,
input reset,
input request, mem_bus.memory mem_bus,
output ack,
input write,
input [25:0] address,
output [15:0] rdata,
input [15:0] wdata,
output sdram_cs, output logic sdram_cs,
output sdram_ras, output logic sdram_ras,
output sdram_cas, output logic sdram_cas,
output sdram_we, output logic sdram_we,
output [1:0] sdram_ba, output logic [1:0] sdram_ba,
output [12:0] sdram_a, output logic [12:0] sdram_a,
output logic [1:0] sdram_dqm,
inout [15:0] sdram_dq 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; localparam real T_INIT = 100_000.0;
parameter real T_RC = 60.0; localparam real T_RC = 60.0;
parameter real T_RP = 15.0; localparam real T_RP = 15.0;
parameter real T_RCD = 15.0; localparam real T_RCD = 15.0;
// parameter real T_RAS = 37.0; //TODO: handle this timing localparam real T_MRD = 14.0;
// parameter real T_WR = T_RAS - T_RCD; //TODO: handle this timing localparam real T_REF = 7_800.0;
parameter real T_MRD = 14.0;
parameter 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_INIT = int'((T_INIT + T_CLK - 1) / T_CLK);
localparam int C_RC = int'((T_RC + 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_RP = int'((T_RP + T_CLK - 1) / T_CLK);
localparam int C_RCD = int'((T_RCD + 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_MRD = int'((T_MRD + T_CLK - 1) / T_CLK);
localparam int C_REF = int'((T_REF + T_CLK - 1) / T_CLK); localparam int C_REF = int'((T_REF + T_CLK - 1) / T_CLK);
localparam INIT_PRECHARGE = C_INIT; localparam INIT_PRECHARGE = 4'd0;
localparam INIT_REFRESH_1 = C_INIT + C_RP; localparam INIT_REFRESH_1 = C_RP;
localparam INIT_REFRESH_2 = C_INIT + C_RP + C_RC; localparam INIT_REFRESH_2 = C_RP + C_RC;
localparam INIT_MODE_REG = C_INIT + C_RP + (2 * C_RC); localparam INIT_MODE_REG = C_RP + (2 * C_RC);
localparam INIT_DONE = C_INIT + C_RP + (2 * C_RC) + C_MRD; localparam INIT_DONE = C_RP + (2 * C_RC) + C_MRD;
typedef enum bit [3:0] { typedef enum bit [3:0] {
CMD_DESL = 4'b1111, CMD_DESL = 4'b1111,
@ -63,37 +56,51 @@ module memory_sdram (
logic [14:0] current_active_bank_row; logic [14:0] current_active_bank_row;
logic request_in_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_cs, sdram_ras, sdram_cas, sdram_we} <= 4'(sdram_next_cmd);
{sdram_ba, sdram_a} <= 15'd0; {sdram_ba, sdram_a} <= 15'd0;
sdram_dqm <= 2'b00;
sdram_dq_input <= sdram_dq; sdram_dq_input <= sdram_dq;
sdram_dq_output <= wdata; sdram_dq_output <= mem_bus.wdata;
sdram_dq_output_enable <= 1'b0; sdram_dq_output_enable <= 1'b0;
case (sdram_next_cmd) case (sdram_next_cmd)
CMD_READ, CMD_WRITE: begin CMD_READ, CMD_WRITE: begin
{sdram_ba, sdram_a} <= {address[25:24], 3'b000, address[10:1]}; {sdram_ba, sdram_a} <= {mem_bus.address[25:24], 3'b000, mem_bus.address[10:1]};
sdram_dq_output_enable <= sdram_next_cmd == CMD_WRITE; sdram_dqm <= (sdram_next_cmd == CMD_WRITE) ? (~mem_bus.wmask) : 2'b00;
sdram_dq_output_enable <= (sdram_next_cmd == CMD_WRITE);
end end
CMD_ACT: begin CMD_ACT: begin
{sdram_ba, sdram_a} <= address[25:11]; {sdram_ba, sdram_a} <= mem_bus.address[25:11];
current_active_bank_row <= 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 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 endcase
end end
assign sdram_dq = sdram_dq_output_enable ? sdram_dq_output : 16'hZZZZ;
always_comb begin always_comb begin
rdata = sdram_dq_input; mem_bus.rdata = sdram_dq_input;
sdram_dq = sdram_dq_output_enable ? sdram_dq_output : 16'hZZZZ; request_in_current_active_bank_row = mem_bus.address[25:11] == current_active_bank_row;
request_in_current_active_bank_row = address[25:11] == current_active_bank_row;
end end
typedef enum bit [2:0] { typedef enum bit [2:0] {
S_POWERUP,
S_INIT, S_INIT,
S_IDLE, S_IDLE,
S_ACTIVATING, S_ACTIVATING,
@ -106,44 +113,54 @@ module memory_sdram (
e_state state; e_state state;
e_state next_state; e_state next_state;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
if (sys.reset) begin if (reset) begin
state <= S_INIT; state <= S_POWERUP;
end else begin end else begin
state <= next_state; state <= next_state;
end end
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 [9:0] refresh_counter;
logic pending_refresh; logic pending_refresh;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
if (sys.reset || state != next_state) begin if (reset) begin
wait_counter <= 14'd0; 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 end else begin
wait_counter <= wait_counter + 1'd1; wait_counter <= wait_counter + 1'd1;
end end
if (sdram_next_cmd == CMD_REF) begin if (sdram_next_cmd == CMD_REF) begin
refresh_counter <= 10'd0; 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; refresh_counter <= refresh_counter + 1'd1;
end else begin
pending_refresh <= 1'b1;
end end
end end
always_comb begin
pending_refresh = refresh_counter >= C_REF;
end
logic [(CAS_LATENCY):0] read_cmd_ack_delay; logic [(CAS_LATENCY):0] read_cmd_ack_delay;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
ack <= 1'b0; mem_bus.ack <= 1'b0;
read_cmd_ack_delay <= {sdram_next_cmd == CMD_READ, read_cmd_ack_delay[(CAS_LATENCY):1]}; 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 if (sdram_next_cmd == CMD_WRITE || read_cmd_ack_delay[0]) begin
ack <= 1'b1; mem_bus.ack <= 1'b1;
end end
end end
@ -152,10 +169,14 @@ module memory_sdram (
next_state = state; next_state = state;
case (state) case (state)
S_INIT: begin S_POWERUP: begin
if (wait_counter < INIT_PRECHARGE) begin
sdram_next_cmd = CMD_DESL; sdram_next_cmd = CMD_DESL;
if (powerup_done) begin
next_state = S_INIT;
end end
end
S_INIT: begin
if (wait_counter == INIT_PRECHARGE) begin if (wait_counter == INIT_PRECHARGE) begin
sdram_next_cmd = CMD_PRE; sdram_next_cmd = CMD_PRE;
end end
@ -174,7 +195,7 @@ module memory_sdram (
if (pending_refresh) begin if (pending_refresh) begin
next_state = S_REFRESH; next_state = S_REFRESH;
sdram_next_cmd = CMD_REF; sdram_next_cmd = CMD_REF;
end else if (request) begin end else if (mem_bus.request) begin
next_state = S_ACTIVATING; next_state = S_ACTIVATING;
sdram_next_cmd = CMD_ACT; sdram_next_cmd = CMD_ACT;
end end
@ -190,10 +211,10 @@ module memory_sdram (
if (pending_refresh) begin if (pending_refresh) begin
next_state = S_PRECHARGE; next_state = S_PRECHARGE;
sdram_next_cmd = CMD_PRE; 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 if (request_in_current_active_bank_row) begin
next_state = S_BUSY; 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 end else begin
next_state = S_PRECHARGE; next_state = S_PRECHARGE;
sdram_next_cmd = CMD_PRE; sdram_next_cmd = CMD_PRE;
@ -202,7 +223,7 @@ module memory_sdram (
end end
S_BUSY: begin S_BUSY: begin
if (ack) begin if (mem_bus.ack) begin
next_state = S_ACTIVE; next_state = S_ACTIVE;
end end
end end

View File

@ -1,94 +0,0 @@
module n64_bootloader (
if_system.sys sys,
if_n64_bus bus,
if_config.flash cfg,
if_flash.flash flash
);
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;
logic request;
logic ack;
logic write;
logic [31:0] address;
logic [31:0] wdata;
logic [31:0] rdata;
always_ff @(posedge sys.clk) begin
if (sys.reset) begin
state <= S_IDLE;
request <= 1'b0;
end else begin
case (state)
S_IDLE: begin
if (bus.request || flash.request) begin
state <= S_WAIT;
request <= 1'b1;
if (bus.request) begin
write <= 1'b0;
address <= bus.address;
wdata <= bus.wdata;
source_request <= T_N64;
end else if (flash.request) begin
write <= flash.write;
address <= flash.address;
wdata <= flash.wdata;
source_request <= T_CPU;
end
end
end
S_WAIT: begin
if (ack) begin
state <= S_IDLE;
request <= 1'b0;
end
end
endcase
end
end
always_comb begin
bus.ack = source_request == T_N64 && ack;
bus.rdata = 16'd0;
if (bus.ack && bus.address < 32'h00010000) begin
if (bus.address[1]) bus.rdata = {rdata[23:16], rdata[31:24]};
else bus.rdata = {rdata[7:0], rdata[15:8]};
end
flash.ack = source_request == T_CPU && ack;
flash.rdata = 32'd0;
if (flash.ack) begin
flash.rdata = rdata;
end
end
vendor_flash vendor_flash_inst (
.clk(sys.clk),
.reset(sys.reset),
.erase_start(cfg.flash_erase_start),
.erase_busy(cfg.flash_erase_busy),
.wp_enable(cfg.flash_wp_enable),
.wp_disable(cfg.flash_wp_disable),
.request(request),
.ack(ack),
.write(write),
.address(address),
.wdata(wdata),
.rdata(rdata)
);
endmodule

View File

@ -1,69 +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
if (id >= NUM_DEVICES) begin
ack = request;
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

View File

@ -1,85 +1,69 @@
module n64_cfg ( module n64_cfg (
if_system sys, input clk,
if_n64_bus bus, input reset,
if_config.n64 cfg
n64_reg_bus.cfg reg_bus,
n64_scb.cfg n64_scb,
output logic irq
); );
typedef enum bit [2:0] { typedef enum bit [2:0] {
R_SR, REG_STATUS,
R_COMMAND, REG_COMMAND,
R_DATA_0_H, REG_DATA_0_H,
R_DATA_0_L, REG_DATA_0_L,
R_DATA_1_H, REG_DATA_1_H,
R_DATA_1_L, REG_DATA_1_L,
R_VERSION_H, REG_VERSION_H,
R_VERSION_L REG_VERSION_L
} e_reg_id; } e_reg;
typedef enum bit [0:0] {
S_IDLE,
S_WAIT
} e_state;
e_state state;
always_comb begin always_comb begin
bus.rdata = 16'd0; reg_bus.rdata = 16'd0;
if (bus.ack) begin case (reg_bus.address[3:1])
case (bus.address[3:1]) REG_STATUS: reg_bus.rdata = {
R_SR: bus.rdata = { n64_scb.cfg_pending,
cfg.cpu_ready, n64_scb.cfg_error,
cfg.cpu_busy, 14'd0
1'b0,
cfg.cmd_error,
12'd0
}; };
R_COMMAND: bus.rdata = {8'd0, cfg.cmd}; REG_DATA_0_H: reg_bus.rdata = n64_scb.cfg_wdata[0][31:16];
R_DATA_0_H: bus.rdata = cfg.data[0][31:16]; REG_DATA_0_L: reg_bus.rdata = n64_scb.cfg_wdata[0][15:0];
R_DATA_0_L: bus.rdata = cfg.data[0][15:0]; REG_DATA_1_H: reg_bus.rdata = n64_scb.cfg_wdata[1][31:16];
R_DATA_1_H: bus.rdata = cfg.data[1][31:16]; REG_DATA_1_L: reg_bus.rdata = n64_scb.cfg_wdata[1][15:0];
R_DATA_1_L: bus.rdata = cfg.data[1][15:0]; REG_VERSION_H: reg_bus.rdata = n64_scb.cfg_version[31:16];
R_VERSION_H: bus.rdata = sc64::SC64_VER[31:16]; REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0];
R_VERSION_L: bus.rdata = sc64::SC64_VER[15:0];
default: bus.rdata = 16'd0;
endcase endcase
end end
end
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
bus.ack <= 1'b0; if (reset) begin
cfg.cmd_request <= 1'b0; n64_scb.cfg_pending <= 1'b0;
irq <= 1'b0;
if (cfg.data_write[0]) cfg.data[0] <= cfg.wdata;
if (cfg.data_write[1]) cfg.data[1] <= cfg.wdata;
if (sys.reset) begin
state <= S_IDLE;
end else begin end else begin
case (state) if (n64_scb.cfg_done) begin
S_IDLE: begin n64_scb.cfg_pending <= 1'b0;
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
end
end
end end
S_WAIT: begin if (n64_scb.cfg_irq) begin
state <= S_IDLE; irq <= 1'b1;
end end
if (reg_bus.write) begin
case (reg_bus.address[3:1])
REG_COMMAND: begin
n64_scb.cfg_pending <= 1'b1;
n64_scb.cfg_cmd <= reg_bus.wdata[7:0];
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_L: irq <= 1'b0;
endcase endcase
end end
end end
end
endmodule endmodule

View File

@ -1,172 +1,16 @@
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;
// N64 controlled regs
logic hard_reset;
logic [15:0] data;
logic [7:0] cmd;
logic cmd_pending;
logic cmd_interrupt;
logic bm_start_pending;
logic bm_stop_pending;
logic bm_transfer_mode;
logic bm_transfer_blocks;
logic bm_pending;
logic bm_interrupt;
logic bm_interrupt_ack;
logic [7:0] sector_num;
logic [7:0] sector_size;
logic [7:0] sector_size_full;
logic [7:0] sectors_in_block;
// CPU controlled regs
logic hard_reset_clear;
logic [15:0] cmd_data;
logic cmd_ready;
logic bm_start_clear;
logic bm_stop_clear;
logic bm_transfer_c2;
logic bm_transfer_data;
logic bm_micro_error;
logic bm_clear;
logic bm_ready;
logic disk_inserted;
logic disk_changed;
logic index_lock;
logic [12:0] head_track;
logic [15:0] drive_id;
always_comb begin
dd_interrupt = cmd_interrupt || bm_interrupt;
end
modport dd (
output hard_reset,
output data,
output cmd,
output cmd_pending,
output cmd_interrupt,
output bm_start_pending,
output bm_stop_pending,
output bm_transfer_mode,
output bm_transfer_blocks,
output bm_pending,
output bm_interrupt,
output bm_interrupt_ack,
output sector_num,
output sector_size,
output sector_size_full,
output sectors_in_block,
input hard_reset_clear,
input cmd_data,
input cmd_ready,
input bm_start_clear,
input bm_stop_clear,
input bm_transfer_c2,
input bm_transfer_data,
input bm_micro_error,
input bm_clear,
input bm_ready,
input disk_inserted,
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
);
endinterface
module n64_dd ( module n64_dd (
if_system.sys sys, input clk,
if_n64_bus bus, input reset,
if_dd.dd dd
n64_reg_bus.dd reg_bus,
n64_scb.dd n64_scb,
output logic irq
); );
const bit [31:0] M_BASE = 32'h0500_0000; const bit [10:0] M_C2_BUFFER = 11'h000;
const bit [31:0] M_C2_BUFFER = M_BASE + 11'h000; const bit [10:0] M_SECTOR_BUFFER = 11'h400;
const bit [31:0] M_SECTOR_BUFFER = M_BASE + 11'h400;
typedef enum bit [10:0] { typedef enum bit [10:0] {
R_DATA = 11'h500, R_DATA = 11'h500,
@ -187,19 +31,19 @@ module n64_dd (
BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8 BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8
} e_bm_control_id; } e_bm_control_id;
typedef enum bit [0:0] { // typedef enum bit [0:0] {
S_IDLE, // S_IDLE,
S_WAIT // S_WAIT
} e_state; // } e_state;
e_state state; // e_state state;
always_comb begin // always_comb begin
dd.sector_address = bus.address[7:1]; // dd.sector_address = bus.address[7:1];
dd.sector_address_valid = bus.request && bus.address[11:8] == M_SECTOR_BUFFER[11:8]; // 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_write = bus.write && dd.sector_address_valid;
dd.sector_wdata = bus.wdata; // dd.sector_wdata = bus.wdata;
end // end
always_comb begin always_comb begin
bus.rdata = 16'd0; bus.rdata = 16'd0;
@ -240,6 +84,38 @@ module n64_dd (
end end
end end
always_comb begin
reg_bus.rdata = 16'd0;
if (reg_bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin
end else begin
case (reg_bus.address[10:0])
R_DATA: reg_bus.rdata = dd.data;
R_CMD_SR: reg_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: reg_bus.rdata = {1'd0, {2{dd.index_lock}}, dd.head_track};
R_BM_SCR: reg_bus.rdata = {6'd0, dd.bm_micro_error, 9'd0};
R_ID: reg_bus.rdata = {dd.drive_id};
default: reg_bus.rdata = 16'd0;
endcase
end
end
always_ff @(posedge sys.clk) begin always_ff @(posedge sys.clk) begin
bus.ack <= 1'b0; bus.ack <= 1'b0;
dd.bm_interrupt_ack <= 1'b0; dd.bm_interrupt_ack <= 1'b0;
@ -354,51 +230,5 @@ module n64_dd (
end end
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
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
end
endmodule endmodule

View File

@ -1,8 +1,10 @@
module n64_flashram ( module n64_flashram (
if_system.sys sys, input clk,
if_n64_bus bus, input reset,
if_config.flashram cfg,
if_flashram.flashram flashram n64_reg_bus.flashram reg_bus,
n64_scb.flashram n64_scb
); );
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001; localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
@ -19,171 +21,134 @@ module n64_flashram (
CMD_WRITE_START = 8'hA5 CMD_WRITE_START = 8'hA5
} e_cmd; } e_cmd;
typedef enum bit [0:0] { typedef enum bit [1:0] {
S_IDLE, STATE_STATUS,
S_WAIT STATE_ID,
} e_bus_state; STATE_READ,
STATE_BUFFER
} e_state;
typedef enum bit [1:0] { typedef enum bit [1:0] {
FS_STATUS, WRITE_BUSY,
FS_ID, ERASE_BUSY,
FS_READ, WRITE_DONE,
FS_BUFFER ERASE_DONE
} e_flashram_state; } e_status_bits;
typedef enum bit [1:0] { e_state state;
B_WRITE_BUSY, logic [3:0] status;
B_ERASE_BUSY, logic [7:0] cmd;
B_WRITE_DONE, logic erase_enabled;
B_ERASE_DONE
} e_flashram_status;
e_bus_state bus_state; logic [15:0] write_buffer [0:63];
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]; always_ff @(posedge clk) begin
logic [1:0] write_buffer_wmask; n64_scb.flashram_buffer_rdata <= write_buffer[n64_scb.flashram_buffer_address];
logic [15:0] high_buffer;
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];
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 end
always_comb begin always_comb begin
bus.rdata = 16'd0; n64_scb.flashram_read_mode = (state == STATE_READ);
if (bus.ack) begin
if (bus.address[1]) begin reg_bus.rdata = 16'd0;
bus.rdata = {12'd0, flashram_status}; if (state == STATE_ID) begin
end case (reg_bus.address[2:1])
if (flashram_state == FS_ID) begin 0: reg_bus.rdata = FLASH_TYPE_ID[31:16];
case (bus.address[2:1]) 1: reg_bus.rdata = FLASH_TYPE_ID[15:0];
0: bus.rdata = FLASH_TYPE_ID[31:16]; 2: reg_bus.rdata = FLASH_MODEL_ID[31:16];
1: bus.rdata = FLASH_TYPE_ID[15:0]; 3: reg_bus.rdata = FLASH_MODEL_ID[15:0];
2: bus.rdata = FLASH_MODEL_ID[31:16];
3: bus.rdata = FLASH_MODEL_ID[15:0];
endcase endcase
end else if (reg_bus.address[1]) begin
reg_bus.rdata = {12'd0, status};
end end
end end
cfg.flashram_read_mode = flashram_state == FS_READ; always_ff @(posedge clk) begin
end if (reset) begin
state <= STATE_STATUS;
always_ff @(posedge sys.clk) begin status <= 4'b0000;
bus.ack <= 1'b0; erase_enabled <= 1'b0;
n64_scb.flashram_pending <= 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;
end else begin end else begin
if (flashram.operation_done) begin if (n64_scb.flashram_done) begin
flashram.operation_pending <= 1'b0; n64_scb.flashram_pending <= 1'b0;
if (flashram.write_or_erase) begin if (n64_scb.flashram_write_or_erase) begin
flashram_status[B_ERASE_BUSY] <= 1'b0; status[ERASE_BUSY] <= 1'b0;
flashram_status[B_ERASE_DONE] <= 1'b1; status[ERASE_DONE] <= 1'b1;
end else begin end else begin
flashram_status[B_WRITE_BUSY] <= 1'b0; status[WRITE_BUSY] <= 1'b0;
flashram_status[B_WRITE_DONE] <= 1'b1; status[WRITE_DONE] <= 1'b1;
end end
end end
case (bus_state) if (reg_bus.write && !n64_scb.flashram_pending) begin
S_IDLE: begin if (reg_bus.address[16]) begin
if (bus.request) begin if (!reg_bus.address[1]) begin
bus_state <= S_WAIT; cmd <= reg_bus.wdata[15:8];
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 end else begin
flashram_erase_enabled <= 1'b0; erase_enabled <= 1'b0;
case (flashram_command) case (cmd)
CMD_STATUS_MODE: begin CMD_STATUS_MODE: begin
flashram_state <= FS_STATUS; state <= STATE_STATUS;
end end
CMD_READID_MODE: begin CMD_READID_MODE: begin
flashram_state <= FS_ID; state <= STATE_ID;
end end
CMD_READ_MODE: begin CMD_READ_MODE: begin
flashram_state <= FS_READ; state <= STATE_READ;
end end
CMD_ERASE_SECTOR: begin CMD_ERASE_SECTOR: begin
flashram_state <= FS_STATUS; state <= STATE_STATUS;
flashram_erase_enabled <= 1'b1; erase_enabled <= 1'b1;
flashram.sector <= bus.wdata[9:0]; n64_scb.flashram_sector <= reg_bus.wdata[9:0];
flashram.sector_or_all <= 1'b0; n64_scb.flashram_sector_or_all <= 1'b0;
end end
CMD_ERASE_CHIP: begin CMD_ERASE_CHIP: begin
flashram_state <= FS_STATUS; state <= STATE_STATUS;
flashram_erase_enabled <= 1'b1; erase_enabled <= 1'b1;
flashram.sector <= 10'd0; n64_scb.flashram_sector <= 10'd0;
flashram.sector_or_all <= 1'b1; n64_scb.flashram_sector_or_all <= 1'b1;
end end
CMD_BUFFER_MODE: begin CMD_BUFFER_MODE: begin
flashram_state <= FS_BUFFER; state <= STATE_BUFFER;
end end
CMD_ERASE_START: begin CMD_ERASE_START: begin
flashram_state <= FS_STATUS; state <= STATE_STATUS;
if (flashram_erase_enabled) begin if (erase_enabled) begin
flashram_status[B_ERASE_BUSY] <= 1'b1; status[ERASE_BUSY] <= 1'b1;
flashram_status[B_ERASE_DONE] <= 1'b0; status[ERASE_DONE] <= 1'b0;
flashram.operation_pending <= 1'b1; n64_scb.flashram_pending <= 1'b1;
flashram.write_or_erase <= 1'b1; n64_scb.flashram_write_or_erase <= 1'b1;
end end
end end
CMD_WRITE_START: begin CMD_WRITE_START: begin
flashram_state <= FS_STATUS; state <= STATE_STATUS;
flashram_status[B_WRITE_BUSY] <= 1'b1; status[WRITE_BUSY] <= 1'b1;
flashram_status[B_WRITE_DONE] <= 1'b0; status[WRITE_DONE] <= 1'b0;
flashram.sector <= bus.wdata[9:0]; n64_scb.flashram_sector <= reg_bus.wdata[9:0];
flashram.operation_pending <= 1'b1; n64_scb.flashram_pending <= 1'b1;
flashram.write_or_erase <= 1'b0; n64_scb.flashram_write_or_erase <= 1'b0;
flashram.sector_or_all <= 1'b0; n64_scb.flashram_sector_or_all <= 1'b0;
end end
endcase endcase
end end
end else begin end else begin
if (bus.address[1] && flashram_state == FS_STATUS) begin if (state == STATE_BUFFER) begin
flashram_status[B_ERASE_BUSY] <= bus.wdata[B_ERASE_BUSY]; write_buffer[reg_bus.address[6:1]] <= reg_bus.wdata;
flashram_status[B_WRITE_BUSY] <= bus.wdata[B_WRITE_BUSY]; end else if (reg_bus.address[1]) begin
status[ERASE_BUSY] <= reg_bus.wdata[ERASE_BUSY];
status[WRITE_BUSY] <= reg_bus.wdata[WRITE_BUSY];
end end
end end
end end
end end
end end
S_WAIT: begin
bus_state <= S_IDLE;
end
endcase
end
end
endmodule endmodule

View File

@ -1,8 +1,14 @@
module n64_pi ( module n64_pi (
if_system.sys sys, input clk,
if_config.pi cfg, input reset,
if_n64_bus.n64 bus,
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_alel,
input n64_pi_aleh, input n64_pi_aleh,
input n64_pi_read, input n64_pi_read,
@ -10,79 +16,34 @@ module n64_pi (
inout [15:0] n64_pi_ad 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 // Control signals and input synchronization
logic [1:0] n64_reset_ff;
logic [1:0] n64_nmi_ff;
logic [2:0] n64_pi_alel_ff; logic [2:0] n64_pi_alel_ff;
logic [2:0] n64_pi_aleh_ff; logic [2:0] n64_pi_aleh_ff;
logic [2:0] n64_pi_read_ff; logic [1:0] n64_pi_read_ff;
logic [2:0] n64_pi_write_ff; logic [2:0] n64_pi_write_ff;
always_ff @(posedge sys.clk) begin 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[1:0], n64_pi_aleh}; 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_alel_ff <= {n64_pi_alel_ff[1:0], n64_pi_alel};
n64_pi_read_ff <= {n64_pi_read_ff[1:0], n64_pi_read}; 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}; n64_pi_write_ff <= {n64_pi_write_ff[1:0], n64_pi_write};
end end
logic pi_reset; logic pi_reset;
logic pi_nmi;
logic pi_aleh; logic pi_aleh;
logic pi_alel; logic pi_alel;
logic pi_read; logic pi_read;
logic pi_write; logic pi_write;
always_comb begin always_comb begin
pi_reset = sys.n64_hard_reset; pi_reset = n64_reset_ff[1];
pi_nmi = n64_nmi_ff[1];
pi_aleh = n64_pi_aleh_ff[2]; pi_aleh = n64_pi_aleh_ff[2];
pi_alel = n64_pi_alel_ff[2]; pi_alel = n64_pi_alel_ff[2];
pi_read = n64_pi_read_ff[1]; pi_read = n64_pi_read_ff[1];
@ -99,16 +60,30 @@ module n64_pi (
PI_MODE_VALID = 2'b00 PI_MODE_VALID = 2'b00
} e_pi_mode; } e_pi_mode;
typedef enum bit [1:0] {
PORT_NONE,
PORT_MEM,
PORT_REG
} e_port;
e_pi_mode pi_mode; e_pi_mode pi_mode;
e_pi_mode last_pi_mode;
logic last_read; e_port read_port;
logic last_write; e_port write_port;
always_comb begin always_comb begin
pi_mode = e_pi_mode'({pi_aleh, pi_alel}); pi_mode = e_pi_mode'({pi_aleh, pi_alel});
end 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_pi_mode <= pi_mode;
last_read <= pi_read; last_read <= pi_read;
last_write <= pi_write; last_write <= pi_write;
@ -121,236 +96,339 @@ module n64_pi (
logic end_op; logic end_op;
always_comb begin always_comb begin
aleh_op = !pi_reset && last_pi_mode != PI_MODE_HIGH && pi_mode == PI_MODE_HIGH; n64_scb.n64_reset = !last_reset && pi_reset;
alel_op = !pi_reset && last_pi_mode == PI_MODE_HIGH && pi_mode == PI_MODE_LOW; n64_scb.n64_nmi = !last_nmi && pi_nmi;
read_op = !pi_reset && pi_mode == PI_MODE_VALID && last_read && !pi_read; aleh_op = pi_reset && (last_pi_mode != PI_MODE_HIGH) && (pi_mode == PI_MODE_HIGH);
write_op = !pi_reset && pi_mode == PI_MODE_VALID && last_write && !pi_write; alel_op = pi_reset && (last_pi_mode == PI_MODE_HIGH) && (pi_mode == PI_MODE_LOW);
end_op = !pi_reset && last_pi_mode == PI_MODE_VALID && pi_mode != PI_MODE_VALID; 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 end
// Input and output data sampling // Input and output data sampling
logic [15:0] n64_pi_ad_input; logic n64_pi_ad_oe;
logic [15:0] n64_pi_ad_output; logic [15:0] n64_pi_ad_out;
logic [15:0] n64_pi_ad_output_data; logic [15:0] n64_pi_dq_in;
logic n64_pi_ad_output_enable; logic [15:0] n64_pi_dq_out;
logic n64_pi_ad_output_enable_data;
logic n64_pi_address_valid; assign n64_pi_ad = n64_pi_ad_oe ? n64_pi_ad_out : 16'hZZZZ;
logic pending_operation;
logic pending_write;
always_comb begin always_ff @(posedge clk) begin
n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ; n64_pi_ad_oe <= pi_reset && (pi_mode == PI_MODE_VALID) && !last_read && (read_port != PORT_NONE);
n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !n64_pi_read_ff[2]; n64_pi_ad_out <= n64_pi_dq_out;
end n64_pi_dq_in <= n64_pi_ad;
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
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
if (aleh_op) begin
bus.real_address[31:16] <= n64_pi_ad_input;
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;
end
end end
// Address decoding // Address decoding
const bit [31:0] DDIPL_OFFSET = 32'h0780_0000; const bit [31:0] DDIPL_OFFSET = 32'h03BC_0000;
const bit [31:0] BUFFERS_OFFSET = 32'h07C0_0000; const bit [31:0] SAVE_OFFSET = 32'h03FC_0000;
const bit [31:0] SAVE_OFFSET = 32'h07EE_0000; const bit [31:0] BUFFER_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'h04FC_0000;
sc64::e_n64_id next_id; logic [31:0] mem_offset;
logic [31:0] next_offset;
logic sram_selected;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
if (aleh_op) begin if (reset) begin
n64_pi_address_valid <= 1'b0; read_port <= PORT_NONE;
next_id <= sc64::__ID_N64_END; write_port <= PORT_NONE;
next_offset <= 32'd0; reg_bus.dd_select <= 1'b0;
sram_selected <= 1'b0; reg_bus.flashram_select <= 1'b0;
if (cfg.dd_enabled) begin reg_bus.cfg_select <= 1'b0;
if (n64_pi_ad_input == 16'h0500) begin end else if (aleh_op) begin
n64_pi_address_valid <= 1'b1; read_port <= PORT_NONE;
next_id <= sc64::ID_N64_DD; write_port <= PORT_NONE;
next_offset <= (-32'h0500_0000); 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 (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin if (n64_pi_dq_in >= 16'h0600 && n64_pi_dq_in < 16'h0640) begin
n64_pi_address_valid <= 1'b1; read_port <= PORT_MEM;
next_id <= sc64::ID_N64_SDRAM; write_port <= PORT_NONE;
next_offset <= (-32'h0600_0000) + DDIPL_OFFSET; mem_offset <= (-32'h0600_0000) + DDIPL_OFFSET;
end end
end end
if (cfg.flashram_enabled) begin
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin if (n64_scb.flashram_enabled) begin
n64_pi_address_valid <= 1'b1; if (n64_pi_dq_in >= 16'h0800 && n64_pi_dq_in < 16'h0802) begin
next_id <= sc64::ID_N64_FLASHRAM; read_port <= PORT_REG;
if (cfg.flashram_read_mode) begin write_port <= PORT_REG;
next_offset <= (-32'h0800_0000) + SAVE_OFFSET; mem_offset <= (-32'h0800_0000) + SAVE_OFFSET;
reg_bus.flashram_select <= 1'b1;
if (n64_scb.flashram_read_mode) begin
read_port <= PORT_MEM;
end end
end end
end else if (cfg.sram_enabled) begin end else if (n64_scb.sram_enabled) begin
if (cfg.sram_banked) begin if (n64_scb.sram_banked) begin
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0810) begin if (n64_pi_dq_in >= 16'h0800 && n64_pi_dq_in < 16'h0810) begin
if (n64_pi_ad_input[3:2] != 2'b11 && n64_pi_ad_input[1:0] == 2'b00) begin if (n64_pi_dq_in[3:2] != 2'b11 && n64_pi_dq_in[1:0] == 2'b00) begin
n64_pi_address_valid <= 1'b1; read_port <= PORT_MEM;
next_id <= sc64::ID_N64_SDRAM; write_port <= PORT_MEM;
next_offset <= (-32'h0800_0000) - {n64_pi_ad_input[3:2], 18'd0} + {n64_pi_ad_input[3:2], 15'd0} + SAVE_OFFSET; mem_offset <= (-32'h0800_0000) - {n64_pi_dq_in[3:2], 18'd0} + {n64_pi_dq_in[3:2], 15'd0} + SAVE_OFFSET;
sram_selected <= 1'b1;
end end
end end
end else begin end else begin
if (n64_pi_ad_input == 16'h0800) begin if (n64_pi_dq_in >= 16'h0800 && n64_pi_dq_in < 16'h0802) begin
n64_pi_address_valid <= 1'b1; read_port <= PORT_MEM;
next_id <= sc64::ID_N64_SDRAM; write_port <= PORT_MEM;
next_offset <= (-32'h0800_0000) + SAVE_OFFSET; mem_offset <= (-32'h0800_0000) + SAVE_OFFSET;
sram_selected <= 1'b1;
end end
end end
end end
if (n64_pi_ad_input >= 16'h1000 && n64_pi_ad_input < 16'h1800) begin
n64_pi_address_valid <= 1'b1; if (n64_scb.bootloader_enabled) begin
next_id <= cfg.sdram_switch ? sc64::ID_N64_SDRAM : sc64::ID_N64_BOOTLOADER; if (n64_pi_dq_in >= 16'h1000 && n64_pi_dq_in < 16'h101C) begin
next_offset <= (-32'h1000_0000); read_port <= PORT_MEM;
write_port <= PORT_NONE;
mem_offset <= (-32'h1000_0000) + BOOTLOADER_OFFSET;
end end
if (n64_pi_ad_input >= 16'h1F80 && n64_pi_ad_input < 16'h1FC0) begin end else begin
n64_pi_address_valid <= 1'b1; if (n64_pi_dq_in >= 16'h1000 && n64_pi_dq_in < 16'h1400) begin
next_id <= sc64::ID_N64_SDRAM; read_port <= PORT_MEM;
next_offset <= (-32'h1F80_0000) + BUFFERS_OFFSET; write_port <= n64_scb.rom_write_enabled ? PORT_MEM : PORT_NONE;
mem_offset <= (-32'h1000_0000);
end end
if (n64_pi_ad_input == 16'h1FFF) begin end
n64_pi_address_valid <= 1'b1;
next_id <= sc64::ID_N64_CFG; if (n64_scb.rom_shadow_enabled) begin
if (n64_pi_dq_in >= 16'h13FC && n64_pi_dq_in < 16'h1400) begin
read_port <= PORT_MEM;
write_port <= PORT_NONE;
mem_offset <= (-32'h13FC_0000) + SHADOW_OFFSET;
end
end
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;
end
if (n64_pi_dq_in >= 16'h1FFC && n64_pi_dq_in < 16'h1FFE) begin
read_port <= PORT_MEM;
write_port <= PORT_MEM;
mem_offset <= (-32'h1FFC_0000) + BUFFER_OFFSET;
end
if (n64_pi_dq_in >= 16'h1FFE && n64_pi_dq_in < 16'h2000) begin
read_port <= PORT_REG;
write_port <= PORT_REG;
reg_bus.cfg_select <= 1'b1;
end end
end 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 (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;
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 (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;
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 [31:0] starting_address;
logic load_starting_address;
logic read_enabled;
logic first_write_op;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
read_fifo_flush <= 1'b0;
write_fifo_read <= 1'b0; write_fifo_read <= 1'b0;
load_starting_address <= 1'b0;
if (sys.reset || sys.n64_hard_reset) begin if (reset || !pi_reset) begin
bus.request <= 1'b0; mem_bus.request <= 1'b0;
read_fifo_flush <= 1'b1; read_enabled <= 1'b0;
write_fifo_flush <= 1'b1;
end else begin end else begin
write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected;
if (aleh_op) begin if (aleh_op) begin
starting_address[31:16] <= n64_pi_ad_input; starting_address[31:16] <= n64_pi_dq_in;
end end
if (alel_op) begin if (alel_op) begin
read_fifo_flush <= 1'b1; starting_address <= {starting_address[31:16], n64_pi_dq_in} + mem_offset;
can_read <= 1'b1; load_starting_address <= 1'b1;
read_enabled <= 1'b1;
first_write_op <= 1'b1; first_write_op <= 1'b1;
load_starting_address <= 1'b1;
starting_id <= next_id;
starting_address <= {starting_address[31:16], n64_pi_ad_input[15:1], 1'b0};
end 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
end
if (!bus.request) begin
if (!write_fifo_empty) begin
bus.request <= 1'b1;
bus.write <= 1'b1;
if (load_starting_address) begin if (load_starting_address) begin
bus.id <= starting_id; mem_bus.address <= starting_address;
bus.address <= starting_address + next_offset;
load_starting_address <= 1'b0;
end 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; write_fifo_read <= 1'b1;
end else if (!read_fifo_full && can_read) begin read_enabled <= 1'b0;
bus.request <= 1'b1; if (first_write_op) begin
bus.write <= 1'b0; mem_bus.address <= starting_address;
if (load_starting_address) begin first_write_op <= 1'b0;
bus.id <= (starting_id == sc64::ID_N64_FLASHRAM && cfg.flashram_read_mode) ? sc64::ID_N64_SDRAM : starting_id; end
bus.address <= starting_address + next_offset; end else if ((read_port == PORT_MEM) && !read_fifo_full && read_enabled) begin
load_starting_address <= 1'b0; mem_bus.request <= 1'b1;
mem_bus.write <= 1'b0;
end end
end end
end else if (bus.ack) begin
bus.request <= 1'b0; if (mem_bus.ack) begin
bus.address <= bus.address + 2'd2; mem_bus.request <= 1'b0;
mem_bus.address[16:0] <= mem_bus.address[16:0] + 2'd2;
end end
if (end_op) begin if (end_op) begin
can_read <= 1'b0; read_enabled <= 1'b0;
end end
end 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 endmodule

View File

@ -1,5 +1,6 @@
module n64_pi_fifo ( module n64_pi_fifo (
if_system.sys sys, input clk,
input reset,
input flush, input flush,
@ -18,15 +19,13 @@ module n64_pi_fifo (
logic empty_or_full; logic empty_or_full;
always_comb begin assign rdata = fifo_mem[fifo_rd_ptr[1:0]];
rdata = fifo_mem[fifo_rd_ptr[1:0]]; assign empty_or_full = fifo_wr_ptr[1:0] == fifo_rd_ptr[1:0];
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];
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];
full = empty_or_full && fifo_wr_ptr[2] != fifo_rd_ptr[2];
end
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
if (sys.reset || flush) begin if (reset || flush) begin
fifo_wr_ptr <= 3'd0; fifo_wr_ptr <= 3'd0;
fifo_rd_ptr <= 3'd0; fifo_rd_ptr <= 3'd0;
end else begin end else begin

66
fw/rtl/n64/n64_reg_bus.sv Normal file
View File

@ -0,0 +1,66 @@
interface n64_reg_bus ();
logic dd_select;
logic flashram_select;
logic cfg_select;
logic read;
logic write;
logic [16:0] address;
logic [15:0] rdata;
logic [15:0] wdata;
logic [15:0] dd_rdata;
logic [15:0] flashram_rdata;
logic [15:0] cfg_rdata;
modport controller (
output dd_select,
output flashram_select,
output cfg_select,
output read,
output write,
output address,
input rdata,
output wdata
);
always_comb begin
rdata = 16'd0;
if (dd_select) begin
rdata = dd_rdata;
end
if (flashram_select) begin
rdata = flashram_rdata;
end
if (cfg_select) begin
rdata = cfg_rdata;
end
end
modport dd (
input .read(read && dd_select),
input .write(write && dd_select),
input address,
output .rdata(dd_rdata),
input wdata
);
modport flashram (
input .read(read && flashram_select),
input .write(write && flashram_select),
input address,
output .rdata(flashram_rdata),
input wdata
);
modport cfg (
input .read(read && cfg_select),
input .write(write && cfg_select),
input address,
output .rdata(cfg_rdata),
input wdata
);
endinterface

141
fw/rtl/n64/n64_scb.sv Normal file
View File

@ -0,0 +1,141 @@
interface n64_scb ();
logic n64_reset;
logic n64_nmi;
logic bootloader_enabled;
logic rom_write_enabled;
logic rom_shadow_enabled;
logic sram_enabled;
logic sram_banked;
logic flashram_enabled;
logic flashram_read_mode;
logic dd_enabled;
logic eeprom_enabled;
logic eeprom_16k_mode;
logic flashram_pending;
logic flashram_done;
logic [9:0] flashram_sector;
logic flashram_sector_or_all;
logic flashram_write_or_erase;
logic [5:0] flashram_buffer_address;
logic [15:0] flashram_buffer_rdata;
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 eeprom_write;
logic [10:0] eeprom_address;
logic [7:0] eeprom_rdata;
logic [7:0] eeprom_wdata;
logic rtc_pending;
logic rtc_done;
logic [41:0] rtc_rdata;
logic [41:0] rtc_wdata;
modport controller (
input n64_reset,
input n64_nmi,
output bootloader_enabled,
output rom_write_enabled,
output rom_shadow_enabled,
output sram_enabled,
output sram_banked,
output flashram_enabled,
output dd_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,
output flashram_buffer_address,
input flashram_buffer_rdata,
input cfg_pending,
output cfg_done,
output cfg_error,
output cfg_irq,
input cfg_cmd,
input cfg_rdata,
output cfg_wdata,
output cfg_version,
output eeprom_write,
output eeprom_address,
input eeprom_rdata,
output eeprom_wdata,
input rtc_pending,
output rtc_done,
input rtc_rdata,
output rtc_wdata
);
modport pi (
output n64_reset,
output n64_nmi,
input bootloader_enabled,
input rom_write_enabled,
input rom_shadow_enabled,
input sram_enabled,
input sram_banked,
input flashram_enabled,
input flashram_read_mode,
input dd_enabled
);
// modport dd (
// );
modport flashram (
output flashram_read_mode,
output flashram_pending,
input flashram_done,
output flashram_sector,
output flashram_sector_or_all,
output flashram_write_or_erase,
input flashram_buffer_address,
output flashram_buffer_rdata
);
modport cfg (
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 si (
input eeprom_enabled,
input eeprom_16k_mode,
input eeprom_write,
input eeprom_address,
output eeprom_rdata,
input eeprom_wdata,
output rtc_pending,
input rtc_done,
output rtc_rdata,
input rtc_wdata
);
endinterface

View File

@ -1,90 +0,0 @@
module n64_sdram (
if_system sys,
if_n64_bus bus,
if_memory_dma.memory usb_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 [1:0] {
T_BUS,
T_SDRAM,
T_USB_DMA
} e_source_request;
e_source_request source_request;
always_ff @(posedge sys.clk) begin
if (sys.reset) begin
mem_request <= 1'b0;
end else begin
if (!mem_request && (bus.request || sdram.request || usb_dma.request)) begin
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 (usb_dma.request) begin
mem_write <= usb_dma.write;
mem_address <= usb_dma.address;
mem_wdata <= usb_dma.wdata;
source_request <= T_USB_DMA;
end
end
if (mem_ack) begin
mem_request <= 1'b0;
end
end
end
always_comb begin
bus.ack = source_request == T_BUS && mem_ack;
bus.rdata = bus.ack ? mem_rdata : 16'd0;
sdram.ack = source_request == T_SDRAM && mem_ack;
sdram.rdata = mem_rdata;
usb_dma.ack = source_request == T_USB_DMA && mem_ack;
usb_dma.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

View File

@ -1,165 +1,254 @@
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 ( module n64_si (
if_system.sys sys, input clk,
if_si.si si, input reset,
n64_scb.si n64_scb,
input n64_reset,
input n64_si_clk, input n64_si_clk,
inout n64_si_dq 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; 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}; n64_si_clk_ff <= {n64_si_clk_ff[0], n64_si_clk};
end end
logic si_reset; logic si_reset;
logic si_clk; logic si_clk;
logic si_dq;
always_comb begin always_comb begin
si_reset = sys.n64_hard_reset; si_reset = n64_reset_ff[1];
si_clk = n64_si_clk_ff[1]; si_clk = n64_si_clk_ff[1];
si_dq = n64_si_dq;
end 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; logic last_si_clk;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
last_si_clk <= si_clk; last_si_clk <= si_clk;
end end
logic si_clk_rising_edge;
logic si_clk_falling_edge; logic si_clk_falling_edge;
logic si_clk_rising_edge;
always_comb begin 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;
si_clk_falling_edge = !si_reset && last_si_clk && !si_clk; si_clk_rising_edge = si_reset && !last_si_clk && si_clk;
end end
logic si_dq_output_enable;
logic si_dq_output_enable_data;
always_ff @(posedge sys.clk) begin // Data falling/rising event generator
si_dq_output_enable <= si_dq_output_enable_data;
logic last_si_dq_in;
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 end
always_comb begin always_comb begin
n64_si_dq = si_dq_output_enable ? 1'b0 : 1'bZ; 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 end
// Data register and shifter // RX byte generator
logic [80:0] trx_data; logic [2:0] rx_bit_counter;
logic rx_shift; logic rx_byte_valid;
logic tx_shift; 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 always_comb begin
si.rx_data = trx_data; rx_stop = si_clk_rising_edge && si_dq_in && (rx_sub_bit_counter == 4'd7) && (rx_bit_counter == 3'd1);
end 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 // TX byte/stop generator
trx_data <= {trx_data[79:0], rx_sub_bit_counter < 2'd2};
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
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 // RX path
typedef enum bit [0:0] { typedef enum bit [1:0] {
S_RX_IDLE, RX_STATE_IDLE,
S_RX_WAITING RX_STATE_DATA,
RX_STATE_IGNORE
} e_rx_state; } e_rx_state;
e_rx_state rx_state; e_rx_state rx_state;
logic [3:0] rx_byte_counter;
logic rx_data_valid;
logic [1:0] rx_sub_bit_counter; always_comb begin
logic [3:0] rx_timeout_counter; rx_data_valid = rx_byte_valid && (rx_state == RX_STATE_DATA);
always_ff @(posedge sys.clk) begin
rx_shift <= 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
end end
if (sys.reset || si.rx_reset) begin always_ff @(posedge clk) begin
rx_state <= S_RX_IDLE; tx_start <= 1'b0;
si.rx_ready <= 1'b0;
si.rx_length <= 7'd0; if (rx_byte_valid) begin
end else if (!si.tx_busy) begin rx_byte_counter <= rx_byte_counter + 1'd1;
end
if (reset || rx_timeout) begin
rx_state <= RX_STATE_IDLE;
end else begin
case (rx_state) case (rx_state)
S_RX_IDLE: begin RX_STATE_IDLE: begin
if (si_clk_rising_edge && !si_dq) begin if (rx_byte_valid) begin
rx_state <= S_RX_WAITING; cmd <= e_cmd'(rx_byte_data);
rx_sub_bit_counter <= 2'd0; rx_byte_counter <= 4'd0;
rx_timeout_counter <= 3'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
end end
S_RX_WAITING: begin RX_STATE_DATA: begin
if (si_clk_rising_edge) begin if (rx_stop) begin
if (si_dq) begin tx_start <= 1'b1;
rx_state <= S_RX_IDLE; rx_state <= RX_STATE_IGNORE;
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 end
end end
RX_STATE_IGNORE: begin
if (rx_stop) begin
rx_state <= RX_STATE_IDLE;
end
end end
endcase endcase
end end
@ -168,57 +257,227 @@ module n64_si (
// TX path // TX path
typedef enum bit [0:0] { typedef enum bit [1:0] {
S_TX_IDLE, TX_STATE_IDLE,
S_TX_SENDING TX_STATE_DATA,
TX_STATE_STOP
} e_tx_state; } e_tx_state;
e_tx_state tx_state; e_tx_state tx_state;
logic [2:0] tx_sub_bit_counter; logic [3:0] tx_byte_counter;
logic [6:0] tx_bit_counter; logic [3:0] tx_length;
always_ff @(posedge sys.clk) begin always_ff @(posedge clk) begin
tx_shift <= 1'b0; tx_byte_valid <= 1'b0;
tx_stop <= 1'b0;
if (sys.reset || si.tx_reset) begin if (!tx_busy && tx_byte_valid) begin
tx_state <= S_TX_IDLE; tx_byte_counter <= tx_byte_counter + 1'd1;
si_dq_output_enable_data <= 1'b0; end
si.tx_busy <= 1'b0;
if (reset) begin
tx_state <= TX_STATE_IDLE;
end else begin end else begin
case (tx_state) case (tx_state)
S_TX_IDLE: begin TX_STATE_IDLE: begin
if (si.tx_start) begin if (tx_start) begin
tx_state <= S_TX_SENDING; tx_byte_counter <= 4'd0;
tx_sub_bit_counter <= 3'd0; tx_state <= TX_STATE_DATA;
tx_bit_counter <= si.tx_length;
si.tx_busy <= 1'b1;
end end
end end
S_TX_SENDING: begin TX_STATE_DATA: begin
if (si_clk_falling_edge) begin tx_byte_valid <= 1'b1;
tx_sub_bit_counter <= tx_sub_bit_counter + 1'd1; if (!tx_busy && tx_byte_valid) begin
if (tx_sub_bit_counter == 3'd7) begin if (tx_byte_counter == tx_length) begin
tx_shift <= 1'b1; tx_state <= TX_STATE_STOP;
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
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;
end end
TX_STATE_STOP: begin
tx_stop <= 1'b1;
if (!tx_busy && tx_stop) begin
tx_state <= TX_STATE_IDLE;
end end
end end
endcase endcase
end end
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
logic [7:0] eeprom_memory [0:2047];
logic [7:0] eeprom_data;
always_ff @(posedge clk) begin
eeprom_data <= eeprom_memory[joybus_full_address];
n64_scb.eeprom_rdata <= eeprom_memory[n64_scb.eeprom_address];
if (rx_data_valid && (cmd == CMD_EEPROM_WRITE)) begin
if (rx_byte_counter > 4'd0) begin
eeprom_memory[joybus_full_address] <= rx_byte_data;
end
end
if (n64_scb.eeprom_write) begin
eeprom_memory[n64_scb.eeprom_address] <= n64_scb.eeprom_wdata;
end
end
// RTC controller
logic rtc_backup_wp;
logic rtc_time_wp;
logic 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 <= 1'b0;
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 && (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];
if (!rx_byte_data[2]) 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 = eeprom_data;
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, 2'd0};
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 endmodule

View File

@ -1,97 +0,0 @@
module n64_soc (
if_system sys,
if_config cfg,
if_memory_dma.memory usb_dma,
if_sdram.memory sdram,
if_flashram.flashram flashram,
if_si.si si,
if_flash.flash 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),
.usb_dma(usb_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),
.cfg(cfg),
.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

92
fw/rtl/n64/n64_top.sv Normal file
View File

@ -0,0 +1,92 @@
module n64_top (
input clk,
input reset,
mem_bus.controller mem_bus,
n64_scb n64_scb,
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;
assign n64_irq = (n64_dd_irq || n64_cfg_irq) ? 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)
);
assign n64_dd_irq = 1'b0;
// n64_dd n64_dd_inst (
// .clk(clk),
// .reset(reset),
// .reg_bus(reg_bus),
// .n64_scb(n64_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

46
fw/rtl/sd/sd_clk.sv Normal file
View File

@ -0,0 +1,46 @@
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
clock_divider <= clock_divider + 1'd1;
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

15
fw/rtl/sd/sd_cmd.sv Normal file
View File

@ -0,0 +1,15 @@
module sd_cmd (
input clk,
input reset,
sd_scb.cmd sd_scb,
input sd_clk_rising,
input sd_clk_falling,
inout sd_cmd
);
assign sd_cmd = 1'bZ;
endmodule

28
fw/rtl/sd/sd_crc_7.sv Normal file
View 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

21
fw/rtl/sd/sd_scb.sv Normal file
View File

@ -0,0 +1,21 @@
interface sd_scb ();
logic [1:0] clock_mode;
logic [5:0] index;
modport controller (
output clock_mode,
output index
);
modport clk (
input clock_mode
);
modport cmd (
input index
);
endinterface

43
fw/rtl/sd/sd_top.sv Normal file
View File

@ -0,0 +1,43 @@
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
);
assign sd_dat = 4'hZ;
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)
);
endmodule

View File

@ -1,76 +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 flash_erase_start;
logic flash_erase_busy;
logic flash_wp_enable;
logic flash_wp_disable;
modport pi (
input sdram_switch,
input sdram_writable,
input dd_enabled,
input sram_enabled,
input sram_banked,
input flashram_enabled,
input flashram_read_mode
);
modport flashram (
output flashram_read_mode
);
modport flash (
input flash_erase_start,
output flash_erase_busy,
input flash_wp_enable,
input flash_wp_disable
);
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 flash_erase_start,
input flash_erase_busy,
output flash_wp_enable,
output flash_wp_disable
);
endinterface

View File

@ -1,22 +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;
parameter bit [31:0] SC64_VER = 32'h53437632;
parameter int CLOCK_FREQUENCY = 32'd100_000_000;
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

View File

@ -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

240
fw/rtl/top.sv Normal file
View File

@ -0,0 +1,240 @@
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 ();
usb_scb usb_scb ();
dma_scb usb_dma_scb ();
sd_scb sd_scb ();
dma_scb sd_dma_scb ();
flash_scb flash_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 ();
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),
.usb_scb(usb_scb),
.usb_dma_scb(usb_dma_scb),
.sd_scb(sd_scb),
.sd_dma_scb(sd_dma_scb),
.flash_scb(flash_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),
.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_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)
);
// 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)
);
endmodule

View File

@ -1,27 +1,40 @@
interface usb_scb ();
logic fifo_flush;
logic reset_pending;
logic reset_ack;
logic write_buffer_flush;
modport controller (
output fifo_flush,
input reset_pending,
output reset_ack,
output write_buffer_flush
);
modport usb (
input fifo_flush,
output reset_pending,
input reset_ack,
input write_buffer_flush
);
endinterface
module usb_ft1248 ( module usb_ft1248 (
input clk, input clk,
input reset, input reset,
output usb_clk, usb_scb.usb usb_scb,
output usb_cs,
fifo_bus.fifo fifo_bus,
input usb_pwrsav,
output logic usb_clk,
output logic usb_cs,
input usb_miso, input usb_miso,
inout [7:0] usb_miosi, inout [7:0] usb_miosi
output reset_pending,
input reset_ack,
input write_buffer_flush,
input rx_flush,
output rx_empty,
output rx_almost_empty,
input rx_read,
output [7:0] rx_rdata,
input tx_flush,
output tx_full,
output tx_almost_full,
input tx_write,
input [7:0] tx_wdata
); );
logic rx_full; logic rx_full;
@ -34,39 +47,41 @@ module usb_ft1248 (
logic tx_read; logic tx_read;
logic [7:0] tx_rdata; logic [7:0] tx_rdata;
intel_fifo_8 fifo_8_rx_inst ( fifo_8kb fifo_8kb_rx_inst (
.clock(clk), .clk(clk),
.sclr(reset || rx_flush), .reset(reset || usb_scb.fifo_flush),
.empty(rx_empty), .empty(fifo_bus.rx_empty),
.almost_empty(rx_almost_empty), .almost_empty(fifo_bus.rx_almost_empty),
.rdreq(rx_read), .read(fifo_bus.rx_read),
.q(rx_rdata), .rdata(fifo_bus.rx_rdata),
.full(rx_full), .full(rx_full),
.almost_full(rx_almost_full), .almost_full(rx_almost_full),
.wrreq(rx_write), .write(rx_write),
.data(rx_wdata) .wdata(rx_wdata)
); );
intel_fifo_8 fifo_8_tx_inst ( fifo_8kb fifo_8kb_tx_inst (
.clock(clk), .clk(clk),
.sclr(reset || tx_flush), .reset(reset || usb_scb.fifo_flush),
.empty(tx_empty), .empty(tx_empty),
.almost_empty(tx_almost_empty), .almost_empty(tx_almost_empty),
.rdreq(tx_read), .read(tx_read),
.q(tx_rdata), .rdata(tx_rdata),
.full(tx_full), .full(fifo_bus.tx_full),
.almost_full(tx_almost_full), .almost_full(fifo_bus.tx_almost_full),
.wrreq(tx_write), .write(fifo_bus.tx_write),
.data(tx_wdata) .wdata(fifo_bus.tx_wdata)
); );
logic [1:0] usb_pwrsav_ff;
logic [7:0] usb_miosi_out; logic [7:0] usb_miosi_out;
logic usb_oe; logic usb_oe;
logic ft_pwrsav;
logic ft_clk; logic ft_clk;
logic ft_cs; logic ft_cs;
logic ft_miso; logic ft_miso;
@ -75,6 +90,8 @@ module usb_ft1248 (
logic ft_oe; logic ft_oe;
always_ff @(posedge clk) begin 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_clk <= ft_clk;
usb_cs <= ft_cs; usb_cs <= ft_cs;
ft_miso <= usb_miso; ft_miso <= usb_miso;
@ -83,9 +100,7 @@ module usb_ft1248 (
usb_oe <= ft_oe; usb_oe <= ft_oe;
end end
always_comb begin assign usb_miosi = usb_oe ? usb_miosi_out : 8'hZZ;
usb_miosi = usb_oe ? usb_miosi_out : 8'hZZ;
end
typedef enum bit [2:0] { typedef enum bit [2:0] {
STATE_IDLE, STATE_IDLE,
@ -102,13 +117,14 @@ module usb_ft1248 (
CMD_READ_MODEM_STATUS = 8'h20, CMD_READ_MODEM_STATUS = 8'h20,
CMD_WRITE_MODEM_STATUS = 8'h60, CMD_WRITE_MODEM_STATUS = 8'h60,
CMD_WRITE_BUFFER_FLUSH = 8'h08 CMD_WRITE_BUFFER_FLUSH = 8'h08
} e_command; } e_cmd;
e_state state; e_state state;
e_state next_state; e_state next_state;
e_command cmd; e_cmd cmd;
e_command next_cmd; e_cmd next_cmd;
logic [3:0] phase; logic [3:0] phase;
logic last_tx_failed;
logic reset_reply; logic reset_reply;
logic last_reset_status; logic last_reset_status;
logic [4:0] modem_status_counter; logic [4:0] modem_status_counter;
@ -125,19 +141,20 @@ module usb_ft1248 (
end end
if (reset) begin if (reset) begin
reset_pending <= 1'b0; last_tx_failed <= 1'b0;
usb_scb.reset_pending <= 1'b0;
last_reset_status <= 1'b0; last_reset_status <= 1'b0;
modem_status_counter <= 5'd0; modem_status_counter <= 5'd0;
write_modem_status_pending <= 1'b0; write_modem_status_pending <= 1'b0;
write_buffer_flush_pending <= 1'b0; write_buffer_flush_pending <= 1'b0;
end else begin end else begin
if (reset_ack) begin if (usb_scb.reset_ack) begin
reset_pending <= 1'b0; usb_scb.reset_pending <= 1'b0;
reset_reply <= 1'b1; reset_reply <= 1'b1;
write_modem_status_pending <= 1'b1; write_modem_status_pending <= 1'b1;
end end
if (write_buffer_flush) begin if (usb_scb.write_buffer_flush) begin
write_buffer_flush_pending <= 1'b1; write_buffer_flush_pending <= 1'b1;
end end
@ -145,11 +162,15 @@ module usb_ft1248 (
modem_status_counter <= modem_status_counter + 1'd1; modem_status_counter <= modem_status_counter + 1'd1;
end end
if ((state == STATE_DATA) && (cmd == CMD_WRITE) && phase[3]) begin
last_tx_failed <= ft_miso;
end
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
if (cmd == CMD_READ_MODEM_STATUS) begin if (cmd == CMD_READ_MODEM_STATUS) begin
last_reset_status <= ft_miosi_in[0]; last_reset_status <= ft_miosi_in[0];
if (!last_reset_status && ft_miosi_in[0]) begin if (!last_reset_status && ft_miosi_in[0]) begin
reset_pending <= 1'b1; usb_scb.reset_pending <= 1'b1;
end end
if (last_reset_status && !ft_miosi_in[0]) begin if (last_reset_status && !ft_miosi_in[0]) begin
reset_reply <= 1'b0; reset_reply <= 1'b0;
@ -214,14 +235,24 @@ module usb_ft1248 (
rx_wdata = ft_miosi_in; rx_wdata = ft_miosi_in;
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin 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 if (cmd == CMD_READ) begin
rx_write = 1'b1; rx_write = 1'b1;
end end
if (cmd == CMD_WRITE) begin if (cmd == CMD_WRITE && !tx_empty) begin
tx_read = 1'b1; tx_read = 1'b1;
end end
end end
endcase
end
end end
always_comb begin always_comb begin
@ -233,13 +264,14 @@ module usb_ft1248 (
end else begin end else begin
case (state) case (state)
STATE_IDLE: begin STATE_IDLE: begin
if (ft_pwrsav) begin
if (write_modem_status_pending) begin if (write_modem_status_pending) begin
next_state = STATE_SELECT; next_state = STATE_SELECT;
next_cmd = CMD_WRITE_MODEM_STATUS; next_cmd = CMD_WRITE_MODEM_STATUS;
end else if (&modem_status_counter) begin end else if (&modem_status_counter) begin
next_state = STATE_SELECT; next_state = STATE_SELECT;
next_cmd = CMD_READ_MODEM_STATUS; next_cmd = CMD_READ_MODEM_STATUS;
end else if (!tx_empty) begin end else if (!tx_empty || last_tx_failed) begin
next_state = STATE_SELECT; next_state = STATE_SELECT;
next_cmd = CMD_WRITE; next_cmd = CMD_WRITE;
end else if (write_buffer_flush_pending) begin end else if (write_buffer_flush_pending) begin
@ -250,6 +282,7 @@ module usb_ft1248 (
next_cmd = CMD_READ; next_cmd = CMD_READ;
end end
end end
end
STATE_SELECT: begin STATE_SELECT: begin
if (phase[3]) begin if (phase[3]) begin
@ -282,7 +315,7 @@ module usb_ft1248 (
next_state = STATE_DESELECT; next_state = STATE_DESELECT;
end end
end else if (cmd == CMD_WRITE) begin end else if (cmd == CMD_WRITE) begin
if (tx_almost_empty) begin if (tx_empty) begin
next_state = STATE_DESELECT; next_state = STATE_DESELECT;
end end
end else begin end else begin

View File

@ -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>

View File

@ -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"

View File

@ -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

View File

@ -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>

View File

@ -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"]

View File

@ -1,341 +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):
// altera_mf
// ============================================================
// ************************************************************
// 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: LIB_FILE: altera_mf
// Retrieval info: CBX_MODULE_PREFIX: ON

View File

@ -1,175 +0,0 @@
module vendor_flash (
input clk,
input reset,
input erase_start,
output erase_busy,
input wp_enable,
input wp_disable,
input request,
output ack,
input write,
input [31:0] address,
input [31:0] wdata,
output [31:0] rdata
);
const int FLASH_SECTORS = 3'd4;
typedef enum bit [1:0] {
STATE_START,
STATE_PENDING,
STATE_ERASING
} e_erase_state;
typedef enum bit [0:0] {
CSR_STATUS = 1'b0,
CSR_CONTROL = 1'b1
} e_flash_csr;
typedef enum bit [1:0] {
STATUS_IDLE = 2'b00,
STATUS_BUSY_ERASE = 2'b01,
STATUS_BUSY_WRITE = 2'b10,
STATUS_BUSY_READ = 2'b11
} e_flash_status;
logic csr_read;
logic csr_write;
e_flash_csr csr_address;
logic [31:0] csr_wdata;
logic [31:0] csr_rdata;
logic wp_setting;
logic [2:0] erase_sector;
e_erase_state state;
always_ff @(posedge clk) begin
csr_read <= 1'b0;
csr_write <= 1'b0;
csr_address <= CSR_STATUS;
if (reset) begin
erase_busy <= 1'b0;
wp_setting <= 1'b1;
end else if (!erase_busy) begin
if (erase_start) begin
erase_busy <= 1'b1;
erase_sector <= 3'd1;
state <= STATE_START;
end else if (wp_enable) begin
csr_write <= 1'b1;
csr_address <= CSR_CONTROL;
csr_wdata <= 32'hFFFF_FFFF;
wp_setting <= 1'b1;
end else if (wp_disable) begin
csr_write <= 1'b1;
csr_address <= CSR_CONTROL;
csr_wdata <= 32'hF07F_FFFF;
wp_setting <= 1'b0;
end
end else begin
csr_read <= 1'b1;
case (state)
STATE_START: begin
if (csr_read && (csr_rdata[1:0] == STATUS_IDLE)) begin
csr_read <= 1'b0;
csr_write <= 1'b1;
csr_address <= CSR_CONTROL;
csr_wdata <= {4'hF, {5{wp_setting}}, erase_sector, 20'hFFFFF};
state <= STATE_PENDING;
end
end
STATE_PENDING: begin
if (csr_read && (csr_rdata[1:0] == STATUS_BUSY_ERASE)) begin
state <= STATE_ERASING;
end
end
STATE_ERASING: begin
if (csr_read && (csr_rdata[1:0] == STATUS_IDLE)) begin
if (erase_sector == FLASH_SECTORS) begin
erase_busy <= 1'b0;
end else begin
erase_sector <= erase_sector + 1'd1;
state <= STATE_START;
end
end
end
endcase
end
end
logic data_read;
logic data_write;
logic data_busy;
logic data_ack;
logic [15:0] data_address;
logic [31:0] data_wdata;
logic [31:0] data_rdata;
logic pending;
logic write_ack;
always_ff @(posedge clk) begin
write_ack <= 1'b0;
if (reset) begin
data_read <= 1'b0;
data_write <= 1'b0;
pending <= 1'b0;
end else begin
if (request && !pending && !erase_busy) begin
pending <= 1'b1;
if (write && !wp_setting) begin
data_write <= 1'b1;
end else begin
data_read <= 1'b1;
end
end
if (data_read && !data_busy) begin
data_read <= 1'b0;
end
if (data_write && !data_busy) begin
data_write <= 1'b0;
pending <= 1'b0;
write_ack <= 1'b1;
end
if (data_ack) begin
pending <= 1'b0;
end
end
end
always_comb begin
ack = data_ack || write_ack;
data_address = address[17:2];
end
intel_flash intel_flash_inst (
.clock(clk),
.reset_n(~reset),
.avmm_csr_read(csr_read),
.avmm_csr_write(csr_write),
.avmm_csr_addr(csr_address),
.avmm_csr_writedata(csr_wdata),
.avmm_csr_readdata(csr_rdata),
.avmm_data_read(data_read),
.avmm_data_write(data_write),
.avmm_data_waitrequest(data_busy),
.avmm_data_readdatavalid(data_ack),
.avmm_data_addr(data_address),
.avmm_data_writedata(wdata),
.avmm_data_readdata(rdata),
.avmm_data_burstcount(2'd1)
);
endmodule

View File

@ -1,42 +0,0 @@
module vendor_reconfigure (
input clk,
input reset,
input trigger_reconfiguration
);
logic [1:0] ru_clk;
logic ru_rconfig;
logic ru_regout;
logic pending;
always_ff @(posedge clk) begin
if (reset) begin
ru_clk <= 2'd0;
ru_rconfig <= 1'b0;
pending <= 1'b0;
end else begin
ru_clk <= ru_clk + 1'd1;
if (trigger_reconfiguration) begin
pending <= 1'b1;
end
if (ru_clk == 2'd1) begin
ru_rconfig <= pending;
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

31
fw/rtl/vendor/lcmxo2/fifo_8kb.sv vendored Normal file
View File

@ -0,0 +1,31 @@
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
);
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)
);
endmodule

View 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

View 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
View 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

View File

@ -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
View File

@ -1,7 +0,0 @@
/CAMOutputs
*.b#*
*.l#*
*.s#*
*.pdf
*.zip
eagle.epf

View File

@ -1,7 +0,0 @@
# SummerCart64 Hardware
Schematics and PCB design for SummerCart64 done in Autodesk Eagle software.
## TODO
- Expand documentation

File diff suppressed because it is too large Load Diff

View File

@ -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"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6
hw/pcb/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
**/*-backups
**/*-bak
**/*.gerbers
**/*.kicad_prl
**/*.zip
**/fp-info-cache

62349
hw/pcb/sc64v2.kicad_pcb Normal file

File diff suppressed because it is too large Load Diff

435
hw/pcb/sc64v2.kicad_pro Normal file
View File

@ -0,0 +1,435 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.09999999999999999,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.15,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.127
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.127,
"min_copper_edge_clearance": 0.19999999999999998,
"min_hole_clearance": 0.254,
"min_hole_to_hole": 0.5,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.127,
"min_via_annular_width": 0.13,
"min_via_diameter": 0.6,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.508,
0.762
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
}
],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "sc64v2.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.127,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.127,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"e63e39d7-6ac0-4ffd-8aa3-1841a4541b55",
""
]
],
"text_variables": {}
}

11759
hw/pcb/sc64v2.kicad_sch Normal file

File diff suppressed because it is too large Load Diff

BIN
hw/shell/sc64_shell.f3d Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,13 +4,15 @@ CXX = $(TOOLCHAIN)g++
OBJCOPY = $(TOOLCHAIN)objcopy OBJCOPY = $(TOOLCHAIN)objcopy
OBJDUMP = $(TOOLCHAIN)objdump OBJDUMP = $(TOOLCHAIN)objdump
SIZE = $(TOOLCHAIN)size SIZE = $(TOOLCHAIN)size
PYTHON = python3
FLAGS = -march=vr4300 -mtune=vr4300 $(USER_FLAGS) FLAGS = -march=vr4300 -mtune=vr4300 $(USER_FLAGS)
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -G 0 -MMD -MP
ASFLAGS = -Wa,-I$(N64_INST)/mips64-elf/lib ASFLAGS = -Wa,-I$(N64_INST)/mips64-elf/lib
LDFLAGS = -lc -nostartfiles -Wl,--gc-sections LDFLAGS = -lc -nostartfiles -Wl,--gc-sections
SRC_DIR = src SRC_DIR = src
ASSET_DIR = assets
BUILD_DIR = build BUILD_DIR = build
SRC_FILES = \ SRC_FILES = \
@ -35,11 +37,15 @@ SRC_FILES = \
fatfs/ffsystem.c \ fatfs/ffsystem.c \
fatfs/ffunicode.c fatfs/ffunicode.c
SRCS = $(addprefix $(SRC_DIR)/, $(SRC_FILES)) ASSET_FILES = \
background.png
SRCS = $(SRC_FILES) $(ASSET_FILES)
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS)))) OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS))))
DEPS = $(OBJS:.o=.d) DEPS = $(OBJS:.o=.d)
$(info $(SRCS))
VPATH = $(SRC_DIR) $(SRC_DIR)/fatfs $(info $(OBJS))
VPATH = $(SRC_DIR) $(SRC_DIR)/fatfs $(ASSET_DIR)
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null)) $(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
@ -49,25 +55,29 @@ $(BUILD_DIR)/%.S.o: %.S
$(BUILD_DIR)/%.c.o: %.c $(BUILD_DIR)/%.c.o: %.c
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@ $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/n64boot.elf: $(OBJS) N64.ld $(BUILD_DIR)/%.png.o: %.png
$(CXX) $(FLAGS) $(LDFLAGS) -TN64.ld $(OBJS) -o $@ $(PYTHON) tools/asset_converter.py $< $@
@$(OBJDUMP) -S $@ > $(BUILD_DIR)/n64boot.lst $(OBJCOPY) -I binary -O elf32-bigmips -B mips:4000 $@ $@
$(BUILD_DIR)/n64boot.bin: $(BUILD_DIR)/n64boot.elf $(BUILD_DIR)/bootloader.elf: $(OBJS) N64.ld
$(CXX) $(FLAGS) $(LDFLAGS) -TN64.ld $(OBJS) -o $@
@$(OBJDUMP) -S $@ > $(BUILD_DIR)/bootloader.lst
$(BUILD_DIR)/bootloader.bin: $(BUILD_DIR)/bootloader.elf
@$(OBJCOPY) -O binary $< $@ @$(OBJCOPY) -O binary $< $@
@chksum64 $@ > /dev/null @chksum64 $@ > /dev/null
@truncate --size=64k $@ @truncate --size=1028k $@
$(BUILD_DIR)/n64boot.hex: $(BUILD_DIR)/n64boot.bin $(BUILD_DIR)/bootloader.hex: $(BUILD_DIR)/bootloader.bin
@$(OBJCOPY) -I binary -O ihex $< $@ @$(OBJCOPY) -I binary -O ihex $< $@
print_size: $(BUILD_DIR)/n64boot.elf print_size: $(BUILD_DIR)/bootloader.elf
@echo 'Size of modules:' @echo 'Size of modules:'
@$(SIZE) -B -d -t --common $(OBJS) @$(SIZE) -B -d -t --common $(OBJS)
@echo 'Size of n64boot:' @echo 'Size of bootloader:'
@$(SIZE) -B -d $< @$(SIZE) -B -d $<
all: $(BUILD_DIR)/n64boot.hex print_size all: $(BUILD_DIR)/bootloader.hex print_size
clean: clean:
@rm -rf ./$(BUILD_DIR)/* @rm -rf ./$(BUILD_DIR)/*

View File

@ -1,6 +1,6 @@
MEMORY { MEMORY {
rdram (rwx) : org = 0x803E0000, len = 128k rdram (rwx) : org = 0x80300000, len = 1M
flash (r) : org = 0xB0000000, len = 64k flash (r) : org = 0xB0000000, len = 1028k
} }
ENTRY(entry_handler) ENTRY(entry_handler)
@ -14,7 +14,7 @@ SECTIONS {
KEEP(*(.text.ipl3)); KEEP(*(.text.ipl3));
} > flash } > flash
.text : { .text : SUBALIGN(4) {
*(.text.entry_handler) *(.text.entry_handler)
*(.text .text.* .gnu.linkonce.t.*) *(.text .text.* .gnu.linkonce.t.*)
*(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata .rodata.* .gnu.linkonce.r.*)
@ -26,11 +26,13 @@ SECTIONS {
} > rdram AT > flash } > rdram AT > flash
.bss : { .bss : {
_sbss = .;
*(.sbss .sbss.* .gnu.linkonce.sb.*) *(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon .scommon.*) *(.scommon .scommon.*)
*(.bss .bss.* .gnu.linkonce.b.*) *(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON) *(COMMON)
. = ALIGN(8); . = ALIGN(8);
_ebss = .;
} > rdram } > rdram
_sheap = .; _sheap = .;

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Some files were not shown because too many files have changed in this diff Show More