mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
[SC64][FW][SW] Complete fw/sw rewrite with RISC-V softcore CPU as flashcart controller (#5)
This commit is contained in:
parent
200f164363
commit
45fbd53001
40
.github/workflows/docker.yml
vendored
Normal file
40
.github/workflows/docker.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Build docker
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: sc64env
|
||||
|
||||
jobs:
|
||||
build-and-push-image:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
11
.github/workflows/main.yml
vendored
11
.github/workflows/main.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Build
|
||||
name: Build fw/hw/sw
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -18,19 +18,14 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install avra
|
||||
|
||||
- name: Build script
|
||||
run: ./build_release.sh
|
||||
run: ./build.sh
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: SummerCart64
|
||||
path: packages/SummerCart64.zip
|
||||
path: SummerCart64.zip
|
||||
|
||||
- name: Get release
|
||||
if: github.event_name == 'release' && github.event.action == 'created'
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,2 @@
|
||||
/packages
|
||||
**/.vscode
|
||||
/sw/test
|
||||
*.zip
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,3 +1,7 @@
|
||||
[submodule "fw/cpu/picorv32"]
|
||||
path = fw/cpu/picorv32
|
||||
url = https://github.com/cliffordwolf/picorv32.git
|
||||
ignore = dirty
|
||||
[submodule "sw/cic"]
|
||||
path = sw/cic
|
||||
url = https://github.com/ManCloud/UltraCIC-III.git
|
||||
|
25
.travis.yml
25
.travis.yml
@ -1,25 +0,0 @@
|
||||
os: linux
|
||||
dist: focal
|
||||
arch: amd64
|
||||
|
||||
language: shell
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y avra
|
||||
|
||||
script:
|
||||
./build_release.sh "${TRAVIS_TAG}"
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token:
|
||||
secure: LNBOWTFd5wz3sR7ec4OA/wbVjIWFCv2WJnx6QBIOhgh2VIicNd91ZgMxq77T7/DBxPJ7GhAuG76s4K68ve8m5+klhpjtxVwstDzHBaNbRIUbhxjKh8oJGX8T+qeB60cnjz1YwmGASWSXNpXPhW/SZRw1lAjpv3W2cxTmDyAzayV+xO7HeVfOAgaKOAL600LwjEdWGLFVRx2MQqMe2NAJ4XWu8oJBXjrlQc/5jHW/3o4oFILs+Jr7VwRt3qYrU0xJ8XPJFDo7AWvAHYH4vrACIOXMPIuI29tsi9eWcT/+q96IKmpDPRvn3nrMnb7bMN995WyW2tFvGqABsFRwUXJ6Ydc7aFdTAC2+u/cWpR4AEpLGNWFqpDlLwjNfqiZ1rhDDAlEI/bA+zU/qyziT5lDaARFJtRxuQIWeZRa7EgmaTc0izghrzIBC807+G1cUTGntSjgVb8B6rtJa6tBt3/9Iu4RmRxJnKkgWQBNo8CEVVDAe/Ms7igashEoaidr545eR/9ervxGLftFUctKWjnsEL4r7ifjUOj9h/E7BZx61WkJ8hORoMValcc+Kv0aCmkzWKe0UsSsuMzsXHc3x782AO2Xq5fZLk0urdqQ/uzu5crSnReJh/lCZxjg11BG31r5kAixBaSkiJFFrAs+GOSR/IskRn8gKThjZtna8DUnHApE=
|
||||
file: packages/SummerCart64-${TRAVIS_TAG}.zip
|
||||
on:
|
||||
repo: Polprzewodnikowy/SummerCollection
|
||||
tags: true
|
||||
skip_cleanup: true
|
@ -55,8 +55,7 @@ Instructions below are mostly written for Windows users and point to Windows spe
|
||||
|
||||
There are several issues with the project at the moment in order of importance. Keep in mind that core flashcart functionality is fully working:
|
||||
|
||||
- No FlashRAM save emulation implementation.
|
||||
- No save write-back to SD card implementation.
|
||||
- No save write-back to SD card without console reset implementation.
|
||||
- No RTC implementation.
|
||||
|
||||
|
||||
|
3
build.sh
Executable file
3
build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker run --mount type=bind,src="$(pwd)",target="/workdir" polprzewodnikowy/sc64env:0.9 /bin/bash ./docker/build.sh
|
@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PACKAGES_FOLDER_NAME="packages"
|
||||
PACKAGE_FILE_NAME="SummerCart64_PCB"
|
||||
FILES=(
|
||||
"./hw/v1/CAMOutputs"
|
||||
# Manually created files
|
||||
"./hw/v1/SummerCart64_sch.pdf"
|
||||
"./hw/v1/SummerCart64_brd_top.pdf"
|
||||
"./hw/v1/SummerCart64_brd_bot.pdf"
|
||||
"./hw/v1/SummerCart64_brd_place_top.pdf"
|
||||
)
|
||||
|
||||
|
||||
# Add version to zip file name if provided
|
||||
if [[ $1 ]]; then
|
||||
PACKAGE_FILE_NAME="${PACKAGE_FILE_NAME}-${1}"
|
||||
fi
|
||||
|
||||
|
||||
# Generate Gerbers
|
||||
pushd hw/v1
|
||||
if [[ -e CAMOutputs ]]; then
|
||||
rm -rf CAMOutputs
|
||||
fi
|
||||
echo "Generating Gerbers"
|
||||
eaglecon.exe -X -dCAMJOB -jSummerCart64.cam SummerCart64.brd
|
||||
popd
|
||||
|
||||
|
||||
# Create packages directory
|
||||
echo "Creating ${PACKAGES_FOLDER_NAME} directory"
|
||||
mkdir -p "${PACKAGES_FOLDER_NAME}"
|
||||
|
||||
|
||||
# ZIP files for release
|
||||
echo "Zipping PCB files"
|
||||
if [[ -e "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ]]; then
|
||||
rm -f "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip"
|
||||
fi
|
||||
zip -r "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
|
@ -1,48 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PACKAGES_FOLDER_NAME="packages"
|
||||
PACKAGE_FILE_NAME="SummerCart64"
|
||||
FILES=(
|
||||
"./fw/output_files/SummerCart64.pof"
|
||||
"./hw/v1/ftdi-template.xml"
|
||||
"./sw/cic/UltraCIC-III.hex"
|
||||
"./sw/cic/UltraCIC-III.eep.hex"
|
||||
)
|
||||
|
||||
|
||||
# Add version to zip file name if provided
|
||||
if [[ $1 ]]; then
|
||||
PACKAGE_FILE_NAME="${PACKAGE_FILE_NAME}-${1}"
|
||||
fi
|
||||
|
||||
|
||||
# Build bootloader
|
||||
echo "Building bootloader"
|
||||
pushd sw/bootloader
|
||||
./build.sh
|
||||
popd
|
||||
|
||||
|
||||
# Build UltraCIC-III
|
||||
pushd sw/cic
|
||||
echo "Building UltraCIC-III"
|
||||
avra UltraCIC-III.asm -D attiny45
|
||||
popd
|
||||
|
||||
|
||||
# Build FPGA firmware
|
||||
echo "Building FPGA firmware"
|
||||
docker run -t --mount type=bind,src="$(pwd)",target="/build" chriz2600/quartus-lite:20.1.0 /usr/local/bin/quartus_wrapper quartus_sh --flow compile /build/fw/SummerCart64.qpf
|
||||
|
||||
|
||||
# Create packages directory
|
||||
echo "Creating ${PACKAGES_FOLDER_NAME} directory"
|
||||
mkdir -p "${PACKAGES_FOLDER_NAME}"
|
||||
|
||||
|
||||
# ZIP files for release
|
||||
echo "Zipping files"
|
||||
if [[ -e "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ]]; then
|
||||
rm -f "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip"
|
||||
fi
|
||||
zip -r "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
|
93
docker/Dockerfile
Normal file
93
docker/Dockerfile
Normal file
@ -0,0 +1,93 @@
|
||||
FROM ubuntu:18.04 AS base
|
||||
|
||||
|
||||
FROM base AS build_base
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
WORKDIR /tmp/scratchpad
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get install -y \
|
||||
autoconf \
|
||||
automake \
|
||||
autotools-dev \
|
||||
bc \
|
||||
bison \
|
||||
build-essential \
|
||||
bzip2 \
|
||||
curl \
|
||||
expect \
|
||||
file \
|
||||
flex \
|
||||
g++ \
|
||||
gawk \
|
||||
gcc \
|
||||
gcc-multilib \
|
||||
git \
|
||||
gperf \
|
||||
libexpat-dev \
|
||||
libgmp-dev \
|
||||
libmpc-dev \
|
||||
libmpfr-dev \
|
||||
libpng-dev \
|
||||
libtool \
|
||||
make \
|
||||
patchutils \
|
||||
python3 \
|
||||
texinfo \
|
||||
texinfo \
|
||||
wget \
|
||||
zlib1g-dev
|
||||
|
||||
|
||||
FROM build_base AS build_riscv
|
||||
RUN git clone --branch 2021.09.21 https://github.com/riscv/riscv-gnu-toolchain && \
|
||||
pushd ./riscv-gnu-toolchain && \
|
||||
./configure --prefix=/opt/riscv --with-arch=rv32i --with-abi=ilp32 && \
|
||||
make -j$(nproc) && \
|
||||
popd && \
|
||||
rm -rf ./riscv-gnu-toolchain
|
||||
|
||||
|
||||
FROM build_base AS build_n64
|
||||
ENV N64_INST=/opt/n64
|
||||
ENV FORCE_DEFAULT_GCC=true
|
||||
RUN git clone https://github.com/DragonMinded/libdragon && \
|
||||
pushd ./libdragon && \
|
||||
git checkout fc4b6708df7439b9386bb6631e24d8909d78d6ae && \
|
||||
pushd ./tools && \
|
||||
./build-toolchain.sh && \
|
||||
popd && \
|
||||
make install && \
|
||||
make tools-install && \
|
||||
popd && \
|
||||
rm -rf ./libdragon
|
||||
|
||||
|
||||
FROM build_base AS build_quartus
|
||||
ADD setup_quartus.sh .
|
||||
RUN mkdir -p ./quartus && \
|
||||
pushd ./quartus && \
|
||||
wget -q http://download.altera.com/akdlm/software/acdsinst/20.1std.1/720/ib_tar/Quartus-lite-20.1.1.720-linux.tar && \
|
||||
tar xvf Quartus-lite-20.1.1.720-linux.tar && \
|
||||
popd && \
|
||||
./setup_quartus.sh 20.1 && \
|
||||
rm -rf ./quartus setup_quartus.sh
|
||||
|
||||
|
||||
FROM base AS release
|
||||
WORKDIR /workdir
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
ENV LC_ALL="en_US.UTF-8"
|
||||
ENV N64_INST="/usr/local"
|
||||
ENV PATH="${PATH}:/opt/intelFPGA_lite/20.1/quartus/bin"
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get install -y avra make python3 libglib2.0-0 libtcmalloc-minimal4 libmpc3 locales zip && \
|
||||
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
|
||||
locale-gen en_US.UTF-8 && \
|
||||
/usr/sbin/update-locale LANG=en_US.UTF-8
|
||||
COPY --from=build_riscv /opt/riscv /usr/local
|
||||
COPY --from=build_n64 /opt/n64 /usr/local
|
||||
COPY --from=build_quartus /opt/intelFPGA_lite /opt/intelFPGA_lite
|
||||
ENV LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc_minimal.so.4"
|
42
docker/build.sh
Executable file
42
docker/build.sh
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
PACKAGE_FILE_NAME="SummerCart64"
|
||||
FILES=(
|
||||
"./fw/output_files/SummerCart64.pof"
|
||||
"./hw/v1/ftdi-template.xml"
|
||||
"./sw/cic/UltraCIC-III.hex"
|
||||
"./sw/riscv/build/controller.rom"
|
||||
"./LICENSE"
|
||||
)
|
||||
|
||||
|
||||
pushd sw/cic
|
||||
echo "Building UltraCIC-III software"
|
||||
avra UltraCIC-III.asm -D attiny45
|
||||
popd
|
||||
|
||||
|
||||
pushd sw/n64
|
||||
echo "Building N64 bootloader software"
|
||||
make clean all
|
||||
popd
|
||||
|
||||
|
||||
pushd sw/riscv
|
||||
echo "Building RISC-V controller software"
|
||||
make clean all
|
||||
popd
|
||||
|
||||
|
||||
pushd fw
|
||||
echo "Building FPGA firmware"
|
||||
quartus_sh --flow compile SummerCart64.qpf
|
||||
popd
|
||||
|
||||
|
||||
echo "Zipping files"
|
||||
if [[ -e "./${PACKAGE_FILE_NAME}.zip" ]]; then
|
||||
rm -f "./${PACKAGE_FILE_NAME}.zip"
|
||||
fi
|
||||
zip -r "./${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
|
25
docker/setup_quartus.sh
Executable file
25
docker/setup_quartus.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout -1
|
||||
|
||||
set version [lindex $argv 0]
|
||||
|
||||
spawn ./quartus/setup.sh
|
||||
|
||||
expect {
|
||||
"Press \\\[Enter\\\] to continue:" { send "\r"; exp_continue }
|
||||
"Do you accept this license? \\\[y/n\\\]" { send "y\r"; exp_continue }
|
||||
"Installation directory \\\[/root/intelFPGA_lite/$version\\\]:" { send "/opt/intelFPGA_lite/$version\r"; exp_continue }
|
||||
"Quartus Prime Lite Edition (Free) \\\[Y/n\\\] :" { send "y\r"; exp_continue }
|
||||
"Quartus Prime Lite Edition (Free) - Quartus Prime Help" { send "n\r"; exp_continue }
|
||||
"Quartus Prime Lite Edition (Free) - Devices \\\[Y/n\\\] " { send "y\r"; exp_continue }
|
||||
"Quartus Prime Lite Edition (Free) - Devices - MAX 10 FPGA" { send "y\r"; exp_continue }
|
||||
"Quartus Prime Lite Edition (Free) - Devices - " { send "n\r"; exp_continue }
|
||||
"ModelSim - Intel FPGA Starter Edition (Free)" { send "n\r"; exp_continue }
|
||||
"ModelSim - Intel FPGA Edition" { send "n\r"; exp_continue }
|
||||
"Is the selection above correct? \\\[Y/n\\\]:" { send "y\r"; exp_continue }
|
||||
"Create shortcuts on Desktop \\\[Y/n\\\]:" { send "n\r"; exp_continue }
|
||||
"Launch Quartus Prime Lite Edition \\\[Y/n\\\]:" { send "n\r"; exp_continue }
|
||||
"Provide your feedback at" { send "n\r"; exp_continue }
|
||||
eof { }
|
||||
}
|
3
fw/.gitignore
vendored
3
fw/.gitignore
vendored
@ -7,3 +7,6 @@
|
||||
*.rpt
|
||||
*.txt
|
||||
*.sopcinfo
|
||||
**/*.elf
|
||||
**/*.bin
|
||||
**/*.dat
|
||||
|
98
fw/README.md
98
fw/README.md
@ -1,98 +0,0 @@
|
||||
# SummerCart64 Firmware
|
||||
|
||||
A FPGA firmware written in Verilog for SummerCart64.
|
||||
|
||||
|
||||
# Technical Reference Manual
|
||||
|
||||
|
||||
## Bus peripheral addresses
|
||||
|
||||
- **`0x1000 0000 - 0x13FF FFFF`** - [R/W] *SDRAM Memory*
|
||||
- **`0x1D00 0000 - 0x1D00 07FF`** - [R/W] *EEPROM Memory*
|
||||
- **`0x1E00 0000 - 0x1E00 0007`** - [R/W] *Cart Registers*
|
||||
|
||||
|
||||
## Memory spaces
|
||||
|
||||
### SDRAM Memory
|
||||
|
||||
Base address: **`0x1000 0000`**\
|
||||
Length: **`64 MB`**\
|
||||
Access: Read or Write, 2 byte (16 bit) aligned
|
||||
|
||||
64 MB of SDRAM memory. Available on the bus when **SDRAM** bit in **CART->CR** register is set. Used as ROM storage.
|
||||
|
||||
### EEPROM Memory
|
||||
|
||||
Base address: **`0x1D00 0000`**\
|
||||
Length: **`2 kB`**\
|
||||
Access: Read or Write, 4 byte (32 bit) aligned
|
||||
|
||||
2 kB of EEPROM Memory. Available on the bus when **EEPROM_PI** bit in **CART->CR** register is set. Used to upload/download EEPROM contents to/from PC.
|
||||
|
||||
|
||||
## Registers
|
||||
|
||||
### Cart (**CART**) registers
|
||||
|
||||
Base address: **`0x1E00 0000`**
|
||||
|
||||
#### Configuration register (**CR**)
|
||||
|
||||
Address offset: **`0x00`**\
|
||||
Powerup value: **`0b0000 0000`**\
|
||||
Soft reset value: **`0b00xx x000`**\
|
||||
Access: Read or write, 4 byte (32 bit) aligned
|
||||
|
||||
This register is used to enable or disable various modules available on the cart.
|
||||
|
||||
31:5 | 4 | 3 | 2 | 1 | 0
|
||||
------|------------|-----------|---|----------|---
|
||||
0 | EEPROM_16K | EEPROM_EN | 0 | SDRAM_EN | 0
|
||||
x | R/W | R/W | x | R/W | x
|
||||
|
||||
- Bits 31:5: Reserved. Reads as 0, writes are ignored but it's recommended to be set as 0 for future compatibility.
|
||||
- Bit 4 **EEPROM_16K**: Sets ID returned by EEPROM to identify itself as 4k or 16k variant.
|
||||
- 0: EEPROM 4k variant
|
||||
- 1: EEPROM 16k variant
|
||||
- Bit 3 **EEPROM_EN**: Enable EEPROM access through SI bus.
|
||||
- 0: EEPROM SI access disabled
|
||||
- 1: EEPROM SI access enabled
|
||||
- Bit 2: Reserved. Reads as 0, writes are ignored but it's recommended to be set as 0 for future compatibility.
|
||||
- Bit 1 **SDRAM_EN**: Enable SDRAM access at address base **`0x1000 0000`**. When disabled bootloader flash image is mapped at this address. Cleared by hardware on N64 Reset/NMI event.
|
||||
- 0: SDRAM disabled
|
||||
- 1: SDRAM enabled
|
||||
- Bit 0: Reserved. Reads as 0, writes are ignored but it's recommended to be set as 0 for future compatibility.
|
||||
- 0: Flash disabled
|
||||
- 1: Flash enabled
|
||||
|
||||
#### CIC and TV type override register (**CIC_TV**)
|
||||
|
||||
Address offset: **`0x04`**\
|
||||
Powerup value: **`0x0000 0000`**\
|
||||
Access: Read or write, 4 byte (32 bit) aligned
|
||||
|
||||
This register is used for PC -> bootloader communication.
|
||||
|
||||
31:6 | 5:4 | 3:0
|
||||
--------|---------|----------
|
||||
SWITCH | TV_TYPE | CIC_TYPE
|
||||
R/W | R/W | R/W
|
||||
|
||||
- Bits 31:6 **SWITCH**: Additional bits that can be passed to bootloader, currently unused.
|
||||
- Bits 5:4 **TV_TYPE**: Overrides TV type in bootloader. Used only when **CIC_TYPE** value is valid (values 1 - 7).
|
||||
- 0: PAL TV type
|
||||
- 1: NTSC TV type
|
||||
- 2: MPAL TV type
|
||||
- 3: No TV type override - use TV type provided by ROM header
|
||||
- Bits 3:0 **CIC_TYPE**: Overrides CIC type in bootloader.
|
||||
- 0: No CIC type override - use CIC type determined from ROM bootcode
|
||||
- 1: CIC 5101
|
||||
- 2: CIC 6101/7102
|
||||
- 3: CIC 6102/7101
|
||||
- 4: CIC X103
|
||||
- 5: CIC X105
|
||||
- 6: CIC X106
|
||||
- 7: CIC 8303
|
||||
- 8 - 15: Same effect as value 0
|
@ -18,13 +18,13 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 20.1.0 Build 711 06/05/2020 SJ Lite Edition
|
||||
# Date created = 23:45:19 July 29, 2020
|
||||
# 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 = "23:45:19 July 29, 2020"
|
||||
DATE = "10:53:32 August 01, 2021"
|
||||
|
||||
# Revisions
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
# Date created = 00:00:00 November 06, 2020
|
||||
# Date created = 21:23:28 September 18, 2021
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
@ -40,55 +40,65 @@
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.0
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:45:19 JULY 29, 2020"
|
||||
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 "20.1.1 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 SMART_RECOMPILE OFF
|
||||
set_global_assignment -name NUM_PARALLEL_PROCESSORS 16
|
||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_usb.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/gpio/gpio_ddro.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/pll/pll.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/ram/ram_n64_eeprom.qip
|
||||
set_global_assignment -name QSYS_FILE rtl/intel/flash/onchip_flash.qsys
|
||||
set_global_assignment -name SDC_FILE constraints.sdc
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/signal_tap_logic_analyzer.stp
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/intel/gpio/gpio_ddro/altera_gpio_lite.sv -library gpio_ddro
|
||||
set_global_assignment -name VERILOG_FILE rtl/cart/cart_control.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/cart/cart_led.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/glue/device_arbiter.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/memory/memory_embedded_flash.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/memory/memory_sdram.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/n64/n64_bank_decoder.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/n64/n64_pi.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/n64/n64_si.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_clk.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_cmd.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_crc_16.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_crc_7.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_dat.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_dma.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_fifo.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_interface.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sd/sd_regs.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/top.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/usb/usb_ftdi_fsi.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/usb/usb_pc.v
|
||||
set_global_assignment -name VERILOG_INCLUDE_FILE rtl/constants.vh
|
||||
set_global_assignment -name SLD_FILE db/signal_tap_logic_analyzer_auto_stripped.stp
|
||||
set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys
|
||||
set_global_assignment -name QSYS_FILE rtl/intel/snp/intel_snp.qsys
|
||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/intel_fifo_8.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip
|
||||
set_global_assignment -name SDC_FILE SummerCart64.sdc
|
||||
set_global_assignment -name SIGNALTAP_FILE stp.stp
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE cpu/picorv32/picorv32.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../sw/riscv/build/cpu_bootloader.sv
|
||||
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_dma.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_flashram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_sdram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_si.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_wrapper.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_flash.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 SIGNALTAP_FILE output_files/signaltap.stp
|
||||
set_global_assignment -name SLD_FILE db/signaltap_auto_stripped.stp
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_location_assignment PIN_6 -to io_pmod[3]
|
||||
set_location_assignment PIN_7 -to io_pmod[4]
|
||||
set_location_assignment PIN_8 -to io_pmod[5]
|
||||
set_location_assignment PIN_10 -to io_pmod[6]
|
||||
set_location_assignment PIN_11 -to io_pmod[7]
|
||||
set_location_assignment PIN_12 -to o_ftdi_si
|
||||
set_location_assignment PIN_13 -to o_ftdi_clk
|
||||
set_location_assignment PIN_14 -to i_ftdi_so
|
||||
set_location_assignment PIN_15 -to i_ftdi_cts
|
||||
set_location_assignment PIN_6 -to o_usb_clk
|
||||
set_location_assignment PIN_7 -to io_usb_miosi[2]
|
||||
set_location_assignment PIN_8 -to io_usb_miosi[3]
|
||||
set_location_assignment PIN_10 -to io_usb_miosi[0]
|
||||
set_location_assignment PIN_11 -to io_usb_miosi[1]
|
||||
set_location_assignment PIN_12 -to i_uart_rxd
|
||||
set_location_assignment PIN_13 -to o_uart_txd
|
||||
set_location_assignment PIN_14 -to i_uart_cts
|
||||
set_location_assignment PIN_15 -to o_uart_rts
|
||||
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
|
||||
@ -97,6 +107,8 @@ 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_29 -to io_n64_cic_clk
|
||||
set_location_assignment PIN_30 -to io_n64_cic_dq
|
||||
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]
|
||||
@ -159,26 +171,27 @@ 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_121 -to io_sram_dq[0]
|
||||
set_location_assignment PIN_122 -to o_sram_clk
|
||||
set_location_assignment PIN_123 -to io_sram_dq[3]
|
||||
set_location_assignment PIN_124 -to o_sram_cs
|
||||
set_location_assignment PIN_126 -to io_sram_dq[1]
|
||||
set_location_assignment PIN_127 -to io_sram_dq[2]
|
||||
set_location_assignment PIN_138 -to io_pmod[0]
|
||||
set_location_assignment PIN_140 -to io_pmod[1]
|
||||
set_location_assignment PIN_141 -to io_pmod[2]
|
||||
set_location_assignment PIN_123 -to o_n64_irq
|
||||
set_location_assignment PIN_127 -to io_avr_mosi
|
||||
set_location_assignment PIN_130 -to io_flash_dq[0]
|
||||
set_location_assignment PIN_131 -to o_flash_clk
|
||||
set_location_assignment PIN_132 -to io_flash_dq[3]
|
||||
set_location_assignment PIN_134 -to o_flash_cs
|
||||
set_location_assignment PIN_135 -to io_flash_dq[1]
|
||||
set_location_assignment PIN_136 -to io_flash_dq[2]
|
||||
set_location_assignment PIN_138 -to i_usb_pwren
|
||||
set_location_assignment PIN_140 -to o_usb_cs
|
||||
set_location_assignment PIN_141 -to i_usb_miso
|
||||
|
||||
# Classic Timing Assignments
|
||||
# ==========================
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_REPORT_TIMING ON
|
||||
|
||||
# Compiler Assignments
|
||||
# ====================
|
||||
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
||||
set_global_assignment -name OPTIMIZATION_MODE BALANCED
|
||||
|
||||
# Analysis & Synthesis Assignments
|
||||
# ================================
|
||||
@ -186,9 +199,12 @@ 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 top
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY SummerCart64
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
@ -196,13 +212,9 @@ 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"
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS INPUT TRI-STATED WITH WEAK PULL-UP"
|
||||
set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE "SINGLE COMP IMAGE"
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING OFF
|
||||
set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON
|
||||
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
|
||||
|
||||
# Assembler Assignments
|
||||
# =====================
|
||||
@ -210,14 +222,10 @@ 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
|
||||
|
||||
# Programmer Assignments
|
||||
# ======================
|
||||
set_global_assignment -name GENERATE_SVF_FILE ON
|
||||
|
||||
# Signal Tap Assignments
|
||||
# ======================
|
||||
set_global_assignment -name ENABLE_SIGNALTAP ON
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/signal_tap_logic_analyzer.stp
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/signaltap.stp
|
||||
|
||||
# Power Estimation Assignments
|
||||
# ============================
|
||||
@ -232,40 +240,62 @@ 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(altera_gpio_lite)
|
||||
# --------------------------
|
||||
# start ENTITY(SummerCart64)
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
|
||||
# end ENTITY(altera_gpio_lite)
|
||||
# ----------------------------
|
||||
|
||||
# -----------------------
|
||||
# start ENTITY(gpio_ddro)
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
|
||||
# end ENTITY(gpio_ddro)
|
||||
# ---------------------
|
||||
|
||||
# -----------------
|
||||
# start ENTITY(top)
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_rxd
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_uart_cts
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_rtc_sda
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_si_dq
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_nmi
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_reset
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_si_clk
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_n64_pi_ad[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_aleh
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_read
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_write
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_n64_pi_alel
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sdram_dq[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to io_sd_*
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_pwren
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to i_usb_miso
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_clk
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_txd
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_uart_rts
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_rtc_scl
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_rtc_sda
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_n64_pi_ad[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sdram_*
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sdram_dq[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_sd_clk
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to io_sd_*
|
||||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to o_usb_cs
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_n64_pi_ad[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sdram_dq[*]
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_sd_*
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to io_rtc_sda
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_usb_miosi[*]
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel
|
||||
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_uart_rxd
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_uart_cts
|
||||
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 io_n64_si_dq
|
||||
set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to i_clk
|
||||
set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to "pll:sys_pll|altpll:altpll_component|pll_altpll:auto_generated|wire_pll1_clk[0]"
|
||||
set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to "pll:sys_pll|altpll:altpll_component|pll_altpll:auto_generated|wire_pll1_clk[1]"
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_write
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_n64_irq
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_pwren
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_usb_miso
|
||||
|
||||
# start DESIGN_PARTITION(Top)
|
||||
# ---------------------------
|
||||
@ -280,5 +310,23 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(top)
|
||||
# ---------------
|
||||
# end ENTITY(SummerCart64)
|
||||
# ------------------------
|
||||
|
||||
# ------------------------------
|
||||
# start ENTITY(altera_gpio_lite)
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
|
||||
# end ENTITY(altera_gpio_lite)
|
||||
# ----------------------------
|
||||
|
||||
# -----------------------------
|
||||
# start ENTITY(intel_gpio_ddro)
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
|
||||
# end ENTITY(intel_gpio_ddro)
|
||||
# ---------------------------
|
87
fw/SummerCart64.sdc
Normal file
87
fw/SummerCart64.sdc
Normal file
@ -0,0 +1,87 @@
|
||||
# Clocks
|
||||
|
||||
derive_pll_clocks -create_base_clocks
|
||||
|
||||
set sys_clk {system_inst|intel_pll_inst|altpll_component|auto_generated|pll1|clk[0]}
|
||||
set sdram_pll_clk {system_inst|intel_pll_inst|altpll_component|auto_generated|pll1|clk[1]}
|
||||
# set sd_reg_clk {sd_interface_inst|sd_clk_inst|o_sd_clk|q}
|
||||
|
||||
create_generated_clock -name sdram_clk -source [get_pins $sdram_pll_clk] [get_ports {o_sdram_clk}]
|
||||
# create_generated_clock -name sd_reg_clk -source [get_pins {sd_interface_inst|sd_clk_inst|o_sd_clk|clk}] -divide_by 2 [get_pins $sd_reg_clk]
|
||||
# create_generated_clock -name sd_clk -source [get_pins $sd_reg_clk] [get_ports {o_sd_clk}]
|
||||
|
||||
create_generated_clock -name flash_se_neg_reg \
|
||||
-source [get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|clk}] \
|
||||
-divide_by 2 \
|
||||
[get_pins -compatibility_mode {*altera_onchip_flash:*onchip_flash_0|altera_onchip_flash_avmm_data_controller:avmm_data_controller|flash_se_neg_reg|q}]
|
||||
|
||||
derive_clock_uncertainty
|
||||
|
||||
|
||||
# SDRAM timings
|
||||
|
||||
set sdram_outputs {o_sdram_cs o_sdram_ras o_sdram_cas o_sdram_we o_sdram_a[*] o_sdram_ba[*] io_sdram_dq[*]}
|
||||
set sdram_inputs {io_sdram_dq[*]}
|
||||
|
||||
set_output_delay -clock [get_clocks {sdram_clk}] -max 1.5 [get_ports $sdram_outputs]
|
||||
set_output_delay -clock [get_clocks {sdram_clk}] -min -0.8 [get_ports $sdram_outputs]
|
||||
|
||||
set_input_delay -clock [get_clocks {sdram_clk}] -max 5.4 [get_ports $sdram_inputs]
|
||||
set_input_delay -clock [get_clocks {sdram_clk}] -min 2.5 [get_ports $sdram_inputs]
|
||||
|
||||
set_multicycle_path -setup -end 2 -from [get_clocks {sdram_clk}] -to [get_clocks $sys_clk]
|
||||
|
||||
|
||||
# SD card timings
|
||||
|
||||
# set_output_delay -clock [get_clocks {sd_clk}] -max 6.0 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
# set_output_delay -clock [get_clocks {sd_clk}] -min -2.0 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
|
||||
# set_input_delay -clock [get_clocks {sd_clk}] -max 15.0 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
# set_input_delay -clock [get_clocks {sd_clk}] -min 6.5 [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
|
||||
# set_multicycle_path -hold -start 1 -from [get_clocks $sys_clk] -to [get_clocks {sd_clk}]
|
||||
|
||||
# set_multicycle_path -setup -end 3 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk]
|
||||
# set_multicycle_path -hold -end 1 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk]
|
||||
|
||||
|
||||
# FT1248 timings
|
||||
|
||||
set_false_path -to [get_ports {o_usb_clk io_usb_miosi[*] o_usb_cs}]
|
||||
set_false_path -from [get_ports {io_usb_miosi[*] i_usb_miso}]
|
||||
|
||||
|
||||
# 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 o_uart_rts}]
|
||||
set_false_path -from [get_ports {i_uart_rxd i_uart_cts}]
|
||||
|
||||
|
||||
# I2C timings
|
||||
|
||||
set_false_path -to [get_ports {o_rtc_scl io_rtc_sda}]
|
||||
set_false_path -from [get_ports {io_rtc_sda}]
|
||||
|
||||
|
||||
# JTAG timings
|
||||
|
||||
# set_false_path -to [get_ports {altera_reserved_tdo}]
|
||||
# set_false_path -from [get_ports {altera_reserved_tdi altera_reserved_tms}]
|
@ -1,61 +0,0 @@
|
||||
# Clocks
|
||||
|
||||
derive_pll_clocks -create_base_clocks
|
||||
|
||||
set sys_clk {sys_pll|altpll_component|auto_generated|pll1|clk[0]}
|
||||
set sdram_pll_clk {sys_pll|altpll_component|auto_generated|pll1|clk[1]}
|
||||
|
||||
create_generated_clock -name sdram_clk -source [get_pins $sdram_pll_clk] -master_clock $sdram_pll_clk [get_ports {o_sdram_clk}]
|
||||
create_generated_clock -name flash_se_neg_reg -divide_by 2 \
|
||||
-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}] \
|
||||
[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]
|
||||
|
||||
|
||||
# FTDI timings
|
||||
|
||||
set_false_path -to [get_ports {o_ftdi_clk o_ftdi_si}]
|
||||
set_false_path -from [get_ports {i_ftdi_so i_ftdi_cts}]
|
||||
|
||||
|
||||
# SD card timings
|
||||
|
||||
set_false_path -to [get_ports {o_sd_clk io_sd_cmd io_sd_dat[*]}]
|
||||
set_false_path -from [get_ports {io_sd_cmd io_sd_dat[*]}]
|
||||
|
||||
|
||||
# N64, PI and SI timings
|
||||
|
||||
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}]
|
||||
|
||||
|
||||
# PMOD timings
|
||||
|
||||
set_false_path -to [get_ports {io_pmod[*]}]
|
||||
set_false_path -from [get_ports {io_pmod[*]}]
|
1
fw/cpu/picorv32
Submodule
1
fw/cpu/picorv32
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f9b1beb4cfd6b382157b54bc8f38c61d5ae7d785
|
143
fw/rtl/SummerCart64.sv
Normal file
143
fw/rtl/SummerCart64.sv
Normal file
@ -0,0 +1,143 @@
|
||||
module SummerCart64 (
|
||||
input i_clk,
|
||||
|
||||
input i_n64_reset,
|
||||
input i_n64_nmi,
|
||||
output o_n64_irq,
|
||||
|
||||
input i_n64_pi_alel,
|
||||
input i_n64_pi_aleh,
|
||||
input i_n64_pi_read,
|
||||
input i_n64_pi_write,
|
||||
inout [15:0] io_n64_pi_ad,
|
||||
|
||||
input i_n64_si_clk,
|
||||
inout io_n64_si_dq,
|
||||
|
||||
output o_sdram_clk,
|
||||
output o_sdram_cs,
|
||||
output o_sdram_ras,
|
||||
output o_sdram_cas,
|
||||
output o_sdram_we,
|
||||
output [1:0] o_sdram_ba,
|
||||
output [12:0] o_sdram_a,
|
||||
inout [15:0] io_sdram_dq,
|
||||
|
||||
output o_rtc_scl,
|
||||
inout io_rtc_sda,
|
||||
|
||||
output o_usb_clk,
|
||||
output o_usb_cs,
|
||||
input i_usb_miso,
|
||||
inout [3:0] io_usb_miosi,
|
||||
input i_usb_pwren,
|
||||
|
||||
input i_uart_rxd,
|
||||
output o_uart_txd,
|
||||
input i_uart_cts,
|
||||
output o_uart_rts,
|
||||
|
||||
output o_sd_clk,
|
||||
inout io_sd_cmd,
|
||||
inout [3:0] io_sd_dat,
|
||||
|
||||
output o_led
|
||||
);
|
||||
|
||||
logic [7:0] gpio_o;
|
||||
logic [7:0] gpio_i;
|
||||
logic [7:0] gpio_oe;
|
||||
|
||||
if_system sys (
|
||||
.in_clk(i_clk),
|
||||
.n64_reset(i_n64_reset),
|
||||
.n64_nmi(i_n64_nmi)
|
||||
);
|
||||
|
||||
if_config cfg ();
|
||||
|
||||
if_dma dma ();
|
||||
|
||||
if_sdram sdram ();
|
||||
|
||||
if_flashram flashram ();
|
||||
|
||||
if_si si ();
|
||||
|
||||
system system_inst (
|
||||
.sys(sys)
|
||||
);
|
||||
|
||||
intel_gpio_ddro sdram_clk_ddro (
|
||||
.outclock(sys.sdram.sdram_clk),
|
||||
.din({1'b0, 1'b1}),
|
||||
.pad_out(o_sdram_clk)
|
||||
);
|
||||
|
||||
n64_soc n64_soc_inst (
|
||||
.sys(sys),
|
||||
.cfg(cfg),
|
||||
.dma(dma),
|
||||
.sdram(sdram),
|
||||
.flashram(flashram),
|
||||
.si(si),
|
||||
|
||||
.n64_pi_alel(i_n64_pi_alel),
|
||||
.n64_pi_aleh(i_n64_pi_aleh),
|
||||
.n64_pi_read(i_n64_pi_read),
|
||||
.n64_pi_write(i_n64_pi_write),
|
||||
.n64_pi_ad(io_n64_pi_ad),
|
||||
|
||||
.n64_si_clk(i_n64_si_clk),
|
||||
.n64_si_dq(io_n64_si_dq),
|
||||
|
||||
.sdram_cs(o_sdram_cs),
|
||||
.sdram_ras(o_sdram_ras),
|
||||
.sdram_cas(o_sdram_cas),
|
||||
.sdram_we(o_sdram_we),
|
||||
.sdram_ba(o_sdram_ba),
|
||||
.sdram_a(o_sdram_a),
|
||||
.sdram_dq(io_sdram_dq)
|
||||
);
|
||||
|
||||
cpu_soc cpu_soc_inst (
|
||||
.sys(sys),
|
||||
.cfg(cfg),
|
||||
.dma(dma),
|
||||
.sdram(sdram),
|
||||
.flashram(flashram),
|
||||
.si(si),
|
||||
|
||||
.gpio_o(gpio_o),
|
||||
.gpio_i(gpio_i),
|
||||
.gpio_oe(gpio_oe),
|
||||
|
||||
.i2c_scl(o_rtc_scl),
|
||||
.i2c_sda(io_rtc_sda),
|
||||
|
||||
.usb_clk(o_usb_clk),
|
||||
.usb_cs(o_usb_cs),
|
||||
.usb_miso(i_usb_miso),
|
||||
.usb_miosi(io_usb_miosi),
|
||||
.usb_pwren(i_usb_pwren),
|
||||
|
||||
.uart_rxd(i_uart_rxd),
|
||||
.uart_txd(o_uart_txd),
|
||||
.uart_cts(i_uart_cts),
|
||||
.uart_rts(o_uart_rts),
|
||||
|
||||
.sd_clk(o_sd_clk),
|
||||
.sd_cmd(io_sd_cmd),
|
||||
.sd_dat(io_sd_dat)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
o_led = gpio_oe[0] ? gpio_o[0] : 1'bZ;
|
||||
o_n64_irq = gpio_oe[1] ? gpio_o[1] : 1'bZ;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
gpio_i <= {4'b0000, i_n64_nmi, i_n64_reset, o_n64_irq, o_led};
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,218 +0,0 @@
|
||||
module cart_control (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_n64_reset,
|
||||
input i_n64_nmi,
|
||||
|
||||
input i_request,
|
||||
input i_write,
|
||||
output o_busy,
|
||||
output reg o_ack,
|
||||
input [10:0] i_address,
|
||||
output reg [31:0] o_data,
|
||||
input [31:0] i_data,
|
||||
|
||||
output reg o_sdram_writable,
|
||||
output reg o_rom_switch,
|
||||
output reg o_ddipl_enable,
|
||||
output reg o_sram_enable,
|
||||
output reg o_sram_768k_mode,
|
||||
output reg o_flashram_enable,
|
||||
output reg o_sd_enable,
|
||||
output reg o_eeprom_pi_enable,
|
||||
output reg o_eeprom_enable,
|
||||
output reg o_eeprom_16k_mode,
|
||||
|
||||
output reg o_n64_reset_btn,
|
||||
|
||||
input i_debug_ready,
|
||||
|
||||
output reg o_debug_dma_start,
|
||||
input i_debug_dma_busy,
|
||||
output reg [3:0] o_debug_dma_bank,
|
||||
output reg [23:0] o_debug_dma_address,
|
||||
output reg [19:0] o_debug_dma_length,
|
||||
|
||||
output reg o_debug_fifo_request,
|
||||
output reg o_debug_fifo_flush,
|
||||
input [10:0] i_debug_fifo_items,
|
||||
input [31:0] i_debug_fifo_data,
|
||||
|
||||
output reg [23:0] o_ddipl_address,
|
||||
output reg [23:0] o_sram_address
|
||||
);
|
||||
|
||||
// Module parameters
|
||||
|
||||
parameter byte VERSION = "a";
|
||||
|
||||
|
||||
// Register offsets
|
||||
|
||||
localparam [3:0] REG_SCR = 4'd0;
|
||||
localparam [3:0] REG_BOOT = 4'd1;
|
||||
localparam [3:0] REG_VERSION = 4'd2;
|
||||
localparam [3:0] REG_GPIO = 4'd3;
|
||||
localparam [3:0] REG_USB_SCR = 4'd4;
|
||||
localparam [3:0] REG_USB_DMA_ADDR = 4'd5;
|
||||
localparam [3:0] REG_USB_DMA_LEN = 4'd6;
|
||||
localparam [3:0] REG_DDIPL_ADDR = 4'd7;
|
||||
localparam [3:0] REG_SRAM_ADDR = 4'd8;
|
||||
|
||||
localparam [10:0] MEM_USB_FIFO_BASE = 11'h400;
|
||||
|
||||
|
||||
// Input synchronization
|
||||
|
||||
reg r_reset_ff1, r_reset_ff2;
|
||||
reg r_nmi_ff1, r_nmi_ff2;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
{r_reset_ff2, r_reset_ff1} <= {r_reset_ff1, i_n64_reset};
|
||||
{r_nmi_ff2, r_nmi_ff1} <= {r_nmi_ff1, i_n64_nmi};
|
||||
end
|
||||
|
||||
|
||||
// Registers
|
||||
|
||||
reg [15:0] r_bootloader;
|
||||
|
||||
|
||||
// Bus controller
|
||||
|
||||
assign o_busy = 1'b0;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= !i_reset && i_request && !i_write && !o_busy;
|
||||
end
|
||||
|
||||
|
||||
// Write logic
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_debug_dma_start <= 1'b0;
|
||||
o_debug_fifo_flush <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
o_sdram_writable <= 1'b0;
|
||||
o_rom_switch <= 1'b0;
|
||||
o_ddipl_enable <= 1'b0;
|
||||
o_sram_enable <= 1'b0;
|
||||
o_sram_768k_mode <= 1'b0;
|
||||
o_flashram_enable <= 1'b0;
|
||||
o_sd_enable <= 1'b0;
|
||||
o_eeprom_pi_enable <= 1'b0;
|
||||
o_eeprom_enable <= 1'b0;
|
||||
o_eeprom_16k_mode <= 1'b0;
|
||||
o_n64_reset_btn <= 1'b1;
|
||||
o_ddipl_address <= 24'hF0_0000;
|
||||
o_sram_address <= 24'hFF_E000;
|
||||
o_debug_dma_bank <= 4'd1;
|
||||
o_debug_dma_address <= 24'hFC_0000;
|
||||
o_debug_dma_length <= 20'd0;
|
||||
r_bootloader <= 16'h0000;
|
||||
end else begin
|
||||
if (i_request && i_write && !o_busy) begin
|
||||
case (i_address[3:0])
|
||||
REG_SCR: begin
|
||||
{
|
||||
o_flashram_enable,
|
||||
o_sram_768k_mode,
|
||||
o_sram_enable,
|
||||
o_sd_enable,
|
||||
o_eeprom_pi_enable,
|
||||
o_eeprom_16k_mode,
|
||||
o_eeprom_enable,
|
||||
o_ddipl_enable,
|
||||
o_rom_switch,
|
||||
o_sdram_writable
|
||||
} <= i_data[9:0];
|
||||
end
|
||||
REG_BOOT: begin
|
||||
r_bootloader <= i_data[15:0];
|
||||
end
|
||||
REG_GPIO: begin
|
||||
o_n64_reset_btn <= ~i_data[0];
|
||||
end
|
||||
REG_USB_SCR: begin
|
||||
{o_debug_fifo_flush, o_debug_dma_start} <= {i_data[2], i_data[0]};
|
||||
end
|
||||
REG_USB_DMA_ADDR: begin
|
||||
{o_debug_dma_bank, o_debug_dma_address} <= {i_data[31:28], i_data[25:2]};
|
||||
end
|
||||
REG_USB_DMA_LEN: begin
|
||||
o_debug_dma_length <= i_data[19:0];
|
||||
end
|
||||
REG_DDIPL_ADDR: begin
|
||||
o_ddipl_address <= i_data[25:2];
|
||||
end
|
||||
REG_SRAM_ADDR: begin
|
||||
o_sram_address <= i_data[25:2];
|
||||
end
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (!r_reset_ff2 || !r_nmi_ff2) begin
|
||||
o_sdram_writable <= 1'b0;
|
||||
o_rom_switch <= 1'b0;
|
||||
o_n64_reset_btn <= 1'b1;
|
||||
o_debug_fifo_flush <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Read logic
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_debug_fifo_request <= 1'b0;
|
||||
|
||||
if (!i_reset && i_request && !i_write && !o_busy) begin
|
||||
if (i_address < MEM_USB_FIFO_BASE) begin
|
||||
case (i_address[3:0])
|
||||
REG_SCR: begin
|
||||
o_data[9:0] <= {
|
||||
o_flashram_enable,
|
||||
o_sram_768k_mode,
|
||||
o_sram_enable,
|
||||
o_sd_enable,
|
||||
o_eeprom_pi_enable,
|
||||
o_eeprom_16k_mode,
|
||||
o_eeprom_enable,
|
||||
o_ddipl_enable,
|
||||
o_rom_switch,
|
||||
o_sdram_writable
|
||||
};
|
||||
end
|
||||
REG_BOOT: begin
|
||||
o_data[15:0] <= r_bootloader;
|
||||
end
|
||||
REG_VERSION: begin
|
||||
o_data <= {"S", "6", "4", VERSION};
|
||||
end
|
||||
REG_GPIO: begin
|
||||
o_data[2:0] <= {r_nmi_ff2, r_reset_ff2, ~o_n64_reset_btn};
|
||||
end
|
||||
REG_USB_SCR: begin
|
||||
{o_data[13:3], o_data[1:0]} <= {i_debug_fifo_items, i_debug_ready, i_debug_dma_busy};
|
||||
end
|
||||
REG_DDIPL_ADDR: begin
|
||||
o_data[25:0] <= {o_ddipl_address, 2'b00};
|
||||
end
|
||||
REG_SRAM_ADDR: begin
|
||||
o_data[25:0] <= {o_sram_address, 2'b00};
|
||||
end
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
o_data <= i_debug_fifo_data;
|
||||
o_debug_fifo_request <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,28 +0,0 @@
|
||||
module cart_led (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_trigger,
|
||||
|
||||
output o_led
|
||||
);
|
||||
|
||||
localparam COUNTER_LOAD_VALUE = 5'd31;
|
||||
|
||||
reg [4:0] r_counter;
|
||||
|
||||
assign o_led = r_counter > 5'd0;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_counter <= 5'd0;
|
||||
end else begin
|
||||
if (i_trigger) begin
|
||||
r_counter <= COUNTER_LOAD_VALUE;
|
||||
end else if (r_counter > 5'd0) begin
|
||||
r_counter <= r_counter - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,8 +0,0 @@
|
||||
`define VERSION "a"
|
||||
|
||||
`define BANK_INVALID 4'd0
|
||||
`define BANK_SDRAM 4'd1
|
||||
`define BANK_CART 4'd2
|
||||
`define BANK_EEPROM 4'd3
|
||||
`define BANK_FLASHRAM 4'd4
|
||||
`define BANK_SD 4'd5
|
54
fw/rtl/cpu/cpu_bus.sv
Normal file
54
fw/rtl/cpu/cpu_bus.sv
Normal file
@ -0,0 +1,54 @@
|
||||
interface if_cpu_bus ();
|
||||
|
||||
localparam [3:0] NUM_DEVICES = sc64::__ID_CPU_END;
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic [3:0] wmask;
|
||||
logic [31:0] address;
|
||||
logic [31:0] wdata;
|
||||
logic [31:0] rdata;
|
||||
|
||||
logic device_ack [(NUM_DEVICES - 1):0];
|
||||
logic [31:0] device_rdata [(NUM_DEVICES - 1):0];
|
||||
|
||||
always_comb begin
|
||||
ack = 1'b0;
|
||||
rdata = 32'd0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
ack = ack | device_ack[i];
|
||||
rdata = rdata | device_rdata[i];
|
||||
end
|
||||
end
|
||||
|
||||
modport cpu (
|
||||
output request,
|
||||
input ack,
|
||||
output wmask,
|
||||
output address,
|
||||
output wdata,
|
||||
input rdata
|
||||
);
|
||||
|
||||
genvar n;
|
||||
generate
|
||||
for (n = 0; n < NUM_DEVICES; n++) begin : at
|
||||
logic device_request;
|
||||
|
||||
always_comb begin
|
||||
device_request = request && address[31:28] == n[3:0];
|
||||
end
|
||||
|
||||
modport device (
|
||||
input .request(device_request),
|
||||
output .ack(device_ack[n]),
|
||||
input .wmask(wmask),
|
||||
input .address(address),
|
||||
input .wdata(wdata),
|
||||
output .rdata(device_rdata[n])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endinterface
|
127
fw/rtl/cpu/cpu_cfg.sv
Normal file
127
fw/rtl/cpu/cpu_cfg.sv
Normal file
@ -0,0 +1,127 @@
|
||||
module cpu_cfg (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_config.cpu cfg
|
||||
);
|
||||
|
||||
logic skip_bootloader;
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
R_SCR,
|
||||
R_DD_OFFSET,
|
||||
R_SAVE_OFFSET,
|
||||
R_COMMAND,
|
||||
R_DATA_0,
|
||||
R_DATA_1,
|
||||
R_VERSION
|
||||
} 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[4:2])
|
||||
R_SCR: bus.rdata = {
|
||||
cfg.cpu_ready,
|
||||
cfg.cpu_busy,
|
||||
cfg.usb_waiting,
|
||||
cfg.cmd_error,
|
||||
21'd0,
|
||||
skip_bootloader,
|
||||
cfg.flashram_enabled,
|
||||
cfg.sram_banked,
|
||||
cfg.sram_enabled,
|
||||
cfg.dd_enabled,
|
||||
cfg.sdram_writable,
|
||||
cfg.sdram_switch
|
||||
};
|
||||
R_DD_OFFSET: bus.rdata = {6'd0, cfg.dd_offset};
|
||||
R_SAVE_OFFSET: bus.rdata = {6'd0, cfg.save_offset};
|
||||
R_COMMAND: bus.rdata = {24'd0, cfg.cmd};
|
||||
R_DATA_0: bus.rdata = cfg.data[0];
|
||||
R_DATA_1: bus.rdata = cfg.data[1];
|
||||
R_VERSION: bus.rdata = sc64::SC64_VER;
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
cfg.wdata = bus.wdata;
|
||||
cfg.data_write = 2'b00;
|
||||
if (bus.request && (&bus.wmask)) begin
|
||||
cfg.data_write[0] = bus.address[4:2] == R_DATA_0;
|
||||
cfg.data_write[1] = bus.address[4:2] == R_DATA_1;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
cfg.cpu_ready <= 1'b0;
|
||||
cfg.cpu_busy <= 1'b0;
|
||||
cfg.usb_waiting <= 1'b0;
|
||||
cfg.cmd_error <= 1'b0;
|
||||
cfg.sdram_switch <= 1'b0;
|
||||
cfg.sdram_writable <= 1'b0;
|
||||
cfg.dd_enabled <= 1'b0;
|
||||
cfg.sram_enabled <= 1'b0;
|
||||
cfg.sram_banked <= 1'b0;
|
||||
cfg.flashram_enabled <= 1'b0;
|
||||
cfg.dd_offset <= 26'h3BE_0000;
|
||||
cfg.save_offset <= 26'h3FE_0000;
|
||||
skip_bootloader <= 1'b0;
|
||||
end else begin
|
||||
if (sys.n64_soft_reset) begin
|
||||
cfg.sdram_switch <= skip_bootloader;
|
||||
cfg.sdram_writable <= 1'b0;
|
||||
end
|
||||
if (cfg.cmd_request) begin
|
||||
cfg.cpu_busy <= 1'b1;
|
||||
end
|
||||
if (bus.request) begin
|
||||
case (bus.address[4:2])
|
||||
R_SCR: begin
|
||||
if (bus.wmask[3]) begin
|
||||
{
|
||||
cfg.cpu_ready,
|
||||
cfg.cpu_busy,
|
||||
cfg.usb_waiting,
|
||||
cfg.cmd_error
|
||||
} <= bus.wdata[31:28];
|
||||
end
|
||||
if (bus.wmask[0]) begin
|
||||
{
|
||||
skip_bootloader,
|
||||
cfg.flashram_enabled,
|
||||
cfg.sram_banked,
|
||||
cfg.sram_enabled,
|
||||
cfg.dd_enabled,
|
||||
cfg.sdram_writable,
|
||||
cfg.sdram_switch
|
||||
} <= bus.wdata[6:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_DD_OFFSET: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.dd_offset <= bus.wdata[25:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_SAVE_OFFSET: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.save_offset <= bus.wdata[25:0];
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
222
fw/rtl/cpu/cpu_dma.sv
Normal file
222
fw/rtl/cpu/cpu_dma.sv
Normal file
@ -0,0 +1,222 @@
|
||||
interface if_dma ();
|
||||
|
||||
localparam [1:0] NUM_DEVICES = sc64::__ID_DMA_END;
|
||||
|
||||
sc64::e_dma_id id;
|
||||
|
||||
logic rx_empty;
|
||||
logic rx_read;
|
||||
logic [7:0] rx_rdata;
|
||||
logic tx_full;
|
||||
logic tx_write;
|
||||
logic [7:0] tx_wdata;
|
||||
|
||||
logic request;
|
||||
logic ack;
|
||||
logic write;
|
||||
logic [31:0] address;
|
||||
logic [15:0] rdata;
|
||||
logic [15:0] wdata;
|
||||
|
||||
modport controller (
|
||||
output id,
|
||||
|
||||
input rx_empty,
|
||||
output rx_read,
|
||||
input rx_rdata,
|
||||
input tx_full,
|
||||
output tx_write,
|
||||
output tx_wdata,
|
||||
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output address,
|
||||
input rdata,
|
||||
output wdata
|
||||
);
|
||||
|
||||
modport memory (
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input address,
|
||||
output rdata,
|
||||
input wdata
|
||||
);
|
||||
|
||||
logic [7:0] device_rx_rdata [(NUM_DEVICES - 1):0];
|
||||
logic device_rx_empty [(NUM_DEVICES - 1):0];
|
||||
logic device_tx_full [(NUM_DEVICES - 1):0];
|
||||
|
||||
always_comb begin
|
||||
rx_rdata = 8'd0;
|
||||
rx_empty = 1'b0;
|
||||
tx_full = 1'b0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
rx_rdata = rx_rdata | (id == i[1:0] ? device_rx_rdata[i] : 8'd0);
|
||||
rx_empty = rx_empty | (device_rx_empty[i] && id == i[1:0]);
|
||||
tx_full = tx_full | (device_tx_full[i] && id == i[1:0]);
|
||||
end
|
||||
end
|
||||
|
||||
genvar n;
|
||||
generate
|
||||
for (n = 0; n < NUM_DEVICES; n++) begin : at
|
||||
logic device_selected;
|
||||
logic device_rx_read;
|
||||
logic device_tx_write;
|
||||
|
||||
always_comb begin
|
||||
device_selected = id == n[1:0];
|
||||
device_rx_read = device_selected && rx_read;
|
||||
device_tx_write = device_selected && tx_write;
|
||||
end
|
||||
|
||||
modport device (
|
||||
output .rx_empty(device_rx_empty[n]),
|
||||
input .rx_read(device_rx_read),
|
||||
output .rx_rdata(device_rx_rdata[n]),
|
||||
output .tx_full(device_tx_full[n]),
|
||||
input .tx_write(device_tx_write),
|
||||
input .tx_wdata(tx_wdata)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module cpu_dma (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_dma.controller dma
|
||||
);
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
S_IDLE,
|
||||
S_FETCH,
|
||||
S_TRANSFER
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
logic pending_stop;
|
||||
logic direction;
|
||||
logic [27:0] length;
|
||||
logic [15:0] rdata_buffer;
|
||||
logic byte_counter;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[3:2])
|
||||
0: bus.rdata = {28'd0, state != S_IDLE, direction, 2'b00};
|
||||
1: bus.rdata = dma.address;
|
||||
2: bus.rdata = {2'b00, dma.id, length};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
|
||||
dma.rx_read <= 1'b0;
|
||||
dma.tx_write <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
pending_stop <= 1'b0;
|
||||
dma.request <= 1'b0;
|
||||
end else begin
|
||||
if (bus.request && bus.address[3:2] == 0 && bus.wmask[0]) begin
|
||||
pending_stop <= bus.wdata[1];
|
||||
end
|
||||
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
pending_stop <= 1'b0;
|
||||
|
||||
if (bus.request) begin
|
||||
case (bus.address[3:2])
|
||||
0: if (bus.wmask[0]) begin
|
||||
direction <= bus.wdata[2];
|
||||
if (bus.wdata[0]) begin
|
||||
state <= S_FETCH;
|
||||
byte_counter <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
1: if (&bus.wmask) begin
|
||||
dma.address <= bus.wdata;
|
||||
end
|
||||
|
||||
2: if (&bus.wmask) begin
|
||||
{dma.id, length} <= {bus.wdata[29:1], 1'b0};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
S_FETCH: begin
|
||||
if (length != 28'd0 && !pending_stop) begin
|
||||
if (direction) begin
|
||||
if (!dma.rx_empty && !dma.rx_read) begin
|
||||
dma.rx_read <= 1'b1;
|
||||
dma.wdata <= {dma.wdata[7:0], dma.rx_rdata};
|
||||
byte_counter <= ~byte_counter;
|
||||
if (byte_counter) begin
|
||||
state <= S_TRANSFER;
|
||||
dma.request <= 1'b1;
|
||||
dma.write <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
dma.request <= 1'b1;
|
||||
dma.write <= 1'b0;
|
||||
if (dma.ack) begin
|
||||
state <= S_TRANSFER;
|
||||
dma.request <= 1'b0;
|
||||
rdata_buffer <= dma.rdata;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_TRANSFER: begin
|
||||
if (direction) begin
|
||||
if (dma.ack) begin
|
||||
state <= S_FETCH;
|
||||
dma.request <= 1'b0;
|
||||
dma.address <= dma.address + 2'd2;
|
||||
length <= length - 2'd2;
|
||||
end
|
||||
end else begin
|
||||
if (!dma.tx_full && !dma.tx_write) begin
|
||||
dma.tx_write <= 1'b1;
|
||||
dma.tx_wdata <= byte_counter ? rdata_buffer[7:0] : rdata_buffer[15:8];
|
||||
byte_counter <= ~byte_counter;
|
||||
if (byte_counter) begin
|
||||
state <= S_FETCH;
|
||||
dma.address <= dma.address + 2'd2;
|
||||
length <= length - 2'd2;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state <= S_IDLE;
|
||||
dma.request <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
77
fw/rtl/cpu/cpu_flashram.sv
Normal file
77
fw/rtl/cpu/cpu_flashram.sv
Normal file
@ -0,0 +1,77 @@
|
||||
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
|
42
fw/rtl/cpu/cpu_gpio.sv
Normal file
42
fw/rtl/cpu/cpu_gpio.sv
Normal file
@ -0,0 +1,42 @@
|
||||
module cpu_gpio (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
|
||||
input [7:0] gpio_i,
|
||||
output [7:0] gpio_o,
|
||||
output [7:0] gpio_oe
|
||||
);
|
||||
|
||||
logic [1:0][7:0] gpio_i_ff;
|
||||
logic [7:0] gpio_o_value;
|
||||
logic [7:0] gpio_oe_value;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
bus.rdata = {8'd0, gpio_oe_value, gpio_i_ff[1], gpio_o_value};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
gpio_i_ff <= {gpio_i_ff[0], gpio_i};
|
||||
gpio_o <= gpio_o_value;
|
||||
gpio_oe <= gpio_oe_value;
|
||||
|
||||
if (sys.reset) begin
|
||||
gpio_o_value <= 8'd0;
|
||||
gpio_oe_value <= 8'd0;
|
||||
end else if (bus.request) begin
|
||||
if (bus.wmask[0]) gpio_o_value <= bus.wdata[7:0];
|
||||
if (bus.wmask[2]) gpio_oe_value <= bus.wdata[23:16];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
155
fw/rtl/cpu/cpu_i2c.sv
Normal file
155
fw/rtl/cpu/cpu_i2c.sv
Normal file
@ -0,0 +1,155 @@
|
||||
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
|
33
fw/rtl/cpu/cpu_ram.sv
Normal file
33
fw/rtl/cpu/cpu_ram.sv
Normal file
@ -0,0 +1,33 @@
|
||||
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
|
76
fw/rtl/cpu/cpu_sdram.sv
Normal file
76
fw/rtl/cpu/cpu_sdram.sv
Normal file
@ -0,0 +1,76 @@
|
||||
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
|
59
fw/rtl/cpu/cpu_si.sv
Normal file
59
fw/rtl/cpu/cpu_si.sv
Normal file
@ -0,0 +1,59 @@
|
||||
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
|
114
fw/rtl/cpu/cpu_soc.sv
Normal file
114
fw/rtl/cpu/cpu_soc.sv
Normal file
@ -0,0 +1,114 @@
|
||||
module cpu_soc (
|
||||
if_system.sys sys,
|
||||
if_config.cpu cfg,
|
||||
if_dma dma,
|
||||
if_sdram.cpu sdram,
|
||||
if_flashram.cpu flashram,
|
||||
if_si.cpu si,
|
||||
|
||||
input [7:0] gpio_i,
|
||||
output [7:0] gpio_o,
|
||||
output [7:0] gpio_oe,
|
||||
|
||||
output i2c_scl,
|
||||
inout i2c_sda,
|
||||
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
input usb_miso,
|
||||
inout [3:0] usb_miosi,
|
||||
input usb_pwren,
|
||||
|
||||
input uart_rxd,
|
||||
output uart_txd,
|
||||
input uart_cts,
|
||||
output uart_rts,
|
||||
|
||||
output sd_clk,
|
||||
inout sd_cmd,
|
||||
inout [3:0] sd_dat
|
||||
);
|
||||
|
||||
if_cpu_bus bus ();
|
||||
|
||||
cpu_wrapper cpu_wrapper_inst (
|
||||
.sys(sys),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
cpu_ram cpu_ram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_RAM].device)
|
||||
);
|
||||
|
||||
cpu_bootloader cpu_bootloader_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_BOOTLOADER].device)
|
||||
);
|
||||
|
||||
cpu_gpio cpu_gpio_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_GPIO].device),
|
||||
.gpio_i(gpio_i),
|
||||
.gpio_o(gpio_o),
|
||||
.gpio_oe(gpio_oe)
|
||||
);
|
||||
|
||||
cpu_i2c cpu_i2c_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_I2C].device),
|
||||
.i2c_scl(i2c_scl),
|
||||
.i2c_sda(i2c_sda)
|
||||
);
|
||||
|
||||
cpu_usb cpu_usb_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_USB].device),
|
||||
.dma(dma.at[sc64::ID_DMA_USB].device),
|
||||
.usb_clk(usb_clk),
|
||||
.usb_cs(usb_cs),
|
||||
.usb_miso(usb_miso),
|
||||
.usb_miosi(usb_miosi),
|
||||
.usb_pwren(usb_pwren)
|
||||
);
|
||||
|
||||
cpu_uart cpu_uart_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_UART].device),
|
||||
.uart_rxd(uart_rxd),
|
||||
.uart_txd(uart_txd),
|
||||
.uart_cts(uart_cts),
|
||||
.uart_rts(uart_rts)
|
||||
);
|
||||
|
||||
cpu_dma cpu_dma_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_DMA].device),
|
||||
.dma(dma)
|
||||
);
|
||||
|
||||
cpu_cfg cpu_cfg_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_CFG].device),
|
||||
.cfg(cfg)
|
||||
);
|
||||
|
||||
cpu_sdram cpu_sdram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_SDRAM].device),
|
||||
.sdram(sdram)
|
||||
);
|
||||
|
||||
cpu_flashram cpu_flashram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_FLASHRAM].device),
|
||||
.flashram(flashram)
|
||||
);
|
||||
|
||||
cpu_si cpu_si_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_SI].device),
|
||||
.si(si)
|
||||
);
|
||||
|
||||
endmodule
|
155
fw/rtl/cpu/cpu_uart.sv
Normal file
155
fw/rtl/cpu/cpu_uart.sv
Normal file
@ -0,0 +1,155 @@
|
||||
module cpu_uart (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
|
||||
input uart_rxd,
|
||||
output uart_txd,
|
||||
input uart_cts,
|
||||
output uart_rts
|
||||
);
|
||||
|
||||
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
|
100
fw/rtl/cpu/cpu_usb.sv
Normal file
100
fw/rtl/cpu/cpu_usb.sv
Normal file
@ -0,0 +1,100 @@
|
||||
module cpu_usb (
|
||||
if_system sys,
|
||||
if_cpu_bus bus,
|
||||
if_dma dma,
|
||||
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
input usb_miso,
|
||||
inout [3:0] usb_miosi,
|
||||
input usb_pwren
|
||||
);
|
||||
|
||||
logic rx_flush;
|
||||
logic rx_empty;
|
||||
logic rx_read;
|
||||
logic [7:0] rx_rdata;
|
||||
|
||||
logic tx_flush;
|
||||
logic tx_full;
|
||||
logic tx_write;
|
||||
logic [7:0] tx_wdata;
|
||||
|
||||
logic cpu_rx_read;
|
||||
logic cpu_tx_write;
|
||||
|
||||
always_comb begin
|
||||
dma.rx_empty = rx_empty;
|
||||
rx_read = cpu_rx_read || dma.rx_read;
|
||||
dma.rx_rdata = rx_rdata;
|
||||
|
||||
dma.tx_full = tx_full;
|
||||
tx_write = cpu_tx_write || dma.tx_write;
|
||||
tx_wdata = dma.tx_write ? dma.tx_wdata : bus.wdata[7:0];
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[2:2])
|
||||
0: bus.rdata = {30'd0, ~tx_full, ~rx_empty};
|
||||
1: bus.rdata = {24'd0, rx_rdata};
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
rx_flush <= 1'b0;
|
||||
cpu_rx_read <= 1'b0;
|
||||
|
||||
tx_flush <= 1'b0;
|
||||
cpu_tx_write <= 1'b0;
|
||||
|
||||
if (bus.request) begin
|
||||
case (bus.address[2:2])
|
||||
2'd0: begin
|
||||
if (bus.wmask[0]) begin
|
||||
{tx_flush, rx_flush} <= bus.wdata[3:2];
|
||||
end
|
||||
end
|
||||
|
||||
2'd1: begin
|
||||
if (bus.wmask[0]) begin
|
||||
cpu_tx_write <= 1'b1;
|
||||
end else begin
|
||||
cpu_rx_read <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
usb_ft1248 usb_ft1248_inst (
|
||||
.sys(sys),
|
||||
|
||||
.usb_clk(usb_clk),
|
||||
.usb_cs(usb_cs),
|
||||
.usb_miso(usb_miso),
|
||||
.usb_miosi(usb_miosi),
|
||||
.usb_pwren(usb_pwren),
|
||||
|
||||
.rx_flush(rx_flush),
|
||||
.rx_empty(rx_empty),
|
||||
.rx_read(rx_read),
|
||||
.rx_rdata(rx_rdata),
|
||||
|
||||
.tx_flush(tx_flush),
|
||||
.tx_full(tx_full),
|
||||
.tx_write(tx_write),
|
||||
.tx_wdata(tx_wdata)
|
||||
);
|
||||
|
||||
endmodule
|
49
fw/rtl/cpu/cpu_wrapper.sv
Normal file
49
fw/rtl/cpu/cpu_wrapper.sv
Normal file
@ -0,0 +1,49 @@
|
||||
module cpu_wrapper (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus.cpu bus
|
||||
);
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAITING
|
||||
} e_bus_state;
|
||||
|
||||
e_bus_state state;
|
||||
|
||||
logic mem_la_read;
|
||||
logic mem_la_write;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.request <= 1'b0;
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
end else begin
|
||||
if (state == S_IDLE && (mem_la_read || mem_la_write)) begin
|
||||
state <= S_WAITING;
|
||||
bus.request <= 1'b1;
|
||||
end
|
||||
if (state == S_WAITING && bus.ack) begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
picorv32 #(
|
||||
.ENABLE_COUNTERS(0),
|
||||
.ENABLE_COUNTERS64(0),
|
||||
.CATCH_MISALIGN(0),
|
||||
.CATCH_ILLINSN(0),
|
||||
.PROGADDR_RESET({4'(sc64::ID_CPU_BOOTLOADER), 28'h000_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)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,91 +0,0 @@
|
||||
module device_arbiter #(
|
||||
parameter NUM_CONTROLLERS = 2,
|
||||
parameter ADDRESS_WIDTH = 26,
|
||||
parameter [3:0] DEVICE_BANK = 4'd0,
|
||||
parameter ACK_FIFO_LENGTH = 4
|
||||
) (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input [(NUM_CONTROLLERS - 1):0] i_request,
|
||||
input [(NUM_CONTROLLERS - 1):0] i_write,
|
||||
output reg [(NUM_CONTROLLERS - 1):0] o_busy,
|
||||
output reg [(NUM_CONTROLLERS - 1):0] o_ack,
|
||||
input [((NUM_CONTROLLERS * 4) - 1):0] i_bank,
|
||||
input [((NUM_CONTROLLERS * ADDRESS_WIDTH) - 1):0] i_address,
|
||||
output reg [((NUM_CONTROLLERS * 32) - 1):0] o_data,
|
||||
input [((NUM_CONTROLLERS * 32) - 1):0] i_data,
|
||||
|
||||
output reg o_device_request,
|
||||
output reg o_device_write,
|
||||
input i_device_busy,
|
||||
input i_device_ack,
|
||||
output reg [(ADDRESS_WIDTH - 1):0] o_device_address,
|
||||
input [31:0] i_device_data,
|
||||
output reg [31:0] o_device_data
|
||||
);
|
||||
|
||||
localparam FIFO_ADDRESS_WIDTH = $clog2(ACK_FIFO_LENGTH);
|
||||
|
||||
reg [(NUM_CONTROLLERS - 1):0] r_request;
|
||||
reg [(NUM_CONTROLLERS - 1):0] r_request_successful;
|
||||
|
||||
reg [(NUM_CONTROLLERS - 1):0] r_ack_fifo_mem [0:(ACK_FIFO_LENGTH - 1)];
|
||||
|
||||
reg [FIFO_ADDRESS_WIDTH:0] r_ack_fifo_wrptr;
|
||||
reg [FIFO_ADDRESS_WIDTH:0] r_ack_fifo_rdptr;
|
||||
|
||||
wire w_ack_fifo_wrreq = |(r_request_successful & ~i_write);
|
||||
wire w_ack_fifo_rdreq = i_device_ack;
|
||||
|
||||
wire w_empty = r_ack_fifo_wrptr[FIFO_ADDRESS_WIDTH] == r_ack_fifo_rdptr[FIFO_ADDRESS_WIDTH];
|
||||
wire w_full_or_empty = r_ack_fifo_wrptr[(FIFO_ADDRESS_WIDTH - 1):0] == r_ack_fifo_rdptr[(FIFO_ADDRESS_WIDTH - 1):0];
|
||||
|
||||
wire w_ack_fifo_full = !w_empty && w_full_or_empty;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_ack_fifo_wrptr <= {(FIFO_ADDRESS_WIDTH + 1){1'b0}};
|
||||
r_ack_fifo_rdptr <= {(FIFO_ADDRESS_WIDTH + 1){1'b0}};
|
||||
end else begin
|
||||
if (w_ack_fifo_wrreq) begin
|
||||
r_ack_fifo_mem[r_ack_fifo_wrptr[(FIFO_ADDRESS_WIDTH - 1):0]] <= r_request_successful & ~i_write;
|
||||
r_ack_fifo_wrptr <= r_ack_fifo_wrptr + 1'd1;
|
||||
end
|
||||
if (w_ack_fifo_rdreq) begin
|
||||
r_ack_fifo_rdptr <= r_ack_fifo_rdptr + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
for (integer i = 0; i < NUM_CONTROLLERS; i = i + 1) begin
|
||||
r_request[i] = i_request[i] && i_bank[(i * 4) +: 4] == DEVICE_BANK;
|
||||
o_busy[i] = r_request[i] && (
|
||||
i_device_busy ||
|
||||
|(r_request & (({{(NUM_CONTROLLERS - 1){1'b0}}, 1'b1} << i) - 1)) ||
|
||||
(!i_write[i] && w_ack_fifo_full)
|
||||
);
|
||||
end
|
||||
|
||||
r_request_successful = r_request & ~o_busy;
|
||||
o_ack = {NUM_CONTROLLERS{i_device_ack}} & r_ack_fifo_mem[r_ack_fifo_rdptr[(FIFO_ADDRESS_WIDTH - 1):0]];
|
||||
o_data = {NUM_CONTROLLERS{i_device_data}};
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
o_device_request = |r_request;
|
||||
o_device_write = 1'b0;
|
||||
o_device_address = {ADDRESS_WIDTH{1'b0}};
|
||||
o_device_data = 32'h0000_0000;
|
||||
|
||||
for (integer i = (NUM_CONTROLLERS - 1); i >= 0 ; i = i - 1) begin
|
||||
if (r_request[i]) begin
|
||||
o_device_write = i_write[i];
|
||||
o_device_address = i_address[(i * ADDRESS_WIDTH) +: ADDRESS_WIDTH];
|
||||
o_device_data = i_data[(i * 32) +: 32];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,4 +1,4 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "FIFO"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "fifo_usb.v"]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "intel_fifo_8.v"]
|
@ -4,7 +4,7 @@
|
||||
// MODULE: scfifo
|
||||
|
||||
// ============================================================
|
||||
// File Name: fifo_usb.v
|
||||
// File Name: intel_fifo_8.v
|
||||
// Megafunction Name(s):
|
||||
// scfifo
|
||||
//
|
||||
@ -37,31 +37,31 @@
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module fifo_usb (
|
||||
module intel_fifo_8 (
|
||||
clock,
|
||||
data,
|
||||
rdreq,
|
||||
sclr,
|
||||
wrreq,
|
||||
empty,
|
||||
full,
|
||||
q,
|
||||
usedw);
|
||||
q);
|
||||
|
||||
input clock;
|
||||
input [31:0] data;
|
||||
input [7:0] data;
|
||||
input rdreq;
|
||||
input sclr;
|
||||
input wrreq;
|
||||
output empty;
|
||||
output full;
|
||||
output [31:0] q;
|
||||
output [9:0] usedw;
|
||||
output [7:0] q;
|
||||
|
||||
wire sub_wire0;
|
||||
wire [31:0] sub_wire1;
|
||||
wire [9:0] sub_wire2;
|
||||
wire full = sub_wire0;
|
||||
wire [31:0] q = sub_wire1[31:0];
|
||||
wire [9:0] usedw = sub_wire2[9:0];
|
||||
wire sub_wire1;
|
||||
wire [7:0] sub_wire2;
|
||||
wire empty = sub_wire0;
|
||||
wire full = sub_wire1;
|
||||
wire [7:0] q = sub_wire2[7:0];
|
||||
|
||||
scfifo scfifo_component (
|
||||
.clock (clock),
|
||||
@ -69,21 +69,21 @@ module fifo_usb (
|
||||
.rdreq (rdreq),
|
||||
.sclr (sclr),
|
||||
.wrreq (wrreq),
|
||||
.full (sub_wire0),
|
||||
.q (sub_wire1),
|
||||
.usedw (sub_wire2),
|
||||
.empty (sub_wire0),
|
||||
.full (sub_wire1),
|
||||
.q (sub_wire2),
|
||||
.aclr (),
|
||||
.almost_empty (),
|
||||
.almost_full (),
|
||||
.eccstatus (),
|
||||
.empty ());
|
||||
.usedw ());
|
||||
defparam
|
||||
scfifo_component.add_ram_output_register = "OFF",
|
||||
scfifo_component.add_ram_output_register = "ON",
|
||||
scfifo_component.intended_device_family = "MAX 10",
|
||||
scfifo_component.lpm_numwords = 1024,
|
||||
scfifo_component.lpm_showahead = "ON",
|
||||
scfifo_component.lpm_type = "scfifo",
|
||||
scfifo_component.lpm_width = 32,
|
||||
scfifo_component.lpm_width = 8,
|
||||
scfifo_component.lpm_widthu = 10,
|
||||
scfifo_component.overflow_checking = "ON",
|
||||
scfifo_component.underflow_checking = "ON",
|
||||
@ -102,23 +102,23 @@ endmodule
|
||||
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Depth NUMERIC "1024"
|
||||
// Retrieval info: PRIVATE: Empty NUMERIC "0"
|
||||
// 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 "0"
|
||||
// Retrieval info: PRIVATE: Optimize NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: UsedW NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: Width NUMERIC "32"
|
||||
// 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 "32"
|
||||
// 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"
|
||||
@ -128,36 +128,36 @@ endmodule
|
||||
// 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: ADD_RAM_OUTPUT_REGISTER STRING "ON"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"
|
||||
// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
|
||||
// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "10"
|
||||
// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
|
||||
// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
|
||||
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
|
||||
// Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL "data[31..0]"
|
||||
// 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 32 0 OUTPUT NODEFVAL "q[31..0]"
|
||||
// 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: usedw 0 0 10 0 OUTPUT NODEFVAL "usedw[9..0]"
|
||||
// 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 32 0 data 0 0 32 0
|
||||
// Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
|
||||
// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
|
||||
// Retrieval info: CONNECT: @sclr 0 0 0 0 sclr 0 0 0 0
|
||||
// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
|
||||
// Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0
|
||||
// Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 32 0 @q 0 0 32 0
|
||||
// Retrieval info: CONNECT: usedw 0 0 10 0 @usedw 0 0 10 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_usb.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_usb.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_usb.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_usb.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_usb_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_usb_bb.v FALSE
|
||||
// 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
|
@ -6,7 +6,7 @@
|
||||
version="1.0"
|
||||
description=""
|
||||
tags="INTERNAL_COMPONENT=true"
|
||||
categories="" />
|
||||
categories="System" />
|
||||
<parameter name="bonusData"><![CDATA[bonusData
|
||||
{
|
||||
element onchip_flash_0
|
||||
@ -68,11 +68,11 @@
|
||||
<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 only,Read only,Hidden,Read only,Hidden</parameter>
|
||||
<parameter name="SECTOR_ACCESS_MODE">Read only,Read only,Hidden,Read only,Read only</parameter>
|
||||
<parameter name="autoInitializationFileName">$${FILENAME}_onchip_flash_0</parameter>
|
||||
<parameter name="initFlashContent" value="true" />
|
||||
<parameter name="initializationFileName">../sw/bootloader/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="initializationFileNameForSim">../sw/bootloader/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="initializationFileName">../sw/n64/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="initializationFileNameForSim">../sw/n64/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="useNonDefaultInitFile" value="true" />
|
||||
</module>
|
||||
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
|
@ -1,76 +0,0 @@
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_TOOL_NAME "altera_gpio_lite"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_TOOL_VERSION "20.1"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_TOOL_ENV "mwpim"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_TARGETED_DEVICE_FAMILY "MAX 10"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_QSYS_MODE "UNKNOWN"
|
||||
set_global_assignment -name SYNTHESIS_ONLY_QIP ON
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_NAME "Z3Bpb19kZHJv"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_DISPLAY_NAME "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_REPORT_HIERARCHY "Off"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_INTERNAL "Off"
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24="
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_VERSION "MjAuMQ=="
|
||||
set_global_assignment -entity "gpio_ddro" -library "gpio_ddro" -name IP_COMPONENT_DESCRIPTION "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_NAME "YWx0ZXJhX2dwaW9fbGl0ZQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_DISPLAY_NAME "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_REPORT_HIERARCHY "Off"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_INTERNAL "Off"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_VERSION "MjAuMQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_DESCRIPTION "R1BJTyBMaXRlIEludGVsIEZQR0EgSVA="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "REVWSUNFX0ZBTUlMWQ==::TUFYIDEw::RGV2aWNlIGZhbWlseQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "UElOX1RZUEU=::b3V0cHV0::RGF0YSBkaXJlY3Rpb24="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "U0laRQ==::MQ==::RGF0YSB3aWR0aA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3RydWVfZGlmZl9idWY=::ZmFsc2U=::VXNlIHRydWUgZGlmZmVyZW50aWFsIGJ1ZmZlcg=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3BzZXVkb19kaWZmX2J1Zg==::ZmFsc2U=::VXNlIHBzZXVkbyBkaWZmZXJlbnRpYWwgYnVmZmVy"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2J1c19ob2xk::ZmFsc2U=::VXNlIGJ1cy1ob2xkIGNpcmN1aXRyeQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX29wZW5fZHJhaW4=::ZmFsc2U=::VXNlIG9wZW4gZHJhaW4gb3V0cHV0"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9vZV9wb3J0::ZmFsc2U=::RW5hYmxlIG9lIHBvcnQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2lvX3JlZ19tb2Rl::ZGRy::UmVnaXN0ZXIgbW9kZQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9hY2xyX3BvcnQ=::ZmFsc2U=::RW5hYmxlIGFjbHIgcG9ydA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9hc2V0X3BvcnQ=::ZmFsc2U=::RW5hYmxlIGFzZXQgcG9ydA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9zY2xyX3BvcnQ=::ZmFsc2U=::RW5hYmxlIHNjbHIgcG9ydA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3NldF9yZWdpc3RlcnNfdG9fcG93ZXJfdXBfaGlnaA==::ZmFsc2U=::U2V0IHJlZ2lzdGVycyB0byBwb3dlciB1cCBoaWdoICh3aGVuIGFjbHIsIHNjbHIgYW5kIGFzZXQgcG9ydHMgYXJlIG5vdCB1c2VkKQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2Nsb2NrX2VuYWJsZQ==::dHJ1ZQ==::RW5hYmxlIGluY2xvY2tlbi9vdXRjbG9ja2VuIHBvcnRz"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vdXRwdXQ=::ZmFsc2U=::SW52ZXJ0IGRpbg=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9yZWdpc3Rlcl90b19kcml2ZV9vYnVmX29l::ZmFsc2U=::VXNlIGEgc2luZ2xlIHJlZ2lzdGVyIHRvIGRyaXZlIHRoZSBvdXRwdXQgZW5hYmxlIChvZSkgc2lnbmFsIGF0IHRoZSBJL08gYnVmZmVy"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9kZGlvX3JlZ190b19kcml2ZV9vZQ==::ZmFsc2U=::VXNlIERESU8gcmVnaXN0ZXJzIHRvIGRyaXZlIHRoZSBvdXRwdXQgZW5hYmxlIChvZSkgc2lnbmFsIGF0IHRoZSBJL08gYnVmZmVy"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9hZHZhbmNlZF9kZHJfZmVhdHVyZXM=::ZmFsc2U=::RW5hYmxlIGFkdmFuY2VkIEREUiBmZWF0dXJlcw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9waGFzZV9kZXRlY3Rvcl9mb3JfY2s=::ZmFsc2U=::RW5hYmxlIFBoYXNlIERldGVjdG9yIGZyb20gQ0sgbG9vcGJhY2sgc2lnbmFs"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9vZV9oYWxmX2N5Y2xlX2RlbGF5::dHJ1ZQ==::QWRkIGhhbGYtY3ljbGUgZGVsYXkgdG8gT0Ugc2lnbmFs"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9ocl9jbG9jaw==::ZmFsc2U=::RW5hYmxlIGhhbGYtcmF0ZSBjbG9jayBwb3J0"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9pbnZlcnRfaHJfY2xvY2tfcG9ydA==::ZmFsc2U=::RW5hYmxlIGludmVydF9ocl9jbG9jayBwb3J0"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9jbGtkaXZfaW5wdXRfY2xvY2s=::ZmFsc2U=::SW52ZXJ0IGNsb2NrIGRpdmlkZXIgaW5wdXQgY2xvY2s="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vdXRwdXRfY2xvY2s=::ZmFsc2U=::SW52ZXJ0IERESU8gb3V0Y2xvY2s="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "Z3VpX2ludmVydF9vZV9pbmNsb2Nr::ZmFsc2U=::SW52ZXJ0IG91dHB1dCBlbmFibGUgKG9lKSByZWdpc3RlciBpbmNsb2Nr"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "UkVHSVNURVJfTU9ERQ==::ZGRy::UkVHSVNURVJfTU9ERQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "QlVGRkVSX1RZUEU=::c2luZ2xlLWVuZGVk::QlVGRkVSX1RZUEU="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "QVNZTkNfTU9ERQ==::bm9uZQ==::QVNZTkNfTU9ERQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "U1lOQ19NT0RF::bm9uZQ==::U1lOQ19NT0RF"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "QlVTX0hPTEQ=::ZmFsc2U=::QlVTX0hPTEQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "T1BFTl9EUkFJTl9PVVRQVVQ=::ZmFsc2U=::T1BFTl9EUkFJTl9PVVRQVVQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX09FX1BPUlQ=::ZmFsc2U=::RU5BQkxFX09FX1BPUlQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX05TTEVFUF9QT1JU::ZmFsc2U=::RU5BQkxFX05TTEVFUF9QT1JU"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0NMT0NLX0VOQV9QT1JU::dHJ1ZQ==::RU5BQkxFX0NMT0NLX0VOQV9QT1JU"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "U0VUX1JFR0lTVEVSX09VVFBVVFNfSElHSA==::ZmFsc2U=::U0VUX1JFR0lTVEVSX09VVFBVVFNfSElHSA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09VVFBVVA==::ZmFsc2U=::SU5WRVJUX09VVFBVVA=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX0lOUFVUX0NMT0NL::ZmFsc2U=::SU5WRVJUX0lOUFVUX0NMT0NL"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX09ORV9SRUdfVE9fRFJJVkVfT0U=::ZmFsc2U=::VVNFX09ORV9SRUdfVE9fRFJJVkVfT0U="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0RESU9fUkVHX1RPX0RSSVZFX09F::ZmFsc2U=::VVNFX0RESU9fUkVHX1RPX0RSSVZFX09F"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFUw==::ZmFsc2U=::VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFUw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFU19GT1JfSU5QVVRfT05MWQ==::ZmFsc2U=::VVNFX0FEVkFOQ0VEX0REUl9GRUFUVVJFU19GT1JfSU5QVVRfT05MWQ=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX09FX0hBTEZfQ1lDTEVfREVMQVk=::dHJ1ZQ==::RU5BQkxFX09FX0hBTEZfQ1lDTEVfREVMQVk="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX0NMS0RJVl9JTlBVVF9DTE9DSw==::ZmFsc2U=::SU5WRVJUX0NMS0RJVl9JTlBVVF9DTE9DSw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX1BIQVNFX0lOVkVSVF9DVFJMX1BPUlQ=::ZmFsc2U=::RU5BQkxFX1BIQVNFX0lOVkVSVF9DVFJMX1BPUlQ="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0hSX0NMT0NL::ZmFsc2U=::RU5BQkxFX0hSX0NMT0NL"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09VVFBVVF9DTE9DSw==::ZmFsc2U=::SU5WRVJUX09VVFBVVF9DTE9DSw=="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "SU5WRVJUX09FX0lOQ0xPQ0s=::ZmFsc2U=::SU5WRVJUX09FX0lOQ0xPQ0s="
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_COMPONENT_PARAMETER "RU5BQkxFX1BIQVNFX0RFVEVDVE9SX0ZPUl9DSw==::ZmFsc2U=::RU5BQkxFX1BIQVNFX0RFVEVDVE9SX0ZPUl9DSw=="
|
||||
|
||||
set_global_assignment -library "gpio_ddro" -name VERILOG_FILE [file join $::quartus(qip_path) "gpio_ddro.v"]
|
||||
set_global_assignment -library "gpio_ddro" -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "gpio_ddro/altera_gpio_lite.sv"]
|
||||
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_TOOL_NAME "altera_gpio_lite"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_TOOL_VERSION "20.1"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "gpio_ddro" -name IP_TOOL_ENV "mwpim"
|
77
fw/rtl/intel/gpio/intel_gpio_ddro.qip
Normal file
77
fw/rtl/intel/gpio/intel_gpio_ddro.qip
Normal file
@ -0,0 +1,77 @@
|
||||
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 "20.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 "MjAuMQ=="
|
||||
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 "MjAuMQ=="
|
||||
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 "20.1"
|
||||
set_global_assignment -entity "altera_gpio_lite" -library "intel_gpio_ddro" -name IP_TOOL_ENV "mwpim"
|
@ -1,15 +1,14 @@
|
||||
// megafunction wizard: %GPIO Lite Intel FPGA IP v20.1%
|
||||
// GENERATION: XML
|
||||
// gpio_ddro.v
|
||||
// intel_gpio_ddro.v
|
||||
|
||||
// Generated using ACDS version 20.1 711
|
||||
// Generated using ACDS version 20.1 720
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
module gpio_ddro (
|
||||
input wire outclock, // outclock.export
|
||||
input wire outclocken, // outclocken.export
|
||||
input wire [1:0] din, // din.export
|
||||
output wire [0:0] pad_out // pad_out.export
|
||||
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 #(
|
||||
@ -23,7 +22,7 @@ module gpio_ddro (
|
||||
.OPEN_DRAIN_OUTPUT ("false"),
|
||||
.ENABLE_OE_PORT ("false"),
|
||||
.ENABLE_NSLEEP_PORT ("false"),
|
||||
.ENABLE_CLOCK_ENA_PORT ("true"),
|
||||
.ENABLE_CLOCK_ENA_PORT ("false"),
|
||||
.SET_REGISTER_OUTPUTS_HIGH ("false"),
|
||||
.INVERT_OUTPUT ("false"),
|
||||
.INVERT_INPUT_CLOCK ("false"),
|
||||
@ -38,29 +37,29 @@ module gpio_ddro (
|
||||
.INVERT_OUTPUT_CLOCK ("false"),
|
||||
.INVERT_OE_INCLOCK ("false"),
|
||||
.ENABLE_PHASE_DETECTOR_FOR_CK ("false")
|
||||
) gpio_ddro_inst (
|
||||
.outclock (outclock), // outclock.export
|
||||
.outclocken (outclocken), // outclocken.export
|
||||
.din (din), // din.export
|
||||
.pad_out (pad_out), // pad_out.export
|
||||
.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)
|
||||
) 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
|
||||
@ -70,7 +69,7 @@ endmodule
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
// ************************************************************
|
||||
// Copyright (C) 1991-2020 Altera Corporation
|
||||
// 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
|
||||
@ -105,7 +104,7 @@ endmodule
|
||||
// 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="true" />
|
||||
// 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" />
|
||||
@ -120,5 +119,5 @@ endmodule
|
||||
// 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 : gpio_ddro.vo
|
||||
// RELATED_FILES: gpio_ddro.v, altera_gpio_lite.sv
|
||||
// IPFS_FILES : intel_gpio_ddro.vo
|
||||
// RELATED_FILES: intel_gpio_ddro.v, altera_gpio_lite.sv
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE pinplan>
|
||||
<pinplan intended_family="MAX 10" variation_name="pll" megafunction_name="ALTPLL" specifies="all_ports">
|
||||
<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" />
|
@ -1,5 +1,5 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
|
||||
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"]
|
@ -4,7 +4,7 @@
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll.v
|
||||
// File Name: intel_pll.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
@ -37,7 +37,7 @@
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll (
|
||||
module intel_pll (
|
||||
inclk0,
|
||||
c0,
|
||||
c1,
|
||||
@ -110,7 +110,7 @@ module pll (
|
||||
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=pll",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=intel_pll",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "NORMAL",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
@ -168,7 +168,7 @@ endmodule
|
||||
// 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 "High"
|
||||
// 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"
|
||||
@ -179,7 +179,7 @@ endmodule
|
||||
// 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 "8"
|
||||
// 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"
|
||||
@ -236,7 +236,7 @@ endmodule
|
||||
// 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 "pll.mif"
|
||||
// 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"
|
||||
@ -330,12 +330,12 @@ endmodule
|
||||
// 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 pll.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE
|
||||
// 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
|
@ -1,4 +0,0 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "ram_n64_eeprom.v"]
|
@ -1,243 +0,0 @@
|
||||
// megafunction wizard: %RAM: 2-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: ram_n64_eeprom.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//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.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module ram_n64_eeprom (
|
||||
address_a,
|
||||
address_b,
|
||||
clock,
|
||||
data_a,
|
||||
data_b,
|
||||
wren_a,
|
||||
wren_b,
|
||||
q_a,
|
||||
q_b);
|
||||
|
||||
input [10:0] address_a;
|
||||
input [8:0] address_b;
|
||||
input clock;
|
||||
input [7:0] data_a;
|
||||
input [31:0] data_b;
|
||||
input wren_a;
|
||||
input wren_b;
|
||||
output [7:0] q_a;
|
||||
output [31:0] q_b;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri1 clock;
|
||||
tri0 wren_a;
|
||||
tri0 wren_b;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [7:0] sub_wire0;
|
||||
wire [31:0] sub_wire1;
|
||||
wire [7:0] q_a = sub_wire0[7:0];
|
||||
wire [31:0] q_b = sub_wire1[31:0];
|
||||
|
||||
altsyncram altsyncram_component (
|
||||
.address_a (address_a),
|
||||
.address_b (address_b),
|
||||
.clock0 (clock),
|
||||
.data_a (data_a),
|
||||
.data_b (data_b),
|
||||
.wren_a (wren_a),
|
||||
.wren_b (wren_b),
|
||||
.q_a (sub_wire0),
|
||||
.q_b (sub_wire1),
|
||||
.aclr0 (1'b0),
|
||||
.aclr1 (1'b0),
|
||||
.addressstall_a (1'b0),
|
||||
.addressstall_b (1'b0),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clock1 (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.clocken2 (1'b1),
|
||||
.clocken3 (1'b1),
|
||||
.eccstatus (),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1));
|
||||
defparam
|
||||
altsyncram_component.address_reg_b = "CLOCK0",
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.indata_reg_b = "CLOCK0",
|
||||
altsyncram_component.intended_device_family = "MAX 10",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 2048,
|
||||
altsyncram_component.numwords_b = 512,
|
||||
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
altsyncram_component.outdata_aclr_b = "NONE",
|
||||
altsyncram_component.outdata_reg_a = "UNREGISTERED",
|
||||
altsyncram_component.outdata_reg_b = "UNREGISTERED",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
|
||||
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
|
||||
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
|
||||
altsyncram_component.widthad_a = 11,
|
||||
altsyncram_component.widthad_b = 9,
|
||||
altsyncram_component.width_a = 8,
|
||||
altsyncram_component.width_b = 32,
|
||||
altsyncram_component.width_byteena_a = 1,
|
||||
altsyncram_component.width_byteena_b = 1,
|
||||
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MEMSIZE NUMERIC "16384"
|
||||
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGq NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: REGrren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: VarWidth NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: enable NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "2048"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
|
||||
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "11"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
|
||||
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "32"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
|
||||
// Retrieval info: USED_PORT: address_a 0 0 11 0 INPUT NODEFVAL "address_a[10..0]"
|
||||
// Retrieval info: USED_PORT: address_b 0 0 9 0 INPUT NODEFVAL "address_b[8..0]"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
// Retrieval info: USED_PORT: data_a 0 0 8 0 INPUT NODEFVAL "data_a[7..0]"
|
||||
// Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]"
|
||||
// Retrieval info: USED_PORT: q_a 0 0 8 0 OUTPUT NODEFVAL "q_a[7..0]"
|
||||
// Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]"
|
||||
// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
|
||||
// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
|
||||
// Retrieval info: CONNECT: @address_a 0 0 11 0 address_a 0 0 11 0
|
||||
// Retrieval info: CONNECT: @address_b 0 0 9 0 address_b 0 0 9 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 8 0 data_a 0 0 8 0
|
||||
// Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0
|
||||
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
|
||||
// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
|
||||
// Retrieval info: CONNECT: q_a 0 0 8 0 @q_a 0 0 8 0
|
||||
// Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
76
fw/rtl/intel/snp/intel_snp.qsys
Normal file
76
fw/rtl/intel/snp/intel_snp.qsys
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<system name="$${FILENAME}">
|
||||
<component
|
||||
name="$${FILENAME}"
|
||||
displayName="$${FILENAME}"
|
||||
version="1.0"
|
||||
description=""
|
||||
tags="INTERNAL_COMPONENT=true"
|
||||
categories="" />
|
||||
<parameter name="bonusData"><![CDATA[bonusData
|
||||
{
|
||||
element in_system_sources_probes_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="probes" internal="in_system_sources_probes_0.probes" />
|
||||
<interface
|
||||
name="source_clk"
|
||||
internal="in_system_sources_probes_0.source_clk"
|
||||
type="clock"
|
||||
dir="end">
|
||||
<port name="source_clk" internal="source_clk" />
|
||||
</interface>
|
||||
<interface
|
||||
name="sources"
|
||||
internal="in_system_sources_probes_0.sources"
|
||||
type="conduit"
|
||||
dir="end">
|
||||
<port name="source" internal="source" />
|
||||
</interface>
|
||||
<module
|
||||
name="in_system_sources_probes_0"
|
||||
kind="altera_in_system_sources_probes"
|
||||
version="20.1"
|
||||
enabled="1"
|
||||
autoexport="1">
|
||||
<parameter name="create_source_clock" value="true" />
|
||||
<parameter name="create_source_clock_enable" value="false" />
|
||||
<parameter name="device_family" value="MAX 10" />
|
||||
<parameter name="gui_use_auto_index" value="true" />
|
||||
<parameter name="instance_id" value="SC64" />
|
||||
<parameter name="probe_width" value="0" />
|
||||
<parameter name="sld_instance_index" value="0" />
|
||||
<parameter name="source_initial_value" value="0" />
|
||||
<parameter name="source_width" value="1" />
|
||||
</module>
|
||||
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
|
||||
<interconnectRequirement for="$system" name="qsys_mm.enableEccProtection" value="FALSE" />
|
||||
<interconnectRequirement for="$system" name="qsys_mm.insertDefaultSlave" value="FALSE" />
|
||||
<interconnectRequirement for="$system" name="qsys_mm.maxAdditionalLatency" value="1" />
|
||||
</system>
|
@ -1,56 +0,0 @@
|
||||
module memory_embedded_flash (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_request,
|
||||
output reg o_busy,
|
||||
output o_ack,
|
||||
input [18:0] i_address,
|
||||
output reg [31:0] o_data
|
||||
);
|
||||
|
||||
localparam [18:0] ONCHIP_FLASH_END = 19'h059FF;
|
||||
|
||||
wire w_onchip_flash_in_address_range = i_address <= ONCHIP_FLASH_END;
|
||||
|
||||
reg r_dummy_ack;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_dummy_ack <= i_request && !w_onchip_flash_in_address_range;
|
||||
end
|
||||
|
||||
reg r_onchip_flash_request;
|
||||
wire w_onchip_flash_busy;
|
||||
wire w_onchip_flash_ack;
|
||||
wire [31:0] w_onchip_flash_o_data;
|
||||
|
||||
assign o_ack = r_dummy_ack || w_onchip_flash_ack;
|
||||
|
||||
always @(*) begin
|
||||
r_onchip_flash_request = 1'b0;
|
||||
o_busy = 1'b0;
|
||||
o_data = 32'h0000_0000;
|
||||
if (w_onchip_flash_in_address_range) begin
|
||||
r_onchip_flash_request = i_request;
|
||||
o_busy = w_onchip_flash_busy;
|
||||
o_data = {
|
||||
w_onchip_flash_o_data[7:0],
|
||||
w_onchip_flash_o_data[15:8],
|
||||
w_onchip_flash_o_data[23:16],
|
||||
w_onchip_flash_o_data[31:24]
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
onchip_flash onchip_flash_inst (
|
||||
.clock(i_clk),
|
||||
.reset_n(~i_reset),
|
||||
.avmm_data_addr(i_address[14:0]),
|
||||
.avmm_data_read(r_onchip_flash_request),
|
||||
.avmm_data_readdata(w_onchip_flash_o_data),
|
||||
.avmm_data_waitrequest(w_onchip_flash_busy),
|
||||
.avmm_data_readdatavalid(w_onchip_flash_ack),
|
||||
.avmm_data_burstcount(2'd1)
|
||||
);
|
||||
|
||||
endmodule
|
76
fw/rtl/memory/memory_flash.sv
Normal file
76
fw/rtl/memory/memory_flash.sv
Normal file
@ -0,0 +1,76 @@
|
||||
module memory_flash (
|
||||
if_system.sys sys,
|
||||
|
||||
input request,
|
||||
output ack,
|
||||
input [31:0] address,
|
||||
output [15:0] rdata
|
||||
);
|
||||
|
||||
logic flash_enable;
|
||||
logic flash_request;
|
||||
logic flash_busy;
|
||||
logic flash_ack;
|
||||
logic [31:0] flash_rdata;
|
||||
|
||||
logic dummy_ack;
|
||||
|
||||
always_comb begin
|
||||
flash_enable = address < 32'h10016800;
|
||||
|
||||
ack = flash_ack | dummy_ack;
|
||||
|
||||
rdata = 16'd0;
|
||||
if (ack && flash_enable) begin
|
||||
if (address[1]) rdata = {flash_rdata[23:16], flash_rdata[31:24]};
|
||||
else rdata = {flash_rdata[7:0], flash_rdata[15:8]};
|
||||
end
|
||||
end
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
dummy_ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
flash_request <= 1'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (request) begin
|
||||
state <= S_WAIT;
|
||||
flash_request <= flash_enable;
|
||||
dummy_ack <= !flash_enable;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
if (!flash_busy) begin
|
||||
flash_request <= 1'b0;
|
||||
end
|
||||
if (ack) begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
intel_flash intel_flash_inst (
|
||||
.clock(sys.clk),
|
||||
.reset_n(~sys.reset),
|
||||
.avmm_data_addr(address[31:2]),
|
||||
.avmm_data_read(flash_request),
|
||||
.avmm_data_readdata(flash_rdata),
|
||||
.avmm_data_waitrequest(flash_busy),
|
||||
.avmm_data_readdatavalid(flash_ack),
|
||||
.avmm_data_burstcount(2'd1)
|
||||
);
|
||||
|
||||
endmodule
|
233
fw/rtl/memory/memory_sdram.sv
Normal file
233
fw/rtl/memory/memory_sdram.sv
Normal file
@ -0,0 +1,233 @@
|
||||
module memory_sdram (
|
||||
if_system sys,
|
||||
|
||||
input request,
|
||||
output ack,
|
||||
input write,
|
||||
input [25:0] address,
|
||||
output [15:0] rdata,
|
||||
input [15:0] wdata,
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
parameter [2:0] CAS_LATENCY = 3'd2;
|
||||
|
||||
parameter real T_INIT = 100_000.0;
|
||||
parameter real T_RC = 60.0;
|
||||
parameter real T_RP = 15.0;
|
||||
parameter real T_RCD = 15.0;
|
||||
// parameter real T_RAS = 37.0; //TODO: handle this timing
|
||||
// parameter real T_WR = T_RAS - T_RCD; //TODO: handle this timing
|
||||
parameter real T_MRD = 14.0;
|
||||
parameter real T_REF = 7_800.0;
|
||||
|
||||
localparam real T_CLK = (1.0 / sc64::CLOCK_FREQUENCY) * 1_000_000_000.0;
|
||||
localparam int C_INIT = int'((T_INIT + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RC = int'((T_RC + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RP = int'((T_RP + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RCD = int'((T_RCD + T_CLK - 1) / T_CLK);
|
||||
// localparam int C_RAS = int'((T_RAS + T_CLK - 1) / T_CLK);
|
||||
// localparam int C_WR = int'((T_WR + T_CLK - 1) / T_CLK);
|
||||
localparam int C_MRD = int'((T_MRD + T_CLK - 1) / T_CLK);
|
||||
localparam int C_REF = int'((T_REF + T_CLK - 1) / T_CLK);
|
||||
|
||||
localparam INIT_PRECHARGE = C_INIT;
|
||||
localparam INIT_REFRESH_1 = C_INIT + C_RP;
|
||||
localparam INIT_REFRESH_2 = C_INIT + C_RP + C_RC;
|
||||
localparam INIT_MODE_REG = C_INIT + C_RP + (2 * C_RC);
|
||||
localparam INIT_DONE = C_INIT + C_RP + (2 * C_RC) + C_MRD;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
CMD_DESL = 4'b1111,
|
||||
CMD_NOP = 4'b0111,
|
||||
CMD_READ = 4'b0101,
|
||||
CMD_WRITE = 4'b0100,
|
||||
CMD_ACT = 4'b0011,
|
||||
CMD_PRE = 4'b0010,
|
||||
CMD_REF = 4'b0001,
|
||||
CMD_MRS = 4'b0000
|
||||
} e_sdram_cmd;
|
||||
|
||||
e_sdram_cmd sdram_next_cmd;
|
||||
logic [15:0] sdram_dq_input;
|
||||
logic [15:0] sdram_dq_output;
|
||||
logic sdram_dq_output_enable;
|
||||
|
||||
logic [14:0] current_active_bank_row;
|
||||
logic request_in_current_active_bank_row;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
{sdram_cs, sdram_ras, sdram_cas, sdram_we} <= 4'(sdram_next_cmd);
|
||||
|
||||
{sdram_ba, sdram_a} <= 15'd0;
|
||||
|
||||
sdram_dq_input <= sdram_dq;
|
||||
sdram_dq_output <= wdata;
|
||||
|
||||
sdram_dq_output_enable <= 1'b0;
|
||||
|
||||
case (sdram_next_cmd)
|
||||
CMD_READ, CMD_WRITE: begin
|
||||
{sdram_ba, sdram_a} <= {address[25:24], 3'b000, address[10:1]};
|
||||
sdram_dq_output_enable <= sdram_next_cmd == CMD_WRITE;
|
||||
end
|
||||
CMD_ACT: begin
|
||||
{sdram_ba, sdram_a} <= address[25:11];
|
||||
current_active_bank_row <= address[25:11];
|
||||
end
|
||||
CMD_PRE: {sdram_ba, sdram_a} <= {2'b00, 2'b00, 1'b1, 10'd0};
|
||||
CMD_MRS: {sdram_ba, sdram_a} <= {2'b00, 1'b0, 1'b0, 2'b00, CAS_LATENCY, 1'b0, 3'b000};
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
rdata = sdram_dq_input;
|
||||
sdram_dq = sdram_dq_output_enable ? sdram_dq_output : 16'hZZZZ;
|
||||
request_in_current_active_bank_row = address[25:11] == current_active_bank_row;
|
||||
end
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
S_INIT,
|
||||
S_IDLE,
|
||||
S_ACTIVATING,
|
||||
S_ACTIVE,
|
||||
S_BUSY,
|
||||
S_PRECHARGE,
|
||||
S_REFRESH
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
e_state next_state;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
state <= S_INIT;
|
||||
end else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
logic [13:0] wait_counter;
|
||||
logic [9:0] refresh_counter;
|
||||
logic pending_refresh;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || state != next_state) begin
|
||||
wait_counter <= 14'd0;
|
||||
end else begin
|
||||
wait_counter <= wait_counter + 1'd1;
|
||||
end
|
||||
|
||||
if (sdram_next_cmd == CMD_REF) begin
|
||||
refresh_counter <= 10'd0;
|
||||
end else if (refresh_counter < 10'h3FF) begin
|
||||
refresh_counter <= refresh_counter + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
pending_refresh = refresh_counter >= C_REF;
|
||||
end
|
||||
|
||||
logic [(CAS_LATENCY):0] read_cmd_ack_delay;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
ack <= 1'b0;
|
||||
read_cmd_ack_delay <= {sdram_next_cmd == CMD_READ, read_cmd_ack_delay[(CAS_LATENCY):1]};
|
||||
|
||||
if (sdram_next_cmd == CMD_WRITE || read_cmd_ack_delay[0]) begin
|
||||
ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
sdram_next_cmd = CMD_NOP;
|
||||
next_state = state;
|
||||
|
||||
case (state)
|
||||
S_INIT: begin
|
||||
if (wait_counter < INIT_PRECHARGE) begin
|
||||
sdram_next_cmd = CMD_DESL;
|
||||
end
|
||||
if (wait_counter == INIT_PRECHARGE) begin
|
||||
sdram_next_cmd = CMD_PRE;
|
||||
end
|
||||
if (wait_counter == INIT_REFRESH_1 || wait_counter == INIT_REFRESH_2) begin
|
||||
sdram_next_cmd = CMD_REF;
|
||||
end
|
||||
if (wait_counter == INIT_MODE_REG) begin
|
||||
sdram_next_cmd = CMD_MRS;
|
||||
end
|
||||
if (wait_counter == INIT_DONE) begin
|
||||
next_state = S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_IDLE: begin
|
||||
if (pending_refresh) begin
|
||||
next_state = S_REFRESH;
|
||||
sdram_next_cmd = CMD_REF;
|
||||
end else if (request) begin
|
||||
next_state = S_ACTIVATING;
|
||||
sdram_next_cmd = CMD_ACT;
|
||||
end
|
||||
end
|
||||
|
||||
S_ACTIVATING: begin
|
||||
if (wait_counter == C_RCD) begin
|
||||
next_state = S_ACTIVE;
|
||||
end
|
||||
end
|
||||
|
||||
S_ACTIVE: begin
|
||||
if (pending_refresh) begin
|
||||
next_state = S_PRECHARGE;
|
||||
sdram_next_cmd = CMD_PRE;
|
||||
end else if (request) begin
|
||||
if (request_in_current_active_bank_row) begin
|
||||
next_state = S_BUSY;
|
||||
sdram_next_cmd = write ? CMD_WRITE : CMD_READ;
|
||||
end else begin
|
||||
next_state = S_PRECHARGE;
|
||||
sdram_next_cmd = CMD_PRE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_BUSY: begin
|
||||
if (ack) begin
|
||||
next_state = S_ACTIVE;
|
||||
end
|
||||
end
|
||||
|
||||
S_PRECHARGE: begin
|
||||
if (wait_counter == C_RP) begin
|
||||
if (pending_refresh) begin
|
||||
next_state = S_REFRESH;
|
||||
sdram_next_cmd = CMD_REF;
|
||||
end else begin
|
||||
next_state = S_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_REFRESH: begin
|
||||
if (wait_counter == C_RC) begin
|
||||
next_state = S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
next_state = S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,371 +0,0 @@
|
||||
module memory_sdram (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
output o_sdram_cs,
|
||||
output o_sdram_ras,
|
||||
output o_sdram_cas,
|
||||
output o_sdram_we,
|
||||
output reg [1:0] o_sdram_ba,
|
||||
output reg [12:0] o_sdram_a,
|
||||
inout reg [15:0] io_sdram_dq,
|
||||
|
||||
input i_request,
|
||||
input i_write,
|
||||
output o_busy,
|
||||
output reg o_ack,
|
||||
input [24:0] i_address,
|
||||
output reg [31:0] o_data,
|
||||
input [31:0] i_data
|
||||
);
|
||||
|
||||
// SDRAM timings (in nanoseconds)
|
||||
|
||||
parameter real CLK_FREQ = 100_000_000.0;
|
||||
|
||||
parameter [2:0] CAS_LATENCY = 3'd2;
|
||||
|
||||
parameter real T_INIT = 100_000.0;
|
||||
parameter real T_RC = 60.0;
|
||||
parameter real T_RP = 15.0;
|
||||
parameter real T_RCD = 15.0;
|
||||
parameter real T_RAS = 37.0;
|
||||
parameter real T_WR = T_RAS - T_RCD;
|
||||
parameter real T_MRD = 14.0;
|
||||
parameter real T_REF = 7_800.0;
|
||||
|
||||
localparam real T_CLK = (1.0 / CLK_FREQ) * 1_000_000_000.0;
|
||||
localparam int C_INIT = int'((T_INIT + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RC = int'((T_RC + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RP = int'((T_RP + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RCD = int'((T_RCD + T_CLK - 1) / T_CLK);
|
||||
localparam int C_RAS = int'((T_RAS + T_CLK - 1) / T_CLK);
|
||||
localparam int C_WR = int'((T_WR + T_CLK - 1) / T_CLK);
|
||||
localparam int C_MRD = int'((T_MRD + T_CLK - 1) / T_CLK);
|
||||
localparam int C_REF = int'((T_REF + T_CLK - 1) / T_CLK);
|
||||
|
||||
localparam INIT_PRECHARGE = C_INIT;
|
||||
localparam INIT_REFRESH_1 = C_INIT + C_RP;
|
||||
localparam INIT_REFRESH_2 = C_INIT + C_RP + C_RC;
|
||||
localparam INIT_MODE_REG = C_INIT + C_RP + (2 * C_RC);
|
||||
localparam INIT_DONE = C_INIT + C_RP + (2 * C_RC) + C_MRD;
|
||||
|
||||
|
||||
// SDRAM commands (CS, RAS, CAS, WE) and mode register
|
||||
|
||||
localparam [3:0] CMD_DESL = 4'b1111;
|
||||
localparam [3:0] CMD_NOP = 4'b0111;
|
||||
localparam [3:0] CMD_READ = 4'b0101;
|
||||
localparam [3:0] CMD_WRITE = 4'b0100;
|
||||
localparam [3:0] CMD_ACT = 4'b0011;
|
||||
localparam [3:0] CMD_PRE = 4'b0010;
|
||||
localparam [3:0] CMD_REF = 4'b0001;
|
||||
localparam [3:0] CMD_MRS = 4'b0000;
|
||||
|
||||
localparam MODE_REGISTER = {2'b00, 1'b0, 1'b0, 2'b00, CAS_LATENCY, 1'b0, 3'b000};
|
||||
|
||||
|
||||
// Command signal decoder
|
||||
|
||||
reg [3:0] r_sdram_cmd;
|
||||
|
||||
assign {o_sdram_cs, o_sdram_ras, o_sdram_cas, o_sdram_we} = r_sdram_cmd;
|
||||
|
||||
|
||||
// Address signal decoder
|
||||
|
||||
reg r_sdram_precharge;
|
||||
reg [1:0] r_sdram_bank;
|
||||
reg [12:0] r_sdram_row;
|
||||
reg [9:0] r_sdram_column;
|
||||
reg [14:0] r_active_bank_row;
|
||||
|
||||
always @(*) begin
|
||||
case (r_sdram_cmd)
|
||||
CMD_READ, CMD_WRITE: o_sdram_a = {2'b00, r_sdram_precharge, r_sdram_column};
|
||||
CMD_ACT: o_sdram_a = r_sdram_row;
|
||||
CMD_PRE: o_sdram_a = {2'b00, r_sdram_precharge, 10'b0000000000};
|
||||
CMD_MRS: o_sdram_a = MODE_REGISTER;
|
||||
default: o_sdram_a = 13'b0000000000000;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (r_sdram_cmd)
|
||||
CMD_READ, CMD_WRITE, CMD_ACT, CMD_PRE: o_sdram_ba = r_sdram_bank;
|
||||
default: o_sdram_ba = 2'b00;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_request && !o_busy) begin
|
||||
{r_sdram_bank, r_sdram_row, r_sdram_column} <= i_address;
|
||||
end
|
||||
if (r_sdram_cmd == CMD_ACT) begin
|
||||
r_active_bank_row <= {r_sdram_bank, r_sdram_row};
|
||||
end
|
||||
if (r_sdram_cmd == CMD_READ || r_sdram_cmd == CMD_WRITE) begin
|
||||
{r_sdram_bank, r_sdram_row, r_sdram_column} <= {r_sdram_bank, r_sdram_row, r_sdram_column} + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire w_next_address_in_another_row = (&r_sdram_column);
|
||||
wire w_request_in_another_row = i_address[24:10] != r_active_bank_row;
|
||||
|
||||
|
||||
// Data signal decoder
|
||||
|
||||
reg [31:0] r_sdram_data;
|
||||
reg r_current_write_word;
|
||||
|
||||
always @(*) begin
|
||||
io_sdram_dq = 16'hZZZZ;
|
||||
if (r_sdram_cmd == CMD_WRITE) begin
|
||||
io_sdram_dq = r_current_write_word ? r_sdram_data[15:0] : r_sdram_data[31:16];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_current_write_word <= 1'b0;
|
||||
end else if (r_sdram_cmd == CMD_WRITE) begin
|
||||
r_current_write_word <= ~r_current_write_word;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Read latency timing
|
||||
|
||||
reg [(CAS_LATENCY - 1):0] r_read_latency;
|
||||
reg r_current_read_word;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= 1'b0;
|
||||
if (i_reset) begin
|
||||
r_read_latency <= {CAS_LATENCY{1'b0}};
|
||||
r_current_read_word <= 1'b0;
|
||||
end else begin
|
||||
r_read_latency <= {r_read_latency[(CAS_LATENCY - 2):0], r_sdram_cmd == CMD_READ};
|
||||
if (r_read_latency[CAS_LATENCY - 1]) begin
|
||||
o_data <= {o_data[15:0], io_sdram_dq};
|
||||
if (r_current_read_word) o_ack <= 1'b1;
|
||||
r_current_read_word <= ~r_current_read_word;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire w_read_pending = |r_read_latency;
|
||||
|
||||
|
||||
// Init timing and logic
|
||||
|
||||
reg [15:0] r_init_counter;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_init_counter <= 16'd0;
|
||||
end else if (r_init_counter < INIT_DONE) begin
|
||||
r_init_counter <= r_init_counter + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
wire w_init_hold = r_init_counter <= C_INIT - 1;
|
||||
wire w_init_precharge = r_init_counter == INIT_PRECHARGE;
|
||||
wire w_init_refresh_1 = r_init_counter == INIT_REFRESH_1;
|
||||
wire w_init_refresh_2 = r_init_counter == INIT_REFRESH_2;
|
||||
wire w_init_mode_reg = r_init_counter == INIT_MODE_REG;
|
||||
wire w_init_done = r_init_counter == INIT_DONE;
|
||||
|
||||
|
||||
// SDRAM controller FSM
|
||||
|
||||
localparam [2:0] STATE_INIT = 3'd0;
|
||||
localparam [2:0] STATE_IDLE = 3'd1;
|
||||
localparam [2:0] STATE_ACTIVATING = 3'd2;
|
||||
localparam [2:0] STATE_ACTIVE = 3'd3;
|
||||
localparam [2:0] STATE_PRECHARGING = 3'd4;
|
||||
localparam [2:0] STATE_REFRESHING = 3'd5;
|
||||
|
||||
reg [9:0] r_refresh_counter;
|
||||
reg [4:0] r_rcd_ras_rc_counter;
|
||||
reg [1:0] r_wr_counter;
|
||||
reg [2:0] r_rp_counter;
|
||||
|
||||
wire w_refresh_pending = r_refresh_counter >= (C_REF - 1'd1);
|
||||
wire w_rcd_timing_met = r_rcd_ras_rc_counter >= (C_RCD - 1'd1);
|
||||
wire w_ras_timing_met = r_rcd_ras_rc_counter >= (C_RAS - 1'd1);
|
||||
wire w_rc_timing_met = r_rcd_ras_rc_counter >= (C_RC - 1'd1);
|
||||
wire w_wr_timing_met = r_wr_counter >= (C_WR - 1'd1);
|
||||
wire w_rp_timing_met = r_rp_counter >= (C_RP - 1'd1);
|
||||
|
||||
reg [2:0] r_state;
|
||||
reg r_busy;
|
||||
reg r_cross_row_request;
|
||||
reg r_request_pending;
|
||||
reg r_write_pending;
|
||||
reg r_current_word;
|
||||
reg r_wr_wait;
|
||||
|
||||
assign o_busy = i_request && (
|
||||
w_refresh_pending ||
|
||||
r_busy ||
|
||||
r_request_pending ||
|
||||
r_cross_row_request ||
|
||||
w_read_pending ||
|
||||
r_sdram_cmd == CMD_READ ||
|
||||
r_sdram_cmd == CMD_WRITE
|
||||
);
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || w_init_hold) begin
|
||||
r_sdram_cmd <= CMD_DESL;
|
||||
r_state <= STATE_INIT;
|
||||
r_busy <= 1'b1;
|
||||
r_cross_row_request <= 1'b0;
|
||||
r_wr_wait <= 1'b0;
|
||||
end else begin
|
||||
r_sdram_cmd <= CMD_NOP;
|
||||
r_sdram_precharge <= 1'b0;
|
||||
|
||||
if (r_refresh_counter < (C_REF - 1)) r_refresh_counter <= r_refresh_counter + 1'd1;
|
||||
if (r_rcd_ras_rc_counter < (C_RC - 1)) r_rcd_ras_rc_counter <= r_rcd_ras_rc_counter + 1'd1;
|
||||
if (r_wr_counter < (C_WR - 1)) r_wr_counter <= r_wr_counter + 1'd1;
|
||||
if (r_rp_counter < (C_RP - 1)) r_rp_counter <= r_rp_counter + 1'd1;
|
||||
|
||||
case (r_state)
|
||||
STATE_INIT: begin
|
||||
if (w_init_precharge) begin
|
||||
r_sdram_cmd <= CMD_PRE;
|
||||
r_sdram_precharge <= 1'b1;
|
||||
end else if (w_init_refresh_1 || w_init_refresh_2) begin
|
||||
r_sdram_cmd <= CMD_REF;
|
||||
r_refresh_counter <= 10'd0;
|
||||
end else if (w_init_mode_reg) begin
|
||||
r_sdram_cmd <= CMD_MRS;
|
||||
end else if (w_init_done) begin
|
||||
r_state <= STATE_IDLE;
|
||||
r_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_IDLE: begin
|
||||
if (w_refresh_pending) begin
|
||||
r_sdram_cmd <= CMD_REF;
|
||||
r_refresh_counter <= 10'd0;
|
||||
r_rcd_ras_rc_counter <= 5'd0;
|
||||
r_state <= STATE_REFRESHING;
|
||||
r_busy <= 1'b1;
|
||||
end else if (r_request_pending || r_cross_row_request) begin
|
||||
r_sdram_cmd <= CMD_ACT;
|
||||
r_rcd_ras_rc_counter <= 5'd0;
|
||||
r_state <= STATE_ACTIVATING;
|
||||
r_busy <= 1'b1;
|
||||
end else if (i_request && !o_busy) begin
|
||||
r_sdram_cmd <= CMD_ACT;
|
||||
r_sdram_data <= i_data;
|
||||
r_rcd_ras_rc_counter <= 5'd0;
|
||||
r_state <= STATE_ACTIVATING;
|
||||
r_request_pending <= 1'b1;
|
||||
r_write_pending <= i_write;
|
||||
r_current_word <= 1'b0;
|
||||
r_busy <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_ACTIVATING: begin
|
||||
if (w_rcd_timing_met) begin
|
||||
r_sdram_cmd <= r_write_pending ? CMD_WRITE : CMD_READ;
|
||||
if (r_write_pending) r_wr_counter <= 2'd0;
|
||||
if (r_cross_row_request) begin
|
||||
r_cross_row_request <= 1'b0;
|
||||
r_busy <= 1'b0;
|
||||
end else if (r_request_pending) begin
|
||||
r_current_word <= 1'b1;
|
||||
end
|
||||
r_state <= STATE_ACTIVE;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_ACTIVE: begin
|
||||
if (r_wr_wait) begin
|
||||
if (w_wr_timing_met) begin
|
||||
r_rp_counter <= 3'd0;
|
||||
r_state <= STATE_PRECHARGING;
|
||||
r_wr_wait <= 1'b0;
|
||||
end
|
||||
end else if (r_request_pending && !(r_write_pending && w_read_pending)) begin
|
||||
r_sdram_cmd <= r_write_pending ? CMD_WRITE : CMD_READ;
|
||||
if (r_write_pending) r_wr_counter <= 2'd0;
|
||||
r_current_word <= 1'b1;
|
||||
if (r_current_word) begin
|
||||
r_busy <= 1'b0;
|
||||
r_request_pending <= 1'b0;
|
||||
end
|
||||
end else if (w_refresh_pending) begin
|
||||
if (w_ras_timing_met && w_wr_timing_met) begin
|
||||
r_sdram_cmd <= CMD_PRE;
|
||||
r_sdram_precharge <= 1'b1;
|
||||
r_rp_counter <= 3'd0;
|
||||
r_state <= STATE_PRECHARGING;
|
||||
end
|
||||
end else if (i_request && !o_busy) begin
|
||||
r_sdram_data <= i_data;
|
||||
r_busy <= 1'b1;
|
||||
r_write_pending <= i_write;
|
||||
|
||||
if (w_request_in_another_row || (i_write && w_read_pending)) begin
|
||||
r_request_pending <= 1'b1;
|
||||
r_current_word <= 1'b0;
|
||||
if (!(i_write && w_read_pending)) begin
|
||||
if (!w_wr_timing_met) begin
|
||||
r_wr_wait <= 1'b1;
|
||||
end else begin
|
||||
r_sdram_cmd <= CMD_PRE;
|
||||
r_sdram_precharge <= 1'b1;
|
||||
r_rp_counter <= 3'd0;
|
||||
r_state <= STATE_PRECHARGING;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
r_sdram_cmd <= i_write ? CMD_WRITE : CMD_READ;
|
||||
if (i_write) r_wr_counter <= 2'd0;
|
||||
r_current_word <= 1'b1;
|
||||
if (w_next_address_in_another_row) begin
|
||||
r_sdram_precharge <= 1'b1;
|
||||
r_cross_row_request <= 1'b1;
|
||||
if (!i_write) begin
|
||||
r_rp_counter <= 3'd0;
|
||||
r_state <= STATE_PRECHARGING;
|
||||
end else begin
|
||||
r_wr_wait <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
r_request_pending <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
STATE_PRECHARGING: begin
|
||||
if (w_rc_timing_met && w_rp_timing_met) begin
|
||||
r_state <= STATE_IDLE;
|
||||
r_busy <= r_request_pending || r_cross_row_request;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_REFRESHING: begin
|
||||
if (w_rc_timing_met) begin
|
||||
r_state <= STATE_IDLE;
|
||||
r_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
r_state <= STATE_IDLE;
|
||||
r_busy <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,81 +0,0 @@
|
||||
`include "../constants.vh"
|
||||
|
||||
module n64_bank_decoder (
|
||||
input [31:0] i_address,
|
||||
output reg [25:0] o_translated_address,
|
||||
output reg [3:0] o_bank,
|
||||
output reg o_bank_prefetch,
|
||||
output o_sram_request,
|
||||
input i_ddipl_enable,
|
||||
input i_sram_enable,
|
||||
input i_sram_768k_mode,
|
||||
input i_flashram_enable,
|
||||
input i_sd_enable,
|
||||
input i_eeprom_enable,
|
||||
input [23:0] i_ddipl_address,
|
||||
input [23:0] i_sram_address
|
||||
);
|
||||
|
||||
localparam [31:0] DDIPL_BASE = 32'h0600_0000;
|
||||
localparam [31:0] DDIPL_END = 32'h063F_FFFF;
|
||||
|
||||
localparam [31:0] SRAM_BASE = 32'h0800_0000;
|
||||
localparam [31:0] SRAM_END = 32'h0800_7FFF;
|
||||
localparam [31:0] SRAM_768K_END = 32'h0801_7FFF;
|
||||
|
||||
localparam [31:0] ROM_BASE = 32'h1000_0000;
|
||||
localparam [31:0] ROM_END = 32'h13FF_FFFF;
|
||||
|
||||
localparam [31:0] CART_BASE = 32'h1E00_0000;
|
||||
localparam [31:0] CART_END = 32'h1E00_3FFF;
|
||||
|
||||
localparam [31:0] EEPROM_BASE = 32'h1E00_4000;
|
||||
localparam [31:0] EEPROM_END = 32'h1E00_47FF;
|
||||
|
||||
localparam [31:0] SD_BASE = 32'h1E00_8000;
|
||||
localparam [31:0] SD_END = 32'h1E00_83FF;
|
||||
|
||||
wire [25:0] w_ddipl_translated_address = i_address[25:0] + {i_ddipl_address, 2'd0};
|
||||
wire [25:0] w_sram_translated_address = i_address[25:0] + {i_sram_address, 2'd0};
|
||||
|
||||
always @(*) begin
|
||||
o_bank = `BANK_INVALID;
|
||||
o_bank_prefetch = 1'b0;
|
||||
o_translated_address = i_address[25:0];
|
||||
o_sram_request = 1'b0;
|
||||
|
||||
if ((i_address >= DDIPL_BASE) && (i_address <= DDIPL_END) && i_ddipl_enable) begin
|
||||
o_translated_address = w_ddipl_translated_address;
|
||||
o_bank = `BANK_SDRAM;
|
||||
o_bank_prefetch = 1'b1;
|
||||
end
|
||||
|
||||
if ((i_address >= SRAM_BASE) && ((i_address <= SRAM_END) || ((i_sram_768k_mode && (i_address <= SRAM_768K_END))))) begin
|
||||
if (i_sram_enable && !i_flashram_enable) begin
|
||||
o_translated_address = w_sram_translated_address;
|
||||
o_bank = `BANK_SDRAM;
|
||||
o_bank_prefetch = 1'b1;
|
||||
o_sram_request = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if ((i_address >= ROM_BASE) && (i_address <= ROM_END)) begin
|
||||
o_bank = `BANK_SDRAM;
|
||||
o_bank_prefetch = 1'b1;
|
||||
end
|
||||
|
||||
if ((i_address >= CART_BASE) && (i_address <= CART_END)) begin
|
||||
o_bank = `BANK_CART;
|
||||
end
|
||||
|
||||
if ((i_address >= EEPROM_BASE) && (i_address <= EEPROM_END) && i_eeprom_enable) begin
|
||||
o_bank = `BANK_EEPROM;
|
||||
o_bank_prefetch = 1'b1;
|
||||
end
|
||||
|
||||
if ((i_address >= SD_BASE) && (i_address <= SD_END) && i_sd_enable) begin
|
||||
o_bank = `BANK_SD;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
14
fw/rtl/n64/n64_bootloader.sv
Normal file
14
fw/rtl/n64/n64_bootloader.sv
Normal file
@ -0,0 +1,14 @@
|
||||
module n64_bootloader (
|
||||
if_system.sys sys,
|
||||
if_n64_bus bus
|
||||
);
|
||||
|
||||
memory_flash memory_flash_inst (
|
||||
.sys(sys),
|
||||
.request(bus.request),
|
||||
.ack(bus.ack),
|
||||
.address(bus.address),
|
||||
.rdata(bus.rdata)
|
||||
);
|
||||
|
||||
endmodule
|
56
fw/rtl/n64/n64_bus.sv
Normal file
56
fw/rtl/n64/n64_bus.sv
Normal file
@ -0,0 +1,56 @@
|
||||
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 device_ack [(NUM_DEVICES - 1):0];
|
||||
logic [15:0] device_rdata [(NUM_DEVICES - 1):0];
|
||||
|
||||
always_comb begin
|
||||
ack = 1'b0;
|
||||
rdata = 16'd0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
ack = ack | device_ack[i];
|
||||
rdata = rdata | device_rdata[i];
|
||||
end
|
||||
end
|
||||
|
||||
modport n64 (
|
||||
output id,
|
||||
output request,
|
||||
input ack,
|
||||
output write,
|
||||
output address,
|
||||
output wdata,
|
||||
input rdata
|
||||
);
|
||||
|
||||
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])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endinterface
|
84
fw/rtl/n64/n64_cfg.sv
Normal file
84
fw/rtl/n64/n64_cfg.sv
Normal file
@ -0,0 +1,84 @@
|
||||
module n64_cfg (
|
||||
if_system sys,
|
||||
if_n64_bus bus,
|
||||
if_config.n64 cfg
|
||||
);
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
R_SR,
|
||||
R_COMMAND,
|
||||
R_DATA_0_H,
|
||||
R_DATA_0_L,
|
||||
R_DATA_1_H,
|
||||
R_DATA_1_L,
|
||||
R_VERSION_H,
|
||||
R_VERSION_L
|
||||
} e_reg_id;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[3:1])
|
||||
R_SR: bus.rdata = {
|
||||
cfg.cpu_ready,
|
||||
cfg.cpu_busy,
|
||||
cfg.usb_waiting,
|
||||
cfg.cmd_error,
|
||||
12'd0
|
||||
};
|
||||
R_COMMAND: bus.rdata = {8'd0, cfg.cmd};
|
||||
R_DATA_0_H: bus.rdata = cfg.data[0][31:16];
|
||||
R_DATA_0_L: bus.rdata = cfg.data[0][15:0];
|
||||
R_DATA_1_H: bus.rdata = cfg.data[1][31:16];
|
||||
R_DATA_1_L: bus.rdata = cfg.data[1][15:0];
|
||||
R_VERSION_H: bus.rdata = sc64::SC64_VER[31:16];
|
||||
R_VERSION_L: bus.rdata = sc64::SC64_VER[15:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
cfg.cmd_request <= 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
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
if (bus.write) begin
|
||||
case (bus.address[3:1])
|
||||
R_COMMAND: begin
|
||||
cfg.cmd <= bus.wdata[7:0];
|
||||
cfg.cmd_request <= 1'b1;
|
||||
end
|
||||
R_DATA_0_H: cfg.data[0][31:16] <= bus.wdata;
|
||||
R_DATA_0_L: cfg.data[0][15:0] <= bus.wdata;
|
||||
R_DATA_1_H: cfg.data[1][31:16] <= bus.wdata;
|
||||
R_DATA_1_L: cfg.data[1][15:0] <= bus.wdata;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
83
fw/rtl/n64/n64_dd.sv
Normal file
83
fw/rtl/n64/n64_dd.sv
Normal file
@ -0,0 +1,83 @@
|
||||
interface if_dd();
|
||||
|
||||
logic hard_reset;
|
||||
logic cmd_request;
|
||||
logic cmd_ack;
|
||||
logic [7:0] command;
|
||||
logic [15:0] status;
|
||||
logic [15:0] data_input;
|
||||
logic [15:0] data_output;
|
||||
logic bm_request;
|
||||
logic [15:0] bm_control;
|
||||
logic [15:0] bm_status;
|
||||
|
||||
modport n64 (
|
||||
output hard_reset,
|
||||
output cmd_request,
|
||||
input cmd_ack,
|
||||
output command,
|
||||
input status,
|
||||
output data_input,
|
||||
input data_output,
|
||||
output bm_request,
|
||||
output bm_control,
|
||||
input bm_status
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
input hard_reset,
|
||||
input cmd_request,
|
||||
output cmd_ack,
|
||||
input command,
|
||||
output status,
|
||||
input data_input,
|
||||
output data_output,
|
||||
input bm_request,
|
||||
input bm_control,
|
||||
output bm_status
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module n64_dd (
|
||||
if_system.sys sys,
|
||||
if_n64_bus bus
|
||||
);
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'h0000;
|
||||
if (bus.ack) begin
|
||||
bus.rdata = !bus.address[1] ? 16'h0040 : 16'h0000;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
190
fw/rtl/n64/n64_flashram.sv
Normal file
190
fw/rtl/n64/n64_flashram.sv
Normal file
@ -0,0 +1,190 @@
|
||||
module n64_flashram (
|
||||
if_system.sys sys,
|
||||
if_n64_bus bus,
|
||||
if_config.flashram cfg,
|
||||
if_flashram.flashram flashram
|
||||
);
|
||||
|
||||
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
|
||||
localparam [31:0] FLASH_MODEL_ID = 32'h00C2_001D;
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
CMD_STATUS_MODE = 8'hD2,
|
||||
CMD_READID_MODE = 8'hE1,
|
||||
CMD_READ_MODE = 8'hF0,
|
||||
CMD_ERASE_SECTOR = 8'h4B,
|
||||
CMD_ERASE_CHIP = 8'h3C,
|
||||
CMD_BUFFER_MODE = 8'hB4,
|
||||
CMD_ERASE_START = 8'h78,
|
||||
CMD_WRITE_START = 8'hA5
|
||||
} e_cmd;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_bus_state;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
FS_STATUS,
|
||||
FS_ID,
|
||||
FS_READ,
|
||||
FS_BUFFER
|
||||
} e_flashram_state;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
B_WRITE_BUSY,
|
||||
B_ERASE_BUSY,
|
||||
B_WRITE_DONE,
|
||||
B_ERASE_DONE
|
||||
} e_flashram_status;
|
||||
|
||||
e_bus_state bus_state;
|
||||
e_flashram_state flashram_state;
|
||||
logic [3:0] flashram_status;
|
||||
logic [7:0] flashram_command;
|
||||
logic flashram_erase_enabled;
|
||||
|
||||
logic [31:0] write_buffer [0:31];
|
||||
logic [1:0] write_buffer_wmask;
|
||||
logic [15:0] high_buffer;
|
||||
|
||||
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
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack) begin
|
||||
if (bus.address[1]) begin
|
||||
bus.rdata = {12'd0, flashram_status};
|
||||
end
|
||||
if (flashram_state == FS_ID) begin
|
||||
case (bus.address[2:1])
|
||||
0: bus.rdata = FLASH_TYPE_ID[31:16];
|
||||
1: bus.rdata = FLASH_TYPE_ID[15:0];
|
||||
2: bus.rdata = FLASH_MODEL_ID[31:16];
|
||||
3: bus.rdata = FLASH_MODEL_ID[15:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
cfg.flashram_read_mode = flashram_state == FS_READ;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
bus_state <= S_IDLE;
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_status <= 4'b0000;
|
||||
flashram_erase_enabled <= 1'b0;
|
||||
flashram.operation_pending <= 1'b0;
|
||||
end else begin
|
||||
if (flashram.operation_done) begin
|
||||
flashram.operation_pending <= 1'b0;
|
||||
if (flashram.write_or_erase) begin
|
||||
flashram_status[B_ERASE_BUSY] <= 1'b0;
|
||||
flashram_status[B_ERASE_DONE] <= 1'b1;
|
||||
end else begin
|
||||
flashram_status[B_WRITE_BUSY] <= 1'b0;
|
||||
flashram_status[B_WRITE_DONE] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
case (bus_state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
bus_state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
if (bus.write && !flashram.operation_pending) begin
|
||||
if (bus.address[16]) begin
|
||||
if (!bus.address[1]) begin
|
||||
flashram_command <= bus.wdata[15:8];
|
||||
end else begin
|
||||
flashram_erase_enabled <= 1'b0;
|
||||
|
||||
case (flashram_command)
|
||||
CMD_STATUS_MODE: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
end
|
||||
|
||||
CMD_READID_MODE: begin
|
||||
flashram_state <= FS_ID;
|
||||
end
|
||||
|
||||
CMD_READ_MODE: begin
|
||||
flashram_state <= FS_READ;
|
||||
end
|
||||
|
||||
CMD_ERASE_SECTOR: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_erase_enabled <= 1'b1;
|
||||
flashram.sector <= bus.wdata[9:0];
|
||||
flashram.sector_or_all <= 1'b0;
|
||||
end
|
||||
|
||||
CMD_ERASE_CHIP: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_erase_enabled <= 1'b1;
|
||||
flashram.sector <= 10'd0;
|
||||
flashram.sector_or_all <= 1'b1;
|
||||
end
|
||||
|
||||
CMD_BUFFER_MODE: begin
|
||||
flashram_state <= FS_BUFFER;
|
||||
end
|
||||
|
||||
CMD_ERASE_START: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
if (flashram_erase_enabled) begin
|
||||
flashram_status[B_ERASE_BUSY] <= 1'b1;
|
||||
flashram_status[B_ERASE_DONE] <= 1'b0;
|
||||
flashram.operation_pending <= 1'b1;
|
||||
flashram.write_or_erase <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
CMD_WRITE_START: begin
|
||||
flashram_state <= FS_STATUS;
|
||||
flashram_status[B_WRITE_BUSY] <= 1'b1;
|
||||
flashram_status[B_WRITE_DONE] <= 1'b0;
|
||||
flashram.sector <= bus.wdata[9:0];
|
||||
flashram.operation_pending <= 1'b1;
|
||||
flashram.write_or_erase <= 1'b0;
|
||||
flashram.sector_or_all <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
// else begin
|
||||
// if (bus.address[1] && flashram_state == FS_STATUS) begin
|
||||
// flashram_status[B_ERASE_DONE] <= bus.wdata[B_ERASE_DONE];
|
||||
// flashram_status[B_WRITE_DONE] <= bus.wdata[B_WRITE_DONE];
|
||||
// end
|
||||
// end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
bus_state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
347
fw/rtl/n64/n64_pi.sv
Normal file
347
fw/rtl/n64/n64_pi.sv
Normal file
@ -0,0 +1,347 @@
|
||||
module n64_pi (
|
||||
if_system.sys sys,
|
||||
if_config.pi cfg,
|
||||
if_n64_bus.n64 bus,
|
||||
|
||||
input n64_pi_alel,
|
||||
input n64_pi_aleh,
|
||||
input n64_pi_read,
|
||||
input n64_pi_write,
|
||||
inout [15:0] n64_pi_ad
|
||||
);
|
||||
|
||||
// FIFOs
|
||||
|
||||
logic read_fifo_flush;
|
||||
|
||||
logic read_fifo_full;
|
||||
logic read_fifo_write;
|
||||
logic [15:0] read_fifo_wdata;
|
||||
|
||||
logic read_fifo_empty;
|
||||
logic read_fifo_read;
|
||||
logic [15:0] read_fifo_rdata;
|
||||
|
||||
n64_pi_fifo read_fifo_inst (
|
||||
.sys(sys),
|
||||
|
||||
.flush(read_fifo_flush),
|
||||
|
||||
.full(read_fifo_full),
|
||||
.write(read_fifo_write),
|
||||
.wdata(read_fifo_wdata),
|
||||
|
||||
.empty(read_fifo_empty),
|
||||
.read(read_fifo_read),
|
||||
.rdata(read_fifo_rdata)
|
||||
);
|
||||
|
||||
logic write_fifo_flush;
|
||||
|
||||
logic write_fifo_full;
|
||||
logic write_fifo_write;
|
||||
logic [15:0] write_fifo_wdata;
|
||||
|
||||
logic write_fifo_empty;
|
||||
logic write_fifo_read;
|
||||
logic [15:0] write_fifo_rdata;
|
||||
|
||||
n64_pi_fifo write_fifo_inst (
|
||||
.sys(sys),
|
||||
|
||||
.flush(write_fifo_flush),
|
||||
|
||||
.full(write_fifo_full),
|
||||
.write(write_fifo_write),
|
||||
.wdata(write_fifo_wdata),
|
||||
|
||||
.empty(write_fifo_empty),
|
||||
.read(write_fifo_read),
|
||||
.rdata(write_fifo_rdata)
|
||||
);
|
||||
|
||||
|
||||
// Control signals and input synchronization
|
||||
|
||||
logic [2:0] n64_pi_alel_ff;
|
||||
logic [2:0] n64_pi_aleh_ff;
|
||||
logic [2:0] n64_pi_read_ff;
|
||||
logic [2:0] n64_pi_write_ff;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_pi_aleh_ff <= {n64_pi_aleh_ff[1:0], n64_pi_aleh};
|
||||
n64_pi_alel_ff <= {n64_pi_alel_ff[1:0], n64_pi_alel};
|
||||
n64_pi_read_ff <= {n64_pi_read_ff[1:0], n64_pi_read};
|
||||
n64_pi_write_ff <= {n64_pi_write_ff[1:0], n64_pi_write};
|
||||
end
|
||||
|
||||
logic pi_reset;
|
||||
logic pi_aleh;
|
||||
logic pi_alel;
|
||||
logic pi_read;
|
||||
logic pi_write;
|
||||
|
||||
always_comb begin
|
||||
pi_reset = sys.n64_hard_reset;
|
||||
pi_aleh = n64_pi_aleh_ff[2];
|
||||
pi_alel = n64_pi_alel_ff[2];
|
||||
pi_read = n64_pi_read_ff[1];
|
||||
pi_write = n64_pi_write_ff[2];
|
||||
end
|
||||
|
||||
|
||||
// PI bus state and event generator
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
PI_MODE_IDLE = 2'b10,
|
||||
PI_MODE_HIGH = 2'b11,
|
||||
PI_MODE_LOW = 2'b01,
|
||||
PI_MODE_VALID = 2'b00
|
||||
} e_pi_mode;
|
||||
|
||||
e_pi_mode pi_mode;
|
||||
e_pi_mode last_pi_mode;
|
||||
logic last_read;
|
||||
logic last_write;
|
||||
|
||||
always_comb begin
|
||||
pi_mode = e_pi_mode'({pi_aleh, pi_alel});
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
last_pi_mode <= pi_mode;
|
||||
last_read <= pi_read;
|
||||
last_write <= pi_write;
|
||||
end
|
||||
|
||||
logic aleh_op;
|
||||
logic alel_op;
|
||||
logic read_op;
|
||||
logic write_op;
|
||||
logic end_op;
|
||||
|
||||
always_comb begin
|
||||
aleh_op = !pi_reset && last_pi_mode != PI_MODE_HIGH && pi_mode == PI_MODE_HIGH;
|
||||
alel_op = !pi_reset && last_pi_mode == PI_MODE_HIGH && pi_mode == PI_MODE_LOW;
|
||||
read_op = !pi_reset && pi_mode == PI_MODE_VALID && last_read && !pi_read;
|
||||
write_op = !pi_reset && pi_mode == PI_MODE_VALID && last_write && !pi_write;
|
||||
end_op = !pi_reset && last_pi_mode == PI_MODE_VALID && pi_mode != PI_MODE_VALID;
|
||||
end
|
||||
|
||||
|
||||
// Input and output data sampling
|
||||
|
||||
logic [15:0] n64_pi_ad_input;
|
||||
logic [15:0] n64_pi_ad_output;
|
||||
logic [15:0] n64_pi_ad_output_data;
|
||||
logic n64_pi_ad_output_enable;
|
||||
logic n64_pi_ad_output_enable_data;
|
||||
|
||||
logic n64_pi_address_valid;
|
||||
logic pending_operation;
|
||||
logic pending_write;
|
||||
|
||||
always_comb begin
|
||||
n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ;
|
||||
n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !n64_pi_read_ff[2];
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_pi_ad_input <= n64_pi_ad;
|
||||
n64_pi_ad_output <= n64_pi_ad_output_data;
|
||||
n64_pi_ad_output_enable <= n64_pi_ad_output_enable_data;
|
||||
end
|
||||
|
||||
logic wait_for_read_fifo;
|
||||
logic wait_for_write_fifo;
|
||||
|
||||
always_comb begin
|
||||
read_fifo_write = bus.ack && !bus.write;
|
||||
read_fifo_wdata = bus.rdata;
|
||||
|
||||
write_fifo_wdata = n64_pi_ad_input;
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
|
||||
// Address decoding
|
||||
|
||||
sc64::e_n64_id next_id;
|
||||
logic [31:0] next_offset;
|
||||
logic sram_selected;
|
||||
logic cfg_selected;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (aleh_op) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
next_offset <= 32'd0;
|
||||
sram_selected <= 1'b0;
|
||||
cfg_selected <= 1'b0;
|
||||
if (cfg.dd_enabled) begin
|
||||
if (n64_pi_ad_input == 16'h0500) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_DD;
|
||||
end
|
||||
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.dd_offset + 32'h0A00_0000;
|
||||
end
|
||||
end
|
||||
if (cfg.flashram_enabled) begin
|
||||
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_FLASHRAM;
|
||||
if (cfg.flashram_read_mode) begin
|
||||
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||
end
|
||||
end
|
||||
end else if (cfg.sram_enabled) begin
|
||||
if (cfg.sram_banked) begin
|
||||
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0810) begin
|
||||
if (n64_pi_ad_input[3:2] != 2'b11 && n64_pi_ad_input[1:0] == 2'b00) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.save_offset - {n64_pi_ad_input[3:2], 18'd0} + {n64_pi_ad_input[3:2], 15'd0} + 32'h0800_0000;
|
||||
sram_selected <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (n64_pi_ad_input == 16'h0800) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||
sram_selected <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if (n64_pi_ad_input >= 16'h1000 && n64_pi_ad_input < 16'h1400) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= cfg.sdram_switch ? sc64::ID_N64_SDRAM : sc64::ID_N64_BOOTLOADER;
|
||||
end
|
||||
if (n64_pi_ad_input == 16'h1FFF) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_CFG;
|
||||
cfg_selected <= 1'b1;
|
||||
end
|
||||
end
|
||||
if (alel_op) begin
|
||||
if (sram_selected) begin
|
||||
if (n64_pi_ad_input[15]) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (cfg_selected) begin
|
||||
if (|n64_pi_ad_input[15:4]) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Bus controller
|
||||
|
||||
logic can_read;
|
||||
logic first_write_op;
|
||||
logic load_starting_address;
|
||||
sc64::e_n64_id starting_id;
|
||||
logic [31:0] starting_address;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
read_fifo_flush <= 1'b0;
|
||||
|
||||
write_fifo_read <= 1'b0;
|
||||
|
||||
if (sys.reset || sys.n64_hard_reset) begin
|
||||
bus.request <= 1'b0;
|
||||
read_fifo_flush <= 1'b1;
|
||||
write_fifo_flush <= 1'b1;
|
||||
end else begin
|
||||
write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected;
|
||||
|
||||
if (aleh_op) begin
|
||||
starting_address[31:16] <= n64_pi_ad_input;
|
||||
end
|
||||
|
||||
if (alel_op) begin
|
||||
read_fifo_flush <= 1'b1;
|
||||
can_read <= 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} + next_offset;
|
||||
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
|
||||
bus.id <= starting_id;
|
||||
bus.address <= starting_address;
|
||||
load_starting_address <= 1'b0;
|
||||
end
|
||||
bus.wdata <= write_fifo_rdata;
|
||||
write_fifo_read <= 1'b1;
|
||||
end else if (!read_fifo_full && can_read) begin
|
||||
bus.request <= 1'b1;
|
||||
bus.write <= 1'b0;
|
||||
if (load_starting_address) begin
|
||||
bus.id <= starting_id;
|
||||
if (starting_id == sc64::ID_N64_FLASHRAM && cfg.flashram_read_mode) begin
|
||||
bus.id <= sc64::ID_N64_SDRAM;
|
||||
end
|
||||
bus.address <= starting_address;
|
||||
load_starting_address <= 1'b0;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (bus.ack) begin
|
||||
bus.request <= 1'b0;
|
||||
bus.address <= bus.address + 2'd2;
|
||||
end
|
||||
end
|
||||
|
||||
if (end_op) begin
|
||||
can_read <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,230 +0,0 @@
|
||||
module n64_pi (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_n64_reset,
|
||||
input i_n64_pi_alel,
|
||||
input i_n64_pi_aleh,
|
||||
input i_n64_pi_read,
|
||||
input i_n64_pi_write,
|
||||
inout reg [15:0] io_n64_pi_ad,
|
||||
|
||||
output reg o_request,
|
||||
output reg o_write,
|
||||
input i_busy,
|
||||
input i_ack,
|
||||
output [3:0] o_bank,
|
||||
output reg [25:0] o_address,
|
||||
input [31:0] i_data,
|
||||
output reg [31:0] o_data,
|
||||
|
||||
output o_sram_request,
|
||||
|
||||
input i_ddipl_enable,
|
||||
input i_sram_enable,
|
||||
input i_sram_768k_mode,
|
||||
input i_flashram_enable,
|
||||
input i_sd_enable,
|
||||
input i_eeprom_enable,
|
||||
|
||||
input [23:0] i_ddipl_address,
|
||||
input [23:0] i_sram_address
|
||||
);
|
||||
|
||||
// Parameters
|
||||
|
||||
parameter bit PREFETCH_DISABLE = 1'b0;
|
||||
|
||||
|
||||
// Input synchronization
|
||||
|
||||
reg r_reset_ff1, r_reset_ff2;
|
||||
reg r_alel_ff1, r_alel_ff2;
|
||||
reg r_aleh_ff1, r_aleh_ff2;
|
||||
reg r_read_ff1, r_read_ff2;
|
||||
reg r_write_ff1, r_write_ff2;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
{r_reset_ff2, r_reset_ff1} <= {r_reset_ff1, i_n64_reset};
|
||||
{r_alel_ff2, r_alel_ff1} <= {r_alel_ff1, i_n64_pi_alel};
|
||||
{r_aleh_ff2, r_aleh_ff1} <= {r_aleh_ff1, i_n64_pi_aleh};
|
||||
{r_read_ff2, r_read_ff1} <= {r_read_ff1, i_n64_pi_read};
|
||||
{r_write_ff2, r_write_ff1} <= {r_write_ff1, i_n64_pi_write};
|
||||
end
|
||||
|
||||
|
||||
// PI event signals generator
|
||||
|
||||
wire [1:0] w_pi_mode = {r_aleh_ff2, r_alel_ff2};
|
||||
reg [1:0] r_last_pi_mode;
|
||||
reg r_last_read;
|
||||
reg r_last_write;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_last_pi_mode <= w_pi_mode;
|
||||
r_last_read <= r_read_ff2;
|
||||
r_last_write <= r_write_ff2;
|
||||
end
|
||||
|
||||
localparam [1:0] PI_MODE_IDLE = 2'b10;
|
||||
localparam [1:0] PI_MODE_HIGH = 2'b11;
|
||||
localparam [1:0] PI_MODE_LOW = 2'b01;
|
||||
localparam [1:0] PI_MODE_VALID = 2'b00;
|
||||
|
||||
wire w_address_high_op = r_reset_ff2 && (r_last_pi_mode != PI_MODE_HIGH) && (w_pi_mode == PI_MODE_HIGH);
|
||||
wire w_address_low_op = r_reset_ff2 && (r_last_pi_mode != PI_MODE_LOW) && (w_pi_mode == PI_MODE_LOW);
|
||||
wire w_address_valid_op = r_reset_ff2 && (r_last_pi_mode != PI_MODE_VALID) && (w_pi_mode == PI_MODE_VALID);
|
||||
wire w_read_op = r_reset_ff2 && (w_pi_mode == PI_MODE_VALID) && r_last_read && !r_read_ff2;
|
||||
wire w_write_op = r_reset_ff2 && (w_pi_mode == PI_MODE_VALID) && r_last_write && !r_write_ff2;
|
||||
|
||||
|
||||
// Bus address register
|
||||
|
||||
reg [31:0] r_pi_address;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_address_high_op) r_pi_address[31:16] <= io_n64_pi_ad;
|
||||
if (w_address_low_op) r_pi_address[15:0] <= {io_n64_pi_ad[15:1], 1'b0};
|
||||
end
|
||||
|
||||
|
||||
// Bank decoder, address translator and prefetch signal
|
||||
|
||||
wire [25:0] w_translated_address;
|
||||
wire w_bank_prefetch;
|
||||
wire w_prefetch = !PREFETCH_DISABLE && w_bank_prefetch;
|
||||
|
||||
n64_bank_decoder n64_bank_decoder_inst (
|
||||
.i_address(r_pi_address),
|
||||
.o_translated_address(w_translated_address),
|
||||
.o_bank(o_bank),
|
||||
.o_bank_prefetch(w_bank_prefetch),
|
||||
.o_sram_request(o_sram_request),
|
||||
.i_ddipl_enable(i_ddipl_enable),
|
||||
.i_sram_enable(i_sram_enable),
|
||||
.i_sram_768k_mode(i_sram_768k_mode),
|
||||
.i_flashram_enable(i_flashram_enable),
|
||||
.i_sd_enable(i_sd_enable),
|
||||
.i_eeprom_enable(i_eeprom_enable),
|
||||
.i_ddipl_address(i_ddipl_address),
|
||||
.i_sram_address(i_sram_address)
|
||||
);
|
||||
|
||||
|
||||
// Read/write current word logic
|
||||
|
||||
reg r_word_counter;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_address_valid_op) r_word_counter <= 1'b0;
|
||||
if (w_read_op || w_write_op) r_word_counter <= ~r_word_counter;
|
||||
end
|
||||
|
||||
|
||||
// N64 PI output data logic
|
||||
|
||||
reg [31:0] r_pi_output_data;
|
||||
|
||||
always @(*) begin
|
||||
io_n64_pi_ad = 16'hZZZZ;
|
||||
if (r_reset_ff2 && !r_read_ff2 && o_bank != 4'd0) begin
|
||||
io_n64_pi_ad = r_word_counter ? r_pi_output_data[31:16] : r_pi_output_data[15:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Bus event signals generator
|
||||
|
||||
wire w_bus_read_op = w_read_op && !r_word_counter;
|
||||
wire w_bus_write_op = w_write_op && r_word_counter;
|
||||
|
||||
|
||||
// Read buffer logic
|
||||
|
||||
reg [31:0] r_pi_read_buffer;
|
||||
reg r_prefetch_read;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_address_valid_op) begin
|
||||
r_prefetch_read <= w_prefetch;
|
||||
end
|
||||
if (i_ack) begin
|
||||
if (w_prefetch) r_pi_read_buffer <= i_data;
|
||||
else r_pi_output_data <= i_data;
|
||||
if (r_prefetch_read) r_pi_output_data <= i_data;
|
||||
r_prefetch_read <= 1'b0;
|
||||
end
|
||||
if (w_prefetch && w_bus_read_op) r_pi_output_data <= r_pi_read_buffer;
|
||||
end
|
||||
|
||||
|
||||
// Write data logic
|
||||
|
||||
reg [15:0] r_pi_write_buffer;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_write_op) begin
|
||||
if (!r_word_counter) begin
|
||||
r_pi_write_buffer <= io_n64_pi_ad;
|
||||
end else begin
|
||||
o_data <= {r_pi_write_buffer, io_n64_pi_ad};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Bus request logic
|
||||
|
||||
reg r_pending_request;
|
||||
reg r_pending_request_write;
|
||||
|
||||
wire w_bus_request_op = (w_address_valid_op && w_prefetch) || w_bus_read_op || w_bus_write_op;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
o_request <= 1'b0;
|
||||
o_write <= 1'b0;
|
||||
r_pending_request <= 1'b0;
|
||||
end else begin
|
||||
if (o_request && !i_busy) begin
|
||||
o_request <= 1'b0;
|
||||
o_write <= 1'b0;
|
||||
end
|
||||
if (w_bus_request_op) begin
|
||||
if (o_request) begin
|
||||
r_pending_request <= 1'b1;
|
||||
r_pending_request_write <= w_bus_write_op;
|
||||
end else begin
|
||||
o_request <= 1'b1;
|
||||
o_write <= w_bus_write_op;
|
||||
end
|
||||
end
|
||||
if (r_pending_request && !i_busy) begin
|
||||
o_request <= 1'b1;
|
||||
o_write <= r_pending_request_write;
|
||||
r_pending_request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Address increment logic
|
||||
|
||||
reg r_first_transfer;
|
||||
|
||||
wire w_address_increment_op = (
|
||||
(w_bus_read_op && (!r_first_transfer || w_prefetch)) ||
|
||||
(w_bus_write_op && !r_first_transfer)
|
||||
);
|
||||
wire w_first_transfer_clear_op = w_bus_read_op || w_bus_write_op;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_address_valid_op) begin
|
||||
o_address <= w_translated_address;
|
||||
r_first_transfer <= 1'b1;
|
||||
end
|
||||
if (w_first_transfer_clear_op) r_first_transfer <= 1'b0;
|
||||
if (w_address_increment_op) o_address[15:2] <= o_address[15:2] + 1'b1;
|
||||
end
|
||||
|
||||
endmodule
|
43
fw/rtl/n64/n64_pi_fifo.sv
Normal file
43
fw/rtl/n64/n64_pi_fifo.sv
Normal file
@ -0,0 +1,43 @@
|
||||
module n64_pi_fifo (
|
||||
if_system.sys sys,
|
||||
|
||||
input flush,
|
||||
|
||||
output full,
|
||||
input write,
|
||||
input [15:0] wdata,
|
||||
|
||||
output empty,
|
||||
input read,
|
||||
output [15:0] rdata
|
||||
);
|
||||
|
||||
logic [15:0] fifo_mem [0:3];
|
||||
logic [2:0] fifo_wr_ptr;
|
||||
logic [2:0] fifo_rd_ptr;
|
||||
|
||||
logic empty_or_full;
|
||||
|
||||
always_comb begin
|
||||
rdata = fifo_mem[fifo_rd_ptr[1:0]];
|
||||
empty_or_full = fifo_wr_ptr[1:0] == fifo_rd_ptr[1:0];
|
||||
empty = empty_or_full && fifo_wr_ptr[2] == fifo_rd_ptr[2];
|
||||
full = empty_or_full && fifo_wr_ptr[2] != fifo_rd_ptr[2];
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || flush) begin
|
||||
fifo_wr_ptr <= 3'd0;
|
||||
fifo_rd_ptr <= 3'd0;
|
||||
end else begin
|
||||
if (write) begin
|
||||
fifo_mem[fifo_wr_ptr[1:0]] <= wdata;
|
||||
fifo_wr_ptr <= fifo_wr_ptr + 1'd1;
|
||||
end
|
||||
if (read) begin
|
||||
fifo_rd_ptr <= fifo_rd_ptr + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
106
fw/rtl/n64/n64_sdram.sv
Normal file
106
fw/rtl/n64/n64_sdram.sv
Normal file
@ -0,0 +1,106 @@
|
||||
module n64_sdram (
|
||||
if_system sys,
|
||||
if_n64_bus bus,
|
||||
if_dma.memory dma,
|
||||
if_sdram.memory sdram,
|
||||
|
||||
output sdram_cs,
|
||||
output sdram_ras,
|
||||
output sdram_cas,
|
||||
output sdram_we,
|
||||
output [1:0] sdram_ba,
|
||||
output [12:0] sdram_a,
|
||||
inout [15:0] sdram_dq
|
||||
);
|
||||
|
||||
logic mem_request;
|
||||
logic mem_ack;
|
||||
logic mem_write;
|
||||
logic [31:0] mem_address;
|
||||
logic [15:0] mem_rdata;
|
||||
logic [15:0] mem_wdata;
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
T_BUS,
|
||||
T_DMA,
|
||||
T_SDRAM
|
||||
} e_source_request;
|
||||
|
||||
e_state state;
|
||||
e_source_request source_request;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
mem_request <= 1'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request || sdram.request || dma.request) begin
|
||||
state <= S_WAIT;
|
||||
mem_request <= 1'b1;
|
||||
if (bus.request) begin
|
||||
mem_write <= bus.write;
|
||||
mem_address <= bus.address;
|
||||
mem_wdata <= bus.wdata;
|
||||
source_request <= T_BUS;
|
||||
end else if (sdram.request) begin
|
||||
mem_write <= sdram.write;
|
||||
mem_address <= sdram.address;
|
||||
mem_wdata <= sdram.wdata;
|
||||
source_request <= T_SDRAM;
|
||||
end else if (dma.request) begin
|
||||
mem_write <= dma.write;
|
||||
mem_address <= dma.address;
|
||||
mem_wdata <= dma.wdata;
|
||||
source_request <= T_DMA;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
if (mem_ack) begin
|
||||
state <= S_IDLE;
|
||||
mem_request <= 1'b0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.ack = source_request == T_BUS && mem_ack;
|
||||
bus.rdata = bus.ack ? mem_rdata : 16'd0;
|
||||
|
||||
dma.ack = source_request == T_DMA && mem_ack;
|
||||
dma.rdata = mem_rdata;
|
||||
|
||||
sdram.ack = source_request == T_SDRAM && mem_ack;
|
||||
sdram.rdata = mem_rdata;
|
||||
end
|
||||
|
||||
memory_sdram memory_sdram_inst (
|
||||
.sys(sys),
|
||||
|
||||
.request(mem_request),
|
||||
.ack(mem_ack),
|
||||
.write(mem_write),
|
||||
.address(mem_address[25:0]),
|
||||
.rdata(mem_rdata),
|
||||
.wdata(mem_wdata),
|
||||
|
||||
.sdram_cs(sdram_cs),
|
||||
.sdram_ras(sdram_ras),
|
||||
.sdram_cas(sdram_cas),
|
||||
.sdram_we(sdram_we),
|
||||
.sdram_ba(sdram_ba),
|
||||
.sdram_a(sdram_a),
|
||||
.sdram_dq(sdram_dq)
|
||||
);
|
||||
|
||||
endmodule
|
224
fw/rtl/n64/n64_si.sv
Normal file
224
fw/rtl/n64/n64_si.sv
Normal file
@ -0,0 +1,224 @@
|
||||
interface if_si ();
|
||||
|
||||
logic rx_reset;
|
||||
logic rx_ready;
|
||||
logic [6:0] rx_length;
|
||||
logic [80:0] rx_data;
|
||||
|
||||
logic tx_reset;
|
||||
logic tx_start;
|
||||
logic tx_busy;
|
||||
logic [2:0] tx_wmask;
|
||||
logic [6:0] tx_length;
|
||||
logic [31:0] tx_data;
|
||||
|
||||
modport si (
|
||||
input rx_reset,
|
||||
output rx_ready,
|
||||
output rx_length,
|
||||
output rx_data,
|
||||
input tx_reset,
|
||||
input tx_start,
|
||||
output tx_busy,
|
||||
input tx_wmask,
|
||||
input tx_length,
|
||||
input tx_data
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
output rx_reset,
|
||||
input rx_ready,
|
||||
input rx_length,
|
||||
input rx_data,
|
||||
output tx_reset,
|
||||
output tx_start,
|
||||
input tx_busy,
|
||||
output tx_wmask,
|
||||
output tx_length,
|
||||
output tx_data
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
module n64_si (
|
||||
if_system.sys sys,
|
||||
if_si.si si,
|
||||
|
||||
input n64_si_clk,
|
||||
inout n64_si_dq
|
||||
);
|
||||
|
||||
// Control signals and input synchronization
|
||||
|
||||
logic [1:0] n64_si_clk_ff;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_si_clk_ff <= {n64_si_clk_ff[0], n64_si_clk};
|
||||
end
|
||||
|
||||
logic si_reset;
|
||||
logic si_clk;
|
||||
logic si_dq;
|
||||
|
||||
always_comb begin
|
||||
si_reset = sys.n64_hard_reset;
|
||||
si_clk = n64_si_clk_ff[1];
|
||||
si_dq = n64_si_dq;
|
||||
end
|
||||
|
||||
logic last_si_clk;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
last_si_clk <= si_clk;
|
||||
end
|
||||
|
||||
logic si_clk_rising_edge;
|
||||
logic si_clk_falling_edge;
|
||||
|
||||
always_comb begin
|
||||
si_clk_rising_edge = !si_reset && !last_si_clk && si_clk;
|
||||
si_clk_falling_edge = !si_reset && last_si_clk && !si_clk;
|
||||
end
|
||||
|
||||
logic si_dq_output_enable;
|
||||
logic si_dq_output_enable_data;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
si_dq_output_enable <= si_dq_output_enable_data;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
n64_si_dq = si_dq_output_enable ? 1'b0 : 1'bZ;
|
||||
end
|
||||
|
||||
|
||||
// Data register and shifter
|
||||
|
||||
logic [80:0] trx_data;
|
||||
logic rx_shift;
|
||||
logic tx_shift;
|
||||
|
||||
always_comb begin
|
||||
si.rx_data = trx_data;
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (si.tx_wmask[0]) trx_data[80:49] <= si.tx_data;
|
||||
if (si.tx_wmask[1]) trx_data[48:17] <= si.tx_data;
|
||||
if (si.tx_wmask[2]) trx_data[16:0] <= si.tx_data[16:0];
|
||||
|
||||
if (rx_shift || tx_shift) begin
|
||||
trx_data <= {trx_data[79:0], rx_sub_bit_counter < 2'd2};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// RX path
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_RX_IDLE,
|
||||
S_RX_WAITING
|
||||
} e_rx_state;
|
||||
|
||||
e_rx_state rx_state;
|
||||
|
||||
logic [1:0] rx_sub_bit_counter;
|
||||
logic [3:0] rx_timeout_counter;
|
||||
|
||||
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
|
||||
|
||||
if (sys.reset || si.rx_reset) begin
|
||||
rx_state <= S_RX_IDLE;
|
||||
si.rx_ready <= 1'b0;
|
||||
si.rx_length <= 7'd0;
|
||||
end else if (!si.tx_busy) begin
|
||||
case (rx_state)
|
||||
S_RX_IDLE: begin
|
||||
if (si_clk_rising_edge && !si_dq) begin
|
||||
rx_state <= S_RX_WAITING;
|
||||
rx_sub_bit_counter <= 2'd0;
|
||||
rx_timeout_counter <= 3'd0;
|
||||
end
|
||||
end
|
||||
|
||||
S_RX_WAITING: begin
|
||||
if (si_clk_rising_edge) begin
|
||||
if (si_dq) begin
|
||||
rx_state <= S_RX_IDLE;
|
||||
rx_shift <= 1'b1;
|
||||
si.rx_length <= si.rx_length + 1'd1;
|
||||
end else if (rx_sub_bit_counter < 2'd3) begin
|
||||
rx_sub_bit_counter <= rx_sub_bit_counter + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// TX path
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_TX_IDLE,
|
||||
S_TX_SENDING
|
||||
} e_tx_state;
|
||||
|
||||
e_tx_state tx_state;
|
||||
|
||||
logic [2:0] tx_sub_bit_counter;
|
||||
logic [6:0] tx_bit_counter;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
tx_shift <= 1'b0;
|
||||
|
||||
if (sys.reset || si.tx_reset) begin
|
||||
tx_state <= S_TX_IDLE;
|
||||
si_dq_output_enable_data <= 1'b0;
|
||||
si.tx_busy <= 1'b0;
|
||||
end else begin
|
||||
case (tx_state)
|
||||
S_TX_IDLE: begin
|
||||
if (si.tx_start) begin
|
||||
tx_state <= S_TX_SENDING;
|
||||
tx_sub_bit_counter <= 3'd0;
|
||||
tx_bit_counter <= si.tx_length;
|
||||
si.tx_busy <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
S_TX_SENDING: begin
|
||||
if (si_clk_falling_edge) begin
|
||||
tx_sub_bit_counter <= tx_sub_bit_counter + 1'd1;
|
||||
if (tx_sub_bit_counter == 3'd7) begin
|
||||
tx_shift <= 1'b1;
|
||||
if (tx_bit_counter >= 7'd1) begin
|
||||
tx_bit_counter <= tx_bit_counter - 1'd1;
|
||||
end else begin
|
||||
tx_state <= S_TX_IDLE;
|
||||
si.tx_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
if (tx_bit_counter == 7'd0) begin
|
||||
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd4;
|
||||
end else if (trx_data[80]) begin
|
||||
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd2;
|
||||
end else begin
|
||||
si_dq_output_enable_data <= tx_sub_bit_counter < 3'd6;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,237 +0,0 @@
|
||||
module n64_si (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_n64_reset,
|
||||
input i_n64_si_clk,
|
||||
inout io_n64_si_dq,
|
||||
|
||||
input i_request,
|
||||
input i_write,
|
||||
output o_busy,
|
||||
output reg o_ack,
|
||||
input [8:0] i_address,
|
||||
input [31:0] i_data,
|
||||
output [31:0] o_data,
|
||||
|
||||
input i_eeprom_enable,
|
||||
input i_eeprom_16k_mode
|
||||
);
|
||||
|
||||
// Input synchronization
|
||||
|
||||
reg r_reset_ff1, r_reset_ff2;
|
||||
reg r_si_clk_ff1, r_si_clk_ff2;
|
||||
reg r_si_dq_ff1, r_si_dq_ff2;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
{r_reset_ff2, r_reset_ff1} <= {r_reset_ff1, i_n64_reset};
|
||||
{r_si_clk_ff2, r_si_clk_ff1} <= {r_si_clk_ff1, i_n64_si_clk};
|
||||
{r_si_dq_ff2, r_si_dq_ff1} <= {r_si_dq_ff1, io_n64_si_dq};
|
||||
end
|
||||
|
||||
reg r_si_dq_o;
|
||||
|
||||
assign io_n64_si_dq = r_si_dq_o ? 1'bZ : 1'b0;
|
||||
|
||||
|
||||
// SI commands
|
||||
|
||||
localparam CMD_EEPROM_STATUS = 8'h00;
|
||||
localparam CMD_EEPROM_READ = 8'h04;
|
||||
localparam CMD_EEPROM_WRITE = 8'h05;
|
||||
|
||||
localparam EEPROM_4K_ID = 8'h80;
|
||||
localparam EEPROM_16K_ID = 8'hC0;
|
||||
|
||||
|
||||
// Event signal generation
|
||||
|
||||
reg r_last_si_clk;
|
||||
reg r_last_si_dq;
|
||||
|
||||
wire w_si_clk_falling_edge = !i_reset && r_reset_ff2 && r_last_si_clk && !r_si_clk_ff2;
|
||||
wire w_si_clk_rising_edge = !i_reset && r_reset_ff2 && !r_last_si_clk && r_si_clk_ff2;
|
||||
wire w_si_dq_falling_edge = r_last_si_dq && !r_si_dq_ff2;
|
||||
wire w_si_dq_rising_edge = !r_last_si_dq && r_si_dq_ff2;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_last_si_clk <= r_si_clk_ff2;
|
||||
if (w_si_clk_rising_edge) r_last_si_dq <= r_si_dq_ff2;
|
||||
end
|
||||
|
||||
|
||||
// RX module
|
||||
|
||||
reg r_rx_enabled;
|
||||
reg [2:0] r_rx_sub_bit_counter;
|
||||
reg [2:0] r_rx_bit_counter;
|
||||
reg [3:0] r_rx_byte_counter;
|
||||
reg [7:0] r_rx_buffer;
|
||||
reg r_rx_byte_ready;
|
||||
reg r_rx_finished, r_last_rx_finished;
|
||||
|
||||
wire w_rx_sub_bit_counter_timeout = &r_rx_sub_bit_counter;
|
||||
wire w_rx_bit_value = r_rx_sub_bit_counter <= 3'd4;
|
||||
wire w_rx_start = r_last_rx_finished && !r_rx_finished;
|
||||
wire w_rx_finish = !r_last_rx_finished && r_rx_finished;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_rx_byte_ready <= 1'b0;
|
||||
r_last_rx_finished <= r_rx_finished;
|
||||
|
||||
if (r_rx_enabled && w_si_clk_rising_edge) begin
|
||||
if (w_rx_sub_bit_counter_timeout) r_rx_finished <= 1'b1;
|
||||
else r_rx_sub_bit_counter <= r_rx_sub_bit_counter + 3'd1;
|
||||
|
||||
if (w_si_dq_falling_edge) begin
|
||||
r_rx_sub_bit_counter <= 3'd0;
|
||||
if (r_rx_finished) begin
|
||||
r_rx_bit_counter <= 3'd0;
|
||||
r_rx_byte_counter <= 4'b1111;
|
||||
end
|
||||
r_rx_finished <= 1'b0;
|
||||
end
|
||||
|
||||
if (w_si_dq_rising_edge) begin
|
||||
r_rx_bit_counter <= r_rx_bit_counter + 3'd1;
|
||||
r_rx_buffer <= {r_rx_buffer[6:0], w_rx_bit_value};
|
||||
if (&r_rx_bit_counter) begin
|
||||
r_rx_byte_counter <= r_rx_byte_counter + 4'd1;
|
||||
r_rx_byte_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg r_tx_finished;
|
||||
|
||||
reg r_cmd_eeprom_status;
|
||||
reg r_cmd_eeprom_read;
|
||||
reg r_cmd_eeprom_write;
|
||||
|
||||
wire w_cmd_valid = r_cmd_eeprom_status || r_cmd_eeprom_read || r_cmd_eeprom_write;
|
||||
wire w_cmd_op = r_rx_byte_ready && r_rx_byte_counter == 4'd0;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || !r_reset_ff2 || w_rx_start || r_tx_finished) begin
|
||||
r_cmd_eeprom_status <= 1'b0;
|
||||
r_cmd_eeprom_read <= 1'b0;
|
||||
r_cmd_eeprom_write <= 1'b0;
|
||||
end else if (w_cmd_op) begin
|
||||
if (i_eeprom_enable) begin
|
||||
r_cmd_eeprom_status <= r_rx_buffer == CMD_EEPROM_STATUS;
|
||||
r_cmd_eeprom_read <= r_rx_buffer == CMD_EEPROM_READ;
|
||||
r_cmd_eeprom_write <= r_rx_buffer == CMD_EEPROM_WRITE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg r_eeprom_read_rq;
|
||||
reg [10:0] r_eeprom_address;
|
||||
|
||||
wire w_eeprom_write_op = r_rx_byte_ready && r_rx_byte_counter >= 4'd2 && r_cmd_eeprom_write;
|
||||
wire w_eeprom_address_op = r_rx_byte_ready && r_rx_byte_counter == 4'd1 && (r_cmd_eeprom_read || r_cmd_eeprom_write);
|
||||
wire w_eeprom_address_next_op = r_eeprom_read_rq || w_eeprom_write_op;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_eeprom_address_op) r_eeprom_address <= {r_rx_buffer, 3'b000};
|
||||
if (w_eeprom_address_next_op) r_eeprom_address[2:0] <= r_eeprom_address[2:0] + 3'd1;
|
||||
end
|
||||
|
||||
|
||||
// TX module
|
||||
|
||||
reg [2:0] r_tx_sub_bit_counter;
|
||||
reg [2:0] r_tx_bit_counter;
|
||||
reg [3:0] r_tx_byte_counter;
|
||||
reg [3:0] r_tx_bytes_to_send;
|
||||
reg [7:0] r_tx_data;
|
||||
|
||||
wire [7:0] w_eeprom_o_data;
|
||||
|
||||
wire w_tx_current_bit = r_tx_data[3'd7 - r_tx_bit_counter];
|
||||
wire w_tx_stop_bit = r_tx_byte_counter == r_tx_bytes_to_send;
|
||||
|
||||
always @(*) begin
|
||||
r_tx_data = 8'h00;
|
||||
if (r_cmd_eeprom_status && r_tx_byte_counter == 4'd1) r_tx_data = i_eeprom_16k_mode ? EEPROM_16K_ID : EEPROM_4K_ID;
|
||||
if (r_cmd_eeprom_read) r_tx_data = w_eeprom_o_data;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || !r_reset_ff2) begin
|
||||
r_si_dq_o <= 1'b1;
|
||||
r_rx_enabled <= 1'b1;
|
||||
r_tx_finished <= 1'b0;
|
||||
r_eeprom_read_rq <= 1'b0;
|
||||
end else begin
|
||||
r_tx_finished <= 1'b0;
|
||||
r_eeprom_read_rq <= 1'b0;
|
||||
|
||||
if (w_rx_finish && w_cmd_valid) begin
|
||||
r_rx_enabled <= 1'b0;
|
||||
r_tx_sub_bit_counter <= 3'd0;
|
||||
r_tx_bit_counter <= 3'd0;
|
||||
r_tx_byte_counter <= 4'd0;
|
||||
r_tx_bytes_to_send <= 4'd0;
|
||||
if (r_cmd_eeprom_status) r_tx_bytes_to_send <= 4'd3;
|
||||
if (r_cmd_eeprom_read) r_tx_bytes_to_send <= 4'd8;
|
||||
if (r_cmd_eeprom_write) r_tx_bytes_to_send <= 4'd1;
|
||||
end
|
||||
|
||||
if (!r_rx_enabled) begin
|
||||
if (w_si_clk_falling_edge) begin
|
||||
r_tx_sub_bit_counter <= r_tx_sub_bit_counter + 3'd1;
|
||||
|
||||
if (r_tx_sub_bit_counter == 3'd0) r_si_dq_o <= 1'b0;
|
||||
|
||||
if ((w_tx_current_bit && r_tx_sub_bit_counter == 3'd2) ||
|
||||
(!w_tx_current_bit && r_tx_sub_bit_counter == 3'd6) ||
|
||||
(w_tx_stop_bit && r_tx_sub_bit_counter == 3'd4)) begin
|
||||
r_si_dq_o <= 1'b1;
|
||||
end
|
||||
|
||||
if (&r_tx_sub_bit_counter) begin
|
||||
if (w_tx_stop_bit) begin
|
||||
r_rx_enabled <= 1'b1;
|
||||
r_tx_finished <= 1'b1;
|
||||
end
|
||||
r_tx_bit_counter <= r_tx_bit_counter + 3'd1;
|
||||
if (&r_tx_bit_counter) begin
|
||||
r_eeprom_read_rq <= 1'b1;
|
||||
r_tx_byte_counter <= r_tx_byte_counter + 4'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Block RAM
|
||||
|
||||
ram_n64_eeprom ram_n64_eeprom_inst (
|
||||
.clock(i_clk),
|
||||
|
||||
.address_a(r_eeprom_address),
|
||||
.data_a(r_rx_buffer),
|
||||
.wren_a(w_eeprom_write_op),
|
||||
.q_a(w_eeprom_o_data),
|
||||
|
||||
.address_b(i_address),
|
||||
.data_b({i_data[7:0], i_data[15:8], i_data[23:16], i_data[31:24]}),
|
||||
.wren_b(!i_reset && i_request && i_write),
|
||||
.q_b({o_data[7:0], o_data[15:8], o_data[23:16], o_data[31:24]})
|
||||
);
|
||||
|
||||
|
||||
// Bus logic
|
||||
|
||||
assign o_busy = 1'b0;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= !i_reset && i_request && !i_write;
|
||||
end
|
||||
|
||||
endmodule
|
87
fw/rtl/n64/n64_soc.sv
Normal file
87
fw/rtl/n64/n64_soc.sv
Normal file
@ -0,0 +1,87 @@
|
||||
module n64_soc (
|
||||
if_system sys,
|
||||
if_config cfg,
|
||||
if_dma.memory dma,
|
||||
if_sdram.memory sdram,
|
||||
if_flashram.flashram flashram,
|
||||
if_si.si si,
|
||||
|
||||
input n64_pi_alel,
|
||||
input n64_pi_aleh,
|
||||
input n64_pi_read,
|
||||
input n64_pi_write,
|
||||
inout [15:0] n64_pi_ad,
|
||||
|
||||
input n64_si_clk,
|
||||
inout n64_si_dq,
|
||||
|
||||
output sdram_cs,
|
||||
output sdram_ras,
|
||||
output sdram_cas,
|
||||
output sdram_we,
|
||||
output [1:0] sdram_ba,
|
||||
output [12:0] sdram_a,
|
||||
inout [15:0] sdram_dq
|
||||
);
|
||||
|
||||
if_n64_bus bus ();
|
||||
|
||||
n64_pi n64_pi_inst (
|
||||
.sys(sys),
|
||||
.cfg(cfg),
|
||||
.bus(bus),
|
||||
|
||||
.n64_pi_alel(n64_pi_alel),
|
||||
.n64_pi_aleh(n64_pi_aleh),
|
||||
.n64_pi_read(n64_pi_read),
|
||||
.n64_pi_write(n64_pi_write),
|
||||
.n64_pi_ad(n64_pi_ad)
|
||||
);
|
||||
|
||||
n64_si n64_si_inst (
|
||||
.sys(sys),
|
||||
.si(si),
|
||||
|
||||
.n64_si_clk(n64_si_clk),
|
||||
.n64_si_dq(n64_si_dq)
|
||||
);
|
||||
|
||||
n64_sdram n64_sdram_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_SDRAM].device),
|
||||
.dma(dma),
|
||||
.sdram(sdram),
|
||||
|
||||
.sdram_cs(sdram_cs),
|
||||
.sdram_ras(sdram_ras),
|
||||
.sdram_cas(sdram_cas),
|
||||
.sdram_we(sdram_we),
|
||||
.sdram_ba(sdram_ba),
|
||||
.sdram_a(sdram_a),
|
||||
.sdram_dq(sdram_dq)
|
||||
);
|
||||
|
||||
n64_bootloader n64_bootloader_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device)
|
||||
);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
n64_cfg n64_cfg_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_CFG].device),
|
||||
.cfg(cfg)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,107 +0,0 @@
|
||||
module sd_clk (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
output reg o_sd_clk,
|
||||
|
||||
input [1:0] i_sd_clk_config,
|
||||
|
||||
output reg o_sd_clk_strobe_rising,
|
||||
output reg o_sd_clk_strobe_falling
|
||||
);
|
||||
|
||||
// Clock configuration values
|
||||
|
||||
localparam [1:0] SD_CLK_CONFIG_STOP = 2'd0;
|
||||
localparam [1:0] SD_CLK_CONFIG_DIV_256 = 2'd1;
|
||||
localparam [1:0] SD_CLK_CONFIG_DIV_4 = 2'd2;
|
||||
localparam [1:0] SD_CLK_CONFIG_DIV_2 = 2'd3;
|
||||
|
||||
|
||||
// Clock configuration change detection
|
||||
|
||||
reg [1:0] r_prev_sd_clk_config;
|
||||
|
||||
wire w_sd_clk_config_changed = r_prev_sd_clk_config != i_sd_clk_config;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_prev_sd_clk_config <= SD_CLK_CONFIG_STOP;
|
||||
end else begin
|
||||
r_prev_sd_clk_config <= i_sd_clk_config;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Clock divider
|
||||
|
||||
reg [7:0] r_sd_clk_counter;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || w_sd_clk_config_changed) begin
|
||||
r_sd_clk_counter <= 8'd0;
|
||||
end else begin
|
||||
r_sd_clk_counter <= r_sd_clk_counter + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Clock divider selector
|
||||
|
||||
reg r_selected_sd_clk;
|
||||
|
||||
always @(*) begin
|
||||
case (r_prev_sd_clk_config)
|
||||
SD_CLK_CONFIG_STOP:
|
||||
r_selected_sd_clk = 1'b0;
|
||||
SD_CLK_CONFIG_DIV_256:
|
||||
r_selected_sd_clk = r_sd_clk_counter[7];
|
||||
SD_CLK_CONFIG_DIV_4:
|
||||
r_selected_sd_clk = r_sd_clk_counter[1];
|
||||
SD_CLK_CONFIG_DIV_2:
|
||||
r_selected_sd_clk = r_sd_clk_counter[0];
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Clock strobe generation
|
||||
|
||||
reg r_prev_selected_sd_clk;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_sd_clk_strobe_rising <= 1'b0;
|
||||
o_sd_clk_strobe_falling <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
r_prev_selected_sd_clk <= 1'b0;
|
||||
end else begin
|
||||
r_prev_selected_sd_clk <= r_selected_sd_clk;
|
||||
|
||||
if (!r_prev_selected_sd_clk && r_selected_sd_clk) begin
|
||||
o_sd_clk_strobe_rising <= 1'b1;
|
||||
end
|
||||
|
||||
if (r_prev_selected_sd_clk && !r_selected_sd_clk) begin
|
||||
o_sd_clk_strobe_falling <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// SD clock generation
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
o_sd_clk <= 1'b0;
|
||||
end else begin
|
||||
if (o_sd_clk_strobe_rising) begin
|
||||
o_sd_clk <= 1'b1;
|
||||
end
|
||||
|
||||
if (o_sd_clk_strobe_falling) begin
|
||||
o_sd_clk <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,249 +0,0 @@
|
||||
module sd_cmd (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
inout io_sd_cmd,
|
||||
|
||||
input i_sd_clk_strobe_rising,
|
||||
input i_sd_clk_strobe_falling,
|
||||
|
||||
input [5:0] i_command_index,
|
||||
input [31:0] i_command_argument,
|
||||
input i_command_long_response,
|
||||
input i_command_skip_response,
|
||||
output reg [5:0] o_command_index,
|
||||
output reg [31:0] o_command_response,
|
||||
input i_command_start,
|
||||
output o_command_busy,
|
||||
output reg o_command_timeout,
|
||||
output reg o_command_response_crc_error
|
||||
);
|
||||
|
||||
// Start synchronizer
|
||||
|
||||
reg r_pending_start;
|
||||
|
||||
wire w_start = r_pending_start && i_sd_clk_strobe_falling;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_pending_start <= 1'b0;
|
||||
end else begin
|
||||
if (i_command_start) begin
|
||||
r_pending_start <= 1'b1;
|
||||
end else if (i_sd_clk_strobe_falling) begin
|
||||
r_pending_start <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Module state
|
||||
|
||||
localparam STATE_IDLE = 0;
|
||||
localparam STATE_SENDING = 1;
|
||||
localparam STATE_RESP_WAIT = 2;
|
||||
localparam STATE_RECEIVING = 3;
|
||||
localparam STATE_HIZ_WAIT = 4;
|
||||
|
||||
reg [4:0] r_state;
|
||||
|
||||
|
||||
// Bit counter logic
|
||||
|
||||
reg [8:0] r_bit_counter;
|
||||
reg r_bit_done;
|
||||
|
||||
wire w_command_start = w_start && r_state[STATE_IDLE];
|
||||
wire w_command_end = r_bit_done && r_state[STATE_SENDING];
|
||||
wire w_response_timeout = r_bit_done && r_state[STATE_RESP_WAIT];
|
||||
wire w_response_start = !io_sd_cmd && i_sd_clk_strobe_rising && r_state[STATE_RESP_WAIT];
|
||||
wire w_response_end = r_bit_done && r_state[STATE_RECEIVING];
|
||||
wire w_hiz_end = r_bit_done && r_state[STATE_HIZ_WAIT];
|
||||
|
||||
localparam [8:0] COMMAND_BIT_LENGTH = (9'd48 - 1'd1);
|
||||
localparam [8:0] RESPONSE_WAIT_BIT_LENGTH = (9'd64 - 1'd1);
|
||||
localparam [8:0] RESPONSE_SHORT_BIT_LENGTH = (9'd48 - 1'd1);
|
||||
localparam [8:0] RESPONSE_LONG_BIT_LENGTH = (9'd136 - 1'd1);
|
||||
localparam [8:0] HIZ_WAIT_BIT_LENGTH = (9'd8 - 1'd1);
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_command_start) begin
|
||||
r_bit_counter <= COMMAND_BIT_LENGTH;
|
||||
r_bit_done <= 1'b0;
|
||||
end else if (w_command_end) begin
|
||||
r_bit_counter <= RESPONSE_WAIT_BIT_LENGTH;
|
||||
r_bit_done <= 1'b0;
|
||||
end else if (w_response_start) begin
|
||||
r_bit_counter <= i_command_long_response ? RESPONSE_LONG_BIT_LENGTH : RESPONSE_SHORT_BIT_LENGTH;
|
||||
r_bit_done <= 1'b0;
|
||||
end else if (w_response_end) begin
|
||||
r_bit_counter <= HIZ_WAIT_BIT_LENGTH;
|
||||
r_bit_done <= 1'b0;
|
||||
end else if (i_sd_clk_strobe_rising) begin
|
||||
if (r_bit_counter > 9'd0) begin
|
||||
r_bit_counter <= r_bit_counter - 1'd1;
|
||||
end else begin
|
||||
r_bit_done <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// CRC7 generator
|
||||
|
||||
reg [6:0] r_crc_7_received;
|
||||
|
||||
wire w_crc_shift_reset = !(r_state[STATE_SENDING] || r_state[STATE_RECEIVING]);
|
||||
wire w_crc_shift_enabled = (r_bit_counter <= 9'd127) && (r_bit_counter > (r_state[STATE_SENDING] ? 9'd7 : 9'd8));
|
||||
wire w_crc_shift = w_crc_shift_enabled && i_sd_clk_strobe_rising;
|
||||
wire [6:0] w_crc_7_calculated;
|
||||
|
||||
sd_crc_7 sd_crc_7_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_crc_reset(w_crc_shift_reset),
|
||||
.i_crc_shift(w_crc_shift),
|
||||
.i_crc_input(io_sd_cmd),
|
||||
.o_crc_output(w_crc_7_calculated)
|
||||
);
|
||||
|
||||
|
||||
// Control signals
|
||||
|
||||
assign o_command_busy = r_pending_start || (!r_state[STATE_IDLE]);
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
o_command_timeout <= 1'b0;
|
||||
o_command_response_crc_error <= 1'b0;
|
||||
end else begin
|
||||
if (w_command_start) begin
|
||||
o_command_timeout <= 1'b0;
|
||||
end
|
||||
|
||||
if (w_response_timeout) begin
|
||||
o_command_timeout <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_response_end) begin
|
||||
o_command_response_crc_error <= (w_crc_7_calculated != r_crc_7_received);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// State machine
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_state <= (1'b1 << STATE_IDLE);
|
||||
end else begin
|
||||
r_state <= 5'b00000;
|
||||
|
||||
unique case (1'b1)
|
||||
r_state[STATE_IDLE]: begin
|
||||
if (w_start) begin
|
||||
r_state[STATE_SENDING] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
r_state[STATE_SENDING]: begin
|
||||
if (w_command_end) begin
|
||||
if (i_command_skip_response) begin
|
||||
r_state[STATE_HIZ_WAIT] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_RESP_WAIT] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
r_state[STATE_SENDING] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
r_state[STATE_RESP_WAIT]: begin
|
||||
if (w_response_timeout) begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end else if (w_response_start) begin
|
||||
r_state[STATE_RECEIVING] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_RESP_WAIT] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
r_state[STATE_RECEIVING]: begin
|
||||
if (w_response_end) begin
|
||||
r_state[STATE_HIZ_WAIT] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_RECEIVING] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
r_state[STATE_HIZ_WAIT]: begin
|
||||
if (w_hiz_end) begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_HIZ_WAIT] <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Shifting operation
|
||||
|
||||
reg [7:0] r_shift;
|
||||
|
||||
wire w_shift = (r_state[STATE_SENDING] && i_sd_clk_strobe_falling) || (r_state[STATE_RECEIVING] && i_sd_clk_strobe_rising);
|
||||
|
||||
assign io_sd_cmd = r_state[STATE_SENDING] ? r_shift[7] : 1'bZ;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_command_start) begin
|
||||
o_command_response <= 32'h0000_0000;
|
||||
r_shift <= {2'b01, i_command_index};
|
||||
end else if (w_response_start) begin
|
||||
r_shift <= 8'h00;
|
||||
end else begin
|
||||
if (w_shift) begin
|
||||
r_shift <= {r_shift[6:0], io_sd_cmd};
|
||||
end
|
||||
|
||||
if (i_sd_clk_strobe_falling && r_state[STATE_SENDING]) begin
|
||||
if (r_bit_counter == 9'd39) begin
|
||||
r_shift <= i_command_argument[31:24];
|
||||
end
|
||||
|
||||
if (r_bit_counter == 9'd31) begin
|
||||
r_shift <= i_command_argument[23:16];
|
||||
end
|
||||
|
||||
if (r_bit_counter == 9'd23) begin
|
||||
r_shift <= i_command_argument[15:8];
|
||||
end
|
||||
|
||||
if (r_bit_counter == 9'd15) begin
|
||||
r_shift <= i_command_argument[7:0];
|
||||
end
|
||||
|
||||
if (r_bit_counter == 9'd7) begin
|
||||
r_shift <= {w_crc_7_calculated, 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
if (i_sd_clk_strobe_rising && r_state[STATE_RECEIVING]) begin
|
||||
if (r_bit_counter == (i_command_long_response ? 9'd128 : 9'd40)) begin
|
||||
o_command_index <= r_shift[5:0];
|
||||
end else if (r_bit_counter[2:0] == 3'd0) begin
|
||||
if (r_bit_counter > 9'd7) begin
|
||||
o_command_response <= {o_command_response[23:0], r_shift};
|
||||
end else begin
|
||||
r_crc_7_received <= r_shift[7:1];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,26 +0,0 @@
|
||||
module sd_crc_16 (
|
||||
input i_clk,
|
||||
input i_crc_reset,
|
||||
input i_crc_shift,
|
||||
input i_crc_input,
|
||||
output reg [15:0] o_crc_output
|
||||
);
|
||||
|
||||
wire w_crc_inv = o_crc_output[15] ^ i_crc_input;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_crc_reset) begin
|
||||
o_crc_output <= 16'd0;
|
||||
end else if (i_crc_shift) begin
|
||||
o_crc_output <= {
|
||||
o_crc_output[14:12],
|
||||
o_crc_output[11] ^ w_crc_inv,
|
||||
o_crc_output[10:5],
|
||||
o_crc_output[4] ^ w_crc_inv,
|
||||
o_crc_output[3:0],
|
||||
w_crc_inv
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,24 +0,0 @@
|
||||
module sd_crc_7 (
|
||||
input i_clk,
|
||||
input i_crc_reset,
|
||||
input i_crc_shift,
|
||||
input i_crc_input,
|
||||
output reg [6:0] o_crc_output
|
||||
);
|
||||
|
||||
wire w_crc_inv = o_crc_output[6] ^ i_crc_input;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_crc_reset) begin
|
||||
o_crc_output <= 7'd0;
|
||||
end else if (i_crc_shift) begin
|
||||
o_crc_output <= {
|
||||
o_crc_output[5:3],
|
||||
o_crc_output[2] ^ w_crc_inv,
|
||||
o_crc_output[1:0],
|
||||
w_crc_inv
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,208 +0,0 @@
|
||||
module sd_dat (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
inout reg [3:0] io_sd_dat,
|
||||
|
||||
input i_sd_clk_strobe_rising,
|
||||
input i_sd_clk_strobe_falling,
|
||||
|
||||
input i_dat_width,
|
||||
input i_dat_direction,
|
||||
input [6:0] i_dat_block_size,
|
||||
input [10:0] i_dat_num_blocks,
|
||||
input i_dat_start,
|
||||
input i_dat_stop,
|
||||
output o_dat_busy,
|
||||
output reg o_dat_crc_error,
|
||||
|
||||
output reg o_rx_fifo_push,
|
||||
input i_rx_fifo_overrun,
|
||||
output reg [31:0] o_rx_fifo_data,
|
||||
|
||||
input i_tx_fifo_full,
|
||||
output reg o_tx_fifo_pop,
|
||||
input [31:0] i_tx_fifo_data
|
||||
);
|
||||
|
||||
// Module state
|
||||
|
||||
localparam STATE_IDLE = 0;
|
||||
localparam STATE_READ_WAIT = 1;
|
||||
localparam STATE_RECEIVING = 2;
|
||||
|
||||
reg [2:0] r_state;
|
||||
|
||||
|
||||
// Bit counter logic
|
||||
|
||||
reg [12:0] r_bit_counter;
|
||||
reg r_bit_done;
|
||||
|
||||
wire w_start_bit = !io_sd_dat[0] && i_sd_clk_strobe_rising && r_state[STATE_READ_WAIT];
|
||||
wire w_data_end = r_bit_done && r_state[STATE_RECEIVING];
|
||||
|
||||
assign o_dat_busy = !r_state[STATE_IDLE];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_start_bit) begin
|
||||
r_bit_counter <= (i_dat_width ? (
|
||||
{2'b00, {1'b0, i_dat_block_size} + 1'd1, 3'b000}
|
||||
) : (
|
||||
{{1'b0, i_dat_block_size} + 1'd1, 5'b00000}
|
||||
)) + 13'd16;
|
||||
r_bit_done <= 1'b0;
|
||||
end else if (i_sd_clk_strobe_rising) begin
|
||||
if (r_bit_counter > 13'd0) begin
|
||||
r_bit_counter <= r_bit_counter - 1'd1;
|
||||
end else begin
|
||||
r_bit_done <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Block counter logic
|
||||
|
||||
reg [10:0] r_block_counter;
|
||||
|
||||
wire w_read_start = i_dat_start && r_state[STATE_IDLE];
|
||||
wire w_read_stop = r_block_counter == 11'd0;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_read_start) begin
|
||||
r_block_counter <= i_dat_num_blocks;
|
||||
end else if (w_data_end) begin
|
||||
if (r_block_counter > 11'd0) begin
|
||||
r_block_counter <= r_block_counter - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// CRC16 generator
|
||||
|
||||
reg [15:0] r_crc_16_received [0:3];
|
||||
|
||||
wire w_crc_shift_reset = !r_state[STATE_RECEIVING];
|
||||
wire w_crc_shift_enabled = r_bit_counter > 13'd16;
|
||||
wire w_crc_shift = w_crc_shift_enabled && i_sd_clk_strobe_rising;
|
||||
wire [15:0] w_crc_16_calculated [0:3];
|
||||
|
||||
wire w_crc_error = (r_bit_counter == 13'd0) && (i_dat_width ? (
|
||||
(w_crc_16_calculated[0] != r_crc_16_received[0]) &&
|
||||
(w_crc_16_calculated[1] != r_crc_16_received[1]) &&
|
||||
(w_crc_16_calculated[2] != r_crc_16_received[2]) &&
|
||||
(w_crc_16_calculated[3] != r_crc_16_received[3])
|
||||
) : (
|
||||
w_crc_16_calculated[0] != r_crc_16_received[0]
|
||||
));
|
||||
|
||||
genvar dat_index;
|
||||
generate
|
||||
for (dat_index = 0; dat_index < 4; dat_index = dat_index + 1) begin : crc_16_loop
|
||||
sd_crc_16 sd_crc_16_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_crc_reset(w_crc_shift_reset),
|
||||
.i_crc_shift(w_crc_shift),
|
||||
.i_crc_input(io_sd_dat[dat_index]),
|
||||
.o_crc_output(w_crc_16_calculated[dat_index])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// Control signals
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
o_dat_crc_error <= 1'b0;
|
||||
end else begin
|
||||
if (w_data_end) begin
|
||||
o_dat_crc_error <= w_crc_error;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// State machine
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_state <= (1'b1 << STATE_IDLE);
|
||||
end else begin
|
||||
r_state <= 3'b000;
|
||||
|
||||
if (i_dat_stop) begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end else begin
|
||||
unique case (1'b1)
|
||||
r_state[STATE_IDLE]: begin
|
||||
if (i_dat_start) begin
|
||||
if (i_dat_direction) begin
|
||||
r_state[STATE_IDLE] <= 1'b1; // TODO: Sending
|
||||
end else begin
|
||||
r_state[STATE_READ_WAIT] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
r_state[STATE_READ_WAIT]: begin
|
||||
if (w_start_bit) begin
|
||||
r_state[STATE_RECEIVING] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_READ_WAIT] <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
r_state[STATE_RECEIVING]: begin
|
||||
if (w_crc_error || i_rx_fifo_overrun) begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end else if (w_data_end) begin
|
||||
if (w_read_stop) begin
|
||||
r_state[STATE_IDLE] <= 1'b1;
|
||||
end else begin
|
||||
r_state[STATE_READ_WAIT] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
r_state[STATE_RECEIVING] <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Shifting operation
|
||||
|
||||
wire [31:0] w_shift_1_bit = {o_rx_fifo_data[30:0], io_sd_dat[0]};
|
||||
wire [31:0] w_shift_4_bit = {o_rx_fifo_data[27:0], io_sd_dat};
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_rx_fifo_push <= 1'b0;
|
||||
|
||||
if (i_sd_clk_strobe_rising && r_state[STATE_RECEIVING]) begin
|
||||
if (r_bit_counter > 13'd16) begin
|
||||
if (i_dat_width) begin
|
||||
o_rx_fifo_data <= w_shift_4_bit;
|
||||
if (r_bit_counter[2:0] == 3'd1) begin
|
||||
o_rx_fifo_push <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
o_rx_fifo_data <= w_shift_1_bit;
|
||||
if (r_bit_counter[4:0] == 5'd17) begin
|
||||
o_rx_fifo_push <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else if (r_bit_counter > 13'd0) begin
|
||||
for (integer i = 0; i < 4; i = i + 1) begin
|
||||
r_crc_16_received[i] <= {r_crc_16_received[i][14:0], io_sd_dat[i]};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,93 +0,0 @@
|
||||
module sd_dma (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input [3:0] i_dma_bank,
|
||||
input [23:0] i_dma_address,
|
||||
input [17:0] i_dma_length,
|
||||
output [17:0] o_dma_left,
|
||||
input i_dma_load_bank_address,
|
||||
input i_dma_load_length,
|
||||
input i_dma_direction,
|
||||
input i_dma_start,
|
||||
input i_dma_stop,
|
||||
output reg o_dma_busy,
|
||||
|
||||
output o_rx_fifo_pop,
|
||||
input i_rx_fifo_empty,
|
||||
input [31:0] i_rx_fifo_data,
|
||||
|
||||
output reg o_tx_fifo_push,
|
||||
input i_tx_fifo_full,
|
||||
output [31:0] o_tx_fifo_data,
|
||||
|
||||
output o_request,
|
||||
output reg o_write,
|
||||
input i_busy,
|
||||
input i_ack,
|
||||
output reg [3:0] o_bank,
|
||||
output reg [23:0] o_address,
|
||||
input [31:0] i_data,
|
||||
output [31:0] o_data
|
||||
);
|
||||
|
||||
wire w_request_successful = o_request && !i_busy;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_dma_load_bank_address && !o_dma_busy) begin
|
||||
o_bank <= i_dma_bank;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_dma_load_bank_address && !o_dma_busy) begin
|
||||
o_address <= i_dma_address;
|
||||
end else if (w_request_successful) begin
|
||||
o_address <= o_address + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
reg [17:0] r_remaining;
|
||||
|
||||
assign o_dma_left = r_remaining;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_dma_load_length && !o_dma_busy) begin
|
||||
r_remaining <= i_dma_length;
|
||||
end else if (w_request_successful && r_remaining > 18'd0) begin
|
||||
r_remaining <= r_remaining - 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
o_dma_busy <= 1'b0;
|
||||
end else begin
|
||||
if (i_dma_start && !o_dma_busy) begin
|
||||
o_dma_busy <= 1'b1;
|
||||
end
|
||||
if (i_dma_stop || (w_request_successful && r_remaining == 18'd0)) begin
|
||||
o_dma_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign o_rx_fifo_pop = o_dma_busy && o_write && w_request_successful;
|
||||
|
||||
assign o_tx_fifo_data = i_data;
|
||||
|
||||
assign o_request = o_dma_busy && (o_write ? (
|
||||
!i_rx_fifo_empty
|
||||
) : (
|
||||
1'b0 // TODO: Reading
|
||||
));
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_dma_start) begin
|
||||
o_write <= i_dma_direction;
|
||||
end
|
||||
end
|
||||
|
||||
assign o_data = i_rx_fifo_data;
|
||||
|
||||
endmodule
|
@ -1,56 +0,0 @@
|
||||
module sd_fifo (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_fifo_flush,
|
||||
input i_fifo_push,
|
||||
input i_fifo_pop,
|
||||
output o_fifo_empty,
|
||||
output o_fifo_full,
|
||||
output [7:0] o_fifo_items,
|
||||
output reg o_fifo_underrun,
|
||||
output reg o_fifo_overrun,
|
||||
input [31:0] i_fifo_data,
|
||||
output [31:0] o_fifo_data
|
||||
);
|
||||
|
||||
reg [31:0] r_fifo_mem [0:127];
|
||||
|
||||
reg [7:0] r_fifo_wrptr;
|
||||
reg [7:0] r_fifo_rdptr;
|
||||
|
||||
assign o_fifo_data = r_fifo_mem[r_fifo_rdptr[6:0]];
|
||||
|
||||
wire w_empty = r_fifo_wrptr[7] == r_fifo_rdptr[7];
|
||||
wire w_full_or_empty = r_fifo_wrptr[6:0] == r_fifo_rdptr[6:0];
|
||||
|
||||
assign o_fifo_empty = w_empty && w_full_or_empty;
|
||||
assign o_fifo_full = !w_empty && w_full_or_empty;
|
||||
assign o_fifo_items = r_fifo_wrptr - r_fifo_rdptr;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_fifo_wrptr <= 8'd0;
|
||||
r_fifo_rdptr <= 8'd0;
|
||||
o_fifo_underrun <= 1'b0;
|
||||
o_fifo_overrun <= 1'b0;
|
||||
end else begin
|
||||
if (i_fifo_flush) begin
|
||||
r_fifo_wrptr <= 8'd0;
|
||||
r_fifo_rdptr <= 8'd0;
|
||||
o_fifo_underrun <= 1'b0;
|
||||
o_fifo_overrun <= 1'b0;
|
||||
end
|
||||
if (i_fifo_push) begin
|
||||
o_fifo_overrun <= o_fifo_overrun ? 1'b1 : o_fifo_full;
|
||||
r_fifo_mem[r_fifo_wrptr[6:0]] <= i_fifo_data;
|
||||
r_fifo_wrptr <= r_fifo_wrptr + 1'd1;
|
||||
end
|
||||
if (i_fifo_pop) begin
|
||||
o_fifo_underrun <= o_fifo_underrun ? 1'b1 : o_fifo_empty;
|
||||
r_fifo_rdptr <= r_fifo_rdptr + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,295 +0,0 @@
|
||||
module sd_interface (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
output o_sd_clk,
|
||||
inout io_sd_cmd,
|
||||
inout [3:0] io_sd_dat,
|
||||
|
||||
input i_request,
|
||||
input i_write,
|
||||
output o_busy,
|
||||
output o_ack,
|
||||
input [3:0] i_address,
|
||||
output [31:0] o_data,
|
||||
input [31:0] i_data,
|
||||
|
||||
output o_dma_request,
|
||||
output o_dma_write,
|
||||
input i_dma_busy,
|
||||
input i_dma_ack,
|
||||
output [3:0] o_dma_bank,
|
||||
output [23:0] o_dma_address,
|
||||
input [31:0] i_dma_data,
|
||||
output [31:0] o_dma_data
|
||||
);
|
||||
|
||||
// Clock generator
|
||||
|
||||
wire [1:0] w_sd_clk_config;
|
||||
wire w_sd_clk_strobe_rising;
|
||||
wire w_sd_clk_strobe_falling;
|
||||
|
||||
sd_clk sd_clk_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.i_sd_clk_config(w_sd_clk_config),
|
||||
|
||||
.o_sd_clk_strobe_rising(w_sd_clk_strobe_rising),
|
||||
.o_sd_clk_strobe_falling(w_sd_clk_strobe_falling),
|
||||
|
||||
.o_sd_clk(o_sd_clk)
|
||||
);
|
||||
|
||||
|
||||
// Command path
|
||||
|
||||
wire [5:0] w_command_index;
|
||||
wire [31:0] w_command_argument;
|
||||
wire w_command_skip_response;
|
||||
wire w_command_long_response;
|
||||
wire [5:0] w_command_response_index;
|
||||
wire [31:0] w_command_response;
|
||||
wire w_command_start;
|
||||
wire w_command_busy;
|
||||
wire w_command_timeout;
|
||||
wire w_command_response_crc_error;
|
||||
|
||||
sd_cmd sd_cmd_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.io_sd_cmd(io_sd_cmd),
|
||||
|
||||
.i_sd_clk_strobe_rising(w_sd_clk_strobe_rising),
|
||||
.i_sd_clk_strobe_falling(w_sd_clk_strobe_falling),
|
||||
|
||||
.i_command_index(w_command_index),
|
||||
.i_command_argument(w_command_argument),
|
||||
.i_command_long_response(w_command_long_response),
|
||||
.i_command_skip_response(w_command_skip_response),
|
||||
.o_command_index(w_command_response_index),
|
||||
.o_command_response(w_command_response),
|
||||
.i_command_start(w_command_start),
|
||||
.o_command_busy(w_command_busy),
|
||||
.o_command_timeout(w_command_timeout),
|
||||
.o_command_response_crc_error(w_command_response_crc_error)
|
||||
);
|
||||
|
||||
|
||||
// SD to FPGA (RX) data path FIFO
|
||||
|
||||
wire w_rx_fifo_flush;
|
||||
wire w_rx_fifo_push;
|
||||
wire w_rx_fifo_regs_pop;
|
||||
wire w_rx_fifo_dma_pop;
|
||||
wire w_rx_fifo_empty;
|
||||
wire [7:0] w_rx_fifo_items;
|
||||
wire w_rx_fifo_overrun;
|
||||
wire [31:0] w_rx_fifo_i_data;
|
||||
wire [31:0] w_rx_fifo_o_data;
|
||||
|
||||
sd_fifo sd_fifo_rx_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.i_fifo_flush(w_rx_fifo_flush),
|
||||
.i_fifo_push(w_rx_fifo_push),
|
||||
.i_fifo_pop(w_rx_fifo_regs_pop || w_rx_fifo_dma_pop),
|
||||
.o_fifo_empty(w_rx_fifo_empty),
|
||||
.o_fifo_full(),
|
||||
.o_fifo_items(w_rx_fifo_items),
|
||||
.o_fifo_underrun(),
|
||||
.o_fifo_overrun(w_rx_fifo_overrun),
|
||||
.i_fifo_data(w_rx_fifo_i_data),
|
||||
.o_fifo_data(w_rx_fifo_o_data)
|
||||
);
|
||||
|
||||
|
||||
// FPGA to SD (TX) data path FIFO
|
||||
|
||||
wire w_tx_fifo_flush;
|
||||
wire w_tx_fifo_regs_push;
|
||||
wire w_tx_fifo_dma_push;
|
||||
wire w_tx_fifo_pop;
|
||||
wire w_tx_fifo_empty;
|
||||
wire w_tx_fifo_full;
|
||||
reg [31:0] r_tx_fifo_i_data;
|
||||
wire [31:0] w_tx_fifo_o_data;
|
||||
|
||||
wire [31:0] w_tx_fifo_i_data_regs;
|
||||
wire [31:0] w_tx_fifo_i_data_dma;
|
||||
|
||||
always @(*) begin
|
||||
r_tx_fifo_i_data = 32'h0000_0000;
|
||||
if (w_tx_fifo_regs_push) r_tx_fifo_i_data = w_tx_fifo_i_data_regs;
|
||||
if (w_tx_fifo_dma_push) r_tx_fifo_i_data = w_tx_fifo_i_data_dma;
|
||||
end
|
||||
|
||||
sd_fifo sd_fifo_tx_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.i_fifo_flush(w_tx_fifo_flush),
|
||||
.i_fifo_push(w_tx_fifo_regs_push || w_tx_fifo_dma_push),
|
||||
.i_fifo_pop(w_tx_fifo_pop),
|
||||
.o_fifo_empty(w_tx_fifo_empty),
|
||||
.o_fifo_full(w_tx_fifo_full),
|
||||
.o_fifo_items(),
|
||||
.o_fifo_underrun(),
|
||||
.o_fifo_overrun(),
|
||||
.i_fifo_data(r_tx_fifo_i_data),
|
||||
.o_fifo_data(w_tx_fifo_o_data)
|
||||
);
|
||||
|
||||
|
||||
// Data path
|
||||
|
||||
wire w_dat_width;
|
||||
wire w_dat_direction;
|
||||
wire [6:0] w_dat_block_size;
|
||||
wire [10:0] w_dat_num_blocks;
|
||||
wire w_dat_start;
|
||||
wire w_dat_stop;
|
||||
wire w_dat_busy;
|
||||
wire w_dat_crc_error;
|
||||
|
||||
sd_dat sd_dat_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.io_sd_dat(io_sd_dat),
|
||||
|
||||
.i_sd_clk_strobe_rising(w_sd_clk_strobe_rising),
|
||||
.i_sd_clk_strobe_falling(w_sd_clk_strobe_falling),
|
||||
|
||||
.i_dat_width(w_dat_width),
|
||||
.i_dat_direction(w_dat_direction),
|
||||
.i_dat_block_size(w_dat_block_size),
|
||||
.i_dat_num_blocks(w_dat_num_blocks),
|
||||
.i_dat_start(w_dat_start),
|
||||
.i_dat_stop(w_dat_stop),
|
||||
.o_dat_busy(w_dat_busy),
|
||||
.o_dat_crc_error(w_dat_crc_error),
|
||||
|
||||
.o_rx_fifo_push(w_rx_fifo_push),
|
||||
.i_rx_fifo_overrun(w_rx_fifo_overrun),
|
||||
.o_rx_fifo_data(w_rx_fifo_i_data),
|
||||
|
||||
.i_tx_fifo_full(w_tx_fifo_full),
|
||||
.o_tx_fifo_pop(w_tx_fifo_pop),
|
||||
.i_tx_fifo_data(w_tx_fifo_o_data)
|
||||
);
|
||||
|
||||
|
||||
// DMA
|
||||
|
||||
wire [3:0] w_dma_bank;
|
||||
wire [23:0] w_dma_address;
|
||||
wire [17:0] w_dma_length;
|
||||
wire [17:0] w_dma_left;
|
||||
wire w_dma_load_bank_address;
|
||||
wire w_dma_load_length;
|
||||
wire w_dma_direction;
|
||||
wire w_dma_start;
|
||||
wire w_dma_stop;
|
||||
wire w_dma_busy;
|
||||
|
||||
sd_dma sd_dma_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.i_dma_bank(w_dma_bank),
|
||||
.i_dma_address(w_dma_address),
|
||||
.i_dma_length(w_dma_length),
|
||||
.o_dma_left(w_dma_left),
|
||||
.i_dma_load_bank_address(w_dma_load_bank_address),
|
||||
.i_dma_load_length(w_dma_load_length),
|
||||
.i_dma_direction(w_dma_direction),
|
||||
.i_dma_start(w_dma_start),
|
||||
.i_dma_stop(w_dma_stop),
|
||||
.o_dma_busy(w_dma_busy),
|
||||
|
||||
.o_rx_fifo_pop(w_rx_fifo_dma_pop),
|
||||
.i_rx_fifo_empty(w_rx_fifo_empty),
|
||||
.i_rx_fifo_data(w_rx_fifo_o_data),
|
||||
|
||||
.o_tx_fifo_push(w_tx_fifo_dma_push),
|
||||
.i_tx_fifo_full(w_tx_fifo_full),
|
||||
.o_tx_fifo_data(w_tx_fifo_i_data_dma),
|
||||
|
||||
.o_request(o_dma_request),
|
||||
.o_write(o_dma_write),
|
||||
.i_busy(i_dma_busy),
|
||||
.i_ack(i_dma_ack),
|
||||
.o_bank(o_dma_bank),
|
||||
.o_address(o_dma_address),
|
||||
.i_data(i_dma_data),
|
||||
.o_data(o_dma_data)
|
||||
);
|
||||
|
||||
|
||||
// Peripheral registers
|
||||
|
||||
sd_regs sd_regs_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.o_sd_clk_config(w_sd_clk_config),
|
||||
|
||||
.o_command_index(w_command_index),
|
||||
.o_command_argument(w_command_argument),
|
||||
.o_command_long_response(w_command_long_response),
|
||||
.o_command_skip_response(w_command_skip_response),
|
||||
.i_command_index(w_command_response_index),
|
||||
.i_command_response(w_command_response),
|
||||
.o_command_start(w_command_start),
|
||||
.i_command_busy(w_command_busy),
|
||||
.i_command_timeout(w_command_timeout),
|
||||
.i_command_response_crc_error(w_command_response_crc_error),
|
||||
|
||||
.o_dat_width(w_dat_width),
|
||||
.o_dat_direction(w_dat_direction),
|
||||
.o_dat_block_size(w_dat_block_size),
|
||||
.o_dat_num_blocks(w_dat_num_blocks),
|
||||
.o_dat_start(w_dat_start),
|
||||
.o_dat_stop(w_dat_stop),
|
||||
.i_dat_busy(w_dat_busy),
|
||||
.i_dat_crc_error(w_dat_crc_error),
|
||||
|
||||
.o_rx_fifo_flush(w_rx_fifo_flush),
|
||||
.o_rx_fifo_pop(w_rx_fifo_regs_pop),
|
||||
.i_rx_fifo_items(w_rx_fifo_items),
|
||||
.i_rx_fifo_overrun(w_rx_fifo_overrun),
|
||||
.i_rx_fifo_data(w_rx_fifo_o_data),
|
||||
|
||||
.o_tx_fifo_flush(w_tx_fifo_flush),
|
||||
.o_tx_fifo_push(w_tx_fifo_regs_push),
|
||||
.i_tx_fifo_empty(w_tx_fifo_empty),
|
||||
.i_tx_fifo_full(w_tx_fifo_full),
|
||||
.o_tx_fifo_data(w_tx_fifo_i_data_regs),
|
||||
|
||||
.o_dma_bank(w_dma_bank),
|
||||
.o_dma_address(w_dma_address),
|
||||
.o_dma_length(w_dma_length),
|
||||
.i_dma_bank(o_dma_bank),
|
||||
.i_dma_address(o_dma_address),
|
||||
.i_dma_left(w_dma_left),
|
||||
.o_dma_load_bank_address(w_dma_load_bank_address),
|
||||
.o_dma_load_length(w_dma_load_length),
|
||||
.o_dma_direction(w_dma_direction),
|
||||
.o_dma_start(w_dma_start),
|
||||
.o_dma_stop(w_dma_stop),
|
||||
.i_dma_busy(w_dma_busy),
|
||||
|
||||
.i_request(i_request),
|
||||
.i_write(i_write),
|
||||
.o_busy(o_busy),
|
||||
.o_ack(o_ack),
|
||||
.i_address(i_address),
|
||||
.o_data(o_data),
|
||||
.i_data(i_data)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,223 +0,0 @@
|
||||
module sd_regs (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
output reg [1:0] o_sd_clk_config,
|
||||
|
||||
output reg [5:0] o_command_index,
|
||||
output reg [31:0] o_command_argument,
|
||||
output reg o_command_long_response,
|
||||
output reg o_command_skip_response,
|
||||
input [5:0] i_command_index,
|
||||
input [31:0] i_command_response,
|
||||
output reg o_command_start,
|
||||
input i_command_busy,
|
||||
input i_command_timeout,
|
||||
input i_command_response_crc_error,
|
||||
|
||||
output reg o_dat_width,
|
||||
output reg o_dat_direction,
|
||||
output reg [6:0] o_dat_block_size,
|
||||
output reg [10:0] o_dat_num_blocks,
|
||||
output reg o_dat_start,
|
||||
output reg o_dat_stop,
|
||||
input i_dat_busy,
|
||||
input i_dat_crc_error,
|
||||
|
||||
output reg o_rx_fifo_flush,
|
||||
output reg o_rx_fifo_pop,
|
||||
input [7:0] i_rx_fifo_items,
|
||||
input i_rx_fifo_overrun,
|
||||
input [31:0] i_rx_fifo_data,
|
||||
|
||||
output reg o_tx_fifo_flush,
|
||||
output reg o_tx_fifo_push,
|
||||
input i_tx_fifo_empty,
|
||||
input i_tx_fifo_full,
|
||||
output reg [31:0] o_tx_fifo_data,
|
||||
|
||||
output reg [3:0] o_dma_bank,
|
||||
output reg [23:0] o_dma_address,
|
||||
output reg [17:0] o_dma_length,
|
||||
input [3:0] i_dma_bank,
|
||||
input [23:0] i_dma_address,
|
||||
input [17:0] i_dma_left,
|
||||
output reg o_dma_load_bank_address,
|
||||
output reg o_dma_load_length,
|
||||
output reg o_dma_direction,
|
||||
output reg o_dma_start,
|
||||
output reg o_dma_stop,
|
||||
input i_dma_busy,
|
||||
|
||||
input i_request,
|
||||
input i_write,
|
||||
output o_busy,
|
||||
output reg o_ack,
|
||||
input [3:0] i_address,
|
||||
output reg [31:0] o_data,
|
||||
input [31:0] i_data
|
||||
);
|
||||
|
||||
localparam [2:0] SD_REG_SCR = 3'd0;
|
||||
localparam [2:0] SD_REG_ARG = 3'd1;
|
||||
localparam [2:0] SD_REG_CMD = 3'd2;
|
||||
localparam [2:0] SD_REG_RSP = 3'd3;
|
||||
localparam [2:0] SD_REG_DAT = 3'd4;
|
||||
localparam [2:0] SD_REG_DMA_SCR = 3'd5;
|
||||
localparam [2:0] SD_REG_DMA_ADDR = 3'd6;
|
||||
localparam [2:0] SD_REG_DMA_LEN = 3'd7;
|
||||
|
||||
wire w_write_request = i_request && i_write && !o_busy;
|
||||
wire w_read_request = i_request && !i_write && !o_busy;
|
||||
|
||||
always @(*) begin
|
||||
o_dma_bank = i_data[31:28];
|
||||
o_dma_address = i_data[25:2];
|
||||
o_dma_length = i_data[17:0];
|
||||
o_dma_load_bank_address = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_ADDR);
|
||||
o_dma_load_length = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_LEN);
|
||||
o_busy = 1'b0;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_command_start <= 1'b0;
|
||||
o_dat_start <= 1'b0;
|
||||
o_rx_fifo_flush <= 1'b0;
|
||||
o_tx_fifo_flush <= 1'b0;
|
||||
o_tx_fifo_push <= 1'b0;
|
||||
o_dma_start <= 1'b0;
|
||||
o_dat_stop <= 1'b0;
|
||||
o_dma_stop <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
o_sd_clk_config <= 2'd0;
|
||||
o_dat_width <= 1'b0;
|
||||
o_dat_direction <= 1'b0;
|
||||
o_dat_block_size <= 7'd0;
|
||||
o_dat_num_blocks <= 11'd0;
|
||||
o_dma_direction <= 1'b0;
|
||||
end else if (w_write_request) begin
|
||||
if (!i_address[3]) begin
|
||||
case (i_address[2:0])
|
||||
SD_REG_SCR: begin
|
||||
{o_dat_width, o_sd_clk_config} <= i_data[2:0];
|
||||
end
|
||||
|
||||
SD_REG_ARG: begin
|
||||
o_command_argument <= i_data;
|
||||
end
|
||||
|
||||
SD_REG_CMD: begin
|
||||
{
|
||||
o_command_skip_response,
|
||||
o_command_long_response,
|
||||
o_command_start,
|
||||
o_command_index
|
||||
} <= i_data[8:0];
|
||||
end
|
||||
|
||||
SD_REG_RSP: begin
|
||||
end
|
||||
|
||||
SD_REG_DAT: begin
|
||||
{
|
||||
o_tx_fifo_flush,
|
||||
o_rx_fifo_flush,
|
||||
o_dat_num_blocks,
|
||||
o_dat_block_size,
|
||||
o_dat_direction,
|
||||
o_dat_stop,
|
||||
o_dat_start
|
||||
} <= i_data[22:0];
|
||||
end
|
||||
|
||||
SD_REG_DMA_SCR: begin
|
||||
{
|
||||
o_dma_direction,
|
||||
o_dma_stop,
|
||||
o_dma_start
|
||||
} <= i_data[2:0];
|
||||
end
|
||||
|
||||
SD_REG_DMA_ADDR: begin
|
||||
end
|
||||
|
||||
SD_REG_DMA_LEN: begin
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
o_tx_fifo_push <= 1'b1;
|
||||
o_tx_fifo_data <= i_data;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_rx_fifo_pop <= 1'b0;
|
||||
o_ack <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
o_data <= 32'h0000_0000;
|
||||
end else if (w_read_request) begin
|
||||
o_ack <= 1'b1;
|
||||
|
||||
if (!i_address[3]) begin
|
||||
case (i_address[2:0])
|
||||
SD_REG_SCR: begin
|
||||
o_data <= {29'd0, o_dat_width, o_sd_clk_config};
|
||||
end
|
||||
|
||||
SD_REG_ARG: begin
|
||||
o_data <= o_command_argument;
|
||||
end
|
||||
|
||||
SD_REG_CMD: begin
|
||||
o_data <= {
|
||||
21'd0,
|
||||
i_command_response_crc_error,
|
||||
i_command_timeout,
|
||||
o_command_skip_response,
|
||||
o_command_long_response,
|
||||
i_command_busy,
|
||||
i_command_index
|
||||
};
|
||||
end
|
||||
|
||||
SD_REG_RSP: begin
|
||||
o_data <= i_command_response;
|
||||
end
|
||||
|
||||
SD_REG_DAT: begin
|
||||
o_data <= {
|
||||
i_rx_fifo_items,
|
||||
i_tx_fifo_full,
|
||||
i_tx_fifo_empty,
|
||||
i_rx_fifo_overrun,
|
||||
o_dat_num_blocks,
|
||||
o_dat_block_size,
|
||||
o_dat_direction,
|
||||
i_dat_crc_error,
|
||||
i_dat_busy
|
||||
};
|
||||
end
|
||||
|
||||
SD_REG_DMA_SCR: begin
|
||||
o_data <= {29'd0, o_dma_direction, 1'b0, i_dma_busy};
|
||||
end
|
||||
|
||||
SD_REG_DMA_ADDR: begin
|
||||
o_data <= {i_dma_bank, 2'd0, i_dma_address, 2'b00};
|
||||
end
|
||||
|
||||
SD_REG_DMA_LEN: begin
|
||||
o_data <= {14'd0, i_dma_left};
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
o_rx_fifo_pop <= 1'b1;
|
||||
o_data <= i_rx_fifo_data;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
70
fw/rtl/system/config.sv
Normal file
70
fw/rtl/system/config.sv
Normal file
@ -0,0 +1,70 @@
|
||||
interface if_config ();
|
||||
|
||||
logic cpu_ready;
|
||||
logic cpu_busy;
|
||||
logic usb_waiting;
|
||||
logic cmd_error;
|
||||
logic cmd_request;
|
||||
logic [7:0] cmd;
|
||||
logic [31:0] data [0:1];
|
||||
logic [1:0] data_write;
|
||||
logic [31:0] wdata;
|
||||
logic sdram_switch;
|
||||
logic sdram_writable;
|
||||
logic dd_enabled;
|
||||
logic sram_enabled;
|
||||
logic sram_banked;
|
||||
logic flashram_enabled;
|
||||
logic flashram_read_mode;
|
||||
logic [25:0] dd_offset;
|
||||
logic [25:0] save_offset;
|
||||
|
||||
modport pi (
|
||||
input sdram_switch,
|
||||
input sdram_writable,
|
||||
input dd_enabled,
|
||||
input sram_enabled,
|
||||
input sram_banked,
|
||||
input flashram_enabled,
|
||||
input flashram_read_mode,
|
||||
input dd_offset,
|
||||
input save_offset
|
||||
);
|
||||
|
||||
modport flashram (
|
||||
output flashram_read_mode
|
||||
);
|
||||
|
||||
modport n64 (
|
||||
input cpu_ready,
|
||||
input cpu_busy,
|
||||
input usb_waiting,
|
||||
input cmd_error,
|
||||
output cmd_request,
|
||||
output cmd,
|
||||
output data,
|
||||
input data_write,
|
||||
input wdata
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
output cpu_ready,
|
||||
output cpu_busy,
|
||||
output usb_waiting,
|
||||
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 dd_offset,
|
||||
output save_offset
|
||||
);
|
||||
|
||||
endinterface
|
41
fw/rtl/system/sc64.sv
Normal file
41
fw/rtl/system/sc64.sv
Normal file
@ -0,0 +1,41 @@
|
||||
package sc64;
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
ID_N64_SDRAM,
|
||||
ID_N64_BOOTLOADER,
|
||||
ID_N64_FLASHRAM,
|
||||
ID_N64_DD,
|
||||
ID_N64_CFG,
|
||||
__ID_N64_END
|
||||
} e_n64_id;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
ID_CPU_RAM,
|
||||
ID_CPU_BOOTLOADER,
|
||||
ID_CPU_GPIO,
|
||||
ID_CPU_I2C,
|
||||
ID_CPU_USB,
|
||||
ID_CPU_UART,
|
||||
ID_CPU_DMA,
|
||||
ID_CPU_CFG,
|
||||
ID_CPU_SDRAM,
|
||||
ID_CPU_FLASHRAM,
|
||||
ID_CPU_SI,
|
||||
__ID_CPU_END
|
||||
} e_cpu_id;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
ID_DMA_USB,
|
||||
ID_DMA_SD,
|
||||
__ID_DMA_END
|
||||
} e_dma_id;
|
||||
|
||||
parameter bit [31:0] SC64_VER = 32'h53437632;
|
||||
|
||||
parameter int CLOCK_FREQUENCY = 32'd100_000_000;
|
||||
|
||||
parameter int UART_BAUD_RATE = 32'd1_000_000;
|
||||
|
||||
parameter bit DEBUG_ENABLED = 1'b0;
|
||||
|
||||
endpackage
|
72
fw/rtl/system/system.sv
Normal file
72
fw/rtl/system/system.sv
Normal file
@ -0,0 +1,72 @@
|
||||
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 external_reset;
|
||||
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)
|
||||
);
|
||||
|
||||
generate
|
||||
if (sc64::DEBUG_ENABLED) begin
|
||||
intel_snp intel_snp_inst (
|
||||
.source(external_reset),
|
||||
.source_clk(sys.clk)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
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 | external_reset;
|
||||
sys.n64_hard_reset = ~n64_reset_ff[1];
|
||||
sys.n64_soft_reset = ~n64_nmi_ff[1];
|
||||
end
|
||||
|
||||
endmodule
|
541
fw/rtl/top.v
541
fw/rtl/top.v
@ -1,541 +0,0 @@
|
||||
`include "constants.vh"
|
||||
|
||||
module top (
|
||||
input i_clk,
|
||||
|
||||
output o_ftdi_clk,
|
||||
output o_ftdi_si,
|
||||
input i_ftdi_so,
|
||||
input i_ftdi_cts,
|
||||
|
||||
input i_n64_reset,
|
||||
input i_n64_nmi,
|
||||
|
||||
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_sd_clk,
|
||||
inout io_sd_cmd,
|
||||
inout [3:0] io_sd_dat,
|
||||
|
||||
output o_sram_clk,
|
||||
output o_sram_cs,
|
||||
inout [3:0] io_sram_dq,
|
||||
|
||||
output o_rtc_scl,
|
||||
inout io_rtc_sda,
|
||||
|
||||
output o_led,
|
||||
|
||||
inout [7:0] io_pmod
|
||||
);
|
||||
|
||||
// Clock and reset signals
|
||||
|
||||
wire w_sys_clk;
|
||||
wire w_sdram_clk;
|
||||
wire w_pll_lock;
|
||||
wire w_sys_reset = ~w_pll_lock;
|
||||
|
||||
|
||||
// Temporary signal names
|
||||
|
||||
wire w_n64_reset_btn;
|
||||
|
||||
assign {o_sram_clk, o_sram_cs, io_sram_dq} = 6'bZZZZZZ;
|
||||
assign {o_rtc_scl, io_rtc_sda} = 2'bZZ;
|
||||
assign io_pmod[3] = w_n64_reset_btn ? 1'bZ : 1'b0;
|
||||
assign {io_pmod[7:4], io_pmod[2:0]} = 7'bZZZZZZZ;
|
||||
|
||||
|
||||
// PLL clock generator
|
||||
|
||||
pll sys_pll (
|
||||
.inclk0(i_clk),
|
||||
.c0(w_sys_clk),
|
||||
.c1(w_sdram_clk),
|
||||
.locked(w_pll_lock)
|
||||
);
|
||||
|
||||
|
||||
// SDRAM clock output
|
||||
|
||||
gpio_ddro sdram_clk_ddro (
|
||||
.outclock(w_sdram_clk),
|
||||
.outclocken(1'b1),
|
||||
.din({1'b0, 1'b1}),
|
||||
.pad_out(o_sdram_clk)
|
||||
);
|
||||
|
||||
|
||||
// N64 PI
|
||||
|
||||
wire w_n64_request;
|
||||
wire w_n64_write;
|
||||
wire w_n64_busy;
|
||||
wire w_n64_ack;
|
||||
wire [3:0] w_n64_bank;
|
||||
wire [25:0] w_n64_address;
|
||||
wire [31:0] w_n64_i_data;
|
||||
wire [31:0] w_n64_o_data;
|
||||
|
||||
wire w_n64_busy_cart_control;
|
||||
wire w_n64_ack_cart_control;
|
||||
wire [31:0] w_n64_i_data_cart_control;
|
||||
|
||||
wire w_n64_busy_sdram;
|
||||
wire w_n64_ack_sdram;
|
||||
wire [31:0] w_n64_i_data_sdram;
|
||||
|
||||
wire w_n64_busy_embedded_flash;
|
||||
wire w_n64_ack_embedded_flash;
|
||||
wire [31:0] w_n64_i_data_embedded_flash;
|
||||
|
||||
wire w_n64_busy_eeprom;
|
||||
wire w_n64_ack_eeprom;
|
||||
wire [31:0] w_n64_i_data_eeprom;
|
||||
|
||||
wire w_n64_busy_sd;
|
||||
wire w_n64_ack_sd;
|
||||
wire [31:0] w_n64_i_data_sd;
|
||||
|
||||
wire w_sram_request;
|
||||
|
||||
wire w_ddipl_enable;
|
||||
wire w_sram_enable;
|
||||
wire w_sram_768k_mode;
|
||||
wire w_flashram_enable;
|
||||
wire w_sd_enable;
|
||||
wire w_eeprom_pi_enable;
|
||||
|
||||
wire [23:0] w_ddipl_address;
|
||||
wire [23:0] w_sram_address;
|
||||
|
||||
always @(*) begin
|
||||
w_n64_busy = w_n64_busy_cart_control || w_n64_busy_sdram || w_n64_busy_embedded_flash || w_n64_busy_eeprom || w_n64_busy_sd;
|
||||
w_n64_ack = w_n64_ack_cart_control || w_n64_ack_sdram || w_n64_ack_embedded_flash || w_n64_ack_eeprom || w_n64_ack_sd;
|
||||
w_n64_i_data = 32'h0000_0000;
|
||||
if (w_n64_ack_cart_control) w_n64_i_data = w_n64_i_data_cart_control;
|
||||
if (w_n64_ack_sdram) w_n64_i_data = w_n64_i_data_sdram;
|
||||
if (w_n64_ack_embedded_flash) w_n64_i_data = w_n64_i_data_embedded_flash;
|
||||
if (w_n64_ack_eeprom) w_n64_i_data = w_n64_i_data_eeprom;
|
||||
if (w_n64_ack_sd) w_n64_i_data = w_n64_i_data_sd;
|
||||
end
|
||||
|
||||
n64_pi n64_pi_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_n64_reset(i_n64_reset),
|
||||
.i_n64_pi_alel(i_n64_pi_alel),
|
||||
.i_n64_pi_aleh(i_n64_pi_aleh),
|
||||
.i_n64_pi_read(i_n64_pi_read),
|
||||
.i_n64_pi_write(i_n64_pi_write),
|
||||
.io_n64_pi_ad(io_n64_pi_ad),
|
||||
|
||||
.o_request(w_n64_request),
|
||||
.o_write(w_n64_write),
|
||||
.i_busy(w_n64_busy),
|
||||
.i_ack(w_n64_ack),
|
||||
.o_bank(w_n64_bank),
|
||||
.o_address(w_n64_address),
|
||||
.i_data(w_n64_i_data),
|
||||
.o_data(w_n64_o_data),
|
||||
|
||||
.o_sram_request(w_sram_request),
|
||||
|
||||
.i_ddipl_enable(w_ddipl_enable),
|
||||
.i_sram_enable(w_sram_enable),
|
||||
.i_sram_768k_mode(w_sram_768k_mode),
|
||||
.i_flashram_enable(w_flashram_enable),
|
||||
.i_sd_enable(w_sd_enable),
|
||||
.i_eeprom_enable(w_eeprom_pi_enable),
|
||||
|
||||
.i_ddipl_address(w_ddipl_address),
|
||||
.i_sram_address(w_sram_address)
|
||||
);
|
||||
|
||||
|
||||
// PC USB
|
||||
|
||||
wire w_pc_request;
|
||||
wire w_pc_write;
|
||||
wire w_pc_busy;
|
||||
wire w_pc_ack;
|
||||
wire [3:0] w_pc_bank;
|
||||
wire [25:0] w_pc_address;
|
||||
wire [31:0] w_pc_i_data;
|
||||
wire [31:0] w_pc_o_data;
|
||||
|
||||
wire w_pc_busy_cart_control;
|
||||
wire w_pc_ack_cart_control;
|
||||
wire [31:0] w_pc_i_data_cart_control;
|
||||
|
||||
wire w_pc_busy_sdram;
|
||||
wire w_pc_ack_sdram;
|
||||
wire [31:0] w_pc_i_data_sdram;
|
||||
|
||||
wire w_pc_busy_eeprom;
|
||||
wire w_pc_ack_eeprom;
|
||||
wire [31:0] w_pc_i_data_eeprom;
|
||||
|
||||
wire w_debug_dma_start;
|
||||
wire w_debug_dma_busy;
|
||||
wire [3:0] w_debug_dma_bank;
|
||||
wire [23:0] w_debug_dma_address;
|
||||
wire [19:0] w_debug_dma_length;
|
||||
|
||||
wire w_debug_fifo_request;
|
||||
wire w_debug_fifo_flush;
|
||||
wire [10:0] w_debug_fifo_items;
|
||||
wire [31:0] w_debug_fifo_data;
|
||||
|
||||
always @(*) begin
|
||||
w_pc_busy = w_pc_busy_cart_control || w_pc_busy_sdram || w_pc_busy_eeprom;
|
||||
w_pc_ack = w_pc_ack_cart_control || w_pc_ack_sdram || w_pc_ack_eeprom;
|
||||
w_pc_i_data = 32'h0000_0000;
|
||||
if (w_pc_ack_cart_control) w_pc_i_data = w_pc_i_data_cart_control;
|
||||
if (w_pc_ack_sdram) w_pc_i_data = w_pc_i_data_sdram;
|
||||
if (w_pc_ack_eeprom) w_pc_i_data = w_pc_i_data_eeprom;
|
||||
end
|
||||
|
||||
usb_pc #(
|
||||
.VERSION(`VERSION)
|
||||
) usb_pc_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.o_ftdi_clk(o_ftdi_clk),
|
||||
.o_ftdi_si(o_ftdi_si),
|
||||
.i_ftdi_so(i_ftdi_so),
|
||||
.i_ftdi_cts(i_ftdi_cts),
|
||||
|
||||
.o_request(w_pc_request),
|
||||
.o_write(w_pc_write),
|
||||
.i_busy(w_pc_busy),
|
||||
.i_ack(w_pc_ack),
|
||||
.o_bank(w_pc_bank),
|
||||
.o_address(w_pc_address),
|
||||
.i_data(w_pc_i_data),
|
||||
.o_data(w_pc_o_data),
|
||||
|
||||
.i_debug_start(w_debug_dma_start),
|
||||
.o_debug_busy(w_debug_dma_busy),
|
||||
.i_debug_bank(w_debug_dma_bank),
|
||||
.i_debug_address(w_debug_dma_address),
|
||||
.i_debug_length(w_debug_dma_length),
|
||||
|
||||
.i_debug_fifo_request(w_debug_fifo_request),
|
||||
.i_debug_fifo_flush(w_debug_fifo_flush),
|
||||
.o_debug_fifo_items(w_debug_fifo_items),
|
||||
.o_debug_fifo_data(w_debug_fifo_data)
|
||||
);
|
||||
|
||||
|
||||
// Cart interface
|
||||
|
||||
wire w_cart_control_request;
|
||||
wire w_cart_control_write;
|
||||
wire w_cart_control_busy;
|
||||
wire w_cart_control_ack;
|
||||
wire [10:0] w_cart_control_address;
|
||||
wire [31:0] w_cart_control_o_data;
|
||||
wire [31:0] w_cart_control_i_data;
|
||||
|
||||
wire w_sdram_writable;
|
||||
wire w_rom_switch;
|
||||
wire w_eeprom_enable;
|
||||
wire w_eeprom_16k_mode;
|
||||
|
||||
device_arbiter #(
|
||||
.NUM_CONTROLLERS(2),
|
||||
.ADDRESS_WIDTH(11),
|
||||
.DEVICE_BANK(`BANK_CART)
|
||||
) device_arbiter_cart_control_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request({w_pc_request, w_n64_request}),
|
||||
.i_write({w_pc_write, w_n64_write}),
|
||||
.o_busy({w_pc_busy_cart_control, w_n64_busy_cart_control}),
|
||||
.o_ack({w_pc_ack_cart_control, w_n64_ack_cart_control}),
|
||||
.i_bank({w_pc_bank, w_n64_bank}),
|
||||
.i_address({w_pc_address[12:2], w_n64_address[12:2]}),
|
||||
.o_data({w_pc_i_data_cart_control, w_n64_i_data_cart_control}),
|
||||
.i_data({w_pc_o_data, w_n64_o_data}),
|
||||
|
||||
.o_device_request(w_cart_control_request),
|
||||
.o_device_write(w_cart_control_write),
|
||||
.i_device_busy(w_cart_control_busy),
|
||||
.i_device_ack(w_cart_control_ack),
|
||||
.o_device_address(w_cart_control_address),
|
||||
.i_device_data(w_cart_control_o_data),
|
||||
.o_device_data(w_cart_control_i_data)
|
||||
);
|
||||
|
||||
cart_control #(
|
||||
.VERSION(`VERSION)
|
||||
) cart_control_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_n64_reset(i_n64_reset),
|
||||
.i_n64_nmi(i_n64_nmi),
|
||||
|
||||
.i_request(w_cart_control_request),
|
||||
.i_write(w_cart_control_write),
|
||||
.o_busy(w_cart_control_busy),
|
||||
.o_ack(w_cart_control_ack),
|
||||
.i_address(w_cart_control_address),
|
||||
.o_data(w_cart_control_o_data),
|
||||
.i_data(w_cart_control_i_data),
|
||||
|
||||
.o_sdram_writable(w_sdram_writable),
|
||||
.o_rom_switch(w_rom_switch),
|
||||
.o_ddipl_enable(w_ddipl_enable),
|
||||
.o_sram_enable(w_sram_enable),
|
||||
.o_sram_768k_mode(w_sram_768k_mode),
|
||||
.o_flashram_enable(w_flashram_enable),
|
||||
.o_sd_enable(w_sd_enable),
|
||||
.o_eeprom_pi_enable(w_eeprom_pi_enable),
|
||||
.o_eeprom_enable(w_eeprom_enable),
|
||||
.o_eeprom_16k_mode(w_eeprom_16k_mode),
|
||||
|
||||
.o_n64_reset_btn(w_n64_reset_btn),
|
||||
|
||||
.i_debug_ready(1'b1),
|
||||
|
||||
.o_debug_dma_start(w_debug_dma_start),
|
||||
.i_debug_dma_busy(w_debug_dma_busy),
|
||||
.o_debug_dma_bank(w_debug_dma_bank),
|
||||
.o_debug_dma_address(w_debug_dma_address),
|
||||
.o_debug_dma_length(w_debug_dma_length),
|
||||
|
||||
.o_debug_fifo_request(w_debug_fifo_request),
|
||||
.o_debug_fifo_flush(w_debug_fifo_flush),
|
||||
.i_debug_fifo_items(w_debug_fifo_items),
|
||||
.i_debug_fifo_data(w_debug_fifo_data),
|
||||
|
||||
.o_ddipl_address(w_ddipl_address),
|
||||
.o_sram_address(w_sram_address)
|
||||
);
|
||||
|
||||
|
||||
// Embedded flash
|
||||
|
||||
wire w_embedded_flash_request_n64 = w_n64_request && !w_rom_switch && !w_n64_write && w_n64_bank == `BANK_SDRAM;
|
||||
|
||||
memory_embedded_flash memory_embedded_flash_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request(w_embedded_flash_request_n64),
|
||||
.o_busy(w_n64_busy_embedded_flash),
|
||||
.o_ack(w_n64_ack_embedded_flash),
|
||||
.i_address(w_n64_address[20:2]),
|
||||
.o_data(w_n64_i_data_embedded_flash)
|
||||
);
|
||||
|
||||
|
||||
// SD card
|
||||
|
||||
wire w_n64_request_sd = w_n64_request && w_n64_bank == `BANK_SD;
|
||||
|
||||
wire w_sd_dma_request;
|
||||
wire w_sd_dma_write;
|
||||
wire w_sd_dma_busy;
|
||||
wire w_sd_dma_ack;
|
||||
wire [3:0] w_sd_dma_bank;
|
||||
wire [23:0] w_sd_dma_address;
|
||||
wire [31:0] w_sd_dma_i_data;
|
||||
wire [31:0] w_sd_dma_o_data;
|
||||
|
||||
wire w_sd_dma_busy_sdram;
|
||||
wire w_sd_dma_ack_sdram;
|
||||
wire [31:0] w_sd_dma_i_data_sdram;
|
||||
|
||||
wire w_sd_dma_busy_eeprom;
|
||||
wire w_sd_dma_ack_eeprom;
|
||||
wire [31:0] w_sd_dma_i_data_eeprom;
|
||||
|
||||
always @(*) begin
|
||||
w_sd_dma_busy = w_sd_dma_busy_sdram || w_sd_dma_busy_eeprom;
|
||||
w_sd_dma_ack = w_sd_dma_ack_sdram || w_sd_dma_ack_eeprom;
|
||||
w_sd_dma_i_data = 32'h0000_0000;
|
||||
if (w_sd_dma_ack_sdram) w_sd_dma_i_data = w_sd_dma_i_data_sdram;
|
||||
if (w_sd_dma_ack_eeprom) w_sd_dma_i_data = w_sd_dma_i_data_eeprom;
|
||||
end
|
||||
|
||||
sd_interface sd_interface_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.o_sd_clk(o_sd_clk),
|
||||
.io_sd_cmd(io_sd_cmd),
|
||||
.io_sd_dat(io_sd_dat),
|
||||
|
||||
.i_request(w_n64_request_sd),
|
||||
.i_write(w_n64_write),
|
||||
.o_busy(w_n64_busy_sd),
|
||||
.o_ack(w_n64_ack_sd),
|
||||
.i_address({w_n64_address[9], w_n64_address[4:2]}),
|
||||
.o_data(w_n64_i_data_sd),
|
||||
.i_data(w_n64_o_data),
|
||||
|
||||
.o_dma_request(w_sd_dma_request),
|
||||
.o_dma_write(w_sd_dma_write),
|
||||
.i_dma_busy(w_sd_dma_busy),
|
||||
.i_dma_ack(w_sd_dma_ack),
|
||||
.o_dma_bank(w_sd_dma_bank),
|
||||
.o_dma_address(w_sd_dma_address),
|
||||
.i_dma_data(w_sd_dma_i_data),
|
||||
.o_dma_data(w_sd_dma_o_data)
|
||||
);
|
||||
|
||||
|
||||
// SDRAM
|
||||
|
||||
wire w_sdram_request_n64 = w_n64_request && w_rom_switch && (!w_n64_write || (w_n64_write && (w_sdram_writable || w_sram_request)));
|
||||
|
||||
wire w_sdram_request;
|
||||
wire w_sdram_write;
|
||||
wire w_sdram_busy;
|
||||
wire w_sdram_ack;
|
||||
wire [24:0] w_sdram_address;
|
||||
wire [31:0] w_sdram_o_data;
|
||||
wire [31:0] w_sdram_i_data;
|
||||
|
||||
device_arbiter #(
|
||||
.NUM_CONTROLLERS(3),
|
||||
.ADDRESS_WIDTH(25),
|
||||
.DEVICE_BANK(`BANK_SDRAM)
|
||||
) device_arbiter_sdram_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request({w_sd_dma_request, w_pc_request, w_sdram_request_n64}),
|
||||
.i_write({w_sd_dma_write, w_pc_write, w_n64_write}),
|
||||
.o_busy({w_sd_dma_busy_sdram, w_pc_busy_sdram, w_n64_busy_sdram}),
|
||||
.o_ack({w_sd_dma_ack_sdram, w_pc_ack_sdram, w_n64_ack_sdram}),
|
||||
.i_bank({w_sd_dma_bank, w_pc_bank, w_n64_bank}),
|
||||
.i_address({{w_sd_dma_address, 1'b0}, w_pc_address[25:1], w_n64_address[25:1]}),
|
||||
.o_data({w_sd_dma_i_data_sdram, w_pc_i_data_sdram, w_n64_i_data_sdram}),
|
||||
.i_data({w_sd_dma_o_data, w_pc_o_data, w_n64_o_data}),
|
||||
|
||||
.o_device_request(w_sdram_request),
|
||||
.o_device_write(w_sdram_write),
|
||||
.i_device_busy(w_sdram_busy),
|
||||
.i_device_ack(w_sdram_ack),
|
||||
.o_device_address(w_sdram_address),
|
||||
.i_device_data(w_sdram_o_data),
|
||||
.o_device_data(w_sdram_i_data)
|
||||
);
|
||||
|
||||
memory_sdram memory_sdram_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.o_sdram_cs(o_sdram_cs),
|
||||
.o_sdram_ras(o_sdram_ras),
|
||||
.o_sdram_cas(o_sdram_cas),
|
||||
.o_sdram_we(o_sdram_we),
|
||||
.o_sdram_ba(o_sdram_ba),
|
||||
.o_sdram_a(o_sdram_a),
|
||||
.io_sdram_dq(io_sdram_dq),
|
||||
|
||||
.i_request(w_sdram_request),
|
||||
.i_write(w_sdram_write),
|
||||
.o_busy(w_sdram_busy),
|
||||
.o_ack(w_sdram_ack),
|
||||
.i_address(w_sdram_address),
|
||||
.o_data(w_sdram_o_data),
|
||||
.i_data(w_sdram_i_data)
|
||||
);
|
||||
|
||||
|
||||
// EEPROM 4/16k
|
||||
|
||||
wire w_eeprom_request;
|
||||
wire w_eeprom_write;
|
||||
wire w_eeprom_busy;
|
||||
wire w_eeprom_ack;
|
||||
wire [8:0] w_eeprom_address;
|
||||
wire [31:0] w_eeprom_o_data;
|
||||
wire [31:0] w_eeprom_i_data;
|
||||
|
||||
device_arbiter #(
|
||||
.NUM_CONTROLLERS(3),
|
||||
.ADDRESS_WIDTH(9),
|
||||
.DEVICE_BANK(`BANK_EEPROM)
|
||||
) device_arbiter_eeprom_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request({w_sd_dma_request, w_pc_request, w_n64_request}),
|
||||
.i_write({w_sd_dma_write, w_pc_write, w_n64_write}),
|
||||
.o_busy({w_sd_dma_busy_eeprom, w_pc_busy_eeprom, w_n64_busy_eeprom}),
|
||||
.o_ack({w_sd_dma_ack_eeprom, w_pc_ack_eeprom, w_n64_ack_eeprom}),
|
||||
.i_bank({w_sd_dma_bank, w_pc_bank, w_n64_bank}),
|
||||
.i_address({w_sd_dma_address[8:0], w_pc_address[10:2], w_n64_address[10:2]}),
|
||||
.o_data({w_sd_dma_i_data_eeprom, w_pc_i_data_eeprom, w_n64_i_data_eeprom}),
|
||||
.i_data({w_sd_dma_o_data, w_pc_o_data, w_n64_o_data}),
|
||||
|
||||
.o_device_request(w_eeprom_request),
|
||||
.o_device_write(w_eeprom_write),
|
||||
.i_device_busy(w_eeprom_busy),
|
||||
.i_device_ack(w_eeprom_ack),
|
||||
.o_device_address(w_eeprom_address),
|
||||
.i_device_data(w_eeprom_o_data),
|
||||
.o_device_data(w_eeprom_i_data)
|
||||
);
|
||||
|
||||
n64_si n64_si_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_n64_reset(i_n64_reset),
|
||||
.i_n64_si_clk(i_n64_si_clk),
|
||||
.io_n64_si_dq(io_n64_si_dq),
|
||||
|
||||
.i_request(w_eeprom_request),
|
||||
.i_write(w_eeprom_write),
|
||||
.o_busy(w_eeprom_busy),
|
||||
.o_ack(w_eeprom_ack),
|
||||
.i_address(w_eeprom_address),
|
||||
.i_data(w_eeprom_i_data),
|
||||
.o_data(w_eeprom_o_data),
|
||||
|
||||
.i_eeprom_enable(w_eeprom_enable),
|
||||
.i_eeprom_16k_mode(w_eeprom_16k_mode)
|
||||
);
|
||||
|
||||
|
||||
// LED
|
||||
|
||||
wire w_led_trigger = (w_n64_request && !w_n64_busy) || (w_pc_request && !w_pc_busy);
|
||||
|
||||
cart_led cart_led_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_trigger(w_led_trigger),
|
||||
|
||||
.o_led(o_led)
|
||||
);
|
||||
|
||||
endmodule
|
221
fw/rtl/usb/usb_ft1248.sv
Normal file
221
fw/rtl/usb/usb_ft1248.sv
Normal file
@ -0,0 +1,221 @@
|
||||
module usb_ft1248 (
|
||||
if_system.sys sys,
|
||||
|
||||
output usb_clk,
|
||||
output usb_cs,
|
||||
input usb_miso,
|
||||
inout [3:0] usb_miosi,
|
||||
input usb_pwren,
|
||||
|
||||
input rx_flush,
|
||||
output rx_empty,
|
||||
input rx_read,
|
||||
output [7:0] rx_rdata,
|
||||
|
||||
input tx_flush,
|
||||
output tx_full,
|
||||
input tx_write,
|
||||
input [7:0] tx_wdata
|
||||
);
|
||||
|
||||
// FIFOs
|
||||
|
||||
logic rx_full;
|
||||
logic rx_write;
|
||||
logic [7:0] rx_wdata;
|
||||
|
||||
logic tx_empty;
|
||||
logic tx_read;
|
||||
logic [7:0] tx_rdata;
|
||||
|
||||
intel_fifo_8 fifo_8_rx_inst (
|
||||
.clock(sys.clk),
|
||||
.sclr(rx_flush),
|
||||
|
||||
.empty(rx_empty),
|
||||
.rdreq(rx_read),
|
||||
.q(rx_rdata),
|
||||
|
||||
.full(rx_full),
|
||||
.wrreq(rx_write),
|
||||
.data(rx_wdata)
|
||||
);
|
||||
|
||||
intel_fifo_8 fifo_8_tx_inst (
|
||||
.clock(sys.clk),
|
||||
.sclr(tx_flush),
|
||||
|
||||
.empty(tx_empty),
|
||||
.rdreq(tx_read),
|
||||
.q(tx_rdata),
|
||||
|
||||
.full(tx_full),
|
||||
.wrreq(tx_write),
|
||||
.data(tx_wdata)
|
||||
);
|
||||
|
||||
|
||||
// FT1248 interface controller
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
S_TRY_RX,
|
||||
S_TRY_TX,
|
||||
S_COMMAND,
|
||||
S_DATA
|
||||
} e_state;
|
||||
|
||||
typedef enum bit [7:0] {
|
||||
C_WRITE = 8'h00,
|
||||
C_READ = 8'h04
|
||||
} e_command;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
P_PRE_RISING,
|
||||
P_RISING,
|
||||
P_PRE_FALLING,
|
||||
P_FALLING
|
||||
} e_clock_phase;
|
||||
|
||||
e_state state;
|
||||
|
||||
logic [3:0] clock_phase;
|
||||
|
||||
logic usb_clk_output;
|
||||
logic usb_cs_output;
|
||||
logic [3:0] usb_miosi_input;
|
||||
logic [3:0] usb_miosi_output;
|
||||
logic [3:0] usb_miosi_output_data;
|
||||
logic usb_miosi_output_enable;
|
||||
logic usb_miosi_output_enable_data;
|
||||
logic usb_miso_input;
|
||||
logic usb_pwren_input;
|
||||
|
||||
logic is_cmd_write;
|
||||
logic [1:0] nibble_counter;
|
||||
logic [7:0] tx_buffer;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || state == S_TRY_RX || state == S_TRY_TX) begin
|
||||
clock_phase <= 4'b0001;
|
||||
end else begin
|
||||
clock_phase <= {clock_phase[2:0], clock_phase[3]};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
usb_clk <= usb_clk_output;
|
||||
usb_cs <= usb_cs_output;
|
||||
|
||||
usb_miosi_input <= usb_miosi;
|
||||
usb_miosi_output <= usb_miosi_output_data;
|
||||
usb_miosi_output_enable <= usb_miosi_output_enable_data;
|
||||
|
||||
usb_miso_input <= usb_miso;
|
||||
usb_pwren_input <= usb_pwren;
|
||||
|
||||
tx_buffer <= tx_rdata;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
usb_miosi = usb_miosi_output_enable ? usb_miosi_output : 4'bZZZZ;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (state)
|
||||
S_COMMAND: begin
|
||||
usb_clk_output = clock_phase[P_PRE_FALLING] || clock_phase[P_FALLING];
|
||||
usb_cs_output = 1'b0;
|
||||
if (is_cmd_write) begin
|
||||
usb_miosi_output_data = nibble_counter[0] ? C_WRITE[3:0] : C_WRITE[7:4];
|
||||
end else begin
|
||||
usb_miosi_output_data = nibble_counter[0] ? C_READ[3:0] : C_READ[7:4];
|
||||
end
|
||||
usb_miosi_output_enable_data = nibble_counter < 2'd2;
|
||||
end
|
||||
|
||||
S_DATA: begin
|
||||
usb_clk_output = clock_phase[P_PRE_FALLING] || clock_phase[P_FALLING];
|
||||
usb_cs_output = 1'b0;
|
||||
usb_miosi_output_data = nibble_counter[0] ? tx_buffer[7:4] : tx_buffer[3:0];
|
||||
usb_miosi_output_enable_data = is_cmd_write;
|
||||
end
|
||||
|
||||
default: begin
|
||||
usb_clk_output = 1'b0;
|
||||
usb_cs_output = 1'b1;
|
||||
usb_miosi_output_data = 4'hF;
|
||||
usb_miosi_output_enable_data = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
rx_write <= 1'b0;
|
||||
tx_read <= 1'b0;
|
||||
|
||||
if (clock_phase[P_RISING]) begin
|
||||
nibble_counter <= nibble_counter + 1'd1;
|
||||
end
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_TRY_RX;
|
||||
end else begin
|
||||
case (state)
|
||||
S_TRY_RX: begin
|
||||
if (!rx_full) begin
|
||||
state <= S_COMMAND;
|
||||
is_cmd_write <= 1'b0;
|
||||
nibble_counter <= 2'b11;
|
||||
end else begin
|
||||
state <= S_TRY_TX;
|
||||
end
|
||||
end
|
||||
|
||||
S_TRY_TX: begin
|
||||
if (!tx_empty) begin
|
||||
state <= S_COMMAND;
|
||||
is_cmd_write <= 1'b1;
|
||||
nibble_counter <= 2'b11;
|
||||
end else begin
|
||||
state <= S_TRY_RX;
|
||||
end
|
||||
end
|
||||
|
||||
S_COMMAND: begin
|
||||
if (clock_phase[P_RISING]) begin
|
||||
if (nibble_counter == 2'd2) begin
|
||||
if (usb_miso_input) begin
|
||||
state <= is_cmd_write ? S_TRY_RX : S_TRY_TX;
|
||||
end else begin
|
||||
state <= S_DATA;
|
||||
nibble_counter <= 2'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_DATA: begin
|
||||
if (clock_phase[P_FALLING]) begin
|
||||
if (nibble_counter[0]) begin
|
||||
tx_read <= is_cmd_write;
|
||||
end
|
||||
end
|
||||
if (clock_phase[P_RISING]) begin
|
||||
rx_wdata <= {usb_miosi_input, rx_wdata[7:4]};
|
||||
if (nibble_counter[0]) begin
|
||||
rx_write <= !is_cmd_write;
|
||||
end
|
||||
if (usb_miso_input || (!is_cmd_write && rx_full) || (is_cmd_write && tx_empty)) begin
|
||||
state <= is_cmd_write ? S_TRY_RX : S_TRY_TX;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state <= S_TRY_RX;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,116 +0,0 @@
|
||||
module usb_ftdi_fsi (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
output reg o_ftdi_clk,
|
||||
output reg o_ftdi_si,
|
||||
input i_ftdi_so,
|
||||
input i_ftdi_cts,
|
||||
|
||||
input i_rx_ready,
|
||||
output reg o_rx_valid,
|
||||
output reg o_rx_channel,
|
||||
output reg [7:0] o_rx_data,
|
||||
|
||||
output reg o_tx_busy,
|
||||
input i_tx_valid,
|
||||
input i_tx_channel,
|
||||
input [7:0] i_tx_data
|
||||
);
|
||||
|
||||
// Output clock generation and control
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || !i_rx_ready) begin
|
||||
o_ftdi_clk <= 1'b1;
|
||||
end else begin
|
||||
o_ftdi_clk <= ~o_ftdi_clk;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// RX module
|
||||
|
||||
reg r_rx_in_progress;
|
||||
reg [3:0] r_rx_bit_counter;
|
||||
reg r_tx_start_bit;
|
||||
reg r_rx_tx_contention;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_rx_valid <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
r_rx_in_progress <= 1'b0;
|
||||
end else begin
|
||||
if (!o_ftdi_clk) begin
|
||||
if (!r_rx_in_progress) begin
|
||||
r_rx_in_progress <= !i_ftdi_so;
|
||||
r_rx_bit_counter <= 4'd0;
|
||||
r_rx_tx_contention <= r_tx_start_bit;
|
||||
end else begin
|
||||
r_rx_bit_counter <= r_rx_bit_counter + 4'd1;
|
||||
|
||||
if (!r_rx_bit_counter[3]) begin
|
||||
o_rx_data <= {i_ftdi_so, o_rx_data[7:1]};
|
||||
end else begin
|
||||
r_rx_in_progress <= 1'b0;
|
||||
o_rx_valid <= !r_rx_tx_contention;
|
||||
o_rx_channel <= i_ftdi_so;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// TX module
|
||||
|
||||
reg r_tx_pending;
|
||||
reg [3:0] r_tx_bit_counter;
|
||||
reg [7:0] r_tx_data;
|
||||
reg r_tx_channel;
|
||||
|
||||
wire w_tx_request_op = i_tx_valid && !o_tx_busy;
|
||||
wire w_tx_pending_op = !o_ftdi_clk || !i_ftdi_cts || !i_rx_ready || r_rx_in_progress;
|
||||
wire w_tx_reset_output_op = o_ftdi_clk && !o_tx_busy;
|
||||
wire w_tx_start_op = (w_tx_request_op || r_tx_pending) && !w_tx_pending_op;
|
||||
wire w_tx_shift_op = o_ftdi_clk && o_tx_busy && !r_tx_pending;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_tx_start_bit <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
o_ftdi_si <= 1'b1;
|
||||
o_tx_busy <= 1'b0;
|
||||
r_tx_pending <= 1'b0;
|
||||
end else begin
|
||||
if (w_tx_request_op) begin
|
||||
o_tx_busy <= 1'b1;
|
||||
r_tx_data <= i_tx_data;
|
||||
r_tx_channel <= i_tx_channel;
|
||||
r_tx_pending <= w_tx_pending_op;
|
||||
end
|
||||
|
||||
if (w_tx_reset_output_op) begin
|
||||
o_ftdi_si <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_tx_start_op) begin
|
||||
o_ftdi_si <= 1'b0;
|
||||
r_tx_start_bit <= 1'b1;
|
||||
r_tx_pending <= 1'b0;
|
||||
r_tx_bit_counter <= 4'd0;
|
||||
end
|
||||
|
||||
if (w_tx_shift_op) begin
|
||||
r_tx_bit_counter <= r_tx_bit_counter + 4'd1;
|
||||
{r_tx_data[6:0], o_ftdi_si} <= r_tx_data;
|
||||
if (r_tx_bit_counter[3]) begin
|
||||
o_ftdi_si <= r_tx_channel;
|
||||
o_tx_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,466 +0,0 @@
|
||||
module usb_pc (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
output o_ftdi_clk,
|
||||
output o_ftdi_si,
|
||||
input i_ftdi_so,
|
||||
input i_ftdi_cts,
|
||||
|
||||
output reg o_request,
|
||||
output reg o_write,
|
||||
input i_busy,
|
||||
input i_ack,
|
||||
output reg [3:0] o_bank,
|
||||
output reg [25:0] o_address,
|
||||
input [31:0] i_data,
|
||||
output reg [31:0] o_data,
|
||||
|
||||
input i_debug_start,
|
||||
output o_debug_busy,
|
||||
input [3:0] i_debug_bank,
|
||||
input [23:0] i_debug_address,
|
||||
input [19:0] i_debug_length,
|
||||
|
||||
input i_debug_fifo_request,
|
||||
input i_debug_fifo_flush,
|
||||
output [10:0] o_debug_fifo_items,
|
||||
output [31:0] o_debug_fifo_data
|
||||
);
|
||||
|
||||
// Module parameters
|
||||
|
||||
parameter byte VERSION = "a";
|
||||
|
||||
|
||||
// FTDI transport
|
||||
|
||||
reg r_ftdi_rx_ready;
|
||||
wire w_ftdi_rx_valid;
|
||||
wire [7:0] w_ftdi_rx_data;
|
||||
|
||||
wire w_ftdi_tx_busy;
|
||||
reg r_ftdi_tx_valid;
|
||||
reg [7:0] r_ftdi_tx_data;
|
||||
|
||||
usb_ftdi_fsi usb_ftdi_fsi_inst (
|
||||
.i_clk(i_clk),
|
||||
.i_reset(i_reset),
|
||||
|
||||
.o_ftdi_clk(o_ftdi_clk),
|
||||
.o_ftdi_si(o_ftdi_si),
|
||||
.i_ftdi_so(i_ftdi_so),
|
||||
.i_ftdi_cts(i_ftdi_cts),
|
||||
|
||||
.i_rx_ready(r_ftdi_rx_ready),
|
||||
.o_rx_valid(w_ftdi_rx_valid),
|
||||
.o_rx_data(w_ftdi_rx_data),
|
||||
|
||||
.o_tx_busy(w_ftdi_tx_busy),
|
||||
.i_tx_valid(r_ftdi_tx_valid),
|
||||
.i_tx_channel(1'b1), // Channel B
|
||||
.i_tx_data(r_ftdi_tx_data)
|
||||
);
|
||||
|
||||
|
||||
// Debug FIFO
|
||||
|
||||
wire w_fifo_usb_full;
|
||||
wire [9:0] w_fifo_usb_items;
|
||||
reg r_fifo_usb_write_request;
|
||||
reg [31:0] r_fifo_usb_data;
|
||||
|
||||
assign o_debug_fifo_items = {w_fifo_usb_full, w_fifo_usb_items};
|
||||
|
||||
fifo_usb fifo_usb_inst (
|
||||
.clock(i_clk),
|
||||
.sclr(i_debug_fifo_flush),
|
||||
|
||||
.full(w_fifo_usb_full),
|
||||
.usedw(w_fifo_usb_items),
|
||||
|
||||
.wrreq(r_fifo_usb_write_request),
|
||||
.data(r_fifo_usb_data),
|
||||
|
||||
.rdreq(i_debug_fifo_request),
|
||||
.q(o_debug_fifo_data)
|
||||
);
|
||||
|
||||
|
||||
// Command ids
|
||||
|
||||
localparam byte CMD_TRIGGER [0:2] = '{"C", "M", "D"};
|
||||
|
||||
localparam byte CMD_IDENTIFY = "I";
|
||||
localparam byte CMD_WRITE = "W";
|
||||
localparam byte CMD_DEBUG_WRITE = "D";
|
||||
localparam byte CMD_DEBUG_SEND = "Q";
|
||||
|
||||
localparam [1:0] RX_STAGE_CMD = 2'd0;
|
||||
localparam [1:0] RX_STAGE_PARAM = 2'd1;
|
||||
localparam [1:0] RX_STAGE_DATA = 2'd2;
|
||||
localparam [1:0] RX_STAGE_IGNORE = 2'd3;
|
||||
|
||||
|
||||
// RX module
|
||||
|
||||
reg [1:0] r_rx_stage;
|
||||
reg [2:0] r_rx_byte_counter;
|
||||
reg [7:0] r_rx_cmd;
|
||||
reg r_rx_buffer_valid;
|
||||
reg r_rx_param_valid;
|
||||
reg [63:0] r_rx_buffer;
|
||||
|
||||
reg [19:0] r_data_items_remaining;
|
||||
|
||||
reg r_tx_cmd_valid;
|
||||
reg [7:0] r_tx_cmd;
|
||||
reg r_tx_done;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_rx_buffer_valid <= 1'b0;
|
||||
r_rx_param_valid <= 1'b0;
|
||||
r_tx_cmd_valid <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
r_rx_stage <= RX_STAGE_CMD;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
end else begin
|
||||
if (i_debug_start) begin
|
||||
r_rx_stage <= RX_STAGE_IGNORE;
|
||||
r_rx_cmd <= CMD_DEBUG_SEND;
|
||||
r_tx_cmd <= CMD_DEBUG_SEND;
|
||||
r_tx_cmd_valid <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_ftdi_rx_valid) begin
|
||||
r_rx_byte_counter <= r_rx_byte_counter + 3'd1;
|
||||
|
||||
case (r_rx_stage)
|
||||
RX_STAGE_CMD: begin
|
||||
if (w_ftdi_rx_data != CMD_TRIGGER[r_rx_byte_counter[1:0]]) begin
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
end
|
||||
|
||||
if (r_rx_byte_counter == 3'd3) begin
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
r_rx_cmd <= w_ftdi_rx_data;
|
||||
|
||||
case (w_ftdi_rx_data)
|
||||
CMD_IDENTIFY: begin
|
||||
r_rx_stage <= RX_STAGE_IGNORE;
|
||||
r_tx_cmd_valid <= 1'b1;
|
||||
r_tx_cmd <= w_ftdi_rx_data;
|
||||
end
|
||||
|
||||
CMD_WRITE: r_rx_stage <= RX_STAGE_PARAM;
|
||||
|
||||
CMD_DEBUG_WRITE: r_rx_stage <= RX_STAGE_PARAM;
|
||||
|
||||
default: r_rx_stage <= RX_STAGE_CMD;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
RX_STAGE_PARAM: begin
|
||||
r_rx_buffer <= {r_rx_buffer[55:0], w_ftdi_rx_data};
|
||||
|
||||
case (r_rx_cmd)
|
||||
CMD_WRITE: begin
|
||||
if (r_rx_byte_counter == 3'd7) begin
|
||||
r_rx_stage <= RX_STAGE_DATA;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
r_rx_param_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
CMD_DEBUG_WRITE: begin
|
||||
if (r_rx_byte_counter == 3'd3) begin
|
||||
r_rx_stage <= RX_STAGE_DATA;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
r_rx_param_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
r_rx_stage <= RX_STAGE_CMD;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
RX_STAGE_DATA: begin
|
||||
r_rx_buffer <= {r_rx_buffer[55:0], w_ftdi_rx_data};
|
||||
|
||||
case (r_rx_cmd)
|
||||
CMD_WRITE: begin
|
||||
if (r_rx_byte_counter == 3'd3) begin
|
||||
if (r_data_items_remaining == 20'd0) begin
|
||||
r_rx_stage <= RX_STAGE_IGNORE;
|
||||
r_tx_cmd_valid <= 1'b1;
|
||||
r_tx_cmd <= r_rx_cmd;
|
||||
end
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
r_rx_buffer_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
CMD_DEBUG_WRITE: begin
|
||||
if (r_rx_byte_counter == 3'd3) begin
|
||||
if (r_data_items_remaining == 20'd0) begin
|
||||
r_rx_stage <= RX_STAGE_CMD;
|
||||
end
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
r_rx_buffer_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
r_rx_stage <= RX_STAGE_CMD;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
RX_STAGE_IGNORE: begin
|
||||
end
|
||||
|
||||
default: begin
|
||||
r_rx_stage <= RX_STAGE_CMD;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (r_tx_done) begin
|
||||
r_rx_stage <= RX_STAGE_CMD;
|
||||
r_rx_byte_counter <= 3'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Command parameter decoder
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
end else begin
|
||||
if (r_rx_param_valid) begin
|
||||
case (r_rx_cmd)
|
||||
CMD_WRITE: begin
|
||||
o_address <= {r_rx_buffer[57:34], 2'b00};
|
||||
o_bank <= r_rx_buffer[27:24];
|
||||
r_data_items_remaining <= r_rx_buffer[19:0];
|
||||
end
|
||||
|
||||
CMD_DEBUG_WRITE: begin
|
||||
r_data_items_remaining <= r_rx_buffer[19:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (r_tx_cmd_valid && r_tx_cmd == CMD_DEBUG_SEND) begin
|
||||
o_bank <= i_debug_bank;
|
||||
o_address <= {i_debug_address, 2'b00};
|
||||
r_data_items_remaining <= i_debug_length;
|
||||
end
|
||||
|
||||
if (o_request && !i_busy && r_data_items_remaining > 20'd0) begin
|
||||
o_address[25:2] <= o_address[25:2] + 1'd1;
|
||||
r_data_items_remaining <= r_data_items_remaining - 1'd1;
|
||||
end
|
||||
|
||||
if (r_fifo_usb_write_request && r_data_items_remaining > 20'd0) begin
|
||||
r_data_items_remaining <= r_data_items_remaining - 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// TX module
|
||||
|
||||
localparam byte IDENTIFY_STRING [0:3] = '{"S", "6", "4", VERSION};
|
||||
localparam byte RSP_COMPLETE [0:2] = '{"C", "M", "P"};
|
||||
|
||||
localparam [1:0] TX_STAGE_IDLE = 2'd0;
|
||||
localparam [1:0] TX_STAGE_DATA = 2'd1;
|
||||
localparam [1:0] TX_STAGE_RESPONSE = 2'd2;
|
||||
|
||||
reg [1:0] r_tx_stage;
|
||||
reg [1:0] r_tx_byte_counter;
|
||||
|
||||
reg [31:0] r_i_data_buffer;
|
||||
|
||||
always @(*) begin
|
||||
r_ftdi_tx_data = 8'h00;
|
||||
|
||||
case (r_tx_stage)
|
||||
TX_STAGE_DATA: begin
|
||||
case (r_tx_cmd)
|
||||
CMD_IDENTIFY: r_ftdi_tx_data = IDENTIFY_STRING[r_tx_byte_counter];
|
||||
CMD_DEBUG_SEND: r_ftdi_tx_data = r_i_data_buffer[(((4 - r_tx_byte_counter) * 8) - 1) -: 8];
|
||||
endcase
|
||||
end
|
||||
|
||||
TX_STAGE_RESPONSE: begin
|
||||
if (r_tx_byte_counter != 2'd3) r_ftdi_tx_data = RSP_COMPLETE[r_tx_byte_counter];
|
||||
else r_ftdi_tx_data = r_tx_cmd;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
wire w_tx_successful = r_ftdi_tx_valid && !w_ftdi_tx_busy;
|
||||
|
||||
reg r_bus_data_request;
|
||||
reg r_bus_data_valid;
|
||||
reg r_bus_data_feisable;
|
||||
|
||||
assign o_debug_busy = r_tx_stage == TX_STAGE_DATA && r_tx_cmd == CMD_DEBUG_SEND;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_ftdi_tx_valid <= 1'b0;
|
||||
r_tx_done <= 1'b0;
|
||||
r_bus_data_request <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
r_tx_stage <= TX_STAGE_IDLE;
|
||||
end else begin
|
||||
if (w_tx_successful) r_tx_byte_counter <= r_tx_byte_counter + 2'd1;
|
||||
|
||||
case (r_tx_stage)
|
||||
TX_STAGE_IDLE: begin
|
||||
r_tx_byte_counter <= 2'd0;
|
||||
|
||||
if (r_tx_cmd_valid) begin
|
||||
case (r_tx_cmd)
|
||||
CMD_IDENTIFY: begin
|
||||
r_tx_stage <= TX_STAGE_DATA;
|
||||
r_ftdi_tx_valid <= 1'b1;
|
||||
end
|
||||
|
||||
CMD_DEBUG_SEND: begin
|
||||
r_bus_data_request <= 1'b1;
|
||||
r_tx_stage <= TX_STAGE_DATA;
|
||||
end
|
||||
|
||||
default: begin
|
||||
r_tx_stage <= TX_STAGE_RESPONSE;
|
||||
r_ftdi_tx_valid <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
TX_STAGE_DATA: begin
|
||||
r_ftdi_tx_valid <= 1'b1;
|
||||
|
||||
if (r_tx_byte_counter == 2'd3 && w_tx_successful) begin
|
||||
case (r_tx_cmd)
|
||||
CMD_IDENTIFY: begin
|
||||
r_tx_stage <= TX_STAGE_RESPONSE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (r_tx_cmd == CMD_DEBUG_SEND) begin
|
||||
r_ftdi_tx_valid <= 1'b0;
|
||||
|
||||
if (r_bus_data_valid) begin
|
||||
r_bus_data_feisable <= 1'b1;
|
||||
end
|
||||
|
||||
if (r_bus_data_feisable) begin
|
||||
r_ftdi_tx_valid <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_tx_successful) begin
|
||||
if (r_tx_byte_counter == 2'd3 && r_bus_data_feisable) begin
|
||||
r_bus_data_request <= 1'b1;
|
||||
r_bus_data_feisable <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (w_tx_successful && r_data_items_remaining == 20'd0 && r_tx_byte_counter == 2'd3) begin
|
||||
r_bus_data_request <= 1'b0;
|
||||
r_tx_stage <= TX_STAGE_IDLE;
|
||||
r_tx_done <= 1'b1;
|
||||
r_bus_data_feisable <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TX_STAGE_RESPONSE: begin
|
||||
r_ftdi_tx_valid <= 1'b1;
|
||||
|
||||
if (r_tx_byte_counter == 2'd3 && w_tx_successful) begin
|
||||
r_tx_stage <= TX_STAGE_IDLE;
|
||||
r_tx_done <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
default: r_tx_stage <= TX_STAGE_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Bus controller
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_request <= 1'b0;
|
||||
o_write <= 1'b0;
|
||||
r_bus_data_valid <= 1'b0;
|
||||
r_fifo_usb_write_request <= 1'b0;
|
||||
|
||||
if (i_reset) begin
|
||||
r_ftdi_rx_ready <= 1'b1;
|
||||
end else begin
|
||||
case (r_rx_cmd)
|
||||
CMD_WRITE: begin
|
||||
if ((r_rx_buffer_valid || !r_ftdi_rx_ready) && !i_busy) begin
|
||||
o_request <= 1'b1;
|
||||
o_write <= 1'b1;
|
||||
o_data <= r_rx_buffer[31:0];
|
||||
r_ftdi_rx_ready <= 1'b1;
|
||||
end
|
||||
|
||||
if (o_request && i_busy) begin
|
||||
o_request <= 1'b1;
|
||||
o_write <= 1'b1;
|
||||
end
|
||||
|
||||
if (r_rx_buffer_valid && i_busy) begin
|
||||
r_ftdi_rx_ready <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
CMD_DEBUG_WRITE: begin
|
||||
if (r_rx_buffer_valid) begin
|
||||
r_fifo_usb_data <= r_rx_buffer[31:0];
|
||||
r_fifo_usb_write_request <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_fifo_usb_full) begin
|
||||
r_ftdi_rx_ready <= 1'b0;
|
||||
end else begin
|
||||
r_ftdi_rx_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
if (r_bus_data_request) begin
|
||||
o_request <= 1'b1;
|
||||
end
|
||||
|
||||
if (o_request && i_busy) begin
|
||||
o_request <= 1'b1;
|
||||
end
|
||||
|
||||
if (i_ack) begin
|
||||
r_i_data_buffer <= i_data;
|
||||
r_bus_data_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
0
hw/v1/.gitignore → hw/.gitignore
vendored
0
hw/v1/.gitignore → hw/.gitignore
vendored
@ -1,58 +0,0 @@
|
||||
ROOTDIR = $(N64_INST)
|
||||
GCCN64PREFIX = $(ROOTDIR)/bin/mips64-elf-
|
||||
CHKSUM64PATH = $(ROOTDIR)/bin/chksum64
|
||||
MKDFSPATH = $(ROOTDIR)/bin/mkdfs
|
||||
HEADERPATH = $(ROOTDIR)/mips64-elf/lib
|
||||
N64TOOL = $(ROOTDIR)/bin/n64tool
|
||||
HEADERNAME = header
|
||||
LINK_FLAGS = -L$(ROOTDIR)/mips64-elf/lib -ldragon -lc -lm -ldragonsys -Tn64.ld
|
||||
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -Os -Wall -I./src -I./src/boot -I./src/fatfs -I./src/sc64 -I$(ROOTDIR)/mips64-elf/include
|
||||
ASFLAGS = -mtune=vr4300 -march=vr4300
|
||||
CC = $(GCCN64PREFIX)gcc
|
||||
AS = $(GCCN64PREFIX)as
|
||||
LD = $(GCCN64PREFIX)ld
|
||||
OBJCOPY = $(GCCN64PREFIX)objcopy
|
||||
OBJDUMP = $(GCCN64PREFIX)objdump
|
||||
|
||||
SRC_DIRS = src src/boot src/fatfs src/sc64
|
||||
SRC_FILES = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIRS)))
|
||||
OBJ_FILES = $(addprefix build/, $(notdir $(SRC_FILES:.c=.o)))
|
||||
VPATH = $(SRC_DIRS)
|
||||
|
||||
ROM_SIZE = 90k
|
||||
|
||||
ifeq ($(N64_BYTE_SWAP),true)
|
||||
ROM_EXTENSION = .v64
|
||||
N64_FLAGS = -b -l $(ROM_SIZE) -h $(HEADERPATH)/$(HEADERNAME) -o build/$(PROG_NAME)$(ROM_EXTENSION)
|
||||
else
|
||||
ROM_EXTENSION = .z64
|
||||
N64_FLAGS = -l $(ROM_SIZE) -h $(HEADERPATH)/$(HEADERNAME) -o build/$(PROG_NAME)$(ROM_EXTENSION)
|
||||
endif
|
||||
|
||||
PROG_NAME = SummerLoader64
|
||||
|
||||
all: make_output_dir build/$(PROG_NAME)$(ROM_EXTENSION)
|
||||
|
||||
$(OBJ_FILES): Makefile
|
||||
|
||||
build/$(PROG_NAME)$(ROM_EXTENSION): build/$(PROG_NAME).elf
|
||||
$(OBJCOPY) build/$(PROG_NAME).elf build/$(PROG_NAME).bin -O binary
|
||||
$(OBJDUMP) -S build/$(PROG_NAME).elf > build/$(PROG_NAME).lst
|
||||
rm -f build/$(PROG_NAME)$(ROM_EXTENSION)
|
||||
$(N64TOOL) $(N64_FLAGS) -t $(PROG_NAME) build/$(PROG_NAME).bin
|
||||
$(CHKSUM64PATH) build/$(PROG_NAME)$(ROM_EXTENSION)
|
||||
$(OBJCOPY) build/$(PROG_NAME)$(ROM_EXTENSION) build/$(PROG_NAME).hex -I binary -O ihex
|
||||
|
||||
build/$(PROG_NAME).elf: $(OBJ_FILES)
|
||||
$(LD) -o build/$(PROG_NAME).elf $(OBJ_FILES) $(LINK_FLAGS)
|
||||
|
||||
build/%.o: %.c
|
||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
make_output_dir:
|
||||
$(shell mkdir ./build 2>/dev/null)
|
||||
|
||||
clean:
|
||||
rm -rf ./build
|
||||
|
||||
.PHONY: all clean make_output_dir
|
@ -1,7 +0,0 @@
|
||||
# SummerLoader64
|
||||
|
||||
A N64 bootloader for SummerCart64. This project is mainly based on work by **`jago85`** contained in [Brutzelkarte_Bootloader repository](https://github.com/jago85/Brutzelkarte_Bootloader) with some modifications that made code a little bit more readable.
|
||||
|
||||
## TODO
|
||||
|
||||
- Expand documentation
|
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker run -t --mount type=bind,src="$(pwd)",target="/libdragon" anacierdem/libdragon:4.1.1 /bin/bash -c "/usr/bin/make clean; /usr/bin/make all N64_BYTE_SWAP=false"
|
@ -1,45 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "error_display.h"
|
||||
|
||||
|
||||
void error_display_and_halt(menu_load_error_t error, const char *path) {
|
||||
init_interrupts();
|
||||
|
||||
display_init(RESOLUTION_320x240, DEPTH_32_BPP, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE);
|
||||
|
||||
console_init();
|
||||
console_set_render_mode(RENDER_MANUAL);
|
||||
console_clear();
|
||||
|
||||
printf("SC64 Bootloader ver. %d.%02d error:\n\n%2d: ", BOOTLOADER_VERSION_MAJOR, BOOTLOADER_VERSION_MINOR, error);
|
||||
|
||||
switch (error) {
|
||||
case E_MENU_OK:
|
||||
printf("No error :O");
|
||||
break;
|
||||
case E_MENU_ERROR_NOT_SC64:
|
||||
printf("SummerCart64 not detected");
|
||||
break;
|
||||
case E_MENU_ERROR_NO_CARD:
|
||||
printf("SD Card not detected");
|
||||
break;
|
||||
case E_MENU_ERROR_NO_FILESYSTEM:
|
||||
printf("No filesystem (FAT or exFAT)\nfound on SD Card");
|
||||
break;
|
||||
case E_MENU_ERROR_NO_FILE:
|
||||
printf("Unable to locate menu file:\n(%s)", path);
|
||||
break;
|
||||
case E_MENU_ERROR_READ_ERROR:
|
||||
printf("Error while reading data from\nSD Card");
|
||||
break;
|
||||
case E_MENU_ERROR_OTHER_ERROR:
|
||||
default:
|
||||
printf("Unknown error");
|
||||
break;
|
||||
}
|
||||
|
||||
console_render();
|
||||
|
||||
while (1);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#ifndef ERROR_DISPLAY_H__
|
||||
#define ERROR_DISPLAY_H__
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
typedef enum menu_load_error_e {
|
||||
E_MENU_OK,
|
||||
E_MENU_ERROR_NOT_SC64,
|
||||
E_MENU_ERROR_NO_CARD,
|
||||
E_MENU_ERROR_NO_FILESYSTEM,
|
||||
E_MENU_ERROR_NO_FILE,
|
||||
E_MENU_ERROR_READ_ERROR,
|
||||
E_MENU_ERROR_OTHER_ERROR,
|
||||
} menu_load_error_t;
|
||||
|
||||
|
||||
void error_display_and_halt(menu_load_error_t error, const char *path);
|
||||
|
||||
|
||||
#endif
|
@ -1,346 +0,0 @@
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.13 (May 21, 2017)
|
||||
|
||||
Changed heading character of configuration keywords "_" to "FF_".
|
||||
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
|
||||
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
|
||||
|
||||
|
||||
|
||||
R0.13a (October 14, 2017)
|
||||
|
||||
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
|
||||
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
|
||||
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
|
||||
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
|
||||
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
|
||||
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.13b (April 07, 2018)
|
||||
|
||||
Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
|
||||
Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
|
||||
Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
|
||||
Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
|
||||
|
||||
|
||||
|
||||
R0.13c (October 14, 2018)
|
||||
Supported stdint.h for C99 and later. (integer.h was included in ff.h)
|
||||
Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
|
||||
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
|
||||
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
|
||||
|
||||
|
||||
|
||||
R0.14 (October 14, 2019)
|
||||
Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1)
|
||||
Changed some API functions, f_mkfs() and f_fdisk().
|
||||
Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters.
|
||||
Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters.
|
||||
Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12)
|
||||
Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12)
|
||||
|
||||
|
||||
R0.14a (December 5, 2020)
|
||||
Limited number of recursive calls in f_findnext().
|
||||
Fixed old floppy disks formatted with MS-DOS 2.x and 3.x cannot be mounted.
|
||||
Fixed some compiler warnings.
|
||||
|
@ -1,21 +0,0 @@
|
||||
FatFs Module Source Files R0.14a
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related functions.
|
||||
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and it does not depend on any specific
|
||||
storage device. You need to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
@ -1,53 +0,0 @@
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
|
||||
#include "sc64_sd.h"
|
||||
|
||||
|
||||
DSTATUS disk_status(BYTE pdrv) {
|
||||
if (pdrv > 0) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
return sc64_sd_get_status() ? 0 : STA_NOINIT;
|
||||
}
|
||||
|
||||
DSTATUS disk_initialize(BYTE pdrv) {
|
||||
if (pdrv > 0) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
if (!sc64_sd_get_status()) {
|
||||
if (sc64_sd_init()) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
|
||||
sc64_sd_err_t error;
|
||||
|
||||
if ((pdrv > 0) || (count == 0)) {
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
if (!sc64_sd_get_status()) {
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
|
||||
error = sc64_sd_read_sectors(sector, count, buff);
|
||||
|
||||
if (error != E_OK) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
|
||||
return RES_PARERR;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2019 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user