forked from cores/microwatt
Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Anton Blanchard | 986881f258 | 5 years ago |
@ -1,109 +0,0 @@
|
|||||||
name: 'test'
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * 5'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
backend:
|
|
||||||
- llvm
|
|
||||||
- gcc
|
|
||||||
container: ghdl/vunit:${{ matrix.backend }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: make GNATMAKE='gnatmake -j'$(nproc)
|
|
||||||
|
|
||||||
py:
|
|
||||||
needs: [build]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: ghdl/vunit:llvm
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: |
|
|
||||||
apt update
|
|
||||||
apt install -y python3-pexpect
|
|
||||||
make -j$(nproc) test_micropython test_micropython_long
|
|
||||||
|
|
||||||
test:
|
|
||||||
needs: [build]
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
max-parallel: 3
|
|
||||||
matrix:
|
|
||||||
task: [
|
|
||||||
"tests_console",
|
|
||||||
"{1..99}",
|
|
||||||
"{100..199}",
|
|
||||||
"{200..299}",
|
|
||||||
"{300..399}",
|
|
||||||
"{400..499}",
|
|
||||||
"{500..599}",
|
|
||||||
"{600..699}",
|
|
||||||
"{700..799}",
|
|
||||||
"{800..899}",
|
|
||||||
"{900..999}",
|
|
||||||
]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: ghdl/vunit:llvm
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: bash -c "make -j$(nproc) ${{ matrix.task }}"
|
|
||||||
|
|
||||||
VUnit:
|
|
||||||
needs: [build]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: docker://ghdl/vunit:llvm
|
|
||||||
with:
|
|
||||||
args: python3 ./run.py -p10
|
|
||||||
|
|
||||||
symbiflow:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
max-parallel: 2
|
|
||||||
matrix:
|
|
||||||
task: [ ECP5-EVN, ORANGE-CRAB, ORANGE-CRAB-0.21 ]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
DOCKER: 1
|
|
||||||
FPGA_TARGET: ${{matrix.task}}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: make microwatt.json
|
|
||||||
- run: make microwatt.bit
|
|
||||||
- run: make microwatt.svf
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: ${{matrix.task}}-bitstream
|
|
||||||
path: microwatt.svf
|
|
||||||
|
|
||||||
# test building verilog target from yosys/nextpnr
|
|
||||||
verilog:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: make DOCKER=1 microwatt.v
|
|
||||||
|
|
||||||
verilator:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
DOCKER: 1
|
|
||||||
FPGA_TARGET: verilator
|
|
||||||
RAM_INIT_FILE: micropython/firmware.hex
|
|
||||||
MEMORY_SIZE: 524288
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y python3-pexpect
|
|
||||||
make -j$(nproc) test_micropython_verilator test_micropython_verilator_long
|
|
@ -0,0 +1,8 @@
|
|||||||
|
language: minimal
|
||||||
|
install: skip
|
||||||
|
|
||||||
|
services: docker
|
||||||
|
|
||||||
|
before_install: docker pull ghdl/vunit:llvm
|
||||||
|
|
||||||
|
script: docker run --rm -t -v `pwd`:/build -w /build ghdl/vunit:llvm bash -c "apt update && apt install -y python3-pexpect && make GNATMAKE='gnatmake -j'$(nproc) && if [ -n \"$TRAVIS_FULL_CHECK\" ] ; then make -j$(nproc) check; else make -j$(nproc) check_light ; fi"
|
@ -1,343 +1,82 @@
|
|||||||
GHDL ?= ghdl
|
GHDL=ghdl
|
||||||
GHDLFLAGS=--std=08
|
GHDLFLAGS=--std=08
|
||||||
CFLAGS=-O3 -Wall
|
CFLAGS=-O2 -Wall
|
||||||
# Need to investigate why yosys is hitting verilator warnings, and eventually turn on -Wall
|
|
||||||
VERILATOR_FLAGS=-O3 -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT #--trace
|
|
||||||
# It takes forever to build with optimisation, so disable by default
|
|
||||||
#VERILATOR_CFLAGS=-O3
|
|
||||||
|
|
||||||
# some yosys builds have ghdl plugin built in, otherwise need "-m ghdl"
|
all = core_tb simple_ram_behavioural_tb soc_reset_tb
|
||||||
GHDLSYNTH ?= $(shell ($(YOSYS) -H | grep -q ghdl) || echo -m ghdl)
|
# XXX
|
||||||
YOSYS ?= yosys
|
# loadstore_tb fetch_tb
|
||||||
NEXTPNR ?= nextpnr-ecp5
|
|
||||||
ECPPACK ?= ecppack
|
|
||||||
ECPPROG ?= ecpprog
|
|
||||||
OPENOCD ?= openocd
|
|
||||||
VUNITRUN ?= python3 ./run.py
|
|
||||||
VERILATOR ?= verilator
|
|
||||||
DFUUTIL ?= dfu-util
|
|
||||||
DFUSUFFIX ?= dfu-suffix
|
|
||||||
|
|
||||||
# We need a version of GHDL built with either the LLVM or gcc backend.
|
|
||||||
# Fedora provides this, but other distros may not. Another option is to use
|
|
||||||
# the Docker image.
|
|
||||||
DOCKER ?= 0
|
|
||||||
PODMAN ?= 0
|
|
||||||
|
|
||||||
ifeq ($(DOCKER), 1)
|
|
||||||
DOCKERBIN=docker
|
|
||||||
USE_DOCKER=1
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(PODMAN), 1)
|
|
||||||
DOCKERBIN=podman
|
|
||||||
USE_DOCKER=1
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(USE_DOCKER), 1)
|
|
||||||
PWD = $(shell pwd)
|
|
||||||
DOCKERARGS = run --rm -v $(PWD):/src:z -w /src
|
|
||||||
GHDL = $(DOCKERBIN) $(DOCKERARGS) ghdl/ghdl:buster-llvm-7 ghdl
|
|
||||||
CC = $(DOCKERBIN) $(DOCKERARGS) ghdl/ghdl:buster-llvm-7 gcc
|
|
||||||
GHDLSYNTH = -m ghdl
|
|
||||||
YOSYS = $(DOCKERBIN) $(DOCKERARGS) hdlc/ghdl:yosys yosys
|
|
||||||
NEXTPNR = $(DOCKERBIN) $(DOCKERARGS) hdlc/nextpnr:ecp5 nextpnr-ecp5
|
|
||||||
ECPPACK = $(DOCKERBIN) $(DOCKERARGS) hdlc/prjtrellis ecppack
|
|
||||||
OPENOCD = $(DOCKERBIN) $(DOCKERARGS) --device /dev/bus/usb hdlc/prog openocd
|
|
||||||
VUNITRUN = $(DOCKERBIN) $(DOCKERARGS) ghdl/vunit:llvm python3 ./run.py
|
|
||||||
VERILATOR = $(DOCKERBIN) $(DOCKERARGS) verilator/verilator:latest
|
|
||||||
endif
|
|
||||||
|
|
||||||
VUNITARGS += -p10
|
|
||||||
|
|
||||||
all = core_tb icache_tb dcache_tb dmi_dtm_tb \
|
|
||||||
wishbone_bram_tb soc_reset_tb
|
|
||||||
|
|
||||||
all: $(all)
|
all: $(all)
|
||||||
|
|
||||||
core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \
|
%.o : %.vhdl
|
||||||
utils.vhdl plru.vhdl cache_ram.vhdl icache.vhdl \
|
$(GHDL) -a $(GHDLFLAGS) $<
|
||||||
decode1.vhdl helpers.vhdl insn_helpers.vhdl \
|
|
||||||
control.vhdl decode2.vhdl register_file.vhdl \
|
common.o: decode_types.o
|
||||||
cr_file.vhdl crhelpers.vhdl ppc_fx_insns.vhdl rotator.vhdl \
|
core_tb.o: common.o core.o soc.o
|
||||||
logical.vhdl countbits.vhdl multiply.vhdl divider.vhdl execute1.vhdl \
|
core.o: common.o wishbone_types.o fetch1.o fetch2.o icache.o decode1.o decode2.o register_file.o cr_file.o execute1.o execute2.o loadstore1.o loadstore2.o multiply.o writeback.o
|
||||||
loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \
|
cr_file.o: common.o
|
||||||
core.vhdl fpu.vhdl pmu.vhdl
|
crhelpers.o: common.o
|
||||||
|
decode1.o: common.o decode_types.o
|
||||||
soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
|
decode2.o: decode_types.o common.o helpers.o insn_helpers.o
|
||||||
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl gpio.vhdl soc.vhdl \
|
decode_types.o:
|
||||||
spi_rxtx.vhdl spi_flash_ctrl.vhdl
|
execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o sim_console.o
|
||||||
|
execute2.o: common.o crhelpers.o ppc_fx_insns.o
|
||||||
uart_files = $(wildcard uart16550/*.v)
|
fetch1.o: common.o
|
||||||
|
fetch2.o: common.o wishbone_types.o
|
||||||
soc_sim_files = $(core_files) $(soc_files) sim_console.vhdl sim_pp_uart.vhdl sim_bram_helpers.vhdl \
|
glibc_random_helpers.o:
|
||||||
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl \
|
glibc_random.o: glibc_random_helpers.o
|
||||||
sim_16550_uart.vhdl \
|
helpers.o:
|
||||||
foreign_random.vhdl glibc_random.vhdl glibc_random_helpers.vhdl
|
icache.o: common.o wishbone_types.o
|
||||||
|
insn_helpers.o:
|
||||||
soc_sim_c_files = sim_vhpi_c.c sim_bram_helpers_c.c sim_console_c.c \
|
loadstore1.o: common.o
|
||||||
sim_jtag_socket_c.c
|
loadstore2.o: common.o helpers.o wishbone_types.o
|
||||||
|
multiply_tb.o: common.o glibc_random.o ppc_fx_insns.o multiply.o
|
||||||
soc_sim_obj_files=$(soc_sim_c_files:.c=.o)
|
multiply.o: common.o decode_types.o ppc_fx_insns.o crhelpers.o
|
||||||
comma := ,
|
ppc_fx_insns.o: helpers.o
|
||||||
soc_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_sim_obj_files))
|
register_file.o: common.o
|
||||||
|
sim_console.o:
|
||||||
unisim_dir = sim-unisim
|
simple_ram_behavioural_helpers.o:
|
||||||
unisim_lib = $(unisim_dir)/unisim-obj08.cf
|
simple_ram_behavioural_tb.o: wishbone_types.o simple_ram_behavioural.o
|
||||||
unisim_lib_files = $(unisim_dir)/BSCANE2.vhdl $(unisim_dir)/BUFG.vhdl \
|
simple_ram_behavioural.o: wishbone_types.o simple_ram_behavioural_helpers.o
|
||||||
$(unisim_dir)/unisim_vcomponents.vhdl
|
sim_uart.o: wishbone_types.o sim_console.o
|
||||||
$(unisim_lib): $(unisim_lib_files)
|
soc.o: common.o wishbone_types.o core.o wishbone_arbiter.o sim_uart.o simple_ram_behavioural.o
|
||||||
$(GHDL) -i --std=08 --work=unisim --workdir=$(unisim_dir) $^
|
wishbone_arbiter.o: wishbone_types.o
|
||||||
GHDLFLAGS += -P$(unisim_dir)
|
wishbone_types.o:
|
||||||
|
writeback.o: common.o
|
||||||
soc_tbs = core_tb icache_tb dcache_tb dmi_dtm_tb wishbone_bram_tb
|
fpga/soc_reset_tb.o: fpga/soc_reset.o
|
||||||
soc_flash_tbs = core_flash_tb
|
|
||||||
soc_dram_tbs = dram_tb core_dram_tb
|
soc_reset_tb: fpga/soc_reset_tb.o fpga/soc_reset.o
|
||||||
|
$(GHDL) -e $(GHDLFLAGS) soc_reset_tb
|
||||||
ifneq ($(FLASH_MODEL_PATH),)
|
|
||||||
fmf_dir = $(FLASH_MODEL_PATH)/fmf
|
core_tb: core_tb.o simple_ram_behavioural_helpers_c.o sim_console_c.o
|
||||||
fmf_lib = $(fmf_dir)/fmf-obj08.cf
|
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o -Wl,sim_console_c.o $@
|
||||||
fmf_lib_files = $(wildcard $(fmf_dir)/*.vhd)
|
|
||||||
GHDLFLAGS += -P$(fmf_dir)
|
fetch_tb: fetch_tb.o
|
||||||
$(fmf_lib): $(fmf_lib_files)
|
$(GHDL) -e $(GHDLFLAGS) $@
|
||||||
$(GHDL) -i --std=08 --work=fmf --workdir=$(fmf_dir) $^
|
|
||||||
|
loadstore_tb: loadstore_tb.o
|
||||||
flash_model_files=$(FLASH_MODEL_PATH)/s25fl128s.vhd
|
$(GHDL) -e $(GHDLFLAGS) $@
|
||||||
flash_model_files: $(fmf_lib)
|
|
||||||
else
|
simple_ram_tb: simple_ram_tb.o
|
||||||
flash_model_files=sim_no_flash.vhdl
|
$(GHDL) -e $(GHDLFLAGS) $@
|
||||||
fmf_lib=
|
|
||||||
endif
|
simple_ram_behavioural_tb: simple_ram_behavioural_helpers_c.o simple_ram_behavioural_tb.o
|
||||||
|
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o $@
|
||||||
$(soc_flash_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) $(fmf_lib) $(flash_model_files) %.vhdl
|
|
||||||
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $(flash_model_files) $@.vhdl $(unisim_files) -e $@
|
|
||||||
|
|
||||||
$(soc_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) %.vhdl
|
|
||||||
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $@.vhdl -e $@
|
|
||||||
|
|
||||||
soc_reset_tb: fpga/soc_reset_tb.vhdl fpga/soc_reset.vhdl
|
|
||||||
$(GHDL) -c $(GHDLFLAGS) fpga/soc_reset_tb.vhdl fpga/soc_reset.vhdl -e $@
|
|
||||||
|
|
||||||
# LiteDRAM sim
|
|
||||||
VERILATOR_ROOT=$(shell verilator -getenv VERILATOR_ROOT 2>/dev/null)
|
|
||||||
ifeq (, $(VERILATOR_ROOT))
|
|
||||||
$(soc_dram_tbs):
|
|
||||||
$(error "Verilator is required to make this target !")
|
|
||||||
else
|
|
||||||
|
|
||||||
verilated_dram: litedram/generated/sim/litedram_core.v
|
|
||||||
verilator $(VERILATOR_FLAGS) -CFLAGS $(VERILATOR_CFLAGS) -Wno-fatal --cc $<
|
|
||||||
make -C obj_dir -f ../litedram/extras/sim_dram_verilate.mk VERILATOR_ROOT=$(VERILATOR_ROOT)
|
|
||||||
|
|
||||||
SIM_DRAM_CFLAGS = -I. -Iobj_dir -Ilitedram/generated/sim -I$(VERILATOR_ROOT)/include -I$(VERILATOR_ROOT)/include/vltstd
|
|
||||||
SIM_DRAM_CFLAGS += -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -DVL_PRINTF=printf -faligned-new
|
|
||||||
sim_litedram_c.o: litedram/extras/sim_litedram_c.cpp verilated_dram
|
|
||||||
$(CC) $(CPPFLAGS) $(SIM_DRAM_CFLAGS) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
soc_dram_files = $(core_files) $(soc_files) litedram/extras/litedram-wrapper-l2.vhdl litedram/generated/sim/litedram-initmem.vhdl
|
|
||||||
soc_dram_sim_files = $(soc_sim_files) litedram/extras/sim_litedram.vhdl
|
|
||||||
soc_dram_sim_obj_files = $(soc_sim_obj_files) sim_litedram_c.o
|
|
||||||
dram_link_files=-Wl,obj_dir/Vlitedram_core__ALL.a -Wl,obj_dir/verilated.o -Wl,obj_dir/verilated_vcd_c.o -Wl,-lstdc++
|
|
||||||
soc_dram_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_dram_sim_obj_files)) $(dram_link_files)
|
|
||||||
|
|
||||||
$(soc_dram_tbs): %: $(soc_dram_files) $(soc_dram_sim_files) $(soc_dram_sim_obj_files) $(flash_model_files) $(unisim_lib) $(fmf_lib) %.vhdl
|
|
||||||
$(GHDL) -c $(GHDLFLAGS) $(soc_dram_sim_link) $(soc_dram_files) $(soc_dram_sim_files) $(flash_model_files) $@.vhdl -e $@
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Hello world
|
|
||||||
MEMORY_SIZE ?=8192
|
|
||||||
RAM_INIT_FILE ?=hello_world/hello_world.hex
|
|
||||||
|
|
||||||
# Micropython
|
|
||||||
#MEMORY_SIZE=393216
|
|
||||||
#RAM_INIT_FILE=micropython/firmware.hex
|
|
||||||
|
|
||||||
FPGA_TARGET ?= ORANGE-CRAB-0.21
|
|
||||||
|
|
||||||
# FIXME: icache RAMs aren't being inferrenced as block RAMs on ECP5
|
|
||||||
# with yosys, so make it smaller for now as a workaround.
|
|
||||||
ICACHE_NUM_LINES=4
|
|
||||||
|
|
||||||
clkgen=fpga/clk_gen_ecp5.vhd
|
|
||||||
toplevel=fpga/top-generic.vhdl
|
|
||||||
dmi_dtm=dmi_dtm_dummy.vhdl
|
|
||||||
LITEDRAM_GHDL_ARG=
|
|
||||||
|
|
||||||
# OrangeCrab with ECP85 (original v0.0 with UM5G-85 chip)
|
|
||||||
ifeq ($(FPGA_TARGET), ORANGE-CRAB)
|
|
||||||
RESET_LOW=true
|
|
||||||
CLK_INPUT=48000000
|
|
||||||
CLK_FREQUENCY=48000000
|
|
||||||
LPF=constraints/orange-crab.lpf
|
|
||||||
PACKAGE=CSFBGA285
|
|
||||||
NEXTPNR_FLAGS=--um5g-85k --freq 48
|
|
||||||
OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
|
|
||||||
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
|
|
||||||
ECP_FLASH_OFFSET=0x80000
|
|
||||||
endif
|
|
||||||
|
|
||||||
# OrangeCrab with ECP85 (v0.21)
|
|
||||||
ifeq ($(FPGA_TARGET), ORANGE-CRAB-0.21)
|
|
||||||
RESET_LOW=true
|
|
||||||
CLK_INPUT=48000000
|
|
||||||
CLK_FREQUENCY=48000000
|
|
||||||
LPF=constraints/orange-crab-0.2.lpf
|
|
||||||
PACKAGE=CSFBGA285
|
|
||||||
NEXTPNR_FLAGS=--85k --speed 8 --freq 48 --timing-allow-fail --ignore-loops
|
|
||||||
OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
|
|
||||||
OPENOCD_DEVICE_CONFIG=openocd/LFE5U-85F.cfg
|
|
||||||
DFU_VENDOR=1209
|
|
||||||
DFU_PRODUCT=5af0
|
|
||||||
ECP_FLASH_OFFSET=0x80000
|
|
||||||
toplevel=fpga/top-orangecrab0.2.vhdl
|
|
||||||
litedram_target=orangecrab-85-0.2
|
|
||||||
soc_extra_v += litesdcard/generated/lattice/litesdcard_core.v
|
|
||||||
dmi_dtm=dmi_dtm_ecp5.vhdl
|
|
||||||
endif
|
|
||||||
|
|
||||||
# ECP5-EVN
|
|
||||||
ifeq ($(FPGA_TARGET), ECP5-EVN)
|
|
||||||
RESET_LOW=true
|
|
||||||
CLK_INPUT=12000000
|
|
||||||
CLK_FREQUENCY=40000000
|
|
||||||
LPF=constraints/ecp5-evn.lpf
|
|
||||||
PACKAGE=CABGA381
|
|
||||||
NEXTPNR_FLAGS=--um5g-85k --freq 40
|
|
||||||
OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg
|
|
||||||
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(litedram_target),)
|
|
||||||
soc_extra_synth += litedram/extras/litedram-wrapper-l2.vhdl \
|
|
||||||
litedram/generated/$(litedram_target)/litedram-initmem.vhdl
|
|
||||||
soc_extra_v += litedram/generated/$(litedram_target)/litedram_core.v
|
|
||||||
LITEDRAM_GHDL_ARG=-gUSE_LITEDRAM=true
|
|
||||||
endif
|
|
||||||
|
|
||||||
GHDL_IMAGE_GENERICS=-gMEMORY_SIZE=$(MEMORY_SIZE) -gRAM_INIT_FILE=$(RAM_INIT_FILE) \
|
|
||||||
-gRESET_LOW=$(RESET_LOW) -gCLK_INPUT=$(CLK_INPUT) -gCLK_FREQUENCY=$(CLK_FREQUENCY) -gICACHE_NUM_LINES=$(ICACHE_NUM_LINES) \
|
|
||||||
$(LITEDRAM_GHDL_ARG)
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(FPGA_TARGET), verilator)
|
|
||||||
RESET_LOW=true
|
|
||||||
CLK_INPUT=50000000
|
|
||||||
CLK_FREQUENCY=50000000
|
|
||||||
clkgen=fpga/clk_gen_bypass.vhd
|
|
||||||
endif
|
|
||||||
|
|
||||||
fpga_files = fpga/soc_reset.vhdl \
|
|
||||||
fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram.vhdl \
|
|
||||||
nonrandom.vhdl
|
|
||||||
|
|
||||||
synth_files = $(core_files) $(soc_files) $(soc_extra_synth) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm)
|
|
||||||
|
|
||||||
microwatt.json: $(synth_files) $(RAM_INIT_FILE)
|
|
||||||
$(YOSYS) $(GHDLSYNTH) -p "ghdl --std=08 --no-formal $(GHDL_IMAGE_GENERICS) $(synth_files) -e toplevel; read_verilog $(uart_files) $(soc_extra_v); synth_ecp5 -abc9 -nowidelut -json $@ $(SYNTH_ECP5_FLAGS)"
|
|
||||||
|
|
||||||
microwatt.v: $(synth_files) $(RAM_INIT_FILE)
|
|
||||||
$(YOSYS) $(GHDLSYNTH) -p "ghdl --std=08 --no-formal $(GHDL_IMAGE_GENERICS) $(synth_files) -e toplevel; write_verilog $@"
|
|
||||||
|
|
||||||
microwatt-verilator: microwatt.v verilator/microwatt-verilator.cpp verilator/uart-verilator.c
|
|
||||||
$(VERILATOR) $(VERILATOR_FLAGS) -CFLAGS "$(VERILATOR_CFLAGS) -DCLK_FREQUENCY=$(CLK_FREQUENCY)" -Iuart16550 --assert --cc --exe --build $^ -o $@ -top-module toplevel
|
|
||||||
@cp -f obj_dir/microwatt-verilator microwatt-verilator
|
|
||||||
|
|
||||||
microwatt_out.config: microwatt.json $(LPF)
|
|
||||||
$(NEXTPNR) --json $< --lpf $(LPF) --textcfg $@.tmp $(NEXTPNR_FLAGS) --package $(PACKAGE)
|
|
||||||
mv -f $@.tmp $@
|
|
||||||
|
|
||||||
microwatt.bit: microwatt_out.config
|
|
||||||
$(ECPPACK) --compress --freq 38.8 --svf microwatt.svf $< $@
|
|
||||||
|
|
||||||
microwatt.svf: microwatt.bit
|
|
||||||
|
|
||||||
prog: microwatt.svf
|
|
||||||
$(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit"
|
|
||||||
|
|
||||||
microwatt.dfu: microwatt.bit
|
|
||||||
cp $< $@.tmp
|
|
||||||
$(DFUSUFFIX) -v $(DFU_VENDOR) -p $(DFU_PRODUCT) -a $@.tmp
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
dfuprog: microwatt.dfu
|
|
||||||
$(DFUUTIL) -a 0 -D $<
|
|
||||||
|
|
||||||
ecpprog: microwatt.bit
|
|
||||||
$(ECPPROG) -S $<
|
|
||||||
|
|
||||||
ecpflash: microwatt.bit
|
|
||||||
test -n "$(ECP_FLASH_OFFSET)" || (echo Error: No ECP_FLASH_OFFSET defined for target; exit 1)
|
|
||||||
$(ECPPROG) -o $(ECP_FLASH_OFFSET) $<
|
|
||||||
|
|
||||||
tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out)))
|
tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out)))
|
||||||
tests_console = $(sort $(patsubst tests/%.console_out,%,$(wildcard tests/*.console_out)))
|
|
||||||
|
|
||||||
tests_console: $(tests_console)
|
|
||||||
|
|
||||||
check_vunit:
|
check: $(tests) test_micropython test_micropython_long
|
||||||
$(VUNITRUN) $(VUNITARGS)
|
|
||||||
|
|
||||||
check: $(tests) tests_console test_micropython test_micropython_long tests_unit
|
check_light: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 test_micropython test_micropython_long
|
||||||
|
|
||||||
check_light: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 test_micropython test_micropython_long tests_console tests_unit
|
|
||||||
|
|
||||||
$(tests): core_tb
|
$(tests): core_tb
|
||||||
@./scripts/run_test.sh $@
|
@./scripts/run_test.sh $@
|
||||||
|
|
||||||
$(tests_console): core_tb
|
|
||||||
@./scripts/run_test_console.sh $@
|
|
||||||
|
|
||||||
test_micropython: core_tb
|
test_micropython: core_tb
|
||||||
@./scripts/test_micropython.py
|
@./scripts/test_micropython.py
|
||||||
|
|
||||||
test_micropython_verilator: microwatt-verilator
|
|
||||||
@./scripts/test_micropython_verilator.py
|
|
||||||
|
|
||||||
test_micropython_long: core_tb
|
test_micropython_long: core_tb
|
||||||
@./scripts/test_micropython_long.py
|
@./scripts/test_micropython_long.py
|
||||||
|
|
||||||
test_micropython_verilator_long: microwatt-verilator
|
clean:
|
||||||
@./scripts/test_micropython_verilator_long.py
|
rm -f *.o work-*cf $(all)
|
||||||
|
|
||||||
tests_soc_tb = $(patsubst %_tb,%_tb_test,$(soc_tbs))
|
|
||||||
|
|
||||||
%_test: %
|
|
||||||
./$< --assert-level=error > /dev/null
|
|
||||||
|
|
||||||
tests_soc: $(tests_soc_tb)
|
|
||||||
|
|
||||||
# FIXME SOC tests have bit rotted, so disable for now
|
|
||||||
#tests_unit: tests_soc
|
|
||||||
|
|
||||||
TAGS:
|
|
||||||
find . -name '*.vhdl' | xargs ./scripts/vhdltags
|
|
||||||
|
|
||||||
.PHONY: TAGS
|
|
||||||
|
|
||||||
_clean:
|
|
||||||
rm -f *.o *.cf $(all)
|
|
||||||
rm -f fpga/*.o fpga/*.cf
|
|
||||||
rm -f sim-unisim/*.o sim-unisim/*.cf
|
|
||||||
rm -f litedram/extras/*.o
|
|
||||||
rm -f TAGS
|
|
||||||
rm -f scripts/mw_debug/*.o
|
|
||||||
rm -f scripts/mw_debug/mw_debug
|
|
||||||
rm -f microwatt.bin microwatt.json microwatt.svf microwatt_out.config
|
|
||||||
rm -f microwatt.v microwatt-verilator
|
|
||||||
rm -rf obj_dir/
|
|
||||||
|
|
||||||
clean: _clean
|
|
||||||
make -f scripts/mw_debug/Makefile clean
|
|
||||||
make -f hello_world/Makefile clean
|
|
||||||
|
|
||||||
distclean: _clean
|
|
||||||
rm -f *~ fpga/*~ lib/*~ console/*~ include/*~
|
|
||||||
rm -rf litedram/build
|
|
||||||
rm -f litedram/extras/*~
|
|
||||||
rm -f litedram/gen-src/*~
|
|
||||||
rm -f litedram/gen-src/sdram_init/*~
|
|
||||||
make -f scripts/mw_debug/Makefile distclean
|
|
||||||
make -f hello_world/Makefile distclean
|
|
||||||
|
|
||||||
.PHONY: all prog check check_light clean distclean
|
|
||||||
.PRECIOUS: microwatt.json microwatt_out.config microwatt.bit
|
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
use ieee.math_real.all;
|
|
||||||
|
|
||||||
entity cache_ram is
|
|
||||||
generic(
|
|
||||||
ROW_BITS : integer := 16;
|
|
||||||
WIDTH : integer := 64;
|
|
||||||
TRACE : boolean := false;
|
|
||||||
ADD_BUF : boolean := false
|
|
||||||
);
|
|
||||||
|
|
||||||
port(
|
|
||||||
clk : in std_logic;
|
|
||||||
rd_en : in std_logic;
|
|
||||||
rd_addr : in std_logic_vector(ROW_BITS - 1 downto 0);
|
|
||||||
rd_data : out std_logic_vector(WIDTH - 1 downto 0);
|
|
||||||
wr_sel : in std_logic_vector(WIDTH/8 - 1 downto 0);
|
|
||||||
wr_addr : in std_logic_vector(ROW_BITS - 1 downto 0);
|
|
||||||
wr_data : in std_logic_vector(WIDTH - 1 downto 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
end cache_ram;
|
|
||||||
|
|
||||||
architecture rtl of cache_ram is
|
|
||||||
constant SIZE : integer := 2**ROW_BITS;
|
|
||||||
|
|
||||||
type ram_type is array (0 to SIZE - 1) of std_logic_vector(WIDTH - 1 downto 0);
|
|
||||||
signal ram : ram_type;
|
|
||||||
attribute ram_style : string;
|
|
||||||
attribute ram_style of ram : signal is "block";
|
|
||||||
|
|
||||||
signal rd_data0 : std_logic_vector(WIDTH - 1 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
process(clk)
|
|
||||||
variable lbit : integer range 0 to WIDTH - 1;
|
|
||||||
variable mbit : integer range 0 to WIDTH - 1;
|
|
||||||
variable widx : integer range 0 to SIZE - 1;
|
|
||||||
constant sel0 : std_logic_vector(WIDTH/8 - 1 downto 0)
|
|
||||||
:= (others => '0');
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if TRACE then
|
|
||||||
if wr_sel /= sel0 then
|
|
||||||
report "write a:" & to_hstring(wr_addr) &
|
|
||||||
" sel:" & to_hstring(wr_sel) &
|
|
||||||
" dat:" & to_hstring(wr_data);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
for i in 0 to WIDTH/8-1 loop
|
|
||||||
lbit := i * 8;
|
|
||||||
mbit := lbit + 7;
|
|
||||||
widx := to_integer(unsigned(wr_addr));
|
|
||||||
if wr_sel(i) = '1' then
|
|
||||||
ram(widx)(mbit downto lbit) <= wr_data(mbit downto lbit);
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
if rd_en = '1' then
|
|
||||||
rd_data0 <= ram(to_integer(unsigned(rd_addr)));
|
|
||||||
if TRACE then
|
|
||||||
report "read a:" & to_hstring(rd_addr) &
|
|
||||||
" dat:" & to_hstring(ram(to_integer(unsigned(rd_addr))));
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
buf: if ADD_BUF generate
|
|
||||||
begin
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
rd_data <= rd_data0;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
nobuf: if not ADD_BUF generate
|
|
||||||
begin
|
|
||||||
rd_data <= rd_data0;
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
end;
|
|
@ -1,19 +0,0 @@
|
|||||||
LOCATE COMP "ext_clk" SITE "A10";
|
|
||||||
IOBUF PORT "ext_clk" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "ext_rst" SITE "P4";
|
|
||||||
IOBUF PORT "rst" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "uart0_txd" SITE "P3";
|
|
||||||
LOCATE COMP "uart0_rxd" SITE "P2";
|
|
||||||
|
|
||||||
IOBUF PORT "uart0_txd" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "uart0_rxd" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "led_a" SITE "A13";
|
|
||||||
LOCATE COMP "led_b" SITE "A12";
|
|
||||||
LOCATE COMP "led_c" SITE "B19";
|
|
||||||
|
|
||||||
IOBUF PORT "led_a" IO_TYPE=LVCMOS25;
|
|
||||||
IOBUF PORT "led_b" IO_TYPE=LVCMOS25;
|
|
||||||
IOBUF PORT "led_c" IO_TYPE=LVCMOS25;
|
|
@ -1,225 +0,0 @@
|
|||||||
LOCATE COMP "ext_clk" SITE "A9";
|
|
||||||
IOBUF PORT "ext_clk" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
// LOCATE COMP "ext_rst_n" SITE "J2"; // io_13
|
|
||||||
// IOBUF PORT "ext_rst_n" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
// user_button as reset
|
|
||||||
LOCATE COMP "ext_rst_n" SITE "J17";
|
|
||||||
IOBUF PORT "ext_rst_n" IO_TYPE=SSTL135_I;
|
|
||||||
|
|
||||||
LOCATE COMP "usb_d_p" SITE "N1";
|
|
||||||
LOCATE COMP "usb_d_n" SITE "M2";
|
|
||||||
LOCATE COMP "usb_pullup" SITE "N2";
|
|
||||||
|
|
||||||
IOBUF PORT "usb_d_p" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "usb_d_n" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "usb_pullup" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "led0_g" SITE "M3";
|
|
||||||
LOCATE COMP "led0_r" SITE "K4";
|
|
||||||
LOCATE COMP "led0_b" SITE "J3";
|
|
||||||
|
|
||||||
IOBUF PORT "led0_g" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "led0_g" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "led0_b" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
// discontinuous gpio numbers, match orangecrab litex platform
|
|
||||||
LOCATE COMP "pin_gpio_0" SITE "N17"; // tx
|
|
||||||
LOCATE COMP "pin_gpio_1" SITE "M18"; // rx
|
|
||||||
LOCATE COMP "pin_gpio_2" SITE "C10"; // sda
|
|
||||||
LOCATE COMP "pin_gpio_3" SITE "C9"; // scl
|
|
||||||
//
|
|
||||||
LOCATE COMP "pin_gpio_5" SITE "B10"; // io_5
|
|
||||||
LOCATE COMP "pin_gpio_6" SITE "B9"; // ...
|
|
||||||
//
|
|
||||||
LOCATE COMP "pin_gpio_9" SITE "C8"; //
|
|
||||||
LOCATE COMP "pin_gpio_10" SITE "B8"; //
|
|
||||||
LOCATE COMP "pin_gpio_11" SITE "A8"; //
|
|
||||||
LOCATE COMP "pin_gpio_12" SITE "H2"; //
|
|
||||||
LOCATE COMP "pin_gpio_13" SITE "J2"; // io_13
|
|
||||||
LOCATE COMP "pin_gpio_14" SITE "N15"; // miso
|
|
||||||
LOCATE COMP "pin_gpio_15" SITE "R17"; // sck
|
|
||||||
LOCATE COMP "pin_gpio_16" SITE "N16"; // mosi
|
|
||||||
|
|
||||||
LOCATE COMP "pin_io_a0" SITE "L4";
|
|
||||||
LOCATE COMP "pin_io_a1" SITE "N3";
|
|
||||||
LOCATE COMP "pin_io_a2" SITE "N4";
|
|
||||||
LOCATE COMP "pin_io_a3" SITE "H4";
|
|
||||||
LOCATE COMP "pin_io_a4" SITE "G4";
|
|
||||||
LOCATE COMP "pin_io_a5" SITE "T17";
|
|
||||||
|
|
||||||
IOBUF PORT "pin_gpio_0" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_1" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_2" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_3" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_5" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_6" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_9" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_10" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_11" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_12" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_13" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_14" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_15" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_16" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a0" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a1" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a2" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a3" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a4" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a5" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_a[0]" SITE "C4";
|
|
||||||
LOCATE COMP "ddram_a[1]" SITE "D2";
|
|
||||||
LOCATE COMP "ddram_a[2]" SITE "D3";
|
|
||||||
LOCATE COMP "ddram_a[3]" SITE "A3";
|
|
||||||
LOCATE COMP "ddram_a[4]" SITE "A4";
|
|
||||||
LOCATE COMP "ddram_a[5]" SITE "D4";
|
|
||||||
LOCATE COMP "ddram_a[6]" SITE "C3";
|
|
||||||
LOCATE COMP "ddram_a[7]" SITE "B2";
|
|
||||||
LOCATE COMP "ddram_a[8]" SITE "B1";
|
|
||||||
LOCATE COMP "ddram_a[9]" SITE "D1";
|
|
||||||
LOCATE COMP "ddram_a[10]" SITE "A7";
|
|
||||||
LOCATE COMP "ddram_a[11]" SITE "C2";
|
|
||||||
LOCATE COMP "ddram_a[12]" SITE "B6";
|
|
||||||
LOCATE COMP "ddram_a[13]" SITE "C1";
|
|
||||||
LOCATE COMP "ddram_a[14]" SITE "A2";
|
|
||||||
LOCATE COMP "ddram_a[15]" SITE "C7";
|
|
||||||
IOBUF PORT "ddram_a[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[2]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[3]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[4]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[5]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[6]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[7]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[8]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[9]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[10]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[11]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[12]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[13]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[14]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[15]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_ba[0]" SITE "D6";
|
|
||||||
LOCATE COMP "ddram_ba[1]" SITE "B7";
|
|
||||||
LOCATE COMP "ddram_ba[2]" SITE "A6";
|
|
||||||
LOCATE COMP "ddram_cas_n" SITE "D13";
|
|
||||||
LOCATE COMP "ddram_cs_n" SITE "A12";
|
|
||||||
LOCATE COMP "ddram_dm[0]" SITE "D16";
|
|
||||||
LOCATE COMP "ddram_dm[1]" SITE "G16";
|
|
||||||
LOCATE COMP "ddram_ras_n" SITE "C12";
|
|
||||||
LOCATE COMP "ddram_we_n" SITE "B12";
|
|
||||||
IOBUF PORT "ddram_ba[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_ba[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_ba[2]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_cas_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_cs_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_dm[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_dm[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_ras_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_we_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
// from litex platform, termination disabled to reduce heat
|
|
||||||
LOCATE COMP "ddram_dq[0]" SITE "C17";
|
|
||||||
LOCATE COMP "ddram_dq[1]" SITE "D15";
|
|
||||||
LOCATE COMP "ddram_dq[2]" SITE "B17";
|
|
||||||
LOCATE COMP "ddram_dq[3]" SITE "C16";
|
|
||||||
LOCATE COMP "ddram_dq[4]" SITE "A15";
|
|
||||||
LOCATE COMP "ddram_dq[5]" SITE "B13";
|
|
||||||
LOCATE COMP "ddram_dq[6]" SITE "A17";
|
|
||||||
LOCATE COMP "ddram_dq[7]" SITE "A13";
|
|
||||||
LOCATE COMP "ddram_dq[8]" SITE "F17";
|
|
||||||
LOCATE COMP "ddram_dq[9]" SITE "F16";
|
|
||||||
LOCATE COMP "ddram_dq[10]" SITE "G15";
|
|
||||||
LOCATE COMP "ddram_dq[11]" SITE "F15";
|
|
||||||
LOCATE COMP "ddram_dq[12]" SITE "J16";
|
|
||||||
LOCATE COMP "ddram_dq[13]" SITE "C18";
|
|
||||||
LOCATE COMP "ddram_dq[14]" SITE "H16";
|
|
||||||
LOCATE COMP "ddram_dq[15]" SITE "F18";
|
|
||||||
IOBUF PORT "ddram_dq[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[2]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[3]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[4]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[5]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[6]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[7]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[8]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[9]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[10]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[11]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[12]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[13]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[14]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[15]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_dqs_n[0]" SITE "A16";
|
|
||||||
LOCATE COMP "ddram_dqs_n[1]" SITE "H17";
|
|
||||||
LOCATE COMP "ddram_dqs_p[0]" SITE "B15";
|
|
||||||
LOCATE COMP "ddram_dqs_p[1]" SITE "G18";
|
|
||||||
IOBUF PORT "ddram_dqs_n[0]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dqs_n[1]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dqs_p[0]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dqs_p[1]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_clk_p" SITE "J18";
|
|
||||||
LOCATE COMP "ddram_clk_n" SITE "K18";
|
|
||||||
IOBUF PORT "ddram_clk_p" IO_TYPE=SSTL135D_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_clk_n" IO_TYPE=SSTL135D_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_cke" SITE "D18";
|
|
||||||
LOCATE COMP "ddram_odt" SITE "C13";
|
|
||||||
LOCATE COMP "ddram_reset_n" SITE "L18";
|
|
||||||
IOBUF PORT "ddram_cke" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_odt" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_reset_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_vccio[0]" SITE "K16";
|
|
||||||
LOCATE COMP "ddram_vccio[1]" SITE "D17";
|
|
||||||
LOCATE COMP "ddram_vccio[2]" SITE "K15";
|
|
||||||
LOCATE COMP "ddram_vccio[3]" SITE "K17";
|
|
||||||
LOCATE COMP "ddram_vccio[4]" SITE "B18";
|
|
||||||
LOCATE COMP "ddram_vccio[5]" SITE "C6";
|
|
||||||
LOCATE COMP "ddram_gnd[0]" SITE "L15";
|
|
||||||
LOCATE COMP "ddram_gnd[1]" SITE "L16";
|
|
||||||
IOBUF PORT "ddram_vccio[0]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[1]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[2]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[3]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[4]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[5]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_gnd[0]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_gnd[1]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
|
|
||||||
// We use USRMCLK instead for clk
|
|
||||||
// LOCATE COMP "spi_flash_clk" SITE "U16";
|
|
||||||
// IOBUF PORT "spi_flash_clk" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_cs_n" SITE "U17";
|
|
||||||
IOBUF PORT "spi_flash_cs_n" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_mosi" SITE "U18";
|
|
||||||
IOBUF PORT "spi_flash_mosi" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_miso" SITE "T18";
|
|
||||||
IOBUF PORT "spi_flash_miso" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_wp_n" SITE "R18";
|
|
||||||
IOBUF PORT "spi_flash_wp_n" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_hold_n" SITE "N18";
|
|
||||||
IOBUF PORT "spi_flash_hold_n" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "sdcard_data[0]" SITE "J1";
|
|
||||||
LOCATE COMP "sdcard_data[1]" SITE "K3";
|
|
||||||
LOCATE COMP "sdcard_data[2]" SITE "L3";
|
|
||||||
LOCATE COMP "sdcard_data[3]" SITE "M1";
|
|
||||||
LOCATE COMP "sdcard_cmd" SITE "K2";
|
|
||||||
LOCATE COMP "sdcard_clk" SITE "K1";
|
|
||||||
LOCATE COMP "sdcard_cd" SITE "L1";
|
|
||||||
|
|
||||||
IOBUF PORT "sdcard_data[0]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_data[1]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_data[2]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_data[3]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_cmd" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_clk" IO_TYPE=LVCMOS33 SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "sdcard_cd" IO_TYPE=LVCMOS33;
|
|
@ -1,19 +0,0 @@
|
|||||||
LOCATE COMP "ext_clk" SITE "A9";
|
|
||||||
IOBUF PORT "ext_clk" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "ext_rst" SITE "J2";
|
|
||||||
IOBUF PORT "ext_rst" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "uart0_txd" SITE "N17";
|
|
||||||
LOCATE COMP "uart0_rxd" SITE "M18";
|
|
||||||
|
|
||||||
IOBUF PORT "uart0_txd" IO_TYPE=LVCMOS25;
|
|
||||||
IOBUF PORT "uart0_rxd" IO_TYPE=LVCMOS25;
|
|
||||||
|
|
||||||
LOCATE COMP "led_a" SITE "V17";
|
|
||||||
LOCATE COMP "led_b" SITE "T17";
|
|
||||||
LOCATE COMP "led_c" SITE "J3";
|
|
||||||
|
|
||||||
IOBUF PORT "led_a" IO_TYPE=LVCMOS25;
|
|
||||||
IOBUF PORT "led_b" IO_TYPE=LVCMOS25;
|
|
||||||
IOBUF PORT "led_c" IO_TYPE=LVCMOS25;
|
|
@ -1,328 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
|
|
||||||
entity control is
|
|
||||||
generic (
|
|
||||||
EX1_BYPASS : boolean := true;
|
|
||||||
PIPELINE_DEPTH : natural := 3
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
|
|
||||||
complete_in : in instr_tag_t;
|
|
||||||
valid_in : in std_ulogic;
|
|
||||||
repeated : in std_ulogic;
|
|
||||||
flush_in : in std_ulogic;
|
|
||||||
busy_in : in std_ulogic;
|
|
||||||
deferred : in std_ulogic;
|
|
||||||
sgl_pipe_in : in std_ulogic;
|
|
||||||
stop_mark_in : in std_ulogic;
|
|
||||||
|
|
||||||
gpr_write_valid_in : in std_ulogic;
|
|
||||||
gpr_write_in : in gspr_index_t;
|
|
||||||
|
|
||||||
gpr_a_read_valid_in : in std_ulogic;
|
|
||||||
gpr_a_read_in : in gspr_index_t;
|
|
||||||
|
|
||||||
gpr_b_read_valid_in : in std_ulogic;
|
|
||||||
gpr_b_read_in : in gspr_index_t;
|
|
||||||
|
|
||||||
gpr_c_read_valid_in : in std_ulogic;
|
|
||||||
gpr_c_read_in : in gspr_index_t;
|
|
||||||
|
|
||||||
execute_next_tag : in instr_tag_t;
|
|
||||||
execute_next_cr_tag : in instr_tag_t;
|
|
||||||
|
|
||||||
cr_read_in : in std_ulogic;
|
|
||||||
cr_write_in : in std_ulogic;
|
|
||||||
|
|
||||||
valid_out : out std_ulogic;
|
|
||||||
stall_out : out std_ulogic;
|
|
||||||
stopped_out : out std_ulogic;
|
|
||||||
|
|
||||||
gpr_bypass_a : out std_ulogic;
|
|
||||||
gpr_bypass_b : out std_ulogic;
|
|
||||||
gpr_bypass_c : out std_ulogic;
|
|
||||||
cr_bypass : out std_ulogic;
|
|
||||||
|
|
||||||
instr_tag_out : out instr_tag_t
|
|
||||||
);
|
|
||||||
end entity control;
|
|
||||||
|
|
||||||
architecture rtl of control is
|
|
||||||
type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);
|
|
||||||
|
|
||||||
type reg_internal_type is record
|
|
||||||
state : state_type;
|
|
||||||
outstanding : integer range -1 to PIPELINE_DEPTH+2;
|
|
||||||
end record;
|
|
||||||
constant reg_internal_init : reg_internal_type := (state => IDLE, outstanding => 0);
|
|
||||||
|
|
||||||
signal r_int, rin_int : reg_internal_type := reg_internal_init;
|
|
||||||
|
|
||||||
signal gpr_write_valid : std_ulogic;
|
|
||||||
signal cr_write_valid : std_ulogic;
|
|
||||||
|
|
||||||
type tag_register is record
|
|
||||||
wr_gpr : std_ulogic;
|
|
||||||
reg : gspr_index_t;
|
|
||||||
recent : std_ulogic;
|
|
||||||
wr_cr : std_ulogic;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type tag_regs_array is array(tag_number_t) of tag_register;
|
|
||||||
signal tag_regs : tag_regs_array;
|
|
||||||
|
|
||||||
signal instr_tag : instr_tag_t;
|
|
||||||
|
|
||||||
signal gpr_tag_stall : std_ulogic;
|
|
||||||
signal cr_tag_stall : std_ulogic;
|
|
||||||
|
|
||||||
signal curr_tag : tag_number_t;
|
|
||||||
signal next_tag : tag_number_t;
|
|
||||||
|
|
||||||
signal curr_cr_tag : tag_number_t;
|
|
||||||
|
|
||||||
begin
|
|
||||||
control0: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
assert rin_int.outstanding >= 0 and rin_int.outstanding <= (PIPELINE_DEPTH+1)
|
|
||||||
report "Outstanding bad " & integer'image(rin_int.outstanding) severity failure;
|
|
||||||
r_int <= rin_int;
|
|
||||||
for i in tag_number_t loop
|
|
||||||
if rst = '1' or flush_in = '1' then
|
|
||||||
tag_regs(i).wr_gpr <= '0';
|
|
||||||
tag_regs(i).wr_cr <= '0';
|
|
||||||
else
|
|
||||||
if complete_in.valid = '1' and i = complete_in.tag then
|
|
||||||
tag_regs(i).wr_gpr <= '0';
|
|
||||||
tag_regs(i).wr_cr <= '0';
|
|
||||||
report "tag " & integer'image(i) & " not valid";
|
|
||||||
end if;
|
|
||||||
if gpr_write_valid = '1' and tag_regs(i).reg = gpr_write_in then
|
|
||||||
tag_regs(i).recent <= '0';
|
|
||||||
if tag_regs(i).recent = '1' and tag_regs(i).wr_gpr = '1' then
|
|
||||||
report "tag " & integer'image(i) & " not recent";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
if instr_tag.valid = '1' and i = instr_tag.tag then
|
|
||||||
tag_regs(i).wr_gpr <= gpr_write_valid;
|
|
||||||
tag_regs(i).reg <= gpr_write_in;
|
|
||||||
tag_regs(i).recent <= gpr_write_valid;
|
|
||||||
tag_regs(i).wr_cr <= cr_write_valid;
|
|
||||||
if gpr_write_valid = '1' then
|
|
||||||
report "tag " & integer'image(i) & " valid for gpr " & to_hstring(gpr_write_in);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
if rst = '1' then
|
|
||||||
curr_tag <= 0;
|
|
||||||
curr_cr_tag <= 0;
|
|
||||||
else
|
|
||||||
curr_tag <= next_tag;
|
|
||||||
if cr_write_valid = '1' then
|
|
||||||
curr_cr_tag <= instr_tag.tag;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
control_hazards : process(all)
|
|
||||||
variable gpr_stall : std_ulogic;
|
|
||||||
variable tag_a : instr_tag_t;
|
|
||||||
variable tag_b : instr_tag_t;
|
|
||||||
variable tag_c : instr_tag_t;
|
|
||||||
variable tag_s : instr_tag_t;
|
|
||||||
variable tag_t : instr_tag_t;
|
|
||||||
variable incr_tag : tag_number_t;
|
|
||||||
variable byp_a : std_ulogic;
|
|
||||||
variable byp_b : std_ulogic;
|
|
||||||
variable byp_c : std_ulogic;
|
|
||||||
variable tag_cr : instr_tag_t;
|
|
||||||
variable byp_cr : std_ulogic;
|
|
||||||
begin
|
|
||||||
tag_a := instr_tag_init;
|
|
||||||
for i in tag_number_t loop
|
|
||||||
if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_a_read_in then
|
|
||||||
tag_a.valid := gpr_a_read_valid_in;
|
|
||||||
tag_a.tag := i;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
if tag_match(tag_a, complete_in) then
|
|
||||||
tag_a.valid := '0';
|
|
||||||
end if;
|
|
||||||
tag_b := instr_tag_init;
|
|
||||||
for i in tag_number_t loop
|
|
||||||
if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_b_read_in then
|
|
||||||
tag_b.valid := gpr_b_read_valid_in;
|
|
||||||
tag_b.tag := i;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
if tag_match(tag_b, complete_in) then
|
|
||||||
tag_b.valid := '0';
|
|
||||||
end if;
|
|
||||||
tag_c := instr_tag_init;
|
|
||||||
for i in tag_number_t loop
|
|
||||||
if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_c_read_in then
|
|
||||||
tag_c.valid := gpr_c_read_valid_in;
|
|
||||||
tag_c.tag := i;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
if tag_match(tag_c, complete_in) then
|
|
||||||
tag_c.valid := '0';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
byp_a := '0';
|
|
||||||
if EX1_BYPASS and tag_match(execute_next_tag, tag_a) then
|
|
||||||
byp_a := '1';
|
|
||||||
end if;
|
|
||||||
byp_b := '0';
|
|
||||||
if EX1_BYPASS and tag_match(execute_next_tag, tag_b) then
|
|
||||||
byp_b := '1';
|
|
||||||
end if;
|
|
||||||
byp_c := '0';
|
|
||||||
if EX1_BYPASS and tag_match(execute_next_tag, tag_c) then
|
|
||||||
byp_c := '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
gpr_bypass_a <= byp_a;
|
|
||||||
gpr_bypass_b <= byp_b;
|
|
||||||
gpr_bypass_c <= byp_c;
|
|
||||||
|
|
||||||
gpr_tag_stall <= (tag_a.valid and not byp_a) or
|
|
||||||
(tag_b.valid and not byp_b) or
|
|
||||||
(tag_c.valid and not byp_c);
|
|
||||||
|
|
||||||
incr_tag := curr_tag;
|
|
||||||
instr_tag.tag <= curr_tag;
|
|
||||||
instr_tag.valid <= valid_out and not deferred;
|
|
||||||
if instr_tag.valid = '1' then
|
|
||||||
incr_tag := (curr_tag + 1) mod TAG_COUNT;
|
|
||||||
end if;
|
|
||||||
next_tag <= incr_tag;
|
|
||||||
instr_tag_out <= instr_tag;
|
|
||||||
|
|
||||||
-- CR hazards
|
|
||||||
tag_cr.tag := curr_cr_tag;
|
|
||||||
tag_cr.valid := cr_read_in and tag_regs(curr_cr_tag).wr_cr;
|
|
||||||
if tag_match(tag_cr, complete_in) then
|
|
||||||
tag_cr.valid := '0';
|
|
||||||
end if;
|
|
||||||
byp_cr := '0';
|
|
||||||
if EX1_BYPASS and tag_match(execute_next_cr_tag, tag_cr) then
|
|
||||||
byp_cr := '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
cr_bypass <= byp_cr;
|
|
||||||
cr_tag_stall <= tag_cr.valid and not byp_cr;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
control1 : process(all)
|
|
||||||
variable v_int : reg_internal_type;
|
|
||||||
variable valid_tmp : std_ulogic;
|
|
||||||
variable stall_tmp : std_ulogic;
|
|
||||||
begin
|
|
||||||
v_int := r_int;
|
|
||||||
|
|
||||||
-- asynchronous
|
|
||||||
valid_tmp := valid_in and not flush_in;
|
|
||||||
stall_tmp := '0';
|
|
||||||
|
|
||||||
if flush_in = '1' then
|
|
||||||
v_int.outstanding := 0;
|
|
||||||
elsif complete_in.valid = '1' then
|
|
||||||
v_int.outstanding := r_int.outstanding - 1;
|
|
||||||
end if;
|
|
||||||
if r_int.outstanding >= PIPELINE_DEPTH + 1 then
|
|
||||||
valid_tmp := '0';
|
|
||||||
stall_tmp := '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
if rst = '1' then
|
|
||||||
gpr_write_valid <= '0';
|
|
||||||
cr_write_valid <= '0';
|
|
||||||
v_int := reg_internal_init;
|
|
||||||
valid_tmp := '0';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Handle debugger stop
|
|
||||||
stopped_out <= '0';
|
|
||||||
if stop_mark_in = '1' and v_int.outstanding = 0 then
|
|
||||||
stopped_out <= '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- state machine to handle instructions that must be single
|
|
||||||
-- through the pipeline.
|
|
||||||
case r_int.state is
|
|
||||||
when IDLE =>
|
|
||||||
if valid_tmp = '1' then
|
|
||||||
if (sgl_pipe_in = '1') then
|
|
||||||
if v_int.outstanding /= 0 then
|
|
||||||
v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
|
|
||||||
stall_tmp := '1';
|
|
||||||
else
|
|
||||||
-- send insn out and wait on it to complete
|
|
||||||
v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
-- let it go out if there are no GPR or CR hazards
|
|
||||||
stall_tmp := gpr_tag_stall or cr_tag_stall;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when WAIT_FOR_PREV_TO_COMPLETE =>
|
|
||||||
if v_int.outstanding = 0 then
|
|
||||||
-- send insn out and wait on it to complete
|
|
||||||
v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
|
|
||||||
else
|
|
||||||
stall_tmp := '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when WAIT_FOR_CURR_TO_COMPLETE =>
|
|
||||||
if v_int.outstanding = 0 then
|
|
||||||
v_int.state := IDLE;
|
|
||||||
-- XXX Don't replicate this
|
|
||||||
if valid_tmp = '1' then
|
|
||||||
if (sgl_pipe_in = '1') then
|
|
||||||
if v_int.outstanding /= 0 then
|
|
||||||
v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
|
|
||||||
stall_tmp := '1';
|
|
||||||
else
|
|
||||||
-- send insn out and wait on it to complete
|
|
||||||
v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
-- let it go out if there are no GPR or CR hazards
|
|
||||||
stall_tmp := gpr_tag_stall or cr_tag_stall;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
stall_tmp := '1';
|
|
||||||
end if;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
if stall_tmp = '1' then
|
|
||||||
valid_tmp := '0';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
gpr_write_valid <= gpr_write_valid_in and valid_tmp;
|
|
||||||
cr_write_valid <= cr_write_in and valid_tmp;
|
|
||||||
|
|
||||||
if valid_tmp = '1' and deferred = '0' then
|
|
||||||
v_int.outstanding := v_int.outstanding + 1;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- update outputs
|
|
||||||
valid_out <= valid_tmp;
|
|
||||||
stall_out <= stall_tmp or deferred;
|
|
||||||
|
|
||||||
-- update registers
|
|
||||||
rin_int <= v_int;
|
|
||||||
end process;
|
|
||||||
end;
|
|
@ -1,325 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.utils.all;
|
|
||||||
use work.common.all;
|
|
||||||
|
|
||||||
entity core_debug is
|
|
||||||
generic (
|
|
||||||
-- Length of log buffer
|
|
||||||
LOG_LENGTH : natural := 512
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
rst : in std_logic;
|
|
||||||
|
|
||||||
dmi_addr : in std_ulogic_vector(3 downto 0);
|
|
||||||
dmi_din : in std_ulogic_vector(63 downto 0);
|
|
||||||
dmi_dout : out std_ulogic_vector(63 downto 0);
|
|
||||||
dmi_req : in std_ulogic;
|
|
||||||
dmi_wr : in std_ulogic;
|
|
||||||
dmi_ack : out std_ulogic;
|
|
||||||
|
|
||||||
-- Debug actions
|
|
||||||
core_stop : out std_ulogic;
|
|
||||||
core_rst : out std_ulogic;
|
|
||||||
icache_rst : out std_ulogic;
|
|
||||||
|
|
||||||
-- Core status inputs
|
|
||||||
terminate : in std_ulogic;
|
|
||||||
core_stopped : in std_ulogic;
|
|
||||||
nia : in std_ulogic_vector(63 downto 0);
|
|
||||||
msr : in std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
-- GSPR register read port
|
|
||||||
dbg_gpr_req : out std_ulogic;
|
|
||||||
dbg_gpr_ack : in std_ulogic;
|
|
||||||
dbg_gpr_addr : out gspr_index_t;
|
|
||||||
dbg_gpr_data : in std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
-- Core logging data
|
|
||||||
log_data : in std_ulogic_vector(255 downto 0);
|
|
||||||
log_read_addr : in std_ulogic_vector(31 downto 0);
|
|
||||||
log_read_data : out std_ulogic_vector(63 downto 0);
|
|
||||||
log_write_addr : out std_ulogic_vector(31 downto 0);
|
|
||||||
|
|
||||||
-- Misc
|
|
||||||
terminated_out : out std_ulogic
|
|
||||||
);
|
|
||||||
end core_debug;
|
|
||||||
|
|
||||||
architecture behave of core_debug is
|
|
||||||
-- DMI needs fixing... make a one clock pulse
|
|
||||||
signal dmi_req_1: std_ulogic;
|
|
||||||
|
|
||||||
-- CTRL register (direct actions, write 1 to act, read back 0)
|
|
||||||
-- bit 0 : Core stop
|
|
||||||
-- bit 1 : Core reset (doesn't clear stop)
|
|
||||||
-- bit 2 : Icache reset
|
|
||||||
-- bit 3 : Single step
|
|
||||||
-- bit 4 : Core start
|
|
||||||
constant DBG_CORE_CTRL : std_ulogic_vector(3 downto 0) := "0000";
|
|
||||||
constant DBG_CORE_CTRL_STOP : integer := 0;
|
|
||||||
constant DBG_CORE_CTRL_RESET : integer := 1;
|
|
||||||
constant DBG_CORE_CTRL_ICRESET : integer := 2;
|
|
||||||
constant DBG_CORE_CTRL_STEP : integer := 3;
|
|
||||||
constant DBG_CORE_CTRL_START : integer := 4;
|
|
||||||
|
|
||||||
-- STAT register (read only)
|
|
||||||
-- bit 0 : Core stopping (wait til bit 1 set)
|
|
||||||
-- bit 1 : Core stopped
|
|
||||||
-- bit 2 : Core terminated (clears with start or reset)
|
|
||||||
constant DBG_CORE_STAT : std_ulogic_vector(3 downto 0) := "0001";
|
|
||||||
constant DBG_CORE_STAT_STOPPING : integer := 0;
|
|
||||||
constant DBG_CORE_STAT_STOPPED : integer := 1;
|
|
||||||
constant DBG_CORE_STAT_TERM : integer := 2;
|
|
||||||
|
|
||||||
-- NIA register (read only for now)
|
|
||||||
constant DBG_CORE_NIA : std_ulogic_vector(3 downto 0) := "0010";
|
|
||||||
|
|
||||||
-- MSR (read only)
|
|
||||||
constant DBG_CORE_MSR : std_ulogic_vector(3 downto 0) := "0011";
|
|
||||||
|
|
||||||
-- GSPR register index
|
|
||||||
constant DBG_CORE_GSPR_INDEX : std_ulogic_vector(3 downto 0) := "0100";
|
|
||||||
|
|
||||||
-- GSPR register data
|
|
||||||
constant DBG_CORE_GSPR_DATA : std_ulogic_vector(3 downto 0) := "0101";
|
|
||||||
|
|
||||||
-- Log buffer address and data registers
|
|
||||||
constant DBG_CORE_LOG_ADDR : std_ulogic_vector(3 downto 0) := "0110";
|
|
||||||
constant DBG_CORE_LOG_DATA : std_ulogic_vector(3 downto 0) := "0111";
|
|
||||||
constant DBG_CORE_LOG_TRIGGER : std_ulogic_vector(3 downto 0) := "1000";
|
|
||||||
|
|
||||||
constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH);
|
|
||||||
|
|
||||||
-- Some internal wires
|
|
||||||
signal stat_reg : std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
-- Some internal latches
|
|
||||||
signal stopping : std_ulogic;
|
|
||||||
signal do_step : std_ulogic;
|
|
||||||
signal do_reset : std_ulogic;
|
|
||||||
signal do_icreset : std_ulogic;
|
|
||||||
signal terminated : std_ulogic;
|
|
||||||
signal do_gspr_rd : std_ulogic;
|
|
||||||
signal gspr_index : gspr_index_t;
|
|
||||||
|
|
||||||
signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0');
|
|
||||||
signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0');
|
|
||||||
signal log_dmi_trigger : std_ulogic_vector(63 downto 0) := (others => '0');
|
|
||||||
signal do_log_trigger : std_ulogic := '0';
|
|
||||||
signal do_dmi_log_rd : std_ulogic;
|
|
||||||
signal dmi_read_log_data : std_ulogic;
|
|
||||||
signal dmi_read_log_data_1 : std_ulogic;
|
|
||||||
signal log_trigger_delay : integer range 0 to 255 := 0;
|
|
||||||
|
|
||||||
begin
|
|
||||||
-- Single cycle register accesses on DMI except for GSPR data
|
|
||||||
dmi_ack <= dmi_req when dmi_addr /= DBG_CORE_GSPR_DATA
|
|
||||||
else dbg_gpr_ack;
|
|
||||||
dbg_gpr_req <= dmi_req when dmi_addr = DBG_CORE_GSPR_DATA
|
|
||||||
else '0';
|
|
||||||
|
|
||||||
-- Status register read composition
|
|
||||||
stat_reg <= (2 => terminated,
|
|
||||||
1 => core_stopped,
|
|
||||||
0 => stopping,
|
|
||||||
others => '0');
|
|
||||||
|
|
||||||
-- DMI read data mux
|
|
||||||
with dmi_addr select dmi_dout <=
|
|
||||||
stat_reg when DBG_CORE_STAT,
|
|
||||||
nia when DBG_CORE_NIA,
|
|
||||||
msr when DBG_CORE_MSR,
|
|
||||||
dbg_gpr_data when DBG_CORE_GSPR_DATA,
|
|
||||||
log_write_addr & log_dmi_addr when DBG_CORE_LOG_ADDR,
|
|
||||||
log_dmi_data when DBG_CORE_LOG_DATA,
|
|
||||||
log_dmi_trigger when DBG_CORE_LOG_TRIGGER,
|
|
||||||
(others => '0') when others;
|
|
||||||
|
|
||||||
-- DMI writes
|
|
||||||
reg_write: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
-- Reset the 1-cycle "do" signals
|
|
||||||
do_step <= '0';
|
|
||||||
do_reset <= '0';
|
|
||||||
do_icreset <= '0';
|
|
||||||
do_dmi_log_rd <= '0';
|
|
||||||
|
|
||||||
if (rst) then
|
|
||||||
stopping <= '0';
|
|
||||||
terminated <= '0';
|
|
||||||
log_trigger_delay <= 0;
|
|
||||||
gspr_index <= (others => '0');
|
|
||||||
else
|
|
||||||
if do_log_trigger = '1' or log_trigger_delay /= 0 then
|
|
||||||
if log_trigger_delay = 255 then
|
|
||||||
log_dmi_trigger(1) <= '1';
|
|
||||||
log_trigger_delay <= 0;
|
|
||||||
else
|
|
||||||
log_trigger_delay <= log_trigger_delay + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
-- Edge detect on dmi_req for 1-shot pulses
|
|
||||||
dmi_req_1 <= dmi_req;
|
|
||||||
if dmi_req = '1' and dmi_req_1 = '0' then
|
|
||||||
if dmi_wr = '1' then
|
|
||||||
report("DMI write to " & to_hstring(dmi_addr));
|
|
||||||
|
|
||||||
-- Control register actions
|
|
||||||
if dmi_addr = DBG_CORE_CTRL then
|
|
||||||
if dmi_din(DBG_CORE_CTRL_RESET) = '1' then
|
|
||||||
do_reset <= '1';
|
|
||||||
terminated <= '0';
|
|
||||||
end if;
|
|
||||||
if dmi_din(DBG_CORE_CTRL_STOP) = '1' then
|
|
||||||
stopping <= '1';
|
|
||||||
end if;
|
|
||||||
if dmi_din(DBG_CORE_CTRL_STEP) = '1' then
|
|
||||||
do_step <= '1';
|
|
||||||
terminated <= '0';
|
|
||||||
end if;
|
|
||||||
if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then
|
|
||||||
do_icreset <= '1';
|
|
||||||
end if;
|
|
||||||
if dmi_din(DBG_CORE_CTRL_START) = '1' then
|
|
||||||
stopping <= '0';
|
|
||||||
terminated <= '0';
|
|
||||||
end if;
|
|
||||||
elsif dmi_addr = DBG_CORE_GSPR_INDEX then
|
|
||||||
gspr_index <= dmi_din(gspr_index_t'left downto 0);
|
|
||||||
elsif dmi_addr = DBG_CORE_LOG_ADDR then
|
|
||||||
log_dmi_addr <= dmi_din(31 downto 0);
|
|
||||||
do_dmi_log_rd <= '1';
|
|
||||||
elsif dmi_addr = DBG_CORE_LOG_TRIGGER then
|
|
||||||
log_dmi_trigger <= dmi_din;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
report("DMI read from " & to_string(dmi_addr));
|
|
||||||
end if;
|
|
||||||
|
|
||||||
elsif dmi_read_log_data = '0' and dmi_read_log_data_1 = '1' then
|
|
||||||
-- Increment log_dmi_addr after the end of a read from DBG_CORE_LOG_DATA
|
|
||||||
log_dmi_addr(LOG_INDEX_BITS + 1 downto 0) <=
|
|
||||||
std_ulogic_vector(unsigned(log_dmi_addr(LOG_INDEX_BITS+1 downto 0)) + 1);
|
|
||||||
do_dmi_log_rd <= '1';
|
|
||||||
end if;
|
|
||||||
dmi_read_log_data_1 <= dmi_read_log_data;
|
|
||||||
if dmi_req = '1' and dmi_addr = DBG_CORE_LOG_DATA then
|
|
||||||
dmi_read_log_data <= '1';
|
|
||||||
else
|
|
||||||
dmi_read_log_data <= '0';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Set core stop on terminate. We'll be stopping some time *after*
|
|
||||||
-- the offending instruction, at least until we can do back flushes
|
|
||||||
-- that preserve NIA which we can't just yet.
|
|
||||||
if terminate = '1' then
|
|
||||||
stopping <= '1';
|
|
||||||
terminated <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dbg_gpr_addr <= gspr_index;
|
|
||||||
|
|
||||||
-- Core control signals generated by the debug module
|
|
||||||
core_stop <= stopping and not do_step;
|
|
||||||
core_rst <= do_reset;
|
|
||||||
icache_rst <= do_icreset;
|
|
||||||
terminated_out <= terminated;
|
|
||||||
|
|
||||||
-- Logging RAM
|
|
||||||
maybe_log: if LOG_LENGTH > 0 generate
|
|
||||||
subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0);
|
|
||||||
type log_array_t is array(0 to LOG_LENGTH - 1) of std_ulogic_vector(255 downto 0);
|
|
||||||
signal log_array : log_array_t;
|
|
||||||
signal log_rd_ptr : log_ptr_t;
|
|
||||||
signal log_wr_ptr : log_ptr_t;
|
|
||||||
signal log_toggle : std_ulogic;
|
|
||||||
signal log_wr_enable : std_ulogic;
|
|
||||||
signal log_rd_ptr_latched : log_ptr_t;
|
|
||||||
signal log_rd : std_ulogic_vector(255 downto 0);
|
|
||||||
signal log_dmi_reading : std_ulogic;
|
|
||||||
signal log_dmi_read_done : std_ulogic;
|
|
||||||
|
|
||||||
function select_dword(data : std_ulogic_vector(255 downto 0);
|
|
||||||
addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is
|
|
||||||
variable firstbit : integer;
|
|
||||||
begin
|
|
||||||
firstbit := to_integer(unsigned(addr(1 downto 0))) * 64;
|
|
||||||
return data(firstbit + 63 downto firstbit);
|
|
||||||
end;
|
|
||||||
|
|
||||||
attribute ram_style : string;
|
|
||||||
attribute ram_style of log_array : signal is "block";
|
|
||||||
attribute ram_decomp : string;
|
|
||||||
attribute ram_decomp of log_array : signal is "power";
|
|
||||||
|
|
||||||
begin
|
|
||||||
-- Use MSB of read addresses to stop the logging
|
|
||||||
log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31) or log_dmi_trigger(1));
|
|
||||||
|
|
||||||
log_ram: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if log_wr_enable = '1' then
|
|
||||||
log_array(to_integer(log_wr_ptr)) <= log_data;
|
|
||||||
end if;
|
|
||||||
log_rd <= log_array(to_integer(log_rd_ptr_latched));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
|
|
||||||
log_buffer: process(clk)
|
|
||||||
variable b : integer;
|
|
||||||
variable data : std_ulogic_vector(255 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
log_wr_ptr <= (others => '0');
|
|
||||||
log_toggle <= '0';
|
|
||||||
elsif log_wr_enable = '1' then
|
|
||||||
if log_wr_ptr = to_unsigned(LOG_LENGTH - 1, LOG_INDEX_BITS) then
|
|
||||||
log_toggle <= not log_toggle;
|
|
||||||
end if;
|
|
||||||
log_wr_ptr <= log_wr_ptr + 1;
|
|
||||||
end if;
|
|
||||||
if do_dmi_log_rd = '1' then
|
|
||||||
log_rd_ptr_latched <= unsigned(log_dmi_addr(LOG_INDEX_BITS + 1 downto 2));
|
|
||||||
else
|
|
||||||
log_rd_ptr_latched <= unsigned(log_read_addr(LOG_INDEX_BITS + 1 downto 2));
|
|
||||||
end if;
|
|
||||||
if log_dmi_read_done = '1' then
|
|
||||||
log_dmi_data <= select_dword(log_rd, log_dmi_addr);
|
|
||||||
else
|
|
||||||
log_read_data <= select_dword(log_rd, log_read_addr);
|
|
||||||
end if;
|
|
||||||
log_dmi_read_done <= log_dmi_reading;
|
|
||||||
log_dmi_reading <= do_dmi_log_rd;
|
|
||||||
do_log_trigger <= '0';
|
|
||||||
if log_data(42) = log_dmi_trigger(63) and
|
|
||||||
log_data(41 downto 0) = log_dmi_trigger(43 downto 2) and
|
|
||||||
log_dmi_trigger(0) = '1' then
|
|
||||||
do_log_trigger <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr);
|
|
||||||
log_write_addr(LOG_INDEX_BITS) <= '1';
|
|
||||||
log_write_addr(31 downto LOG_INDEX_BITS + 1) <= (others => '0');
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
no_log: if LOG_LENGTH = 0 generate
|
|
||||||
begin
|
|
||||||
log_read_data <= (others => '0');
|
|
||||||
log_write_addr <= x"00000001";
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
end behave;
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
use work.utils.all;
|
|
||||||
|
|
||||||
entity core_dram_tb is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : natural := (384*1024);
|
|
||||||
MAIN_RAM_FILE : string := "main_ram.bin";
|
|
||||||
DRAM_INIT_FILE : string := "";
|
|
||||||
DRAM_INIT_SIZE : natural := 16#c000#
|
|
||||||
);
|
|
||||||
end core_dram_tb;
|
|
||||||
|
|
||||||
architecture behave of core_dram_tb is
|
|
||||||
signal clk, rst: std_logic;
|
|
||||||
signal system_clk, soc_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- testbench signals
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
|
|
||||||
-- Sim DRAM
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic := '1';
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
signal fl_hold_n : std_logic;
|
|
||||||
signal fl_wp_n : std_logic;
|
|
||||||
signal fl_mosi : std_logic;
|
|
||||||
signal fl_miso : std_logic;
|
|
||||||
|
|
||||||
-- ROM size
|
|
||||||
function get_rom_size return natural is
|
|
||||||
begin
|
|
||||||
if MEMORY_SIZE = 0 then
|
|
||||||
return DRAM_INIT_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant ROM_SIZE : natural := get_rom_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
SIM => true,
|
|
||||||
MEMORY_SIZE => MEMORY_SIZE,
|
|
||||||
RAM_INIT_FILE => MAIN_RAM_FILE,
|
|
||||||
HAS_DRAM => true,
|
|
||||||
DRAM_SIZE => 256 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => ROM_SIZE,
|
|
||||||
CLK_FREQ => 100000000,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => 0
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
rst => soc_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
flash: entity work.s25fl128s
|
|
||||||
generic map (
|
|
||||||
TimingModel => "S25FL128SAGNFI000_R_30pF",
|
|
||||||
LongTimming => false,
|
|
||||||
tdevice_PU => 10 ns,
|
|
||||||
tdevice_PP256 => 100 ns,
|
|
||||||
tdevice_PP512 => 100 ns,
|
|
||||||
tdevice_WRR => 100 ns,
|
|
||||||
UserPreload => TRUE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
SCK => spi_sck,
|
|
||||||
SI => fl_mosi,
|
|
||||||
CSNeg => spi_cs_n,
|
|
||||||
HOLDNeg => fl_hold_n,
|
|
||||||
WPNeg => fl_wp_n,
|
|
||||||
RSTNeg => '1',
|
|
||||||
SO => fl_miso
|
|
||||||
);
|
|
||||||
|
|
||||||
fl_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
fl_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
fl_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
fl_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else '1' when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
|
|
||||||
spi_sdat_i(0) <= fl_mosi;
|
|
||||||
spi_sdat_i(1) <= fl_miso;
|
|
||||||
spi_sdat_i(2) <= fl_wp_n;
|
|
||||||
spi_sdat_i(3) <= fl_hold_n;
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 1,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => DRAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => ROM_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => clk,
|
|
||||||
rst => rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => soc_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_ext_io_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init
|
|
||||||
);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
rst_process: process
|
|
||||||
begin
|
|
||||||
rst <= '1';
|
|
||||||
wait for 10*clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
jtag: entity work.sim_jtag;
|
|
||||||
|
|
||||||
end;
|
|
@ -1,97 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity core_flash_tb is
|
|
||||||
end core_flash_tb;
|
|
||||||
|
|
||||||
architecture behave of core_flash_tb is
|
|
||||||
signal clk, rst: std_logic;
|
|
||||||
|
|
||||||
-- testbench signals
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic := '1';
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
signal fl_hold_n : std_logic;
|
|
||||||
signal fl_wp_n : std_logic;
|
|
||||||
signal fl_mosi : std_logic;
|
|
||||||
signal fl_miso : std_logic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
SIM => true,
|
|
||||||
MEMORY_SIZE => (384*1024),
|
|
||||||
RAM_INIT_FILE => "main_ram.bin",
|
|
||||||
CLK_FREQ => 100000000,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => 0
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
rst => rst,
|
|
||||||
system_clk => clk,
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i
|
|
||||||
);
|
|
||||||
|
|
||||||
flash: entity work.s25fl128s
|
|
||||||
generic map (
|
|
||||||
TimingModel => "S25FL128SAGNFI000_R_30pF",
|
|
||||||
LongTimming => false,
|
|
||||||
tdevice_PU => 10 ns,
|
|
||||||
tdevice_PP256 => 100 ns,
|
|
||||||
tdevice_PP512 => 100 ns,
|
|
||||||
tdevice_WRR => 100 ns
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
SCK => spi_sck,
|
|
||||||
SI => fl_mosi,
|
|
||||||
CSNeg => spi_cs_n,
|
|
||||||
HOLDNeg => fl_hold_n,
|
|
||||||
WPNeg => fl_wp_n,
|
|
||||||
RSTNeg => '1',
|
|
||||||
SO => fl_miso
|
|
||||||
);
|
|
||||||
|
|
||||||
fl_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
fl_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
fl_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
fl_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else '1' when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
|
|
||||||
spi_sdat_i(0) <= fl_mosi;
|
|
||||||
spi_sdat_i(1) <= fl_miso;
|
|
||||||
spi_sdat_i(2) <= fl_wp_n;
|
|
||||||
spi_sdat_i(3) <= fl_hold_n;
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
rst_process: process
|
|
||||||
begin
|
|
||||||
rst <= '1';
|
|
||||||
wait for 10*clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
jtag: entity work.sim_jtag;
|
|
||||||
|
|
||||||
end;
|
|
@ -1,136 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.helpers.all;
|
|
||||||
|
|
||||||
entity bit_counter is
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
rs : in std_ulogic_vector(63 downto 0);
|
|
||||||
count_right : in std_ulogic;
|
|
||||||
do_popcnt : in std_ulogic;
|
|
||||||
is_32bit : in std_ulogic;
|
|
||||||
datalen : in std_ulogic_vector(3 downto 0);
|
|
||||||
result : out std_ulogic_vector(63 downto 0)
|
|
||||||
);
|
|
||||||
end entity bit_counter;
|
|
||||||
|
|
||||||
architecture behaviour of bit_counter is
|
|
||||||
-- signals for count-leading/trailing-zeroes
|
|
||||||
signal inp : std_ulogic_vector(63 downto 0);
|
|
||||||
signal inp_r : std_ulogic_vector(63 downto 0);
|
|
||||||
signal sum : std_ulogic_vector(64 downto 0);
|
|
||||||
signal sum_r : std_ulogic_vector(64 downto 0);
|
|
||||||
signal onehot : std_ulogic_vector(63 downto 0);
|
|
||||||
signal edge : std_ulogic_vector(63 downto 0);
|
|
||||||
signal bitnum : std_ulogic_vector(5 downto 0);
|
|
||||||
signal cntz : std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
-- signals for popcnt
|
|
||||||
signal dlen_r : std_ulogic_vector(3 downto 0);
|
|
||||||
signal pcnt_r : std_ulogic;
|
|
||||||
subtype twobit is unsigned(1 downto 0);
|
|
||||||
type twobit32 is array(0 to 31) of twobit;
|
|
||||||
signal pc2 : twobit32;
|
|
||||||
subtype threebit is unsigned(2 downto 0);
|
|
||||||
type threebit16 is array(0 to 15) of threebit;
|
|
||||||
signal pc4 : threebit16;
|
|
||||||
subtype fourbit is unsigned(3 downto 0);
|
|
||||||
type fourbit8 is array(0 to 7) of fourbit;
|
|
||||||
signal pc8 : fourbit8;
|
|
||||||
signal pc8_r : fourbit8;
|
|
||||||
subtype sixbit is unsigned(5 downto 0);
|
|
||||||
type sixbit2 is array(0 to 1) of sixbit;
|
|
||||||
signal pc32 : sixbit2;
|
|
||||||
signal popcnt : std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
countzero_r: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
inp_r <= inp;
|
|
||||||
sum_r <= sum;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
countzero: process(all)
|
|
||||||
variable bitnum_e, bitnum_o : std_ulogic_vector(5 downto 0);
|
|
||||||
begin
|
|
||||||
if is_32bit = '0' then
|
|
||||||
if count_right = '0' then
|
|
||||||
inp <= bit_reverse(rs);
|
|
||||||
else
|
|
||||||
inp <= rs;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
inp(63 downto 32) <= x"FFFFFFFF";
|
|
||||||
if count_right = '0' then
|
|
||||||
inp(31 downto 0) <= bit_reverse(rs(31 downto 0));
|
|
||||||
else
|
|
||||||
inp(31 downto 0) <= rs(31 downto 0);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
sum <= std_ulogic_vector(unsigned('0' & not inp) + 1);
|
|
||||||
|
|
||||||
-- The following occurs after a clock edge
|
|
||||||
edge <= sum_r(63 downto 0) or inp_r;
|
|
||||||
bitnum_e := edgelocation(edge, 6);
|
|
||||||
onehot <= sum_r(63 downto 0) and inp_r;
|
|
||||||
bitnum_o := bit_number(onehot);
|
|
||||||
bitnum(5 downto 2) <= bitnum_e(5 downto 2);
|
|
||||||
bitnum(1 downto 0) <= bitnum_o(1 downto 0);
|
|
||||||
|
|
||||||
cntz <= 57x"0" & sum_r(64) & bitnum;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
popcnt_r: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
pc8_r(i) <= pc8(i);
|
|
||||||
end loop;
|
|
||||||
dlen_r <= datalen;
|
|
||||||
pcnt_r <= do_popcnt;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
popcnt_a: process(all)
|
|
||||||
begin
|
|
||||||
for i in 0 to 31 loop
|
|
||||||
pc2(i) <= unsigned("0" & rs(i * 2 downto i * 2)) + unsigned("0" & rs(i * 2 + 1 downto i * 2 + 1));
|
|
||||||
end loop;
|
|
||||||
for i in 0 to 15 loop
|
|
||||||
pc4(i) <= ('0' & pc2(i * 2)) + ('0' & pc2(i * 2 + 1));
|
|
||||||
end loop;
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
pc8(i) <= ('0' & pc4(i * 2)) + ('0' & pc4(i * 2 + 1));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
-- after a clock edge
|
|
||||||
for i in 0 to 1 loop
|
|
||||||
pc32(i) <= ("00" & pc8_r(i * 4)) + ("00" & pc8_r(i * 4 + 1)) +
|
|
||||||
("00" & pc8_r(i * 4 + 2)) + ("00" & pc8_r(i * 4 + 3));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
popcnt <= (others => '0');
|
|
||||||
if dlen_r(3 downto 2) = "00" then
|
|
||||||
-- popcntb
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
popcnt(i * 8 + 3 downto i * 8) <= std_ulogic_vector(pc8_r(i));
|
|
||||||
end loop;
|
|
||||||
elsif dlen_r(3) = '0' then
|
|
||||||
-- popcntw
|
|
||||||
for i in 0 to 1 loop
|
|
||||||
popcnt(i * 32 + 5 downto i * 32) <= std_ulogic_vector(pc32(i));
|
|
||||||
end loop;
|
|
||||||
else
|
|
||||||
popcnt(6 downto 0) <= std_ulogic_vector(('0' & pc32(0)) + ('0' & pc32(1)));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
result <= cntz when pcnt_r = '0' else popcnt;
|
|
||||||
|
|
||||||
end behaviour;
|
|
@ -1,118 +0,0 @@
|
|||||||
library vunit_lib;
|
|
||||||
context vunit_lib.vunit_context;
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
|
|
||||||
library osvvm;
|
|
||||||
use osvvm.RandomPkg.all;
|
|
||||||
|
|
||||||
entity countbits_tb is
|
|
||||||
generic (runner_cfg : string := runner_cfg_default);
|
|
||||||
end countbits_tb;
|
|
||||||
|
|
||||||
architecture behave of countbits_tb is
|
|
||||||
constant clk_period: time := 10 ns;
|
|
||||||
signal rs: std_ulogic_vector(63 downto 0);
|
|
||||||
signal is_32bit, count_right: std_ulogic := '0';
|
|
||||||
signal res: std_ulogic_vector(63 downto 0);
|
|
||||||
signal clk: std_ulogic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
bitcounter_0: entity work.bit_counter
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
rs => rs,
|
|
||||||
result => res,
|
|
||||||
count_right => count_right,
|
|
||||||
is_32bit => is_32bit,
|
|
||||||
do_popcnt => '0',
|
|
||||||
datalen => "0000"
|
|
||||||
);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
stim_process: process
|
|
||||||
variable r: std_ulogic_vector(63 downto 0);
|
|
||||||
variable rnd : RandomPType;
|
|
||||||
begin
|
|
||||||
rnd.InitSeed(stim_process'path_name);
|
|
||||||
|
|
||||||
test_runner_setup(runner, runner_cfg);
|
|
||||||
|
|
||||||
while test_suite loop
|
|
||||||
if run("Test with input = 0") then
|
|
||||||
rs <= (others => '0');
|
|
||||||
is_32bit <= '0';
|
|
||||||
count_right <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#40#, result("for cntlzd"));
|
|
||||||
count_right <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#40#, result("for cnttzd"));
|
|
||||||
is_32bit <= '1';
|
|
||||||
count_right <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#20#, result("for cntlzw"));
|
|
||||||
count_right <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#20#, result("for cnttzw"));
|
|
||||||
|
|
||||||
elsif run("Test cntlzd/w") then
|
|
||||||
count_right <= '0';
|
|
||||||
for j in 0 to 100 loop
|
|
||||||
r := rnd.RandSlv(64);
|
|
||||||
r(63) := '1';
|
|
||||||
for i in 0 to 63 loop
|
|
||||||
rs <= r;
|
|
||||||
is_32bit <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, i, result("for cntlzd " & to_hstring(rs)));
|
|
||||||
rs <= r(31 downto 0) & r(63 downto 32);
|
|
||||||
is_32bit <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
if i < 32 then
|
|
||||||
check_equal(res, i, result("for cntlzw " & to_hstring(rs)));
|
|
||||||
else
|
|
||||||
check_equal(res, 32, result("for cntlzw " & to_hstring(rs)));
|
|
||||||
end if;
|
|
||||||
r := '0' & r(63 downto 1);
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test cnttzd/w") then
|
|
||||||
count_right <= '1';
|
|
||||||
for j in 0 to 100 loop
|
|
||||||
r := rnd.RandSlv(64);
|
|
||||||
r(0) := '1';
|
|
||||||
for i in 0 to 63 loop
|
|
||||||
rs <= r;
|
|
||||||
is_32bit <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, i, result("for cnttzd " & to_hstring(rs)));
|
|
||||||
is_32bit <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
if i < 32 then
|
|
||||||
check_equal(res, i, result("for cnttzw " & to_hstring(rs)));
|
|
||||||
else
|
|
||||||
check_equal(res, 32, result("for cnttzw " & to_hstring(rs)));
|
|
||||||
end if;
|
|
||||||
r := r(62 downto 0) & '0';
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
test_runner_cleanup(runner);
|
|
||||||
end process;
|
|
||||||
end behave;
|
|
File diff suppressed because it is too large
Load Diff
@ -1,138 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity dcache_tb is
|
|
||||||
end dcache_tb;
|
|
||||||
|
|
||||||
architecture behave of dcache_tb is
|
|
||||||
signal clk : std_ulogic;
|
|
||||||
signal rst : std_ulogic;
|
|
||||||
|
|
||||||
signal d_in : Loadstore1ToDcacheType;
|
|
||||||
signal d_out : DcacheToLoadstore1Type;
|
|
||||||
|
|
||||||
signal m_in : MmuToDcacheType;
|
|
||||||
signal m_out : DcacheToMmuType;
|
|
||||||
|
|
||||||
signal wb_bram_in : wishbone_master_out;
|
|
||||||
signal wb_bram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
begin
|
|
||||||
dcache0: entity work.dcache
|
|
||||||
generic map(
|
|
||||||
LINE_SIZE => 64,
|
|
||||||
NUM_LINES => 4
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
d_in => d_in,
|
|
||||||
d_out => d_out,
|
|
||||||
m_in => m_in,
|
|
||||||
m_out => m_out,
|
|
||||||
wishbone_out => wb_bram_in,
|
|
||||||
wishbone_in => wb_bram_out
|
|
||||||
);
|
|
||||||
|
|
||||||
-- BRAM Memory slave
|
|
||||||
bram0: entity work.wishbone_bram_wrapper
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => 1024,
|
|
||||||
RAM_INIT_FILE => "icache_test.bin"
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
wishbone_in => wb_bram_in,
|
|
||||||
wishbone_out => wb_bram_out
|
|
||||||
);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
rst_process: process
|
|
||||||
begin
|
|
||||||
rst <= '1';
|
|
||||||
wait for 2*clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
stim: process
|
|
||||||
begin
|
|
||||||
-- Clear stuff
|
|
||||||
d_in.valid <= '0';
|
|
||||||
d_in.load <= '0';
|
|
||||||
d_in.nc <= '0';
|
|
||||||
d_in.addr <= (others => '0');
|
|
||||||
d_in.data <= (others => '0');
|
|
||||||
m_in.valid <= '0';
|
|
||||||
m_in.addr <= (others => '0');
|
|
||||||
m_in.pte <= (others => '0');
|
|
||||||
|
|
||||||
wait for 4*clk_period;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
-- Cacheable read of address 4
|
|
||||||
d_in.load <= '1';
|
|
||||||
d_in.nc <= '0';
|
|
||||||
d_in.addr <= x"0000000000000004";
|
|
||||||
d_in.valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
d_in.valid <= '0';
|
|
||||||
|
|
||||||
wait until rising_edge(clk) and d_out.valid = '1';
|
|
||||||
assert d_out.data = x"0000000100000000"
|
|
||||||
report "data @" & to_hstring(d_in.addr) &
|
|
||||||
"=" & to_hstring(d_out.data) &
|
|
||||||
" expected 0000000100000000"
|
|
||||||
severity failure;
|
|
||||||
-- wait for clk_period;
|
|
||||||
|
|
||||||
-- Cacheable read of address 30
|
|
||||||
d_in.load <= '1';
|
|
||||||
d_in.nc <= '0';
|
|
||||||
d_in.addr <= x"0000000000000030";
|
|
||||||
d_in.valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
d_in.valid <= '0';
|
|
||||||
|
|
||||||
wait until rising_edge(clk) and d_out.valid = '1';
|
|
||||||
assert d_out.data = x"0000000D0000000C"
|
|
||||||
report "data @" & to_hstring(d_in.addr) &
|
|
||||||
"=" & to_hstring(d_out.data) &
|
|
||||||
" expected 0000000D0000000C"
|
|
||||||
severity failure;
|
|
||||||
|
|
||||||
-- Non-cacheable read of address 100
|
|
||||||
d_in.load <= '1';
|
|
||||||
d_in.nc <= '1';
|
|
||||||
d_in.addr <= x"0000000000000100";
|
|
||||||
d_in.valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
d_in.valid <= '0';
|
|
||||||
wait until rising_edge(clk) and d_out.valid = '1';
|
|
||||||
assert d_out.data = x"0000004100000040"
|
|
||||||
report "data @" & to_hstring(d_in.addr) &
|
|
||||||
"=" & to_hstring(d_out.data) &
|
|
||||||
" expected 0000004100000040"
|
|
||||||
severity failure;
|
|
||||||
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
std.env.finish;
|
|
||||||
end process;
|
|
||||||
end;
|
|
File diff suppressed because it is too large
Load Diff
@ -1,137 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.decode_types.all;
|
|
||||||
|
|
||||||
entity divider is
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
rst : in std_logic;
|
|
||||||
d_in : in Execute1ToDividerType;
|
|
||||||
d_out : out DividerToExecute1Type
|
|
||||||
);
|
|
||||||
end entity divider;
|
|
||||||
|
|
||||||
architecture behaviour of divider is
|
|
||||||
signal dend : std_ulogic_vector(128 downto 0);
|
|
||||||
signal div : unsigned(63 downto 0);
|
|
||||||
signal quot : std_ulogic_vector(63 downto 0);
|
|
||||||
signal result : std_ulogic_vector(63 downto 0);
|
|
||||||
signal sresult : std_ulogic_vector(64 downto 0);
|
|
||||||
signal oresult : std_ulogic_vector(63 downto 0);
|
|
||||||
signal running : std_ulogic;
|
|
||||||
signal count : unsigned(6 downto 0);
|
|
||||||
signal neg_result : std_ulogic;
|
|
||||||
signal is_modulus : std_ulogic;
|
|
||||||
signal is_32bit : std_ulogic;
|
|
||||||
signal extended : std_ulogic;
|
|
||||||
signal is_signed : std_ulogic;
|
|
||||||
signal overflow : std_ulogic;
|
|
||||||
signal ovf32 : std_ulogic;
|
|
||||||
signal did_ovf : std_ulogic;
|
|
||||||
begin
|
|
||||||
divider_0: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
dend <= (others => '0');
|
|
||||||
div <= (others => '0');
|
|
||||||
quot <= (others => '0');
|
|
||||||
running <= '0';
|
|
||||||
count <= "0000000";
|
|
||||||
is_32bit <= '0';
|
|
||||||
overflow <= '0';
|
|
||||||
elsif d_in.valid = '1' then
|
|
||||||
if d_in.is_extended = '1' then
|
|
||||||
dend <= '0' & d_in.dividend & x"0000000000000000";
|
|
||||||
else
|
|
||||||
dend <= '0' & x"0000000000000000" & d_in.dividend;
|
|
||||||
end if;
|
|
||||||
div <= unsigned(d_in.divisor);
|
|
||||||
quot <= (others => '0');
|
|
||||||
neg_result <= d_in.neg_result;
|
|
||||||
is_modulus <= d_in.is_modulus;
|
|
||||||
extended <= d_in.is_extended;
|
|
||||||
is_32bit <= d_in.is_32bit;
|
|
||||||
is_signed <= d_in.is_signed;
|
|
||||||
count <= "1111111";
|
|
||||||
running <= '1';
|
|
||||||
overflow <= '0';
|
|
||||||
ovf32 <= '0';
|
|
||||||
elsif running = '1' then
|
|
||||||
if count = "0111111" then
|
|
||||||
running <= '0';
|
|
||||||
end if;
|
|
||||||
overflow <= quot(63);
|
|
||||||
if dend(128) = '1' or unsigned(dend(127 downto 64)) >= div then
|
|
||||||
ovf32 <= ovf32 or quot(31);
|
|
||||||
dend <= std_ulogic_vector(unsigned(dend(127 downto 64)) - div) &
|
|
||||||
dend(63 downto 0) & '0';
|
|
||||||
quot <= quot(62 downto 0) & '1';
|
|
||||||
count <= count + 1;
|
|
||||||
elsif dend(128 downto 57) = x"000000000000000000" and count(6 downto 3) /= "0111" then
|
|
||||||
-- consume 8 bits of zeroes in one cycle
|
|
||||||
ovf32 <= or (ovf32 & quot(31 downto 24));
|
|
||||||
dend <= dend(120 downto 0) & x"00";
|
|
||||||
quot <= quot(55 downto 0) & x"00";
|
|
||||||
count <= count + 8;
|
|
||||||
else
|
|
||||||
ovf32 <= ovf32 or quot(31);
|
|
||||||
dend <= dend(127 downto 0) & '0';
|
|
||||||
quot <= quot(62 downto 0) & '0';
|
|
||||||
count <= count + 1;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
count <= "0000000";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
divider_1: process(all)
|
|
||||||
begin
|
|
||||||
if is_modulus = '1' then
|
|
||||||
result <= dend(128 downto 65);
|
|
||||||
else
|
|
||||||
result <= quot;
|
|
||||||
end if;
|
|
||||||
if neg_result = '1' then
|
|
||||||
sresult <= std_ulogic_vector(- signed('0' & result));
|
|
||||||
else
|
|
||||||
sresult <= '0' & result;
|
|
||||||
end if;
|
|
||||||
did_ovf <= '0';
|
|
||||||
if is_32bit = '0' then
|
|
||||||
did_ovf <= overflow or (is_signed and (sresult(64) xor sresult(63)));
|
|
||||||
elsif is_signed = '1' then
|
|
||||||
if ovf32 = '1' or sresult(32) /= sresult(31) then
|
|
||||||
did_ovf <= '1';
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
did_ovf <= ovf32;
|
|
||||||
end if;
|
|
||||||
if did_ovf = '1' then
|
|
||||||
oresult <= (others => '0');
|
|
||||||
elsif (is_32bit = '1') and (is_modulus = '0') then
|
|
||||||
-- 32-bit divisions set the top 32 bits of the result to 0
|
|
||||||
oresult <= x"00000000" & sresult(31 downto 0);
|
|
||||||
else
|
|
||||||
oresult <= sresult(63 downto 0);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
divider_out: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
d_out.valid <= '0';
|
|
||||||
d_out.write_reg_data <= oresult;
|
|
||||||
d_out.overflow <= did_ovf;
|
|
||||||
if count = "1000000" then
|
|
||||||
d_out.valid <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,523 +0,0 @@
|
|||||||
library vunit_lib;
|
|
||||||
context vunit_lib.vunit_context;
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.decode_types.all;
|
|
||||||
use work.common.all;
|
|
||||||
use work.ppc_fx_insns.all;
|
|
||||||
|
|
||||||
library osvvm;
|
|
||||||
use osvvm.RandomPkg.all;
|
|
||||||
|
|
||||||
entity divider_tb is
|
|
||||||
generic (runner_cfg : string := runner_cfg_default);
|
|
||||||
end divider_tb;
|
|
||||||
|
|
||||||
architecture behave of divider_tb is
|
|
||||||
signal clk : std_ulogic;
|
|
||||||
signal rst : std_ulogic;
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
|
|
||||||
signal d1 : Execute1ToDividerType;
|
|
||||||
signal d2 : DividerToExecute1Type;
|
|
||||||
begin
|
|
||||||
divider_0: entity work.divider
|
|
||||||
port map (clk => clk, rst => rst, d_in => d1, d_out => d2);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
stim_process: process
|
|
||||||
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
|
|
||||||
variable si: std_ulogic_vector(15 downto 0);
|
|
||||||
variable d128: std_ulogic_vector(127 downto 0);
|
|
||||||
variable q128: std_ulogic_vector(127 downto 0);
|
|
||||||
variable q64: std_ulogic_vector(63 downto 0);
|
|
||||||
variable rem32: std_ulogic_vector(31 downto 0);
|
|
||||||
variable rnd : RandomPType;
|
|
||||||
begin
|
|
||||||
rnd.InitSeed(stim_process'path_name);
|
|
||||||
|
|
||||||
test_runner_setup(runner, runner_cfg);
|
|
||||||
|
|
||||||
while test_suite loop
|
|
||||||
rst <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
|
|
||||||
d1.is_signed <= '0';
|
|
||||||
d1.neg_result <= '0';
|
|
||||||
d1.is_extended <= '0';
|
|
||||||
d1.is_32bit <= '0';
|
|
||||||
d1.is_modulus <= '0';
|
|
||||||
d1.valid <= '0';
|
|
||||||
|
|
||||||
if run("Test interface") then
|
|
||||||
d1.valid <= '1';
|
|
||||||
d1.dividend <= x"0000000010001000";
|
|
||||||
d1.divisor <= x"0000000000001111";
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
check_false(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
check_equal(d2.write_reg_data, 16#f001#);
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
check_false(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
check_false(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
check_equal(d2.write_reg_data, 16#f001#);
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
check_false(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
elsif run("Test divd") then
|
|
||||||
divd_loop : for dlength in 1 to 8 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
|
|
||||||
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
|
|
||||||
d1.is_signed <= '1';
|
|
||||||
d1.neg_result <= ra(63) xor rb(63);
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" and (ra /= x"8000000000000000" or rb /= x"ffffffffffffffff") then
|
|
||||||
behave_rt := ppc_divd(ra, rb);
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divd"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divdu") then
|
|
||||||
divdu_loop : for dlength in 1 to 8 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra;
|
|
||||||
d1.divisor <= rb;
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
behave_rt := ppc_divdu(ra, rb);
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divdu"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divde") then
|
|
||||||
divde_loop : for vlength in 1 to 8 loop
|
|
||||||
for dlength in 1 to vlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
|
|
||||||
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
|
|
||||||
d1.is_signed <= '1';
|
|
||||||
d1.neg_result <= ra(63) xor rb(63);
|
|
||||||
d1.is_extended <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
d128 := ra & x"0000000000000000";
|
|
||||||
q128 := std_ulogic_vector(signed(d128) / signed(rb));
|
|
||||||
if q128(127 downto 63) = x"0000000000000000" & '0' or
|
|
||||||
q128(127 downto 63) = x"ffffffffffffffff" & '1' then
|
|
||||||
behave_rt := q128(63 downto 0);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divde"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divdeu") then
|
|
||||||
divdeu_loop : for vlength in 1 to 8 loop
|
|
||||||
for dlength in 1 to vlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra;
|
|
||||||
d1.divisor <= rb;
|
|
||||||
d1.is_extended <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if unsigned(rb) > unsigned(ra) then
|
|
||||||
d128 := ra & x"0000000000000000";
|
|
||||||
q128 := std_ulogic_vector(unsigned(d128) / unsigned(rb));
|
|
||||||
behave_rt := q128(63 downto 0);
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divdeu"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divw") then
|
|
||||||
divw_loop : for dlength in 1 to 4 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
|
|
||||||
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
|
|
||||||
d1.is_signed <= '1';
|
|
||||||
d1.neg_result <= ra(63) xor rb(63);
|
|
||||||
d1.is_32bit <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" and (ra /= x"ffffffff80000000" or rb /= x"ffffffffffffffff") then
|
|
||||||
behave_rt := ppc_divw(ra, rb);
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divw"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divwu") then
|
|
||||||
divwu_loop : for dlength in 1 to 4 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra;
|
|
||||||
d1.divisor <= rb;
|
|
||||||
d1.is_32bit <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
behave_rt := ppc_divwu(ra, rb);
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divwu"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divwe") then
|
|
||||||
divwe_loop : for vlength in 1 to 4 loop
|
|
||||||
for dlength in 1 to vlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 32)) & x"00000000";
|
|
||||||
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
|
|
||||||
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
|
|
||||||
d1.is_signed <= '1';
|
|
||||||
d1.neg_result <= ra(63) xor rb(63);
|
|
||||||
d1.is_32bit <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
q64 := std_ulogic_vector(signed(ra) / signed(rb));
|
|
||||||
if q64(63 downto 31) = x"00000000" & '0' or
|
|
||||||
q64(63 downto 31) = x"ffffffff" & '1' then
|
|
||||||
behave_rt := x"00000000" & q64(31 downto 0);
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divwe"));
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test divweu") then
|
|
||||||
divweu_loop : for vlength in 1 to 4 loop
|
|
||||||
for dlength in 1 to vlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 32)) & x"00000000";
|
|
||||||
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra;
|
|
||||||
d1.divisor <= rb;
|
|
||||||
d1.is_32bit <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if unsigned(rb(31 downto 0)) > unsigned(ra(63 downto 32)) then
|
|
||||||
behave_rt := std_ulogic_vector(unsigned(ra) / unsigned(rb));
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for divweu"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test modsd") then
|
|
||||||
modsd_loop : for dlength in 1 to 8 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
|
|
||||||
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
|
|
||||||
d1.is_signed <= '1';
|
|
||||||
d1.neg_result <= ra(63);
|
|
||||||
d1.is_modulus <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
behave_rt := std_ulogic_vector(signed(ra) rem signed(rb));
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for modsd"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test modud") then
|
|
||||||
modud_loop : for dlength in 1 to 8 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra;
|
|
||||||
d1.divisor <= rb;
|
|
||||||
d1.is_modulus <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
behave_rt := std_ulogic_vector(unsigned(ra) rem unsigned(rb));
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for modud"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test modsw") then
|
|
||||||
modsw_loop : for dlength in 1 to 4 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(signed(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(signed(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra when ra(63) = '0' else std_ulogic_vector(- signed(ra));
|
|
||||||
d1.divisor <= rb when rb(63) = '0' else std_ulogic_vector(- signed(rb));
|
|
||||||
d1.is_signed <= '1';
|
|
||||||
d1.neg_result <= ra(63);
|
|
||||||
d1.is_32bit <= '1';
|
|
||||||
d1.is_modulus <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
rem32 := std_ulogic_vector(signed(ra(31 downto 0)) rem signed(rb(31 downto 0)));
|
|
||||||
if rem32(31) = '0' then
|
|
||||||
behave_rt := x"00000000" & rem32;
|
|
||||||
else
|
|
||||||
behave_rt := x"ffffffff" & rem32;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data, behave_rt, result("for modsw"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test moduw") then
|
|
||||||
moduw_loop : for dlength in 1 to 4 loop
|
|
||||||
for vlength in 1 to dlength loop
|
|
||||||
for i in 0 to 100 loop
|
|
||||||
ra := std_ulogic_vector(resize(unsigned(rnd.RandSlv(dlength * 8)), 64));
|
|
||||||
rb := std_ulogic_vector(resize(unsigned(rnd.RandSlv(vlength * 8)), 64));
|
|
||||||
|
|
||||||
d1.dividend <= ra;
|
|
||||||
d1.divisor <= rb;
|
|
||||||
d1.is_32bit <= '1';
|
|
||||||
d1.is_modulus <= '1';
|
|
||||||
d1.valid <= '1';
|
|
||||||
|
|
||||||
wait for clk_period;
|
|
||||||
|
|
||||||
d1.valid <= '0';
|
|
||||||
for j in 0 to 66 loop
|
|
||||||
wait for clk_period;
|
|
||||||
if d2.valid = '1' then
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
check_true(?? d2.valid, result("for valid"));
|
|
||||||
|
|
||||||
behave_rt := (others => '0');
|
|
||||||
if rb /= x"0000000000000000" then
|
|
||||||
behave_rt := x"00000000" & std_ulogic_vector(unsigned(ra(31 downto 0)) rem unsigned(rb(31 downto 0)));
|
|
||||||
end if;
|
|
||||||
check_equal(d2.write_reg_data(31 downto 0), behave_rt(31 downto 0), result("for moduw"));
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
test_runner_cleanup(runner);
|
|
||||||
end process;
|
|
||||||
end behave;
|
|
@ -1,31 +0,0 @@
|
|||||||
-- Dummy/empty DMI interface to make toplevel happy on unsupported FPGAs
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity dmi_dtm is
|
|
||||||
generic(ABITS : INTEGER:=8;
|
|
||||||
DBITS : INTEGER:=32);
|
|
||||||
|
|
||||||
port(sys_clk : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
|
|
||||||
dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_req : out std_ulogic;
|
|
||||||
dmi_wr : out std_ulogic;
|
|
||||||
dmi_ack : in std_ulogic
|
|
||||||
);
|
|
||||||
end entity dmi_dtm;
|
|
||||||
|
|
||||||
architecture behaviour of dmi_dtm is
|
|
||||||
begin
|
|
||||||
dmi_addr <= (others => '0');
|
|
||||||
dmi_dout <= (others => '0');
|
|
||||||
dmi_req <= '0';
|
|
||||||
dmi_wr <= '0';
|
|
||||||
end architecture behaviour;
|
|
||||||
|
|
@ -1,298 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.math_real.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity dmi_dtm is
|
|
||||||
generic(ABITS : INTEGER:=8;
|
|
||||||
DBITS : INTEGER:=64);
|
|
||||||
|
|
||||||
port(sys_clk : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
|
|
||||||
dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_req : out std_ulogic;
|
|
||||||
dmi_wr : out std_ulogic;
|
|
||||||
dmi_ack : in std_ulogic
|
|
||||||
-- dmi_err : in std_ulogic TODO: Add error response
|
|
||||||
);
|
|
||||||
end entity dmi_dtm;
|
|
||||||
|
|
||||||
architecture behaviour of dmi_dtm is
|
|
||||||
-- Signals coming out of the JTAGG block
|
|
||||||
signal jtag_reset_n : std_ulogic;
|
|
||||||
signal tdi : std_ulogic;
|
|
||||||
signal tdo : std_ulogic;
|
|
||||||
signal tck : std_ulogic;
|
|
||||||
signal jce1 : std_ulogic;
|
|
||||||
signal jshift : std_ulogic;
|
|
||||||
signal update : std_ulogic;
|
|
||||||
|
|
||||||
-- signals to match dmi_dtb_xilinx
|
|
||||||
signal jtag_reset : std_ulogic;
|
|
||||||
signal capture : std_ulogic;
|
|
||||||
signal jtag_clk : std_ulogic;
|
|
||||||
signal sel : std_ulogic;
|
|
||||||
signal shift : std_ulogic;
|
|
||||||
|
|
||||||
-- delays
|
|
||||||
signal jce1_d : std_ulogic;
|
|
||||||
constant TCK_DELAY : INTEGER := 8;
|
|
||||||
signal tck_d : std_ulogic_vector(TCK_DELAY+1 downto 1);
|
|
||||||
|
|
||||||
-- ** JTAG clock domain **
|
|
||||||
|
|
||||||
-- Shift register
|
|
||||||
signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
|
|
||||||
|
|
||||||
-- Latched request
|
|
||||||
signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
|
|
||||||
|
|
||||||
-- A request is present
|
|
||||||
signal jtag_req : std_ulogic;
|
|
||||||
|
|
||||||
-- Synchronizer for jtag_rsp (sys clk -> jtag_clk)
|
|
||||||
signal dmi_ack_0 : std_ulogic;
|
|
||||||
signal dmi_ack_1 : std_ulogic;
|
|
||||||
|
|
||||||
-- ** sys clock domain **
|
|
||||||
|
|
||||||
-- Synchronizer for jtag_req (jtag clk -> sys clk)
|
|
||||||
signal jtag_req_0 : std_ulogic;
|
|
||||||
signal jtag_req_1 : std_ulogic;
|
|
||||||
|
|
||||||
-- ** combination signals
|
|
||||||
signal jtag_bsy : std_ulogic;
|
|
||||||
signal op_valid : std_ulogic;
|
|
||||||
signal rsp_op : std_ulogic_vector(1 downto 0);
|
|
||||||
|
|
||||||
-- ** Constants **
|
|
||||||
constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant DMI_REQ_RD : std_ulogic_vector(1 downto 0) := "01";
|
|
||||||
constant DMI_REQ_WR : std_ulogic_vector(1 downto 0) := "10";
|
|
||||||
constant DMI_RSP_OK : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant DMI_RSP_BSY : std_ulogic_vector(1 downto 0) := "11";
|
|
||||||
|
|
||||||
attribute ASYNC_REG : string;
|
|
||||||
attribute ASYNC_REG of jtag_req_0: signal is "TRUE";
|
|
||||||
attribute ASYNC_REG of jtag_req_1: signal is "TRUE";
|
|
||||||
attribute ASYNC_REG of dmi_ack_0: signal is "TRUE";
|
|
||||||
attribute ASYNC_REG of dmi_ack_1: signal is "TRUE";
|
|
||||||
|
|
||||||
-- ECP5 JTAGG
|
|
||||||
component JTAGG is
|
|
||||||
generic (
|
|
||||||
ER1 : string := "ENABLED";
|
|
||||||
ER2 : string := "ENABLED"
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
JTDO1 : in std_ulogic;
|
|
||||||
JTDO2 : in std_ulogic;
|
|
||||||
JTDI : out std_ulogic;
|
|
||||||
JTCK : out std_ulogic;
|
|
||||||
JRTI1 : out std_ulogic;
|
|
||||||
JRTI2 : out std_ulogic;
|
|
||||||
JSHIFT : out std_ulogic;
|
|
||||||
JUPDATE : out std_ulogic;
|
|
||||||
JRSTN : out std_ulogic;
|
|
||||||
JCE1 : out std_ulogic;
|
|
||||||
JCE2 : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
component LUT4 is
|
|
||||||
generic (
|
|
||||||
INIT : std_logic_vector
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
A : in STD_ULOGIC;
|
|
||||||
B : in STD_ULOGIC;
|
|
||||||
C : in STD_ULOGIC;
|
|
||||||
D : in STD_ULOGIC;
|
|
||||||
Z : out STD_ULOGIC
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
jtag: JTAGG
|
|
||||||
generic map(
|
|
||||||
ER2 => "DISABLED"
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
JTDO1 => tdo,
|
|
||||||
JTDO2 => '0',
|
|
||||||
JTDI => tdi,
|
|
||||||
JTCK => tck,
|
|
||||||
JRTI1 => open,
|
|
||||||
JRTI2 => open,
|
|
||||||
JSHIFT => jshift,
|
|
||||||
JUPDATE => update,
|
|
||||||
JRSTN => jtag_reset_n,
|
|
||||||
JCE1 => jce1,
|
|
||||||
JCE2 => open
|
|
||||||
);
|
|
||||||
|
|
||||||
-- JRTI1 looks like it could be connected to SEL, but
|
|
||||||
-- in practise JRTI1 is only high briefly, not for the duration
|
|
||||||
-- of the transmission. possibly mw_debug could be modified.
|
|
||||||
-- The ecp5 is probably the only jtag device anyway.
|
|
||||||
sel <= '1';
|
|
||||||
|
|
||||||
-- TDI needs to align with TCK, we use LUT delays here.
|
|
||||||
-- From https://github.com/enjoy-digital/litex/pull/1087
|
|
||||||
tck_d(1) <= tck;
|
|
||||||
del: for i in 1 to TCK_DELAY generate
|
|
||||||
attribute keep : boolean;
|
|
||||||
attribute keep of l: label is true;
|
|
||||||
begin
|
|
||||||
l: LUT4
|
|
||||||
generic map(
|
|
||||||
INIT => b"0000_0000_0000_0010"
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
A => tck_d(i),
|
|
||||||
B => '0', C => '0', D => '0',
|
|
||||||
Z => tck_d(i+1)
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
jtag_clk <= tck_d(TCK_DELAY+1);
|
|
||||||
|
|
||||||
-- capture signal
|
|
||||||
jce1_sync : process(jtag_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(jtag_clk) then
|
|
||||||
jce1_d <= jce1;
|
|
||||||
capture <= jce1 and not jce1_d;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- latch the shift signal, otherwise
|
|
||||||
-- we miss the last shift in
|
|
||||||
-- (maybe because we are delaying tck?)
|
|
||||||
shift_sync : process(jtag_clk)
|
|
||||||
begin
|
|
||||||
if (sys_reset = '1') then
|
|
||||||
shift <= '0';
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
shift <= jshift;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
jtag_reset <= not jtag_reset_n;
|
|
||||||
|
|
||||||
-- dmi_req synchronization
|
|
||||||
dmi_req_sync : process(sys_clk)
|
|
||||||
begin
|
|
||||||
-- sys_reset is synchronous
|
|
||||||
if rising_edge(sys_clk) then
|
|
||||||
if (sys_reset = '1') then
|
|
||||||
jtag_req_0 <= '0';
|
|
||||||
jtag_req_1 <= '0';
|
|
||||||
else
|
|
||||||
jtag_req_0 <= jtag_req;
|
|
||||||
jtag_req_1 <= jtag_req_0;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
dmi_req <= jtag_req_1;
|
|
||||||
|
|
||||||
-- dmi_ack synchronization
|
|
||||||
dmi_ack_sync: process(jtag_clk, jtag_reset)
|
|
||||||
begin
|
|
||||||
-- jtag_reset is async (see comments)
|
|
||||||
if jtag_reset = '1' then
|
|
||||||
dmi_ack_0 <= '0';
|
|
||||||
dmi_ack_1 <= '0';
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
dmi_ack_0 <= dmi_ack;
|
|
||||||
dmi_ack_1 <= dmi_ack_0;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- jtag_bsy indicates whether we can start a new request, we can when
|
|
||||||
-- we aren't already processing one (jtag_req) and the synchronized ack
|
|
||||||
-- of the previous one is 0.
|
|
||||||
--
|
|
||||||
jtag_bsy <= jtag_req or dmi_ack_1;
|
|
||||||
|
|
||||||
-- decode request type in shift register
|
|
||||||
with shiftr(1 downto 0) select op_valid <=
|
|
||||||
'1' when DMI_REQ_RD,
|
|
||||||
'1' when DMI_REQ_WR,
|
|
||||||
'0' when others;
|
|
||||||
|
|
||||||
-- encode response op
|
|
||||||
rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK;
|
|
||||||
|
|
||||||
-- Some DMI out signals are directly driven from the request register
|
|
||||||
dmi_addr <= request(ABITS + DBITS + 1 downto DBITS + 2);
|
|
||||||
dmi_dout <= request(DBITS + 1 downto 2);
|
|
||||||
dmi_wr <= '1' when request(1 downto 0) = DMI_REQ_WR else '0';
|
|
||||||
|
|
||||||
-- TDO is wired to shift register bit 0
|
|
||||||
tdo <= shiftr(0);
|
|
||||||
|
|
||||||
-- Main state machine. Handles shift registers, request latch and
|
|
||||||
-- jtag_req latch. Could be split into 3 processes but it's probably
|
|
||||||
-- not worthwhile.
|
|
||||||
--
|
|
||||||
shifter: process(jtag_clk, jtag_reset, sys_reset)
|
|
||||||
begin
|
|
||||||
if jtag_reset = '1' or sys_reset = '1' then
|
|
||||||
shiftr <= (others => '0');
|
|
||||||
jtag_req <= '0';
|
|
||||||
request <= (others => '0');
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
|
|
||||||
-- Handle jtag "commands" when sel is 1
|
|
||||||
if sel = '1' then
|
|
||||||
-- Shift state, rotate the register
|
|
||||||
if shift = '1' then
|
|
||||||
shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Update state (trigger)
|
|
||||||
--
|
|
||||||
-- Latch the request if we aren't already processing one and
|
|
||||||
-- it has a valid command opcode.
|
|
||||||
--
|
|
||||||
if update = '1' and op_valid = '1' then
|
|
||||||
if jtag_bsy = '0' then
|
|
||||||
request <= shiftr;
|
|
||||||
jtag_req <= '1';
|
|
||||||
end if;
|
|
||||||
-- Set the shift register "op" to "busy". This will prevent
|
|
||||||
-- us from re-starting the command on the next update if
|
|
||||||
-- the command completes before that.
|
|
||||||
shiftr(1 downto 0) <= DMI_RSP_BSY;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Request completion.
|
|
||||||
--
|
|
||||||
-- Capture the response data for reads and clear request flag.
|
|
||||||
--
|
|
||||||
-- Note: We clear req (and thus dmi_req) here which relies on tck
|
|
||||||
-- ticking and sel set. This means we are stuck with dmi_req up if
|
|
||||||
-- the jtag interface stops. Slaves must be resilient to this.
|
|
||||||
--
|
|
||||||
if jtag_req = '1' and dmi_ack_1 = '1' then
|
|
||||||
jtag_req <= '0';
|
|
||||||
if request(1 downto 0) = DMI_REQ_RD then
|
|
||||||
request(DBITS + 1 downto 2) <= dmi_din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Capture state, grab latch content with updated status
|
|
||||||
if capture = '1' then
|
|
||||||
shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end architecture behaviour;
|
|
||||||
|
|
@ -1,250 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
entity dmi_dtm_tb is
|
|
||||||
end dmi_dtm_tb;
|
|
||||||
|
|
||||||
architecture behave of dmi_dtm_tb is
|
|
||||||
signal clk : std_ulogic;
|
|
||||||
signal rst : std_ulogic;
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
constant jclk_period : time := 30 ns;
|
|
||||||
|
|
||||||
-- DMI debug bus signals
|
|
||||||
signal dmi_addr : std_ulogic_vector(7 downto 0);
|
|
||||||
signal dmi_din : std_ulogic_vector(63 downto 0);
|
|
||||||
signal dmi_dout : std_ulogic_vector(63 downto 0);
|
|
||||||
signal dmi_req : std_ulogic;
|
|
||||||
signal dmi_wr : std_ulogic;
|
|
||||||
signal dmi_ack : std_ulogic;
|
|
||||||
|
|
||||||
-- Global JTAG signals (used by BSCANE2 inside dmi_dtm
|
|
||||||
alias j : glob_jtag_t is glob_jtag;
|
|
||||||
|
|
||||||
-- Wishbone interfaces
|
|
||||||
signal wishbone_ram_in : wishbone_slave_out;
|
|
||||||
signal wishbone_ram_out : wishbone_master_out;
|
|
||||||
|
|
||||||
begin
|
|
||||||
dtm: entity work.dmi_dtm
|
|
||||||
generic map(
|
|
||||||
ABITS => 8,
|
|
||||||
DBITS => 64
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
sys_clk => clk,
|
|
||||||
sys_reset => rst,
|
|
||||||
dmi_addr => dmi_addr,
|
|
||||||
dmi_din => dmi_din,
|
|
||||||
dmi_dout => dmi_dout,
|
|
||||||
dmi_req => dmi_req,
|
|
||||||
dmi_wr => dmi_wr,
|
|
||||||
dmi_ack => dmi_ack
|
|
||||||
);
|
|
||||||
|
|
||||||
simple_ram_0: entity work.wishbone_bram_wrapper
|
|
||||||
generic map(RAM_INIT_FILE => "main_ram.bin",
|
|
||||||
MEMORY_SIZE => 524288)
|
|
||||||
port map(clk => clk, rst => rst,
|
|
||||||
wishbone_in => wishbone_ram_out,
|
|
||||||
wishbone_out => wishbone_ram_in);
|
|
||||||
|
|
||||||
wishbone_debug_0: entity work.wishbone_debug_master
|
|
||||||
port map(clk => clk, rst => rst,
|
|
||||||
dmi_addr => dmi_addr(1 downto 0),
|
|
||||||
dmi_dout => dmi_din,
|
|
||||||
dmi_din => dmi_dout,
|
|
||||||
dmi_wr => dmi_wr,
|
|
||||||
dmi_ack => dmi_ack,
|
|
||||||
dmi_req => dmi_req,
|
|
||||||
wb_in => wishbone_ram_in,
|
|
||||||
wb_out => wishbone_ram_out);
|
|
||||||
|
|
||||||
-- system clock
|
|
||||||
sys_clk: process
|
|
||||||
begin
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period / 2;
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period / 2;
|
|
||||||
end process sys_clk;
|
|
||||||
|
|
||||||
-- system sim: just reset and wait
|
|
||||||
sys_sim: process
|
|
||||||
begin
|
|
||||||
rst <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- jtag sim process
|
|
||||||
sim_jtag: process
|
|
||||||
procedure clock(count: in INTEGER) is
|
|
||||||
begin
|
|
||||||
for i in 1 to count loop
|
|
||||||
j.tck <= '0';
|
|
||||||
wait for jclk_period/2;
|
|
||||||
j.tck <= '1';
|
|
||||||
wait for jclk_period/2;
|
|
||||||
end loop;
|
|
||||||
end procedure clock;
|
|
||||||
|
|
||||||
procedure shift_out(val: in std_ulogic_vector) is
|
|
||||||
begin
|
|
||||||
for i in 0 to val'length-1 loop
|
|
||||||
j.tdi <= val(i);
|
|
||||||
clock(1);
|
|
||||||
end loop;
|
|
||||||
end procedure shift_out;
|
|
||||||
|
|
||||||
procedure shift_in(val: out std_ulogic_vector) is
|
|
||||||
begin
|
|
||||||
for i in val'length-1 downto 0 loop
|
|
||||||
val := j.tdo & val(val'length-1 downto 1);
|
|
||||||
clock(1);
|
|
||||||
end loop;
|
|
||||||
end procedure shift_in;
|
|
||||||
|
|
||||||
procedure send_command(
|
|
||||||
addr : in std_ulogic_vector(7 downto 0);
|
|
||||||
data : in std_ulogic_vector(63 downto 0);
|
|
||||||
op : in std_ulogic_vector(1 downto 0)) is
|
|
||||||
begin
|
|
||||||
j.capture <= '1';
|
|
||||||
clock(1);
|
|
||||||
j.capture <= '0';
|
|
||||||
clock(1);
|
|
||||||
j.shift <= '1';
|
|
||||||
shift_out(op);
|
|
||||||
shift_out(data);
|
|
||||||
shift_out(addr);
|
|
||||||
j.shift <= '0';
|
|
||||||
j.update <= '1';
|
|
||||||
clock(1);
|
|
||||||
j.update <= '0';
|
|
||||||
clock(1);
|
|
||||||
end procedure send_command;
|
|
||||||
|
|
||||||
procedure read_resp(
|
|
||||||
op : out std_ulogic_vector(1 downto 0);
|
|
||||||
data : out std_ulogic_vector(63 downto 0)) is
|
|
||||||
|
|
||||||
variable addr : std_ulogic_vector(7 downto 0);
|
|
||||||
begin
|
|
||||||
j.capture <= '1';
|
|
||||||
clock(1);
|
|
||||||
j.capture <= '0';
|
|
||||||
clock(1);
|
|
||||||
j.shift <= '1';
|
|
||||||
shift_in(op);
|
|
||||||
shift_in(data);
|
|
||||||
shift_in(addr);
|
|
||||||
j.shift <= '0';
|
|
||||||
j.update <= '1';
|
|
||||||
clock(1);
|
|
||||||
j.update <= '0';
|
|
||||||
clock(1);
|
|
||||||
end procedure read_resp;
|
|
||||||
|
|
||||||
procedure dmi_write(addr : in std_ulogic_vector(7 downto 0);
|
|
||||||
data : in std_ulogic_vector(63 downto 0)) is
|
|
||||||
variable resp_op : std_ulogic_vector(1 downto 0);
|
|
||||||
variable resp_data : std_ulogic_vector(63 downto 0);
|
|
||||||
variable timeout : integer;
|
|
||||||
begin
|
|
||||||
send_command(addr, data, "10");
|
|
||||||
loop
|
|
||||||
read_resp(resp_op, resp_data);
|
|
||||||
case resp_op is
|
|
||||||
when "00" =>
|
|
||||||
return;
|
|
||||||
when "11" =>
|
|
||||||
timeout := timeout + 1;
|
|
||||||
assert timeout < 0
|
|
||||||
report "dmi_write timed out !" severity error;
|
|
||||||
when others =>
|
|
||||||
assert 0 > 1 report "dmi_write got odd status: " &
|
|
||||||
to_hstring(resp_op) severity error;
|
|
||||||
end case;
|
|
||||||
end loop;
|
|
||||||
end procedure dmi_write;
|
|
||||||
|
|
||||||
|
|
||||||
procedure dmi_read(addr : in std_ulogic_vector(7 downto 0);
|
|
||||||
data : out std_ulogic_vector(63 downto 0)) is
|
|
||||||
variable resp_op : std_ulogic_vector(1 downto 0);
|
|
||||||
variable timeout : integer;
|
|
||||||
begin
|
|
||||||
send_command(addr, (others => '0'), "01");
|
|
||||||
loop
|
|
||||||
read_resp(resp_op, data);
|
|
||||||
case resp_op is
|
|
||||||
when "00" =>
|
|
||||||
return;
|
|
||||||
when "11" =>
|
|
||||||
timeout := timeout + 1;
|
|
||||||
assert timeout < 0
|
|
||||||
report "dmi_read timed out !" severity error;
|
|
||||||
when others =>
|
|
||||||
assert 0 > 1 report "dmi_read got odd status: " &
|
|
||||||
to_hstring(resp_op) severity error;
|
|
||||||
end case;
|
|
||||||
end loop;
|
|
||||||
end procedure dmi_read;
|
|
||||||
|
|
||||||
variable data : std_ulogic_vector(63 downto 0);
|
|
||||||
begin
|
|
||||||
-- init & reset
|
|
||||||
j.reset <= '1';
|
|
||||||
j.sel <= "0000";
|
|
||||||
j.capture <= '0';
|
|
||||||
j.update <= '0';
|
|
||||||
j.shift <= '0';
|
|
||||||
j.tdi <= '0';
|
|
||||||
j.tms <= '0';
|
|
||||||
j.runtest <= '0';
|
|
||||||
clock(5);
|
|
||||||
j.reset <= '0';
|
|
||||||
clock(5);
|
|
||||||
|
|
||||||
-- select chain 2
|
|
||||||
j.sel <= "0010";
|
|
||||||
clock(1);
|
|
||||||
|
|
||||||
-- send command
|
|
||||||
dmi_read(x"00", data);
|
|
||||||
report "Read addr reg:" & to_hstring(data);
|
|
||||||
report "Writing addr reg to all 1's";
|
|
||||||
dmi_write(x"00", (others => '1'));
|
|
||||||
dmi_read(x"00", data);
|
|
||||||
report "Read addr reg:" & to_hstring(data);
|
|
||||||
|
|
||||||
report "Writing ctrl reg to all 1's";
|
|
||||||
dmi_write(x"02", (others => '1'));
|
|
||||||
dmi_read(x"02", data);
|
|
||||||
report "Read ctrl reg:" & to_hstring(data);
|
|
||||||
|
|
||||||
report "Read memory at 0...\n";
|
|
||||||
dmi_write(x"00", x"0000000000000000");
|
|
||||||
dmi_write(x"02", x"00000000000007ff");
|
|
||||||
dmi_read(x"01", data);
|
|
||||||
report "00:" & to_hstring(data);
|
|
||||||
dmi_read(x"01", data);
|
|
||||||
report "08:" & to_hstring(data);
|
|
||||||
dmi_read(x"01", data);
|
|
||||||
report "10:" & to_hstring(data);
|
|
||||||
dmi_read(x"01", data);
|
|
||||||
report "18:" & to_hstring(data);
|
|
||||||
clock(10);
|
|
||||||
std.env.finish;
|
|
||||||
end process;
|
|
||||||
end behave;
|
|
@ -1,280 +0,0 @@
|
|||||||
-- Xilinx internal JTAG to DMI interface
|
|
||||||
--
|
|
||||||
-- DMI bus
|
|
||||||
--
|
|
||||||
-- req : ____/------------\_____
|
|
||||||
-- addr: xxxx< >xxxxx
|
|
||||||
-- dout: xxxx< >xxxxx
|
|
||||||
-- wr : xxxx< >xxxxx
|
|
||||||
-- din : xxxxxxxxxxxx< >xxx
|
|
||||||
-- ack : ____________/------\___
|
|
||||||
--
|
|
||||||
-- * addr/dout set along with req, can be latched on same cycle by slave
|
|
||||||
-- * ack & din remain up until req is dropped by master, the slave must
|
|
||||||
-- provide a stable output on din on reads during that time.
|
|
||||||
-- * req remains low at until at least one sysclk after ack seen down.
|
|
||||||
--
|
|
||||||
-- JTAG (tck) DMI (sys_clk)
|
|
||||||
--
|
|
||||||
-- * jtag_req = 1
|
|
||||||
-- (jtag_req_0) *
|
|
||||||
-- (jtag_req_1) -> * dmi_req = 1 >
|
|
||||||
-- *.../...
|
|
||||||
-- * dmi_ack = 1 <
|
|
||||||
-- * (dmi_ack_0)
|
|
||||||
-- * <- (dmi_ack_1)
|
|
||||||
-- * jtag_req = 0 (and latch dmi_din)
|
|
||||||
-- (jtag_req_0) *
|
|
||||||
-- (jtag_req_1) -> * dmi_req = 0 >
|
|
||||||
-- * dmi_ack = 0 <
|
|
||||||
-- * (dmi_ack_0)
|
|
||||||
-- * <- (dmi_ack_1)
|
|
||||||
--
|
|
||||||
-- jtag_req can go back to 1 when jtag_rsp_1 is 0
|
|
||||||
--
|
|
||||||
-- Questions/TODO:
|
|
||||||
-- - I use 2 flip fops for sync, is that enough ?
|
|
||||||
-- - I treat the jtag_reset as an async reset, is that necessary ?
|
|
||||||
-- - Dbl check reset situation since we have two different resets
|
|
||||||
-- each only resetting part of the logic...
|
|
||||||
-- - Look at optionally removing the synchronizer on the ack path,
|
|
||||||
-- assuming JTAG is always slow enough that ack will have been
|
|
||||||
-- stable long enough by the time CAPTURE comes in.
|
|
||||||
-- - We could avoid the latched request by not shifting while a
|
|
||||||
-- request is in progress (and force TDO to 1 to return a busy
|
|
||||||
-- status).
|
|
||||||
--
|
|
||||||
-- WARNING: This isn't the real DMI JTAG protocol (at least not yet).
|
|
||||||
-- a command while busy will be ignored. A response of "11"
|
|
||||||
-- means the previous command is still going, try again.
|
|
||||||
-- As such We don't implement the DMI "error" status, and
|
|
||||||
-- we don't implement DTMCS yet... This may still all change
|
|
||||||
-- but for now it's easier that way as the real DMI protocol
|
|
||||||
-- requires for a command to work properly that enough TCK
|
|
||||||
-- are sent while IDLE and I'm having trouble getting that
|
|
||||||
-- working with UrJtag and the Xilinx BSCAN2 for now.
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.math_real.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
entity dmi_dtm is
|
|
||||||
generic(ABITS : INTEGER:=8;
|
|
||||||
DBITS : INTEGER:=32);
|
|
||||||
|
|
||||||
port(sys_clk : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
|
|
||||||
dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_req : out std_ulogic;
|
|
||||||
dmi_wr : out std_ulogic;
|
|
||||||
dmi_ack : in std_ulogic
|
|
||||||
-- dmi_err : in std_ulogic TODO: Add error response
|
|
||||||
);
|
|
||||||
end entity dmi_dtm;
|
|
||||||
|
|
||||||
architecture behaviour of dmi_dtm is
|
|
||||||
|
|
||||||
-- Signals coming out of the BSCANE2 block
|
|
||||||
signal jtag_reset : std_ulogic;
|
|
||||||
signal capture : std_ulogic;
|
|
||||||
signal update : std_ulogic;
|
|
||||||
signal drck : std_ulogic;
|
|
||||||
signal jtag_clk : std_ulogic;
|
|
||||||
signal sel : std_ulogic;
|
|
||||||
signal shift : std_ulogic;
|
|
||||||
signal tdi : std_ulogic;
|
|
||||||
signal tdo : std_ulogic;
|
|
||||||
signal tck : std_ulogic;
|
|
||||||
|
|
||||||
-- ** JTAG clock domain **
|
|
||||||
|
|
||||||
-- Shift register
|
|
||||||
signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
|
|
||||||
|
|
||||||
-- Latched request
|
|
||||||
signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
|
|
||||||
|
|
||||||
-- A request is present
|
|
||||||
signal jtag_req : std_ulogic;
|
|
||||||
|
|
||||||
-- Synchronizer for jtag_rsp (sys clk -> jtag_clk)
|
|
||||||
signal dmi_ack_0 : std_ulogic;
|
|
||||||
signal dmi_ack_1 : std_ulogic;
|
|
||||||
|
|
||||||
-- ** sys clock domain **
|
|
||||||
|
|
||||||
-- Synchronizer for jtag_req (jtag clk -> sys clk)
|
|
||||||
signal jtag_req_0 : std_ulogic;
|
|
||||||
signal jtag_req_1 : std_ulogic;
|
|
||||||
|
|
||||||
-- ** combination signals
|
|
||||||
signal jtag_bsy : std_ulogic;
|
|
||||||
signal op_valid : std_ulogic;
|
|
||||||
signal rsp_op : std_ulogic_vector(1 downto 0);
|
|
||||||
|
|
||||||
-- ** Constants **
|
|
||||||
constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant DMI_REQ_RD : std_ulogic_vector(1 downto 0) := "01";
|
|
||||||
constant DMI_REQ_WR : std_ulogic_vector(1 downto 0) := "10";
|
|
||||||
constant DMI_RSP_OK : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant DMI_RSP_BSY : std_ulogic_vector(1 downto 0) := "11";
|
|
||||||
|
|
||||||
attribute ASYNC_REG : string;
|
|
||||||
attribute ASYNC_REG of jtag_req_0: signal is "TRUE";
|
|
||||||
attribute ASYNC_REG of jtag_req_1: signal is "TRUE";
|
|
||||||
attribute ASYNC_REG of dmi_ack_0: signal is "TRUE";
|
|
||||||
attribute ASYNC_REG of dmi_ack_1: signal is "TRUE";
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Implement the Xilinx bscan2 for series 7 devices (TODO: use PoC to
|
|
||||||
-- wrap this if compatibility is required with older devices).
|
|
||||||
bscan : BSCANE2
|
|
||||||
generic map (
|
|
||||||
JTAG_CHAIN => 2
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
CAPTURE => capture,
|
|
||||||
DRCK => drck,
|
|
||||||
RESET => jtag_reset,
|
|
||||||
RUNTEST => open,
|
|
||||||
SEL => sel,
|
|
||||||
SHIFT => shift,
|
|
||||||
TCK => tck,
|
|
||||||
TDI => tdi,
|
|
||||||
TMS => open,
|
|
||||||
UPDATE => update,
|
|
||||||
TDO => tdo
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Some examples out there suggest buffering the clock so it's
|
|
||||||
-- treated as a proper clock net. This is probably needed when using
|
|
||||||
-- drck (the gated clock) but I'm using the real tck here to avoid
|
|
||||||
-- missing the update phase so maybe not...
|
|
||||||
--
|
|
||||||
clkbuf : BUFG
|
|
||||||
port map (
|
|
||||||
-- I => drck,
|
|
||||||
I => tck,
|
|
||||||
O => jtag_clk
|
|
||||||
);
|
|
||||||
|
|
||||||
-- dmi_req synchronization
|
|
||||||
dmi_req_sync : process(sys_clk)
|
|
||||||
begin
|
|
||||||
-- sys_reset is synchronous
|
|
||||||
if rising_edge(sys_clk) then
|
|
||||||
if (sys_reset = '1') then
|
|
||||||
jtag_req_0 <= '0';
|
|
||||||
jtag_req_1 <= '0';
|
|
||||||
else
|
|
||||||
jtag_req_0 <= jtag_req;
|
|
||||||
jtag_req_1 <= jtag_req_0;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
dmi_req <= jtag_req_1;
|
|
||||||
|
|
||||||
-- dmi_ack synchronization
|
|
||||||
dmi_ack_sync: process(jtag_clk, jtag_reset)
|
|
||||||
begin
|
|
||||||
-- jtag_reset is async (see comments)
|
|
||||||
if jtag_reset = '1' then
|
|
||||||
dmi_ack_0 <= '0';
|
|
||||||
dmi_ack_1 <= '0';
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
dmi_ack_0 <= dmi_ack;
|
|
||||||
dmi_ack_1 <= dmi_ack_0;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- jtag_bsy indicates whether we can start a new request, we can when
|
|
||||||
-- we aren't already processing one (jtag_req) and the synchronized ack
|
|
||||||
-- of the previous one is 0.
|
|
||||||
--
|
|
||||||
jtag_bsy <= jtag_req or dmi_ack_1;
|
|
||||||
|
|
||||||
-- decode request type in shift register
|
|
||||||
with shiftr(1 downto 0) select op_valid <=
|
|
||||||
'1' when DMI_REQ_RD,
|
|
||||||
'1' when DMI_REQ_WR,
|
|
||||||
'0' when others;
|
|
||||||
|
|
||||||
-- encode response op
|
|
||||||
rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK;
|
|
||||||
|
|
||||||
-- Some DMI out signals are directly driven from the request register
|
|
||||||
dmi_addr <= request(ABITS + DBITS + 1 downto DBITS + 2);
|
|
||||||
dmi_dout <= request(DBITS + 1 downto 2);
|
|
||||||
dmi_wr <= '1' when request(1 downto 0) = DMI_REQ_WR else '0';
|
|
||||||
|
|
||||||
-- TDO is wired to shift register bit 0
|
|
||||||
tdo <= shiftr(0);
|
|
||||||
|
|
||||||
-- Main state machine. Handles shift registers, request latch and
|
|
||||||
-- jtag_req latch. Could be split into 3 processes but it's probably
|
|
||||||
-- not worthwhile.
|
|
||||||
--
|
|
||||||
shifter: process(jtag_clk, jtag_reset, sys_reset)
|
|
||||||
begin
|
|
||||||
if jtag_reset = '1' or sys_reset = '1' then
|
|
||||||
shiftr <= (others => '0');
|
|
||||||
jtag_req <= '0';
|
|
||||||
request <= (others => '0');
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
|
|
||||||
-- Handle jtag "commands" when sel is 1
|
|
||||||
if sel = '1' then
|
|
||||||
-- Shift state, rotate the register
|
|
||||||
if shift = '1' then
|
|
||||||
shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Update state (trigger)
|
|
||||||
--
|
|
||||||
-- Latch the request if we aren't already processing one and
|
|
||||||
-- it has a valid command opcode.
|
|
||||||
--
|
|
||||||
if update = '1' and op_valid = '1' then
|
|
||||||
if jtag_bsy = '0' then
|
|
||||||
request <= shiftr;
|
|
||||||
jtag_req <= '1';
|
|
||||||
end if;
|
|
||||||
-- Set the shift register "op" to "busy". This will prevent
|
|
||||||
-- us from re-starting the command on the next update if
|
|
||||||
-- the command completes before that.
|
|
||||||
shiftr(1 downto 0) <= DMI_RSP_BSY;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Request completion.
|
|
||||||
--
|
|
||||||
-- Capture the response data for reads and clear request flag.
|
|
||||||
--
|
|
||||||
-- Note: We clear req (and thus dmi_req) here which relies on tck
|
|
||||||
-- ticking and sel set. This means we are stuck with dmi_req up if
|
|
||||||
-- the jtag interface stops. Slaves must be resilient to this.
|
|
||||||
--
|
|
||||||
if jtag_req = '1' and dmi_ack_1 = '1' then
|
|
||||||
jtag_req <= '0';
|
|
||||||
if request(1 downto 0) = DMI_REQ_RD then
|
|
||||||
request(DBITS + 1 downto 2) <= dmi_din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Capture state, grab latch content with updated status
|
|
||||||
if capture = '1' then
|
|
||||||
shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end architecture behaviour;
|
|
||||||
|
|
@ -1,338 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity dram_tb is
|
|
||||||
generic (
|
|
||||||
DRAM_INIT_FILE : string := "";
|
|
||||||
DRAM_INIT_SIZE : natural := 0
|
|
||||||
);
|
|
||||||
end dram_tb;
|
|
||||||
|
|
||||||
architecture behave of dram_tb is
|
|
||||||
signal clk, rst: std_logic;
|
|
||||||
signal clk_in, soc_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- testbench signals
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
|
|
||||||
-- Sim DRAM
|
|
||||||
signal wb_in : wishbone_master_out;
|
|
||||||
signal wb_out : wishbone_slave_out;
|
|
||||||
signal wb_ctrl_in : wb_io_master_out;
|
|
||||||
|
|
||||||
subtype addr_t is std_ulogic_vector(wb_in.adr'left downto 0);
|
|
||||||
subtype data_t is std_ulogic_vector(wb_in.dat'left downto 0);
|
|
||||||
subtype sel_t is std_ulogic_vector(wb_in.sel'left downto 0);
|
|
||||||
|
|
||||||
-- Counter for acks
|
|
||||||
signal acks : integer := 0;
|
|
||||||
signal reset_acks : std_ulogic;
|
|
||||||
|
|
||||||
-- Read data fifo
|
|
||||||
signal rd_ready : std_ulogic := '0';
|
|
||||||
signal rd_valid : std_ulogic;
|
|
||||||
signal rd_data : data_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 1,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => DRAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => DRAM_INIT_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => clk_in,
|
|
||||||
rst => rst,
|
|
||||||
system_clk => clk,
|
|
||||||
system_reset => soc_rst,
|
|
||||||
core_alt_reset => open,
|
|
||||||
pll_locked => open,
|
|
||||||
|
|
||||||
wb_in => wb_in,
|
|
||||||
wb_out => wb_out,
|
|
||||||
wb_ctrl_in => wb_ctrl_in,
|
|
||||||
wb_ctrl_out => open,
|
|
||||||
wb_ctrl_is_csr => '0',
|
|
||||||
wb_ctrl_is_init => '0',
|
|
||||||
|
|
||||||
init_done => open,
|
|
||||||
init_error => open,
|
|
||||||
|
|
||||||
ddram_a => open,
|
|
||||||
ddram_ba => open,
|
|
||||||
ddram_ras_n => open,
|
|
||||||
ddram_cas_n => open,
|
|
||||||
ddram_we_n => open,
|
|
||||||
ddram_cs_n => open,
|
|
||||||
ddram_dm => open,
|
|
||||||
ddram_dq => open,
|
|
||||||
ddram_dqs_p => open,
|
|
||||||
ddram_dqs_n => open,
|
|
||||||
ddram_clk_p => open,
|
|
||||||
ddram_clk_n => open,
|
|
||||||
ddram_cke => open,
|
|
||||||
ddram_odt => open,
|
|
||||||
ddram_reset_n => open
|
|
||||||
);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk_in <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk_in <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
rst_process: process
|
|
||||||
begin
|
|
||||||
rst <= '1';
|
|
||||||
wait for 10*clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
wb_ctrl_in.cyc <= '0';
|
|
||||||
wb_ctrl_in.stb <= '0';
|
|
||||||
|
|
||||||
-- Read data receive queue
|
|
||||||
data_queue: entity work.sync_fifo
|
|
||||||
generic map (
|
|
||||||
DEPTH => 16,
|
|
||||||
WIDTH => rd_data'length
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
reset => soc_rst or reset_acks,
|
|
||||||
rd_ready => rd_ready,
|
|
||||||
rd_valid => rd_valid,
|
|
||||||
rd_data => rd_data,
|
|
||||||
wr_ready => open,
|
|
||||||
wr_valid => wb_out.ack,
|
|
||||||
wr_data => wb_out.dat
|
|
||||||
);
|
|
||||||
|
|
||||||
recv_acks: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' or reset_acks = '1' then
|
|
||||||
acks <= 0;
|
|
||||||
elsif wb_out.ack = '1' then
|
|
||||||
acks <= acks + 1;
|
|
||||||
-- report "WB ACK ! DATA=" & to_hstring(wb_out.dat);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
sim: process
|
|
||||||
procedure wb_write(addr: addr_t; data: data_t; sel: sel_t) is
|
|
||||||
begin
|
|
||||||
wb_in.adr <= addr;
|
|
||||||
wb_in.sel <= sel;
|
|
||||||
wb_in.dat <= data;
|
|
||||||
wb_in.we <= '1';
|
|
||||||
wb_in.stb <= '1';
|
|
||||||
wb_in.cyc <= '1';
|
|
||||||
loop
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
if wb_out.stall = '0' then
|
|
||||||
wb_in.stb <= '0';
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
procedure wb_read(addr: addr_t) is
|
|
||||||
begin
|
|
||||||
wb_in.adr <= addr;
|
|
||||||
wb_in.sel <= x"ff";
|
|
||||||
wb_in.we <= '0';
|
|
||||||
wb_in.stb <= '1';
|
|
||||||
wb_in.cyc <= '1';
|
|
||||||
loop
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
if wb_out.stall = '0' then
|
|
||||||
wb_in.stb <= '0';
|
|
||||||
exit;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
procedure wait_acks(count: integer) is
|
|
||||||
begin
|
|
||||||
wait until acks = count;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
procedure clr_acks is
|
|
||||||
begin
|
|
||||||
reset_acks <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
reset_acks <= '0';
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
procedure read_data(data: out data_t) is
|
|
||||||
begin
|
|
||||||
assert rd_valid = '1' report "No data to read" severity failure;
|
|
||||||
rd_ready <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rd_ready <= '0';
|
|
||||||
data := rd_data;
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
function add_off(a: addr_t; off: integer) return addr_t is
|
|
||||||
begin
|
|
||||||
return addr_t(unsigned(a) + off);
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function make_pattern(num : integer) return data_t is
|
|
||||||
variable r : data_t;
|
|
||||||
variable t,b : integer;
|
|
||||||
begin
|
|
||||||
for i in 0 to (data_t'length/8)-1 loop
|
|
||||||
t := (i+1)*8-1;
|
|
||||||
b := i*8;
|
|
||||||
r(t downto b) := std_ulogic_vector(to_unsigned(num+1, 8));
|
|
||||||
end loop;
|
|
||||||
return r;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
procedure check_data(p: data_t) is
|
|
||||||
variable d : data_t;
|
|
||||||
begin
|
|
||||||
read_data(d);
|
|
||||||
assert d = p report "bad data, want " & to_hstring(p) &
|
|
||||||
" got " & to_hstring(d) severity failure;
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
variable a : addr_t := (others => '0');
|
|
||||||
variable d : data_t := (others => '0');
|
|
||||||
variable d1 : data_t := (others => '0');
|
|
||||||
begin
|
|
||||||
reset_acks <= '0';
|
|
||||||
rst <= '1';
|
|
||||||
wait until rising_edge(clk_in);
|
|
||||||
wait until rising_edge(clk_in);
|
|
||||||
wait until rising_edge(clk_in);
|
|
||||||
wait until rising_edge(clk_in);
|
|
||||||
wait until rising_edge(clk_in);
|
|
||||||
rst <= '0';
|
|
||||||
wait until rising_edge(clk_in);
|
|
||||||
wait until soc_rst = '0';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
report "Simple write miss...";
|
|
||||||
clr_acks;
|
|
||||||
wb_write(a, x"0123456789abcdef", x"ff");
|
|
||||||
wait_acks(1);
|
|
||||||
|
|
||||||
report "Simple read miss...";
|
|
||||||
clr_acks;
|
|
||||||
wb_read(a);
|
|
||||||
wait_acks(1);
|
|
||||||
read_data(d);
|
|
||||||
assert d = x"0123456789abcdef" report "bad data, got " & to_hstring(d) severity failure;
|
|
||||||
|
|
||||||
report "Simple read hit...";
|
|
||||||
clr_acks;
|
|
||||||
wb_read(a);
|
|
||||||
wait_acks(1);
|
|
||||||
read_data(d);
|
|
||||||
assert d = x"0123456789abcdef" report "bad data, got " & to_hstring(d) severity failure;
|
|
||||||
|
|
||||||
report "Back to back 4 stores 4 reads on hit...";
|
|
||||||
clr_acks;
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
wb_write(add_off(a, i), make_pattern(i), x"ff");
|
|
||||||
end loop;
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
wb_read(add_off(a, i));
|
|
||||||
end loop;
|
|
||||||
wait_acks(8);
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
if i < 4 then
|
|
||||||
read_data(d);
|
|
||||||
else
|
|
||||||
check_data(make_pattern(i-4));
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
report "Back to back 4 stores 4 reads on miss...";
|
|
||||||
a(10) := '1';
|
|
||||||
clr_acks;
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
wb_write(add_off(a, i), make_pattern(i), x"ff");
|
|
||||||
end loop;
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
wb_read(add_off(a, i));
|
|
||||||
end loop;
|
|
||||||
wait_acks(8);
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
if i < 4 then
|
|
||||||
read_data(d);
|
|
||||||
else
|
|
||||||
check_data(make_pattern(i-4));
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
report "Back to back interleaved 4 stores 4 reads on hit...";
|
|
||||||
a(10) := '1';
|
|
||||||
clr_acks;
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
wb_write(add_off(a, i), make_pattern(i), x"ff");
|
|
||||||
wb_read(add_off(a, i));
|
|
||||||
end loop;
|
|
||||||
wait_acks(8);
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
read_data(d);
|
|
||||||
check_data(make_pattern(i));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
report "Pre-fill a line";
|
|
||||||
a(11) := '1';
|
|
||||||
clr_acks;
|
|
||||||
wb_write(add_off(a, 0), x"1111111100000000", x"ff");
|
|
||||||
wb_write(add_off(a, 1), x"3333333322222222", x"ff");
|
|
||||||
wb_write(add_off(a, 2), x"5555555544444444", x"ff");
|
|
||||||
wb_write(add_off(a, 3), x"7777777766666666", x"ff");
|
|
||||||
wb_write(add_off(a, 4), x"9999999988888888", x"ff");
|
|
||||||
wb_write(add_off(a, 5), x"bbbbbbbbaaaaaaaa", x"ff");
|
|
||||||
wb_write(add_off(a, 6), x"ddddddddcccccccc", x"ff");
|
|
||||||
wb_write(add_off(a, 7), x"ffffffffeeeeeeee", x"ff");
|
|
||||||
wb_write(add_off(a, 8), x"1111111100000000", x"ff");
|
|
||||||
wb_write(add_off(a, 9), x"3333333322222222", x"ff");
|
|
||||||
wb_write(add_off(a, 10), x"5555555544444444", x"ff");
|
|
||||||
wb_write(add_off(a, 11), x"7777777766666666", x"ff");
|
|
||||||
wb_write(add_off(a, 12), x"9999999988888888", x"ff");
|
|
||||||
wb_write(add_off(a, 13), x"bbbbbbbbaaaaaaaa", x"ff");
|
|
||||||
wb_write(add_off(a, 14), x"ddddddddcccccccc", x"ff");
|
|
||||||
wb_write(add_off(a, 15), x"ffffffffeeeeeeee", x"ff");
|
|
||||||
wait_acks(16);
|
|
||||||
|
|
||||||
report "Scattered from middle of line...";
|
|
||||||
clr_acks;
|
|
||||||
wb_read(add_off(a, 3));
|
|
||||||
wb_read(add_off(a, 4));
|
|
||||||
wb_read(add_off(a, 0));
|
|
||||||
wb_read(add_off(a, 2));
|
|
||||||
wait_acks(4);
|
|
||||||
read_data(d);
|
|
||||||
assert d = x"7777777766666666" report "bad data (24), got " & to_hstring(d) severity failure;
|
|
||||||
read_data(d);
|
|
||||||
assert d = x"9999999988888888" report "bad data (32), got " & to_hstring(d) severity failure;
|
|
||||||
read_data(d);
|
|
||||||
assert d = x"1111111100000000" report "bad data (0), got " & to_hstring(d) severity failure;
|
|
||||||
read_data(d);
|
|
||||||
assert d = x"5555555544444444" report "bad data (16), got " & to_hstring(d) severity failure;
|
|
||||||
|
|
||||||
std.env.finish;
|
|
||||||
end process;
|
|
||||||
end architecture;
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,57 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.common.all;
|
||||||
|
use work.crhelpers.all;
|
||||||
|
use work.ppc_fx_insns.all;
|
||||||
|
|
||||||
|
-- 2 cycle ALU
|
||||||
|
-- We handle rc form instructions here
|
||||||
|
|
||||||
|
entity execute2 is
|
||||||
|
port (
|
||||||
|
clk : in std_ulogic;
|
||||||
|
|
||||||
|
e_in : in Execute1ToExecute2Type;
|
||||||
|
e_out : out Execute2ToWritebackType
|
||||||
|
);
|
||||||
|
end execute2;
|
||||||
|
|
||||||
|
architecture behave of execute2 is
|
||||||
|
signal r, rin : Execute2ToWritebackType;
|
||||||
|
begin
|
||||||
|
execute2_0: process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
r <= rin;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
execute2_1: process(all)
|
||||||
|
variable v : Execute2ToWritebackType;
|
||||||
|
begin
|
||||||
|
v := rin;
|
||||||
|
|
||||||
|
v.valid := e_in.valid;
|
||||||
|
v.write_enable := e_in.write_enable;
|
||||||
|
v.write_reg := e_in.write_reg;
|
||||||
|
v.write_data := e_in.write_data;
|
||||||
|
v.write_cr_enable := e_in.write_cr_enable;
|
||||||
|
v.write_cr_mask := e_in.write_cr_mask;
|
||||||
|
v.write_cr_data := e_in.write_cr_data;
|
||||||
|
|
||||||
|
if e_in.valid = '1' and e_in.rc = '1' then
|
||||||
|
v.write_cr_enable := '1';
|
||||||
|
v.write_cr_mask := num_to_fxm(0);
|
||||||
|
v.write_cr_data := ppc_cmpi('1', e_in.write_data, x"0000") & x"0000000";
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Update registers
|
||||||
|
rin <= v;
|
||||||
|
|
||||||
|
-- Update outputs
|
||||||
|
e_out <= r;
|
||||||
|
end process;
|
||||||
|
end;
|
@ -0,0 +1,65 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.common.all;
|
||||||
|
use work.wishbone_types.all;
|
||||||
|
|
||||||
|
entity fetch2 is
|
||||||
|
port(
|
||||||
|
clk : in std_ulogic;
|
||||||
|
rst : in std_ulogic;
|
||||||
|
|
||||||
|
stall_in : in std_ulogic;
|
||||||
|
stall_out : out std_ulogic;
|
||||||
|
|
||||||
|
flush_in : in std_ulogic;
|
||||||
|
|
||||||
|
i_in : in IcacheToFetch2Type;
|
||||||
|
i_out : out Fetch2ToIcacheType;
|
||||||
|
|
||||||
|
f_in : in Fetch1ToFetch2Type;
|
||||||
|
|
||||||
|
f_out : out Fetch2ToDecode1Type
|
||||||
|
);
|
||||||
|
end entity fetch2;
|
||||||
|
|
||||||
|
architecture behaviour of fetch2 is
|
||||||
|
signal r, rin : Fetch2ToDecode1Type;
|
||||||
|
begin
|
||||||
|
regs : process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
-- Output state remains unchanged on stall, unless we are flushing
|
||||||
|
if rst = '1' or flush_in = '1' or stall_in = '0' then
|
||||||
|
r <= rin;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
comb : process(all)
|
||||||
|
variable v : Fetch2ToDecode1Type;
|
||||||
|
begin
|
||||||
|
v := r;
|
||||||
|
|
||||||
|
-- asynchronous icache lookup
|
||||||
|
i_out.req <= '1';
|
||||||
|
i_out.addr <= f_in.nia;
|
||||||
|
v.valid := i_in.ack;
|
||||||
|
v.nia := f_in.nia;
|
||||||
|
v.insn := i_in.insn;
|
||||||
|
stall_out <= not i_in.ack;
|
||||||
|
|
||||||
|
|
||||||
|
if flush_in = '1' then
|
||||||
|
v.valid := '0';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Update registers
|
||||||
|
rin <= v;
|
||||||
|
|
||||||
|
-- Update outputs
|
||||||
|
f_out <= r;
|
||||||
|
end process;
|
||||||
|
end architecture behaviour;
|
@ -1,30 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.glibc_random.all;
|
|
||||||
|
|
||||||
entity random is
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
data : out std_ulogic_vector(63 downto 0);
|
|
||||||
raw : out std_ulogic_vector(63 downto 0);
|
|
||||||
err : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity random;
|
|
||||||
|
|
||||||
architecture behaviour of random is
|
|
||||||
begin
|
|
||||||
err <= '0';
|
|
||||||
|
|
||||||
process(clk)
|
|
||||||
variable rand : std_ulogic_vector(63 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
rand := pseudorand(64);
|
|
||||||
data <= rand;
|
|
||||||
raw <= rand;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end behaviour;
|
|
@ -1,338 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
# clkin, reset, uart pins...
|
|
||||||
################################################################################
|
|
||||||
# clk200:0.p
|
|
||||||
set_property LOC J19 [get_ports {clk200_p}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {clk200_p}]
|
|
||||||
|
|
||||||
# clk200:0.n
|
|
||||||
set_property LOC H19 [get_ports {clk200_n}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {clk200_n}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# P2 header used as UART
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { p2_io1_n }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { p2_io1_p }];
|
|
||||||
# AIO2_N
|
|
||||||
set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { uart_tx }];
|
|
||||||
# AIO2_P
|
|
||||||
set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { uart_rx }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# DRAM
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M15 [get_ports {ddram_a[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[0]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC L21 [get_ports {ddram_a[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[1]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M16 [get_ports {ddram_a[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[2]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC L18 [get_ports {ddram_a[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[3]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[3]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC K21 [get_ports {ddram_a[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[4]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[4]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M18 [get_ports {ddram_a[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[5]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[5]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M21 [get_ports {ddram_a[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[6]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[6]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC N20 [get_ports {ddram_a[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[7]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[7]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M20 [get_ports {ddram_a[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[8]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[8]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC N19 [get_ports {ddram_a[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[9]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[9]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC J21 [get_ports {ddram_a[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[10]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[10]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M22 [get_ports {ddram_a[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[11]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[11]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC K22 [get_ports {ddram_a[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[12]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[12]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC N18 [get_ports {ddram_a[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[13]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[13]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC N22 [get_ports {ddram_a[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[14]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[14]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC J22 [get_ports {ddram_a[15]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[15]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[15]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC L19 [get_ports {ddram_ba[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ba[0]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC J20 [get_ports {ddram_ba[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ba[1]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC L20 [get_ports {ddram_ba[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ba[2]}]
|
|
||||||
|
|
||||||
# ddram:0.ras_n
|
|
||||||
set_property LOC H20 [get_ports {ddram_ras_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ras_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ras_n}]
|
|
||||||
|
|
||||||
# ddram:0.cas_n
|
|
||||||
set_property LOC K18 [get_ports {ddram_cas_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cas_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_cas_n}]
|
|
||||||
|
|
||||||
# ddram:0.we_n
|
|
||||||
set_property LOC L16 [get_ports {ddram_we_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_we_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_we_n}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC A19 [get_ports {ddram_dm[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dm[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC G22 [get_ports {ddram_dm[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dm[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D19 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B20 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC E19 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC A20 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC F19 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[4]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C19 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[5]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC F20 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[6]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C18 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[7]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC E22 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[8]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC G21 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[9]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D20 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[10]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC E21 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[11]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C22 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[12]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D21 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[13]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B22 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[14]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D22 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {ddram_dq[15]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC F18 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC B21 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC E18 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC A21 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
|
|
||||||
# ddram:0.clk_p
|
|
||||||
set_property LOC K17 [get_ports {ddram_clk_p}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_p}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_clk_p}]
|
|
||||||
|
|
||||||
# ddram:0.clk_n
|
|
||||||
set_property LOC J17 [get_ports {ddram_clk_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_n}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_clk_n}]
|
|
||||||
|
|
||||||
# ddram:0.cke
|
|
||||||
set_property LOC H22 [get_ports {ddram_cke}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cke}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_cke}]
|
|
||||||
|
|
||||||
# ddram:0.odt
|
|
||||||
set_property LOC K19 [get_ports {ddram_odt}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_odt}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_odt}]
|
|
||||||
|
|
||||||
# ddram:0.reset_n
|
|
||||||
set_property LOC K16 [get_ports {ddram_reset_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_reset_n}]
|
|
||||||
set_property IOSTANDARD LVCMOS15 [get_ports {ddram_reset_n}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# LEDs
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { led0 }];
|
|
||||||
set_property -dict { PACKAGE_PIN H3 IOSTANDARD LVCMOS33 } [get_ports { led1 }];
|
|
||||||
set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { led2 }];
|
|
||||||
set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { led3 }];
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# SPI Flash
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN T19 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN P22 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }];
|
|
||||||
set_property -dict { PACKAGE_PIN R22 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }];
|
|
||||||
set_property -dict { PACKAGE_PIN P21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Design constraints
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property INTERNAL_VREF 0.750 [get_iobanks 34]
|
|
||||||
set_property CONFIG_MODE SPIx4 [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design]
|
|
||||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
|
||||||
set_property CFGBVS VCCO [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
|
|
||||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN Div-1 [current_design]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Clock constraints
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
create_clock -name clk200_p -period 5.0 [get_nets clk200_p]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# False path constraints
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
|
||||||
|
|
||||||
set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
|
||||||
|
|
||||||
set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
|
@ -0,0 +1,10 @@
|
|||||||
|
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { ext_clk }];
|
||||||
|
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { ext_clk }];
|
||||||
|
|
||||||
|
set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ext_rst }];
|
||||||
|
|
||||||
|
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart0_txd }];
|
||||||
|
set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart0_rxd }];
|
||||||
|
|
||||||
|
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||||
|
set_property CFGBVS VCCO [current_design]
|
@ -1,554 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
# clkin, reset, uart pins...
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { ext_clk }];
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { ext_rst_n }];
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart_main_tx }];
|
|
||||||
set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart_main_rx }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# RGB LEDs
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }];
|
|
||||||
set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }];
|
|
||||||
set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { led1_b }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { led1_g }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { led1_r }];
|
|
||||||
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { led2_b }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { led2_g }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { led2_r }];
|
|
||||||
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { led3_b }];
|
|
||||||
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { led3_g }];
|
|
||||||
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { led3_r }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Normal LEDs
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { led4 }];
|
|
||||||
set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { led5 }];
|
|
||||||
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { led6 }];
|
|
||||||
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { led7 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# SPI Flash
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_clk }];
|
|
||||||
set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }];
|
|
||||||
set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }];
|
|
||||||
set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];
|
|
||||||
|
|
||||||
# Put registers into IOBs to improve timing
|
|
||||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/*sck_1*}]
|
|
||||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/input_delay_1.dat_i_l*}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header JA (standard, 200 ohm protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { pmod_ja_10 }];
|
|
||||||
|
|
||||||
# connection to Digilent PmodSD on JA
|
|
||||||
set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
|
|
||||||
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
|
|
||||||
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
|
|
||||||
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
|
||||||
set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
|
|
||||||
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
|
|
||||||
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
|
||||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
|
|
||||||
|
|
||||||
# Put registers into IOBs to improve timing
|
|
||||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdcard_*}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header JB (high-speed, no protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_10 }];
|
|
||||||
|
|
||||||
# connection to Digilent PmodSD on JB
|
|
||||||
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_cmd }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[0] }];
|
|
||||||
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[1] }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[2] }];
|
|
||||||
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sdcard_wp }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header JC (high-speed, no protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_10 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header JD (standard, 200 ohm protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { pmod_jd_10 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Arduino/chipKIT shield connector
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[0] }];
|
|
||||||
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[1] }];
|
|
||||||
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[2] }];
|
|
||||||
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[3] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[4] }];
|
|
||||||
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[5] }];
|
|
||||||
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[6] }];
|
|
||||||
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[7] }];
|
|
||||||
set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[8] }];
|
|
||||||
set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[9] }];
|
|
||||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[10] }];
|
|
||||||
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[11] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[12] }];
|
|
||||||
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[13] }];
|
|
||||||
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[26] }];
|
|
||||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[27] }];
|
|
||||||
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[28] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[29] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[30] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[31] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[32] }];
|
|
||||||
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[33] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[34] }];
|
|
||||||
set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[35] }];
|
|
||||||
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[36] }];
|
|
||||||
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[37] }];
|
|
||||||
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[38] }];
|
|
||||||
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[39] }];
|
|
||||||
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[40] }];
|
|
||||||
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[41] }];
|
|
||||||
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[42] }]; # A
|
|
||||||
set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[43] }]; # SCL
|
|
||||||
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[44] }]; # SDA
|
|
||||||
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { shield_rst }];
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { spi_hdr_ss }];
|
|
||||||
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { spi_hdr_clk }];
|
|
||||||
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { spi_hdr_mosi }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { spi_hdr_miso }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Ethernet (generated by LiteX)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# eth_ref_clk:0
|
|
||||||
set_property LOC G18 [get_ports {eth_ref_clk}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_ref_clk}]
|
|
||||||
|
|
||||||
# eth_clocks:0.tx
|
|
||||||
set_property LOC H16 [get_ports {eth_clocks_tx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_tx}]
|
|
||||||
|
|
||||||
# eth_clocks:0.rx
|
|
||||||
set_property LOC F15 [get_ports {eth_clocks_rx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_rx}]
|
|
||||||
|
|
||||||
# eth:0.rst_n
|
|
||||||
set_property LOC C16 [get_ports {eth_rst_n}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rst_n}]
|
|
||||||
|
|
||||||
# eth:0.mdio
|
|
||||||
set_property LOC K13 [get_ports {eth_mdio}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdio}]
|
|
||||||
|
|
||||||
# eth:0.mdc
|
|
||||||
set_property LOC F16 [get_ports {eth_mdc}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdc}]
|
|
||||||
|
|
||||||
# eth:0.rx_dv
|
|
||||||
set_property LOC G16 [get_ports {eth_rx_dv}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_dv}]
|
|
||||||
|
|
||||||
# eth:0.rx_er
|
|
||||||
set_property LOC C17 [get_ports {eth_rx_er}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_er}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC D18 [get_ports {eth_rx_data[0]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[0]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC E17 [get_ports {eth_rx_data[1]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[1]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC E18 [get_ports {eth_rx_data[2]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[2]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC G17 [get_ports {eth_rx_data[3]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[3]}]
|
|
||||||
|
|
||||||
# eth:0.tx_en
|
|
||||||
set_property LOC H15 [get_ports {eth_tx_en}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_en}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC H14 [get_ports {eth_tx_data[0]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[0]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC J14 [get_ports {eth_tx_data[1]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[1]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC J13 [get_ports {eth_tx_data[2]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[2]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC H17 [get_ports {eth_tx_data[3]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[3]}]
|
|
||||||
|
|
||||||
# eth:0.col
|
|
||||||
set_property LOC D17 [get_ports {eth_col}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_col}]
|
|
||||||
|
|
||||||
# eth:0.crs
|
|
||||||
set_property LOC G14 [get_ports {eth_crs}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_crs}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# DRAM (generated by LiteX)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC R2 [get_ports {ddram_a[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[0]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC M6 [get_ports {ddram_a[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[1]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC N4 [get_ports {ddram_a[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[2]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC T1 [get_ports {ddram_a[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[3]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[3]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC N6 [get_ports {ddram_a[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[4]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[4]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC R7 [get_ports {ddram_a[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[5]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[5]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC V6 [get_ports {ddram_a[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[6]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[6]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC U7 [get_ports {ddram_a[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[7]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[7]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC R8 [get_ports {ddram_a[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[8]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[8]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC V7 [get_ports {ddram_a[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[9]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[9]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC R6 [get_ports {ddram_a[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[10]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[10]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC U6 [get_ports {ddram_a[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[11]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[11]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC T6 [get_ports {ddram_a[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[12]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[12]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC T8 [get_ports {ddram_a[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[13]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[13]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC R1 [get_ports {ddram_ba[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[0]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC P4 [get_ports {ddram_ba[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[1]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC P2 [get_ports {ddram_ba[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[2]}]
|
|
||||||
|
|
||||||
# ddram:0.ras_n
|
|
||||||
set_property LOC P3 [get_ports {ddram_ras_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ras_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ras_n}]
|
|
||||||
|
|
||||||
# ddram:0.cas_n
|
|
||||||
set_property LOC M4 [get_ports {ddram_cas_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cas_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cas_n}]
|
|
||||||
|
|
||||||
# ddram:0.we_n
|
|
||||||
set_property LOC P5 [get_ports {ddram_we_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_we_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_we_n}]
|
|
||||||
|
|
||||||
# ddram:0.cs_n
|
|
||||||
set_property LOC U8 [get_ports {ddram_cs_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cs_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cs_n}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC L1 [get_ports {ddram_dm[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC U1 [get_ports {ddram_dm[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC K5 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC L3 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC K3 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC L6 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC M3 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[4]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC M1 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[5]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC L4 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[6]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC M2 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[7]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC V4 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[8]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC T5 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[9]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC U4 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[10]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC V5 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[11]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC V1 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[12]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC T3 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[13]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC U3 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[14]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC R3 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[15]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC N2 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC U2 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC N1 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC V2 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
|
|
||||||
# ddram:0.clk_p
|
|
||||||
set_property LOC U9 [get_ports {ddram_clk_p}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_p}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_clk_p}]
|
|
||||||
|
|
||||||
# ddram:0.clk_n
|
|
||||||
set_property LOC V9 [get_ports {ddram_clk_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_n}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_clk_n}]
|
|
||||||
|
|
||||||
# ddram:0.cke
|
|
||||||
set_property LOC N5 [get_ports {ddram_cke}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cke}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cke}]
|
|
||||||
|
|
||||||
# ddram:0.odt
|
|
||||||
set_property LOC R5 [get_ports {ddram_odt}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_odt}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_odt}]
|
|
||||||
|
|
||||||
# ddram:0.reset_n
|
|
||||||
set_property LOC K6 [get_ports {ddram_reset_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_reset_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_reset_n}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Design constraints and bitsteam attributes
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#Internal VREF
|
|
||||||
set_property INTERNAL_VREF 0.675 [get_iobanks 34]
|
|
||||||
|
|
||||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
|
||||||
set_property CFGBVS VCCO [current_design]
|
|
||||||
|
|
||||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
|
|
||||||
set_property CONFIG_MODE SPIx4 [current_design]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Clock constraints
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
create_clock -name sys_clk_pin -period 10.00 [get_ports { ext_clk }];
|
|
||||||
|
|
||||||
create_clock -name eth_rx_clk -period 40.0 [get_ports { eth_clocks_rx }]
|
|
||||||
|
|
||||||
create_clock -name eth_tx_clk -period 40.0 [get_ports { eth_clocks_tx }]
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets system_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_rx]] -asynchronous
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets system_clk]] -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_tx]] -asynchronous
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_rx]] -group [get_clocks -include_generated_clocks -of [get_nets eth_clocks_tx]] -asynchronous
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# False path constraints (from LiteX as they relate to LiteDRAM and LiteEth)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
|
||||||
|
|
||||||
set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
|
||||||
|
|
||||||
set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
|
@ -1,136 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
entity clock_generator is
|
|
||||||
generic (
|
|
||||||
CLK_INPUT_HZ : positive := 12000000;
|
|
||||||
CLK_OUTPUT_HZ : positive := 50000000
|
|
||||||
);
|
|
||||||
|
|
||||||
port (
|
|
||||||
ext_clk : in std_logic;
|
|
||||||
pll_rst_in : in std_logic;
|
|
||||||
pll_clk_out : out std_logic;
|
|
||||||
pll_locked_out : out std_logic
|
|
||||||
);
|
|
||||||
|
|
||||||
end entity clock_generator;
|
|
||||||
|
|
||||||
architecture bypass of clock_generator is
|
|
||||||
|
|
||||||
-- prototype of ECP5 PLL
|
|
||||||
component EHXPLLL is
|
|
||||||
generic (
|
|
||||||
CLKI_DIV : integer := 1;
|
|
||||||
CLKFB_DIV : integer := 1;
|
|
||||||
CLKOP_DIV : integer := 8;
|
|
||||||
CLKOS_DIV : integer := 8;
|
|
||||||
CLKOS2_DIV : integer := 8;
|
|
||||||
CLKOS3_DIV : integer := 8;
|
|
||||||
CLKOP_ENABLE : string := "ENABLED";
|
|
||||||
CLKOS_ENABLE : string := "DISABLED";
|
|
||||||
CLKOS2_ENABLE : string := "DISABLED";
|
|
||||||
CLKOS3_ENABLE : string := "DISABLED";
|
|
||||||
CLKOP_CPHASE : integer := 0;
|
|
||||||
CLKOS_CPHASE : integer := 0;
|
|
||||||
CLKOS2_CPHASE : integer := 0;
|
|
||||||
CLKOS3_CPHASE : integer := 0;
|
|
||||||
CLKOP_FPHASE : integer := 0;
|
|
||||||
CLKOS_FPHASE : integer := 0;
|
|
||||||
CLKOS2_FPHASE : integer := 0;
|
|
||||||
CLKOS3_FPHASE : integer := 0;
|
|
||||||
FEEDBK_PATH : string := "CLKOP";
|
|
||||||
CLKOP_TRIM_POL : string := "RISING";
|
|
||||||
CLKOP_TRIM_DELAY : integer := 0;
|
|
||||||
CLKOS_TRIM_POL : string := "RISING";
|
|
||||||
CLKOS_TRIM_DELAY : integer := 0;
|
|
||||||
OUTDIVIDER_MUXA : string := "DIVA";
|
|
||||||
OUTDIVIDER_MUXB : string := "DIVB";
|
|
||||||
OUTDIVIDER_MUXC : string := "DIVC";
|
|
||||||
OUTDIVIDER_MUXD : string := "DIVD";
|
|
||||||
PLL_LOCK_MODE : integer := 0;
|
|
||||||
PLL_LOCK_DELAY : integer := 200;
|
|
||||||
STDBY_ENABLE : string := "DISABLED";
|
|
||||||
REFIN_RESET : string := "DISABLED";
|
|
||||||
SYNC_ENABLE : string := "DISABLED";
|
|
||||||
INT_LOCK_STICKY : string := "ENABLED";
|
|
||||||
DPHASE_SOURCE : string := "DISABLED";
|
|
||||||
PLLRST_ENA : string := "DISABLED";
|
|
||||||
INTFB_WAKE : string := "DISABLED" );
|
|
||||||
port (
|
|
||||||
CLKI : in std_logic;
|
|
||||||
CLKFB : in std_logic;
|
|
||||||
PHASESEL1 : in std_logic;
|
|
||||||
PHASESEL0 : in std_logic;
|
|
||||||
PHASEDIR : in std_logic;
|
|
||||||
PHASESTEP : in std_logic;
|
|
||||||
PHASELOADREG : in std_logic;
|
|
||||||
STDBY : in std_logic;
|
|
||||||
PLLWAKESYNC : in std_logic;
|
|
||||||
RST : in std_logic;
|
|
||||||
ENCLKOP : in std_logic;
|
|
||||||
ENCLKOS : in std_logic;
|
|
||||||
ENCLKOS2 : in std_logic;
|
|
||||||
ENCLKOS3 : in std_logic;
|
|
||||||
CLKOP : out std_logic;
|
|
||||||
CLKOS : out std_logic;
|
|
||||||
CLKOS2 : out std_logic;
|
|
||||||
CLKOS3 : out std_logic;
|
|
||||||
LOCK : out std_logic;
|
|
||||||
INTLOCK : out std_logic;
|
|
||||||
REFCLK : out std_logic;
|
|
||||||
CLKINTFB : out std_logic );
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal clkos : std_ulogic;
|
|
||||||
signal clkop : std_logic;
|
|
||||||
signal lock : std_logic;
|
|
||||||
|
|
||||||
-- PLL constants
|
|
||||||
-- According to the datasheet, PLL_IN needs to be between 10 and 400 MHz
|
|
||||||
-- PLL_OUT needs to be between 400 and 800 MHz
|
|
||||||
-- PLL_IN is chosen based on 12 and 48 MHz being common values
|
|
||||||
-- for the reference clock.
|
|
||||||
constant PLL_IN : natural := 12000000;
|
|
||||||
constant PLL_OUT : natural := 480000000;
|
|
||||||
|
|
||||||
-- Configration for ECP5 PLL
|
|
||||||
constant PLL_CLKOP_DIV : natural := PLL_OUT/CLK_OUTPUT_HZ;
|
|
||||||
constant PLL_CLKOS_DIV : natural := 2;
|
|
||||||
constant PLL_CLKFB_DIV : natural := PLL_OUT/PLL_CLKOS_DIV/PLL_IN;
|
|
||||||
constant PLL_CLKI_DIV : natural := CLK_INPUT_HZ/PLL_IN;
|
|
||||||
|
|
||||||
begin
|
|
||||||
pll_clk_out <= clkop;
|
|
||||||
pll_locked_out <= lock;
|
|
||||||
|
|
||||||
clkgen: EHXPLLL
|
|
||||||
generic map(
|
|
||||||
CLKOP_DIV => PLL_CLKOP_DIV,
|
|
||||||
CLKOS_ENABLE => "ENABLED",
|
|
||||||
CLKOS_DIV => PLL_CLKOS_DIV,
|
|
||||||
CLKFB_DIV => PLL_CLKFB_DIV,
|
|
||||||
CLKI_DIV => PLL_CLKI_DIV,
|
|
||||||
FEEDBK_PATH => "CLKOS"
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
CLKI => ext_clk,
|
|
||||||
CLKOP => clkop,
|
|
||||||
CLKOS => clkos,
|
|
||||||
CLKFB => clkos,
|
|
||||||
LOCK => lock,
|
|
||||||
RST => pll_rst_in,
|
|
||||||
PHASESEL1 => '0',
|
|
||||||
PHASESEL0 => '0',
|
|
||||||
PHASEDIR => '0',
|
|
||||||
PHASESTEP => '0',
|
|
||||||
PHASELOADREG => '0',
|
|
||||||
STDBY => '0',
|
|
||||||
PLLWAKESYNC => '0',
|
|
||||||
ENCLKOP => '1',
|
|
||||||
ENCLKOS => '1',
|
|
||||||
ENCLKOS2 => '0',
|
|
||||||
ENCLKOS3 => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
end architecture bypass;
|
|
@ -1,53 +0,0 @@
|
|||||||
-- Random number generator for Microwatt
|
|
||||||
-- Based on https://pdfs.semanticscholar.org/83ac/9e9c1bb3dad5180654984604c8d5d8137412.pdf
|
|
||||||
-- "High Speed True Random Number Generators in Xilinx FPGAs"
|
|
||||||
-- by Catalin Baetoniu, Xilinx Inc.
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
|
|
||||||
entity random is
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
data : out std_ulogic_vector(63 downto 0);
|
|
||||||
raw : out std_ulogic_vector(63 downto 0);
|
|
||||||
err : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity random;
|
|
||||||
|
|
||||||
architecture behaviour of random is
|
|
||||||
signal ringosc : std_ulogic_vector(63 downto 0);
|
|
||||||
signal ro_reg : std_ulogic_vector(63 downto 0);
|
|
||||||
signal lhca : std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
constant lhca_diag : std_ulogic_vector(63 downto 0) := x"fffffffffffffffb";
|
|
||||||
|
|
||||||
begin
|
|
||||||
random_osc : process(all)
|
|
||||||
begin
|
|
||||||
-- chaotic set of ring oscillators
|
|
||||||
ringosc(0) <= ringosc(63) xor ringosc(0) xor ringosc(1);
|
|
||||||
for i in 1 to 62 loop
|
|
||||||
ringosc(i) <= ringosc(i-1) xor ringosc(i) xor ringosc(i+1);
|
|
||||||
end loop;
|
|
||||||
ringosc(63) <= not (ringosc(62) xor ringosc(63) xor ringosc(0));
|
|
||||||
end process;
|
|
||||||
|
|
||||||
lhca_update : process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
ro_reg <= ringosc;
|
|
||||||
raw <= ro_reg;
|
|
||||||
-- linear hybrid cellular automaton
|
|
||||||
-- used to even out the statistics of the ring oscillators
|
|
||||||
lhca <= ('0' & lhca(63 downto 1)) xor (lhca and lhca_diag) xor
|
|
||||||
(lhca(62 downto 0) & '0') xor ro_reg;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
data <= lhca;
|
|
||||||
err <= '0';
|
|
||||||
end behaviour;
|
|
@ -1,3 +0,0 @@
|
|||||||
set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets soc0/processor/execute1_0/random_0/ro_reg*]
|
|
||||||
set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets soc0/processor/execute1_0/random_0/p_*]
|
|
||||||
set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets soc0/processor/execute1_0/random_0/D*]
|
|
@ -1,463 +0,0 @@
|
|||||||
#### Genesys-2 Rev.H
|
|
||||||
|
|
||||||
## Clock & Reset
|
|
||||||
set_property -dict { PACKAGE_PIN AD11 IOSTANDARD LVDS } [get_ports { clk200_n }]
|
|
||||||
set_property -dict { PACKAGE_PIN AD12 IOSTANDARD LVDS } [get_ports { clk200_p }]
|
|
||||||
create_clock -period 5.000 -name tc_clk100_p [get_ports clk200_p]
|
|
||||||
create_clock -period 5.000 -name tc_clk100_n [get_ports clk200_n]
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN R19 IOSTANDARD LVCMOS33 } [get_ports { ext_rst }]
|
|
||||||
|
|
||||||
## UART
|
|
||||||
set_property -dict { PACKAGE_PIN Y20 IOSTANDARD LVCMOS33 } [get_ports { uart_main_rx }]
|
|
||||||
set_property -dict { PACKAGE_PIN Y23 IOSTANDARD LVCMOS33 } [get_ports { uart_main_tx }]
|
|
||||||
|
|
||||||
## LEDs
|
|
||||||
set_property -dict { PACKAGE_PIN T28 IOSTANDARD LVCMOS33 } [get_ports { led0 }]
|
|
||||||
set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports { led1 }]
|
|
||||||
set_property -dict { PACKAGE_PIN U30 IOSTANDARD LVCMOS33 } [get_ports { led2 }]
|
|
||||||
set_property -dict { PACKAGE_PIN U29 IOSTANDARD LVCMOS33 } [get_ports { led3 }]
|
|
||||||
|
|
||||||
## QSPI
|
|
||||||
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }]
|
|
||||||
set_property -dict { PACKAGE_PIN P24 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }]
|
|
||||||
set_property -dict { PACKAGE_PIN R25 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }]
|
|
||||||
set_property -dict { PACKAGE_PIN R20 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }]
|
|
||||||
set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }]
|
|
||||||
|
|
||||||
|
|
||||||
## DRAM
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AC12 [get_ports {ddram_a[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[0]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[0]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AE8 [get_ports {ddram_a[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[1]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[1]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AD8 [get_ports {ddram_a[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[2]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[2]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AC10 [get_ports {ddram_a[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[3]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[3]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[3]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AD9 [get_ports {ddram_a[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[4]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[4]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[4]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AA13 [get_ports {ddram_a[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[5]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[5]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[5]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AA10 [get_ports {ddram_a[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[6]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[6]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[6]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AA11 [get_ports {ddram_a[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[7]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[7]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[7]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC Y10 [get_ports {ddram_a[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[8]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[8]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[8]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC Y11 [get_ports {ddram_a[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[9]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[9]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[9]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AB8 [get_ports {ddram_a[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[10]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[10]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[10]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AA8 [get_ports {ddram_a[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[11]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[11]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[11]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AB12 [get_ports {ddram_a[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[12]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[12]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[12]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AA12 [get_ports {ddram_a[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[13]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[13]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[13]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC AH9 [get_ports {ddram_a[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[14]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_a[14]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_a[14]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC AE9 [get_ports {ddram_ba[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[0]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_ba[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ba[0]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC AB10 [get_ports {ddram_ba[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[1]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_ba[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ba[1]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC AC11 [get_ports {ddram_ba[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[2]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_ba[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ba[2]}]
|
|
||||||
|
|
||||||
# ddram:0.ras_n
|
|
||||||
set_property LOC AE11 [get_ports {ddram_ras_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ras_n}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_ras_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_ras_n}]
|
|
||||||
|
|
||||||
# ddram:0.cas_n
|
|
||||||
set_property LOC AF11 [get_ports {ddram_cas_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cas_n}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_cas_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_cas_n}]
|
|
||||||
|
|
||||||
# ddram:0.we_n
|
|
||||||
set_property LOC AG13 [get_ports {ddram_we_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_we_n}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_we_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_we_n}]
|
|
||||||
|
|
||||||
# ddram:0.cs_n
|
|
||||||
set_property LOC AH12 [get_ports {ddram_cs_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cs_n}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_cs_n}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_cs_n}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC AD4 [get_ports {ddram_dm[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[0]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dm[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dm[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC AF3 [get_ports {ddram_dm[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[1]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dm[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dm[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC AH4 [get_ports {ddram_dm[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[2]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dm[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dm[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC AF8 [get_ports {ddram_dm[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[3]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dm[3]}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_dm[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AD3 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[0]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AC2 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[1]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AC1 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[2]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AC5 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[3]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AC4 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[4]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[4]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AD6 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[5]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[5]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AE6 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[6]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[6]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AC7 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[7]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[7]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AF2 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[8]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[8]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AE1 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[9]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[9]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AF1 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[10]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[10]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AE4 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[11]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[11]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AE3 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[12]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[12]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AE5 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[13]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[13]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AF5 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[14]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[14]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AF6 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[15]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[15]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AJ4 [get_ports {ddram_dq[16]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[16]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[16]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[16]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AH6 [get_ports {ddram_dq[17]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[17]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[17]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[17]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AH5 [get_ports {ddram_dq[18]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[18]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[18]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[18]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AH2 [get_ports {ddram_dq[19]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[19]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[19]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[19]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AJ2 [get_ports {ddram_dq[20]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[20]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[20]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[20]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AJ1 [get_ports {ddram_dq[21]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[21]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[21]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[21]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AK1 [get_ports {ddram_dq[22]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[22]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[22]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[22]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AJ3 [get_ports {ddram_dq[23]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[23]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[23]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[23]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AF7 [get_ports {ddram_dq[24]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[24]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[24]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[24]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AG7 [get_ports {ddram_dq[25]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[25]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[25]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[25]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AJ6 [get_ports {ddram_dq[26]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[26]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[26]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[26]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AK6 [get_ports {ddram_dq[27]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[27]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[27]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[27]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AJ8 [get_ports {ddram_dq[28]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[28]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[28]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[28]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AK8 [get_ports {ddram_dq[29]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[29]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[29]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[29]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AK5 [get_ports {ddram_dq[30]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[30]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[30]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[30]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC AK4 [get_ports {ddram_dq[31]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[31]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dq[31]}]
|
|
||||||
set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddram_dq[31]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC AD2 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC AG4 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC AG2 [get_ports {ddram_dqs_p[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[2]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_p[2]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_p[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC AH7 [get_ports {ddram_dqs_p[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[3]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_p[3]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_p[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC AD1 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC AG3 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC AH1 [get_ports {ddram_dqs_n[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[2]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_n[2]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_n[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC AJ7 [get_ports {ddram_dqs_n[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[3]}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_dqs_n[3]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_dqs_n[3]}]
|
|
||||||
|
|
||||||
# ddram:0.clk_p
|
|
||||||
set_property LOC AB9 [get_ports {ddram_clk_p}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_p}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_clk_p}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_clk_p}]
|
|
||||||
|
|
||||||
# ddram:0.clk_n
|
|
||||||
set_property LOC AC9 [get_ports {ddram_clk_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_n}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_clk_n}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddram_clk_n}]
|
|
||||||
|
|
||||||
# ddram:0.cke
|
|
||||||
set_property LOC AJ9 [get_ports {ddram_cke}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cke}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_cke}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_cke}]
|
|
||||||
|
|
||||||
# ddram:0.odt
|
|
||||||
set_property LOC AK9 [get_ports {ddram_odt}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_odt}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_odt}]
|
|
||||||
set_property IOSTANDARD SSTL15 [get_ports {ddram_odt}]
|
|
||||||
|
|
||||||
# ddram:0.reset_n
|
|
||||||
set_property LOC AG5 [get_ports {ddram_reset_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_reset_n}]
|
|
||||||
set_property VCCAUX_IO HIGH [get_ports {ddram_reset_n}]
|
|
||||||
set_property IOSTANDARD LVCMOS15 [get_ports {ddram_reset_n}]
|
|
||||||
|
|
||||||
|
|
||||||
set_property INTERNAL_VREF 0.750 [get_iobanks 34]
|
|
||||||
|
|
||||||
# False path constraints
|
|
||||||
set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
|
||||||
set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
|
||||||
set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
|
@ -1,82 +0,0 @@
|
|||||||
-- Single port Block RAM with one cycle output buffer
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
|
|
||||||
entity main_bram is
|
|
||||||
generic(
|
|
||||||
WIDTH : natural := 64;
|
|
||||||
HEIGHT_BITS : natural := 1024;
|
|
||||||
MEMORY_SIZE : natural := 65536;
|
|
||||||
RAM_INIT_FILE : string
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
clk : in std_logic;
|
|
||||||
addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
|
|
||||||
din : in std_logic_vector(WIDTH-1 downto 0);
|
|
||||||
dout : out std_logic_vector(WIDTH-1 downto 0);
|
|
||||||
sel : in std_logic_vector((WIDTH/8)-1 downto 0);
|
|
||||||
re : in std_ulogic;
|
|
||||||
we : in std_ulogic
|
|
||||||
);
|
|
||||||
end entity main_bram;
|
|
||||||
|
|
||||||
architecture behaviour of main_bram is
|
|
||||||
|
|
||||||
constant WIDTH_BYTES : natural := WIDTH / 8;
|
|
||||||
|
|
||||||
-- RAM type definition
|
|
||||||
type ram_t is array(0 to (MEMORY_SIZE / WIDTH_BYTES) - 1) of std_logic_vector(WIDTH-1 downto 0);
|
|
||||||
|
|
||||||
-- RAM loading
|
|
||||||
impure function init_ram(name : STRING) return ram_t is
|
|
||||||
file ram_file : text open read_mode is name;
|
|
||||||
variable ram_line : line;
|
|
||||||
variable temp_word : std_logic_vector(WIDTH-1 downto 0);
|
|
||||||
variable temp_ram : ram_t := (others => (others => '0'));
|
|
||||||
begin
|
|
||||||
for i in 0 to (MEMORY_SIZE / WIDTH_BYTES) - 1 loop
|
|
||||||
exit when endfile(ram_file);
|
|
||||||
readline(ram_file, ram_line);
|
|
||||||
hread(ram_line, temp_word);
|
|
||||||
temp_ram(i) := temp_word;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return temp_ram;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
-- RAM instance
|
|
||||||
signal memory : ram_t := init_ram(RAM_INIT_FILE);
|
|
||||||
attribute ram_style : string;
|
|
||||||
attribute ram_style of memory : signal is "block";
|
|
||||||
attribute ram_decomp : string;
|
|
||||||
attribute ram_decomp of memory : signal is "power";
|
|
||||||
|
|
||||||
-- Others
|
|
||||||
signal obuf : std_logic_vector(WIDTH-1 downto 0);
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Actual RAM template
|
|
||||||
memory_0: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if we = '1' then
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
if sel(i) = '1' then
|
|
||||||
memory(to_integer(unsigned(addr)))((i + 1) * 8 - 1 downto i * 8) <=
|
|
||||||
din((i + 1) * 8 - 1 downto i * 8);
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
if re = '1' then
|
|
||||||
obuf <= memory(to_integer(unsigned(addr)));
|
|
||||||
end if;
|
|
||||||
dout <= obuf;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -0,0 +1,106 @@
|
|||||||
|
-- Based on:
|
||||||
|
-- The Potato Processor - A simple processor for FPGAs
|
||||||
|
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use std.textio.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.wishbone_types.all;
|
||||||
|
|
||||||
|
use work.pp_utilities.all;
|
||||||
|
|
||||||
|
--! @brief Simple memory module for use in Wishbone-based systems.
|
||||||
|
entity mw_soc_memory is
|
||||||
|
generic(
|
||||||
|
MEMORY_SIZE : natural := 4096; --! Memory size in bytes.
|
||||||
|
RAM_INIT_FILE : string
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
|
||||||
|
-- Wishbone interface:
|
||||||
|
wishbone_in : in wishbone_master_out;
|
||||||
|
wishbone_out : out wishbone_slave_out
|
||||||
|
);
|
||||||
|
end entity mw_soc_memory;
|
||||||
|
|
||||||
|
architecture behaviour of mw_soc_memory is
|
||||||
|
signal wb_adr_in : std_logic_vector(log2(MEMORY_SIZE) - 1 downto 0);
|
||||||
|
type ram_t is array(0 to (MEMORY_SIZE / 8) - 1) of std_logic_vector(63 downto 0);
|
||||||
|
|
||||||
|
impure function init_ram(name : STRING) return ram_t is
|
||||||
|
file ram_file : text open read_mode is name;
|
||||||
|
variable ram_line : line;
|
||||||
|
variable temp_word : std_logic_vector(63 downto 0);
|
||||||
|
variable temp_ram : ram_t := (others => (others => '0'));
|
||||||
|
begin
|
||||||
|
for i in 0 to (MEMORY_SIZE/8)-1 loop
|
||||||
|
exit when endfile(ram_file);
|
||||||
|
readline(ram_file, ram_line);
|
||||||
|
hread(ram_line, temp_word);
|
||||||
|
temp_ram(i) := temp_word;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return temp_ram;
|
||||||
|
end function;
|
||||||
|
|
||||||
|
signal memory : ram_t := init_ram(RAM_INIT_FILE);
|
||||||
|
|
||||||
|
attribute ram_style : string;
|
||||||
|
attribute ram_style of memory : signal is "block";
|
||||||
|
|
||||||
|
attribute ram_decomp : string;
|
||||||
|
attribute ram_decomp of memory : signal is "power";
|
||||||
|
|
||||||
|
type state_type is (IDLE, ACK);
|
||||||
|
signal state : state_type;
|
||||||
|
|
||||||
|
signal read_ack : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
wb_adr_in <= wishbone_in.adr(log2(MEMORY_SIZE) - 1 downto 0);
|
||||||
|
|
||||||
|
wishbone_out.ack <= read_ack and wishbone_in.stb;
|
||||||
|
|
||||||
|
memory_0: process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
read_ack <= '0';
|
||||||
|
state <= IDLE;
|
||||||
|
else
|
||||||
|
if wishbone_in.cyc = '1' then
|
||||||
|
case state is
|
||||||
|
when IDLE =>
|
||||||
|
if wishbone_in.stb = '1' and wishbone_in.we = '1' then
|
||||||
|
for i in 0 to 7 loop
|
||||||
|
if wishbone_in.sel(i) = '1' then
|
||||||
|
memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3))))(((i + 1) * 8) - 1 downto i * 8)
|
||||||
|
<= wishbone_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
read_ack <= '1';
|
||||||
|
state <= ACK;
|
||||||
|
elsif wishbone_in.stb = '1' then
|
||||||
|
wishbone_out.dat <= memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3))));
|
||||||
|
read_ack <= '1';
|
||||||
|
state <= ACK;
|
||||||
|
end if;
|
||||||
|
when ACK =>
|
||||||
|
read_ack <= '0';
|
||||||
|
state <= IDLE;
|
||||||
|
end case;
|
||||||
|
else
|
||||||
|
state <= IDLE;
|
||||||
|
read_ack <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end architecture behaviour;
|
@ -0,0 +1,216 @@
|
|||||||
|
[PATCH] Hack out ppc64le gcc fixed point divide instructions
|
||||||
|
|
||||||
|
This is a pretty horrible short term hack that removes hardware fixed
|
||||||
|
point divides from ppc64le gcc. It breaks VMX/VSX, but we aren't using
|
||||||
|
either on microwatt. We'll implement a hardware divide shortly and this
|
||||||
|
can go away. Please don't tell my toolchain team.
|
||||||
|
|
||||||
|
The firmware.hex file in this directory is a build of micropython using
|
||||||
|
a recent mainline gcc with this patch.
|
||||||
|
|
||||||
|
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
|
||||||
|
index 0a2bdb79e15..02e325b73a9 100644
|
||||||
|
--- a/gcc/config/rs6000/rs6000-builtin.def
|
||||||
|
+++ b/gcc/config/rs6000/rs6000-builtin.def
|
||||||
|
@@ -1581,7 +1581,6 @@ BU_VSX_2 (VEC_MERGEH_V2DF, "mergeh_2df", CONST, vsx_mergeh_v2df)
|
||||||
|
BU_VSX_2 (VEC_MERGEH_V2DI, "mergeh_2di", CONST, vsx_mergeh_v2di)
|
||||||
|
BU_VSX_2 (XXSPLTD_V2DF, "xxspltd_2df", CONST, vsx_xxspltd_v2df)
|
||||||
|
BU_VSX_2 (XXSPLTD_V2DI, "xxspltd_2di", CONST, vsx_xxspltd_v2di)
|
||||||
|
-BU_VSX_2 (DIV_V2DI, "div_2di", CONST, vsx_div_v2di)
|
||||||
|
BU_VSX_2 (UDIV_V2DI, "udiv_2di", CONST, vsx_udiv_v2di)
|
||||||
|
BU_VSX_2 (MUL_V2DI, "mul_2di", CONST, vsx_mul_v2di)
|
||||||
|
|
||||||
|
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
|
||||||
|
index 7f0cdc73d9b..ad0a8a74e63 100644
|
||||||
|
--- a/gcc/config/rs6000/rs6000-c.c
|
||||||
|
+++ b/gcc/config/rs6000/rs6000-c.c
|
||||||
|
@@ -1459,8 +1459,6 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||||||
|
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
|
||||||
|
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP,
|
||||||
|
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||||||
|
- { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_DIV_V2DI,
|
||||||
|
- RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||||||
|
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_UDIV_V2DI,
|
||||||
|
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
|
||||||
|
{ VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVSXDDP,
|
||||||
|
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
|
||||||
|
index 832eda7cbad..1c5245c781b 100644
|
||||||
|
--- a/gcc/config/rs6000/rs6000-call.c
|
||||||
|
+++ b/gcc/config/rs6000/rs6000-call.c
|
||||||
|
@@ -5445,7 +5445,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
|
||||||
|
gsi_replace (gsi, g, true);
|
||||||
|
return true;
|
||||||
|
/* Flavors of vec_div (Integer). */
|
||||||
|
- case VSX_BUILTIN_DIV_V2DI:
|
||||||
|
case VSX_BUILTIN_UDIV_V2DI:
|
||||||
|
arg0 = gimple_call_arg (stmt, 0);
|
||||||
|
arg1 = gimple_call_arg (stmt, 1);
|
||||||
|
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
|
||||||
|
index 9a7a1da987f..c443c2fe579 100644
|
||||||
|
--- a/gcc/config/rs6000/rs6000.md
|
||||||
|
+++ b/gcc/config/rs6000/rs6000.md
|
||||||
|
@@ -3071,45 +3071,6 @@
|
||||||
|
"maddld %0,%1,%2,%3"
|
||||||
|
[(set_attr "type" "mul")])
|
||||||
|
|
||||||
|
-(define_insn "udiv<mode>3"
|
||||||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||||
|
- (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||||
|
- (match_operand:GPR 2 "gpc_reg_operand" "r")))]
|
||||||
|
- ""
|
||||||
|
- "div<wd>u %0,%1,%2"
|
||||||
|
- [(set_attr "type" "div")
|
||||||
|
- (set_attr "size" "<bits>")])
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
|
||||||
|
-;; modulus. If it isn't a power of two, force operands into register and do
|
||||||
|
-;; a normal divide.
|
||||||
|
-(define_expand "div<mode>3"
|
||||||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand")
|
||||||
|
- (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
|
||||||
|
- (match_operand:GPR 2 "reg_or_cint_operand")))]
|
||||||
|
- ""
|
||||||
|
-{
|
||||||
|
- if (CONST_INT_P (operands[2])
|
||||||
|
- && INTVAL (operands[2]) > 0
|
||||||
|
- && exact_log2 (INTVAL (operands[2])) >= 0)
|
||||||
|
- {
|
||||||
|
- emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
|
||||||
|
- DONE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- operands[2] = force_reg (<MODE>mode, operands[2]);
|
||||||
|
-})
|
||||||
|
-
|
||||||
|
-(define_insn "*div<mode>3"
|
||||||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||||
|
- (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||||
|
- (match_operand:GPR 2 "gpc_reg_operand" "r")))]
|
||||||
|
- ""
|
||||||
|
- "div<wd> %0,%1,%2"
|
||||||
|
- [(set_attr "type" "div")
|
||||||
|
- (set_attr "size" "<bits>")])
|
||||||
|
-
|
||||||
|
(define_insn "div<mode>3_sra"
|
||||||
|
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||||||
|
(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||||||
|
@@ -3170,37 +3131,6 @@
|
||||||
|
(set_attr "length" "8,12")
|
||||||
|
(set_attr "cell_micro" "not")])
|
||||||
|
|
||||||
|
-(define_expand "mod<mode>3"
|
||||||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand")
|
||||||
|
- (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
|
||||||
|
- (match_operand:GPR 2 "reg_or_cint_operand")))]
|
||||||
|
- ""
|
||||||
|
-{
|
||||||
|
- int i;
|
||||||
|
- rtx temp1;
|
||||||
|
- rtx temp2;
|
||||||
|
-
|
||||||
|
- if (!CONST_INT_P (operands[2])
|
||||||
|
- || INTVAL (operands[2]) <= 0
|
||||||
|
- || (i = exact_log2 (INTVAL (operands[2]))) < 0)
|
||||||
|
- {
|
||||||
|
- if (!TARGET_MODULO)
|
||||||
|
- FAIL;
|
||||||
|
-
|
||||||
|
- operands[2] = force_reg (<MODE>mode, operands[2]);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- temp1 = gen_reg_rtx (<MODE>mode);
|
||||||
|
- temp2 = gen_reg_rtx (<MODE>mode);
|
||||||
|
-
|
||||||
|
- emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
|
||||||
|
- emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
|
||||||
|
- emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
|
||||||
|
- DONE;
|
||||||
|
- }
|
||||||
|
-})
|
||||||
|
-
|
||||||
|
;; In order to enable using a peephole2 for combining div/mod to eliminate the
|
||||||
|
;; mod, prefer putting the result of mod into a different register
|
||||||
|
(define_insn "*mod<mode>3"
|
||||||
|
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
|
||||||
|
index 7633171df9c..1a2ac66bd43 100644
|
||||||
|
--- a/gcc/config/rs6000/vsx.md
|
||||||
|
+++ b/gcc/config/rs6000/vsx.md
|
||||||
|
@@ -1602,53 +1602,6 @@
|
||||||
|
"xvdiv<sd>p %x0,%x1,%x2"
|
||||||
|
[(set_attr "type" "<VStype_div>")])
|
||||||
|
|
||||||
|
-; Emulate vector with scalar for vec_div in V2DImode
|
||||||
|
-(define_insn_and_split "vsx_div_v2di"
|
||||||
|
- [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
|
||||||
|
- (unspec:V2DI [(match_operand:V2DI 1 "vsx_register_operand" "wa")
|
||||||
|
- (match_operand:V2DI 2 "vsx_register_operand" "wa")]
|
||||||
|
- UNSPEC_VSX_DIVSD))]
|
||||||
|
- "VECTOR_MEM_VSX_P (V2DImode)"
|
||||||
|
- "#"
|
||||||
|
- "VECTOR_MEM_VSX_P (V2DImode) && !reload_completed"
|
||||||
|
- [(const_int 0)]
|
||||||
|
-{
|
||||||
|
- rtx op0 = operands[0];
|
||||||
|
- rtx op1 = operands[1];
|
||||||
|
- rtx op2 = operands[2];
|
||||||
|
- rtx op3 = gen_reg_rtx (DImode);
|
||||||
|
- rtx op4 = gen_reg_rtx (DImode);
|
||||||
|
- rtx op5 = gen_reg_rtx (DImode);
|
||||||
|
- emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||||||
|
- emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||||||
|
- if (TARGET_POWERPC64)
|
||||||
|
- emit_insn (gen_divdi3 (op5, op3, op4));
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- rtx libfunc = optab_libfunc (sdiv_optab, DImode);
|
||||||
|
- rtx target = emit_library_call_value (libfunc,
|
||||||
|
- op5, LCT_NORMAL, DImode,
|
||||||
|
- op3, DImode,
|
||||||
|
- op4, DImode);
|
||||||
|
- emit_move_insn (op5, target);
|
||||||
|
- }
|
||||||
|
- emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||||||
|
- emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||||||
|
- if (TARGET_POWERPC64)
|
||||||
|
- emit_insn (gen_divdi3 (op3, op3, op4));
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- rtx libfunc = optab_libfunc (sdiv_optab, DImode);
|
||||||
|
- rtx target = emit_library_call_value (libfunc,
|
||||||
|
- op3, LCT_NORMAL, DImode,
|
||||||
|
- op3, DImode,
|
||||||
|
- op4, DImode);
|
||||||
|
- emit_move_insn (op3, target);
|
||||||
|
- }
|
||||||
|
- emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
|
||||||
|
- DONE;
|
||||||
|
-}
|
||||||
|
- [(set_attr "type" "div")])
|
||||||
|
|
||||||
|
(define_insn_and_split "vsx_udiv_v2di"
|
||||||
|
[(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
|
||||||
|
@@ -1668,9 +1621,6 @@
|
||||||
|
rtx op5 = gen_reg_rtx (DImode);
|
||||||
|
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||||||
|
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||||||
|
- if (TARGET_POWERPC64)
|
||||||
|
- emit_insn (gen_udivdi3 (op5, op3, op4));
|
||||||
|
- else
|
||||||
|
{
|
||||||
|
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||||||
|
rtx target = emit_library_call_value (libfunc,
|
||||||
|
@@ -1681,9 +1631,6 @@
|
||||||
|
}
|
||||||
|
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||||||
|
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||||||
|
- if (TARGET_POWERPC64)
|
||||||
|
- emit_insn (gen_udivdi3 (op3, op3, op4));
|
||||||
|
- else
|
||||||
|
{
|
||||||
|
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||||||
|
rtx target = emit_library_call_value (libfunc,
|
@ -1,327 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
USE_LITEDRAM : boolean := false;
|
|
||||||
NO_BRAM : boolean := false;
|
|
||||||
DISABLE_FLATTEN_CORE : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 10485760;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 2048;
|
|
||||||
UART_IS_16550 : boolean := true
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
clk200_p : in std_ulogic;
|
|
||||||
clk200_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- P2 signals used as UART
|
|
||||||
uart_rx : in std_ulogic;
|
|
||||||
uart_tx : out std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0 : out std_logic;
|
|
||||||
led1 : out std_logic;
|
|
||||||
led2 : out std_logic;
|
|
||||||
led3 : out std_logic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_logic_vector(15 downto 0);
|
|
||||||
ddram_ba : out std_logic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_logic;
|
|
||||||
ddram_cas_n : out std_logic;
|
|
||||||
ddram_we_n : out std_logic;
|
|
||||||
ddram_dm : out std_logic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_logic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_logic_vector(1 downto 0);
|
|
||||||
ddram_dqs_n : inout std_logic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_logic;
|
|
||||||
ddram_clk_n : out std_logic;
|
|
||||||
ddram_cke : out std_logic;
|
|
||||||
ddram_odt : out std_logic;
|
|
||||||
ddram_reset_n : out std_logic
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Internal clock
|
|
||||||
signal ext_clk : std_ulogic;
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- ddram clock signals as vectors
|
|
||||||
signal ddram_clk_p_vec : std_logic_vector(0 downto 0);
|
|
||||||
signal ddram_clk_n_vec : std_logic_vector(0 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 1024 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
|
||||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
|
||||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
|
||||||
LOG_LENGTH => LOG_LENGTH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => uart_tx,
|
|
||||||
uart0_rxd => uart_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash. The SPI clk needs to be fed through the STARTUPE2
|
|
||||||
-- primitive of the FPGA as it's not a normal pin
|
|
||||||
--
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
STARTUPE2_INST: STARTUPE2
|
|
||||||
port map (
|
|
||||||
CLK => '0',
|
|
||||||
GSR => '0',
|
|
||||||
GTS => '0',
|
|
||||||
KEYCLEARB => '0',
|
|
||||||
PACK => '0',
|
|
||||||
USRCCLKO => spi_sck,
|
|
||||||
USRCCLKTS => '0',
|
|
||||||
USRDONEO => '1',
|
|
||||||
USRDONETS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
clk200: IBUFDS
|
|
||||||
port map (
|
|
||||||
i => clk200_p,
|
|
||||||
ib => clk200_n,
|
|
||||||
o => ext_clk
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => false
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => '0',
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => 200000000,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
led0 <= soc_rst;
|
|
||||||
led1 <= pll_rst;
|
|
||||||
led2 <= not system_clk_locked;
|
|
||||||
led3 <= '0';
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
-- Vivado barfs on those differential signals if left
|
|
||||||
-- unconnected. So instanciate a diff. buffer and feed
|
|
||||||
-- it a constant '0'.
|
|
||||||
dummy_dram_clk: OBUFDS
|
|
||||||
port map (
|
|
||||||
O => ddram_clk_p,
|
|
||||||
OB => ddram_clk_n,
|
|
||||||
I => ddram_clk_dummy
|
|
||||||
);
|
|
||||||
ddram_clk_dummy <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from the generator
|
|
||||||
-- but for now, assert it's 100Mhz
|
|
||||||
assert CLK_FREQUENCY = 100000000;
|
|
||||||
|
|
||||||
ddram_clk_p_vec <= (others => ddram_clk_p);
|
|
||||||
ddram_clk_n_vec <= (others => ddram_clk_n);
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => false,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => '1',
|
|
||||||
ext_rst_in => '0',
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => open
|
|
||||||
);
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 26,
|
|
||||||
DRAM_ALINES => 16,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => soc_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_ext_io_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => open,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_dqs_n => ddram_dqs_n,
|
|
||||||
ddram_clk_p => ddram_clk_p_vec,
|
|
||||||
ddram_clk_n => ddram_clk_n_vec,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
led0 <= soc_rst;
|
|
||||||
led1 <= pll_rst;
|
|
||||||
led2 <= not dram_init_done or dram_init_error;
|
|
||||||
led3 <= not dram_init_error; -- Make it blink ?
|
|
||||||
end generate;
|
|
||||||
end architecture behaviour;
|
|
@ -1,770 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
HAS_FPU : boolean := true;
|
|
||||||
HAS_BTC : boolean := true;
|
|
||||||
HAS_SHORT_MULT : boolean := false;
|
|
||||||
USE_LITEDRAM : boolean := false;
|
|
||||||
NO_BRAM : boolean := false;
|
|
||||||
DISABLE_FLATTEN_CORE : boolean := false;
|
|
||||||
SCLK_STARTUPE2 : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 4194304;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 512;
|
|
||||||
USE_LITEETH : boolean := false;
|
|
||||||
UART_IS_16550 : boolean := false;
|
|
||||||
HAS_UART1 : boolean := true;
|
|
||||||
USE_LITESDCARD : boolean := false;
|
|
||||||
HAS_GPIO : boolean := true;
|
|
||||||
NGPIO : natural := 32
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
ext_clk : in std_ulogic;
|
|
||||||
ext_rst_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
uart_main_tx : out std_ulogic;
|
|
||||||
uart_main_rx : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0_b : out std_ulogic;
|
|
||||||
led0_g : out std_ulogic;
|
|
||||||
led0_r : out std_ulogic;
|
|
||||||
led4 : out std_ulogic;
|
|
||||||
led5 : out std_ulogic;
|
|
||||||
led6 : out std_ulogic;
|
|
||||||
led7 : out std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_clk : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- GPIO
|
|
||||||
shield_io : inout std_ulogic_vector(44 downto 0);
|
|
||||||
|
|
||||||
-- Ethernet
|
|
||||||
eth_ref_clk : out std_ulogic;
|
|
||||||
eth_clocks_tx : in std_ulogic;
|
|
||||||
eth_clocks_rx : in std_ulogic;
|
|
||||||
eth_rst_n : out std_ulogic;
|
|
||||||
eth_mdio : inout std_ulogic;
|
|
||||||
eth_mdc : out std_ulogic;
|
|
||||||
eth_rx_dv : in std_ulogic;
|
|
||||||
eth_rx_er : in std_ulogic;
|
|
||||||
eth_rx_data : in std_ulogic_vector(3 downto 0);
|
|
||||||
eth_tx_en : out std_ulogic;
|
|
||||||
eth_tx_data : out std_ulogic_vector(3 downto 0);
|
|
||||||
eth_col : in std_ulogic;
|
|
||||||
eth_crs : in std_ulogic;
|
|
||||||
|
|
||||||
-- SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
|
||||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_ulogic;
|
|
||||||
ddram_cas_n : out std_ulogic;
|
|
||||||
ddram_we_n : out std_ulogic;
|
|
||||||
ddram_cs_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_ulogic;
|
|
||||||
ddram_clk_n : out std_ulogic;
|
|
||||||
ddram_cke : out std_ulogic;
|
|
||||||
ddram_odt : out std_ulogic;
|
|
||||||
ddram_reset_n : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
signal eth_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- External IOs from the SoC
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal wb_ext_is_eth : std_ulogic;
|
|
||||||
signal wb_ext_is_sdcard : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteEth connection
|
|
||||||
signal ext_irq_eth : std_ulogic;
|
|
||||||
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteSDCard connection
|
|
||||||
signal ext_irq_sdcard : std_ulogic := '0';
|
|
||||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
|
||||||
signal wb_sddma_in : wb_io_slave_out;
|
|
||||||
signal wb_sddma_nr : wb_io_master_out;
|
|
||||||
signal wb_sddma_ir : wb_io_slave_out;
|
|
||||||
-- for conversion from non-pipelined wishbone to pipelined
|
|
||||||
signal wb_sddma_stb_sent : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- Status LED
|
|
||||||
signal led0_b_pwm : std_ulogic;
|
|
||||||
signal led0_r_pwm : std_ulogic;
|
|
||||||
signal led0_g_pwm : std_ulogic;
|
|
||||||
|
|
||||||
-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
|
|
||||||
signal pwm_counter : std_ulogic_vector(8 downto 0);
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- GPIO
|
|
||||||
signal gpio_in : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal gpio_out : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal gpio_dir : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
-- ddram clock signals as vectors
|
|
||||||
signal ddram_clk_p_vec : std_logic_vector(0 downto 0);
|
|
||||||
signal ddram_clk_n_vec : std_logic_vector(0 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_FPU => HAS_FPU,
|
|
||||||
HAS_BTC => HAS_BTC,
|
|
||||||
HAS_SHORT_MULT => HAS_SHORT_MULT,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 256 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
|
||||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
|
||||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
|
||||||
LOG_LENGTH => LOG_LENGTH,
|
|
||||||
HAS_LITEETH => USE_LITEETH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550,
|
|
||||||
HAS_UART1 => HAS_UART1,
|
|
||||||
HAS_SD_CARD => USE_LITESDCARD,
|
|
||||||
HAS_GPIO => HAS_GPIO,
|
|
||||||
NGPIO => NGPIO
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => uart_main_tx,
|
|
||||||
uart0_rxd => uart_main_rx,
|
|
||||||
|
|
||||||
-- UART1 signals
|
|
||||||
--uart1_txd => uart_pmod_tx,
|
|
||||||
--uart1_rxd => uart_pmod_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- GPIO signals
|
|
||||||
gpio_in => gpio_in,
|
|
||||||
gpio_out => gpio_out,
|
|
||||||
gpio_dir => gpio_dir,
|
|
||||||
|
|
||||||
-- External interrupts
|
|
||||||
ext_irq_eth => ext_irq_eth,
|
|
||||||
ext_irq_sdcard => ext_irq_sdcard,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
|
|
||||||
-- IO wishbone
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
wb_ext_is_eth => wb_ext_is_eth,
|
|
||||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
|
||||||
|
|
||||||
-- DMA wishbone
|
|
||||||
wishbone_dma_in => wb_sddma_in,
|
|
||||||
wishbone_dma_out => wb_sddma_out,
|
|
||||||
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
--uart_pmod_rts_n <= '0';
|
|
||||||
|
|
||||||
-- SPI Flash
|
|
||||||
--
|
|
||||||
-- Note: Unlike many other boards, the SPI flash on the Arty has
|
|
||||||
-- an actual pin to generate the clock and doesn't require to use
|
|
||||||
-- the STARTUPE2 primitive.
|
|
||||||
--
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
spi_sclk_startupe2: if SCLK_STARTUPE2 generate
|
|
||||||
spi_flash_clk <= 'Z';
|
|
||||||
|
|
||||||
STARTUPE2_INST: STARTUPE2
|
|
||||||
port map (
|
|
||||||
CLK => '0',
|
|
||||||
GSR => '0',
|
|
||||||
GTS => '0',
|
|
||||||
KEYCLEARB => '0',
|
|
||||||
PACK => '0',
|
|
||||||
USRCCLKO => spi_sck,
|
|
||||||
USRCCLKTS => '0',
|
|
||||||
USRDONEO => '1',
|
|
||||||
USRDONETS => '0'
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
spi_direct_sclk: if not SCLK_STARTUPE2 generate
|
|
||||||
spi_flash_clk <= spi_sck;
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked and eth_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => 100000000,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
led0_b_pwm <= '1';
|
|
||||||
led0_r_pwm <= '1';
|
|
||||||
led0_g_pwm <= '0';
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
-- Vivado barfs on those differential signals if left
|
|
||||||
-- unconnected. So instanciate a diff. buffer and feed
|
|
||||||
-- it a constant '0'.
|
|
||||||
dummy_dram_clk: OBUFDS
|
|
||||||
port map (
|
|
||||||
O => ddram_clk_p,
|
|
||||||
OB => ddram_clk_n,
|
|
||||||
I => ddram_clk_dummy
|
|
||||||
);
|
|
||||||
ddram_clk_dummy <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
signal rst_gen_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from the generator
|
|
||||||
-- but for now, assert it's 100Mhz
|
|
||||||
assert CLK_FREQUENCY = 100000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => eth_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => rst_gen_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Generate SoC reset
|
|
||||||
soc_rst_gen: process(system_clk)
|
|
||||||
begin
|
|
||||||
if ext_rst_n = '0' then
|
|
||||||
soc_rst <= '1';
|
|
||||||
elsif rising_edge(system_clk) then
|
|
||||||
soc_rst <= dram_sys_rst or not eth_clk_locked or not system_clk_locked;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
ddram_clk_p_vec <= (others => ddram_clk_p);
|
|
||||||
ddram_clk_n_vec <= (others => ddram_clk_n);
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 14,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => dram_sys_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_dram_ctrl_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => ddram_cs_n,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_dqs_n => ddram_dqs_n,
|
|
||||||
ddram_clk_p => ddram_clk_p_vec,
|
|
||||||
ddram_clk_n => ddram_clk_n_vec,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
led0_b_pwm <= not dram_init_done;
|
|
||||||
led0_r_pwm <= dram_init_error;
|
|
||||||
led0_g_pwm <= dram_init_done and not dram_init_error;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_liteeth : if USE_LITEETH generate
|
|
||||||
|
|
||||||
component liteeth_core port (
|
|
||||||
sys_clock : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
mii_eth_clocks_tx : in std_ulogic;
|
|
||||||
mii_eth_clocks_rx : in std_ulogic;
|
|
||||||
mii_eth_rst_n : out std_ulogic;
|
|
||||||
mii_eth_mdio : in std_ulogic;
|
|
||||||
mii_eth_mdc : out std_ulogic;
|
|
||||||
mii_eth_rx_dv : in std_ulogic;
|
|
||||||
mii_eth_rx_er : in std_ulogic;
|
|
||||||
mii_eth_rx_data : in std_ulogic_vector(3 downto 0);
|
|
||||||
mii_eth_tx_en : out std_ulogic;
|
|
||||||
mii_eth_tx_data : out std_ulogic_vector(3 downto 0);
|
|
||||||
mii_eth_col : in std_ulogic;
|
|
||||||
mii_eth_crs : in std_ulogic;
|
|
||||||
wishbone_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wishbone_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wishbone_cyc : in std_ulogic;
|
|
||||||
wishbone_stb : in std_ulogic;
|
|
||||||
wishbone_ack : out std_ulogic;
|
|
||||||
wishbone_we : in std_ulogic;
|
|
||||||
wishbone_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wishbone_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wishbone_err : out std_ulogic;
|
|
||||||
interrupt : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_eth_cyc : std_ulogic;
|
|
||||||
signal wb_eth_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
-- Change this to use a PLL instead of a BUFR to generate the 25Mhz
|
|
||||||
-- reference clock to the PHY.
|
|
||||||
constant USE_PLL : boolean := false;
|
|
||||||
begin
|
|
||||||
eth_use_pll: if USE_PLL generate
|
|
||||||
signal eth_clk_25 : std_ulogic;
|
|
||||||
signal eth_clkfb : std_ulogic;
|
|
||||||
begin
|
|
||||||
pll_eth : PLLE2_BASE
|
|
||||||
generic map (
|
|
||||||
BANDWIDTH => "OPTIMIZED",
|
|
||||||
CLKFBOUT_MULT => 16,
|
|
||||||
CLKIN1_PERIOD => 10.0,
|
|
||||||
CLKOUT0_DIVIDE => 64,
|
|
||||||
DIVCLK_DIVIDE => 1,
|
|
||||||
STARTUP_WAIT => "FALSE")
|
|
||||||
port map (
|
|
||||||
CLKOUT0 => eth_clk_25,
|
|
||||||
CLKOUT1 => open,
|
|
||||||
CLKOUT2 => open,
|
|
||||||
CLKOUT3 => open,
|
|
||||||
CLKOUT4 => open,
|
|
||||||
CLKOUT5 => open,
|
|
||||||
CLKFBOUT => eth_clkfb,
|
|
||||||
LOCKED => eth_clk_locked,
|
|
||||||
CLKIN1 => ext_clk,
|
|
||||||
PWRDWN => '0',
|
|
||||||
RST => pll_rst,
|
|
||||||
CLKFBIN => eth_clkfb);
|
|
||||||
|
|
||||||
eth_clk_buf: BUFG
|
|
||||||
port map (
|
|
||||||
I => eth_clk_25,
|
|
||||||
O => eth_ref_clk
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
eth_use_bufr: if not USE_PLL generate
|
|
||||||
eth_clk_div: BUFR
|
|
||||||
generic map (
|
|
||||||
BUFR_DIVIDE => "4"
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
I => system_clk,
|
|
||||||
O => eth_ref_clk,
|
|
||||||
CE => '1',
|
|
||||||
CLR => '0'
|
|
||||||
);
|
|
||||||
eth_clk_locked <= '1';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
liteeth : liteeth_core
|
|
||||||
port map(
|
|
||||||
sys_clock => system_clk,
|
|
||||||
sys_reset => soc_rst,
|
|
||||||
mii_eth_clocks_tx => eth_clocks_tx,
|
|
||||||
mii_eth_clocks_rx => eth_clocks_rx,
|
|
||||||
mii_eth_rst_n => eth_rst_n,
|
|
||||||
mii_eth_mdio => eth_mdio,
|
|
||||||
mii_eth_mdc => eth_mdc,
|
|
||||||
mii_eth_rx_dv => eth_rx_dv,
|
|
||||||
mii_eth_rx_er => eth_rx_er,
|
|
||||||
mii_eth_rx_data => eth_rx_data,
|
|
||||||
mii_eth_tx_en => eth_tx_en,
|
|
||||||
mii_eth_tx_data => eth_tx_data,
|
|
||||||
mii_eth_col => eth_col,
|
|
||||||
mii_eth_crs => eth_crs,
|
|
||||||
wishbone_adr => wb_eth_adr,
|
|
||||||
wishbone_dat_w => wb_ext_io_in.dat,
|
|
||||||
wishbone_dat_r => wb_eth_out.dat,
|
|
||||||
wishbone_sel => wb_ext_io_in.sel,
|
|
||||||
wishbone_cyc => wb_eth_cyc,
|
|
||||||
wishbone_stb => wb_ext_io_in.stb,
|
|
||||||
wishbone_ack => wb_eth_out.ack,
|
|
||||||
wishbone_we => wb_ext_io_in.we,
|
|
||||||
wishbone_cti => "000",
|
|
||||||
wishbone_bte => "00",
|
|
||||||
wishbone_err => open,
|
|
||||||
interrupt => ext_irq_eth
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with "chip select" from soc
|
|
||||||
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
|
|
||||||
|
|
||||||
-- Remove top address bits as liteeth decoder doesn't know about them
|
|
||||||
wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
|
|
||||||
|
|
||||||
-- LiteETH isn't pipelined
|
|
||||||
wb_eth_out.stall <= not wb_eth_out.ack;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
no_liteeth : if not USE_LITEETH generate
|
|
||||||
eth_clk_locked <= '1';
|
|
||||||
ext_irq_eth <= '0';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- SD card pmod
|
|
||||||
has_sdcard : if USE_LITESDCARD generate
|
|
||||||
component litesdcard_core port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
-- wishbone for accessing control registers
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
-- wishbone for SD card core to use for DMA
|
|
||||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
|
||||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
|
||||||
wb_dma_cyc : out std_ulogic;
|
|
||||||
wb_dma_stb : out std_ulogic;
|
|
||||||
wb_dma_ack : in std_ulogic;
|
|
||||||
wb_dma_we : out std_ulogic;
|
|
||||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
|
||||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
|
||||||
wb_dma_err : in std_ulogic;
|
|
||||||
-- connections to SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
irq : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_sdcard_cyc : std_ulogic;
|
|
||||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
litesdcard : litesdcard_core
|
|
||||||
port map (
|
|
||||||
clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
wb_ctrl_adr => wb_sdcard_adr,
|
|
||||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
|
||||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
|
||||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
|
||||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
|
||||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
|
||||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
|
||||||
wb_ctrl_we => wb_ext_io_in.we,
|
|
||||||
wb_ctrl_cti => "000",
|
|
||||||
wb_ctrl_bte => "00",
|
|
||||||
wb_ctrl_err => open,
|
|
||||||
wb_dma_adr => wb_sddma_nr.adr,
|
|
||||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
|
||||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
|
||||||
wb_dma_sel => wb_sddma_nr.sel,
|
|
||||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
|
||||||
wb_dma_stb => wb_sddma_nr.stb,
|
|
||||||
wb_dma_ack => wb_sddma_ir.ack,
|
|
||||||
wb_dma_we => wb_sddma_nr.we,
|
|
||||||
wb_dma_cti => open,
|
|
||||||
wb_dma_bte => open,
|
|
||||||
wb_dma_err => '0',
|
|
||||||
sdcard_data => sdcard_data,
|
|
||||||
sdcard_cmd => sdcard_cmd,
|
|
||||||
sdcard_clk => sdcard_clk,
|
|
||||||
sdcard_cd => sdcard_cd,
|
|
||||||
irq => ext_irq_sdcard
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with chip select from SoC
|
|
||||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
|
||||||
|
|
||||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
|
|
||||||
|
|
||||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
|
||||||
|
|
||||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
|
||||||
-- non-acknowledged strobes
|
|
||||||
process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
wb_sddma_out <= wb_sddma_nr;
|
|
||||||
if wb_sddma_stb_sent = '1' or
|
|
||||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
|
||||||
wb_sddma_out.stb <= '0';
|
|
||||||
end if;
|
|
||||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
|
||||||
wb_sddma_stb_sent <= '0';
|
|
||||||
elsif wb_sddma_in.stall = '0' then
|
|
||||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
|
||||||
end if;
|
|
||||||
wb_sddma_ir <= wb_sddma_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- Mux WB response on the IO bus
|
|
||||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
|
|
||||||
wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
|
||||||
wb_dram_ctrl_out;
|
|
||||||
|
|
||||||
leds_pwm : process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
|
|
||||||
if pwm_counter(8 downto 4) = "00000" then
|
|
||||||
led0_b <= led0_b_pwm;
|
|
||||||
led0_r <= led0_r_pwm;
|
|
||||||
led0_g <= led0_g_pwm;
|
|
||||||
else
|
|
||||||
led0_b <= '0';
|
|
||||||
led0_r <= '0';
|
|
||||||
led0_g <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
led4 <= system_clk_locked;
|
|
||||||
led5 <= eth_clk_locked;
|
|
||||||
led6 <= not soc_rst;
|
|
||||||
|
|
||||||
-- GPIO
|
|
||||||
gpio_in(0) <= shield_io(0);
|
|
||||||
gpio_in(1) <= shield_io(1);
|
|
||||||
gpio_in(2) <= shield_io(2);
|
|
||||||
gpio_in(3) <= shield_io(3);
|
|
||||||
gpio_in(4) <= shield_io(4);
|
|
||||||
gpio_in(5) <= shield_io(5);
|
|
||||||
gpio_in(6) <= shield_io(6);
|
|
||||||
gpio_in(7) <= shield_io(7);
|
|
||||||
gpio_in(8) <= shield_io(8);
|
|
||||||
gpio_in(9) <= shield_io(9);
|
|
||||||
gpio_in(10) <= shield_io(10);
|
|
||||||
gpio_in(11) <= shield_io(11);
|
|
||||||
gpio_in(12) <= shield_io(12);
|
|
||||||
gpio_in(13) <= shield_io(13);
|
|
||||||
gpio_in(14) <= shield_io(26);
|
|
||||||
gpio_in(15) <= shield_io(27);
|
|
||||||
gpio_in(16) <= shield_io(28);
|
|
||||||
gpio_in(17) <= shield_io(29);
|
|
||||||
gpio_in(18) <= shield_io(30);
|
|
||||||
gpio_in(19) <= shield_io(31);
|
|
||||||
gpio_in(20) <= shield_io(32);
|
|
||||||
gpio_in(21) <= shield_io(33);
|
|
||||||
gpio_in(22) <= shield_io(34);
|
|
||||||
gpio_in(23) <= shield_io(35);
|
|
||||||
gpio_in(24) <= shield_io(36);
|
|
||||||
gpio_in(25) <= shield_io(37);
|
|
||||||
gpio_in(26) <= shield_io(38);
|
|
||||||
gpio_in(27) <= shield_io(39);
|
|
||||||
gpio_in(28) <= shield_io(40);
|
|
||||||
gpio_in(29) <= shield_io(41);
|
|
||||||
gpio_in(30) <= shield_io(43);
|
|
||||||
gpio_in(31) <= shield_io(44);
|
|
||||||
|
|
||||||
shield_io(0) <= gpio_out(0) when gpio_dir(0) = '1' else 'Z';
|
|
||||||
shield_io(1) <= gpio_out(1) when gpio_dir(1) = '1' else 'Z';
|
|
||||||
shield_io(2) <= gpio_out(2) when gpio_dir(2) = '1' else 'Z';
|
|
||||||
shield_io(3) <= gpio_out(3) when gpio_dir(3) = '1' else 'Z';
|
|
||||||
shield_io(4) <= gpio_out(4) when gpio_dir(4) = '1' else 'Z';
|
|
||||||
shield_io(5) <= gpio_out(5) when gpio_dir(5) = '1' else 'Z';
|
|
||||||
shield_io(6) <= gpio_out(6) when gpio_dir(6) = '1' else 'Z';
|
|
||||||
shield_io(7) <= gpio_out(7) when gpio_dir(7) = '1' else 'Z';
|
|
||||||
shield_io(8) <= gpio_out(8) when gpio_dir(8) = '1' else 'Z';
|
|
||||||
shield_io(9) <= gpio_out(9) when gpio_dir(9) = '1' else 'Z';
|
|
||||||
shield_io(10) <= gpio_out(10) when gpio_dir(10) = '1' else 'Z';
|
|
||||||
shield_io(11) <= gpio_out(11) when gpio_dir(11) = '1' else 'Z';
|
|
||||||
shield_io(12) <= gpio_out(12) when gpio_dir(12) = '1' else 'Z';
|
|
||||||
shield_io(13) <= gpio_out(13) when gpio_dir(13) = '1' else 'Z';
|
|
||||||
shield_io(26) <= gpio_out(14) when gpio_dir(14) = '1' else 'Z';
|
|
||||||
shield_io(27) <= gpio_out(15) when gpio_dir(15) = '1' else 'Z';
|
|
||||||
shield_io(28) <= gpio_out(16) when gpio_dir(16) = '1' else 'Z';
|
|
||||||
shield_io(29) <= gpio_out(17) when gpio_dir(17) = '1' else 'Z';
|
|
||||||
shield_io(30) <= gpio_out(18) when gpio_dir(18) = '1' else 'Z';
|
|
||||||
shield_io(31) <= gpio_out(19) when gpio_dir(19) = '1' else 'Z';
|
|
||||||
shield_io(32) <= gpio_out(20) when gpio_dir(20) = '1' else 'Z';
|
|
||||||
shield_io(33) <= gpio_out(21) when gpio_dir(21) = '1' else 'Z';
|
|
||||||
shield_io(34) <= gpio_out(22) when gpio_dir(22) = '1' else 'Z';
|
|
||||||
shield_io(35) <= gpio_out(23) when gpio_dir(23) = '1' else 'Z';
|
|
||||||
shield_io(36) <= gpio_out(24) when gpio_dir(24) = '1' else 'Z';
|
|
||||||
shield_io(37) <= gpio_out(25) when gpio_dir(25) = '1' else 'Z';
|
|
||||||
shield_io(38) <= gpio_out(26) when gpio_dir(26) = '1' else 'Z';
|
|
||||||
shield_io(39) <= gpio_out(27) when gpio_dir(27) = '1' else 'Z';
|
|
||||||
shield_io(40) <= gpio_out(28) when gpio_dir(28) = '1' else 'Z';
|
|
||||||
shield_io(41) <= gpio_out(29) when gpio_dir(29) = '1' else 'Z';
|
|
||||||
shield_io(43) <= gpio_out(30) when gpio_dir(30) = '1' else 'Z';
|
|
||||||
shield_io(44) <= gpio_out(31) when gpio_dir(31) = '1' else 'Z';
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,330 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
USE_LITEDRAM : boolean := false;
|
|
||||||
NO_BRAM : boolean := false;
|
|
||||||
DISABLE_FLATTEN_CORE : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 10485760;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 2048;
|
|
||||||
UART_IS_16550 : boolean := true
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
clk200_p : in std_ulogic;
|
|
||||||
clk200_n : in std_ulogic;
|
|
||||||
ext_rst : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
uart_main_tx : out std_ulogic;
|
|
||||||
uart_main_rx : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0 : out std_logic;
|
|
||||||
led1 : out std_logic;
|
|
||||||
led2 : out std_logic;
|
|
||||||
led3 : out std_logic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_logic_vector(14 downto 0);
|
|
||||||
ddram_ba : out std_logic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_logic;
|
|
||||||
ddram_cas_n : out std_logic;
|
|
||||||
ddram_we_n : out std_logic;
|
|
||||||
ddram_cs_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_logic_vector(3 downto 0);
|
|
||||||
ddram_dq : inout std_logic_vector(31 downto 0);
|
|
||||||
ddram_dqs_p : inout std_logic_vector(3 downto 0);
|
|
||||||
ddram_dqs_n : inout std_logic_vector(3 downto 0);
|
|
||||||
ddram_clk_p : out std_logic;
|
|
||||||
ddram_clk_n : out std_logic;
|
|
||||||
ddram_cke : out std_logic;
|
|
||||||
ddram_odt : out std_logic;
|
|
||||||
ddram_reset_n : out std_logic
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Internal clock
|
|
||||||
signal ext_clk : std_ulogic;
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- ddram clock signals as vectors
|
|
||||||
signal ddram_clk_p_vec : std_logic_vector(0 downto 0);
|
|
||||||
signal ddram_clk_n_vec : std_logic_vector(0 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 1024 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
|
||||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
|
||||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
|
||||||
LOG_LENGTH => LOG_LENGTH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => uart_main_tx,
|
|
||||||
uart0_rxd => uart_main_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash. The SPI clk needs to be fed through the STARTUPE2
|
|
||||||
-- primitive of the FPGA as it's not a normal pin
|
|
||||||
--
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
STARTUPE2_INST: STARTUPE2
|
|
||||||
port map (
|
|
||||||
CLK => '0',
|
|
||||||
GSR => '0',
|
|
||||||
GTS => '0',
|
|
||||||
KEYCLEARB => '0',
|
|
||||||
PACK => '0',
|
|
||||||
USRCCLKO => spi_sck,
|
|
||||||
USRCCLKTS => '0',
|
|
||||||
USRDONEO => '1',
|
|
||||||
USRDONETS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
clk200: IBUFDS
|
|
||||||
port map (
|
|
||||||
i => clk200_p,
|
|
||||||
ib => clk200_n,
|
|
||||||
o => ext_clk
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => 200000000,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
led0 <= soc_rst;
|
|
||||||
led1 <= pll_rst;
|
|
||||||
led2 <= not system_clk_locked;
|
|
||||||
led3 <= '0';
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
-- Vivado barfs on those differential signals if left
|
|
||||||
-- unconnected. So instanciate a diff. buffer and feed
|
|
||||||
-- it a constant '0'.
|
|
||||||
dummy_dram_clk: OBUFDS
|
|
||||||
port map (
|
|
||||||
O => ddram_clk_p,
|
|
||||||
OB => ddram_clk_n,
|
|
||||||
I => ddram_clk_dummy
|
|
||||||
);
|
|
||||||
ddram_clk_dummy <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from the generator
|
|
||||||
-- but for now, assert it's 100Mhz
|
|
||||||
assert CLK_FREQUENCY = 100000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => '1',
|
|
||||||
ext_rst_in => ext_rst,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => open
|
|
||||||
);
|
|
||||||
|
|
||||||
ddram_clk_p_vec <= (others => ddram_clk_p);
|
|
||||||
ddram_clk_n_vec <= (others => ddram_clk_n);
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 25,
|
|
||||||
DRAM_ALINES => 15,
|
|
||||||
DRAM_DLINES => 32,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 256,
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => soc_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_ext_io_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => ddram_cs_n,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_dqs_n => ddram_dqs_n,
|
|
||||||
ddram_clk_p => ddram_clk_p_vec,
|
|
||||||
ddram_clk_n => ddram_clk_n_vec,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
led0 <= soc_rst;
|
|
||||||
led1 <= pll_rst;
|
|
||||||
led2 <= not dram_init_done or dram_init_error;
|
|
||||||
led3 <= not dram_init_error; -- Make it blink ?
|
|
||||||
end generate;
|
|
||||||
end architecture behaviour;
|
|
@ -1,587 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
HAS_FPU : boolean := true;
|
|
||||||
HAS_BTC : boolean := true;
|
|
||||||
HAS_SHORT_MULT: boolean := false;
|
|
||||||
USE_LITEDRAM : boolean := false;
|
|
||||||
NO_BRAM : boolean := false;
|
|
||||||
DISABLE_FLATTEN_CORE : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 10485760;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 2048;
|
|
||||||
UART_IS_16550 : boolean := true;
|
|
||||||
USE_LITEETH : boolean := false;
|
|
||||||
USE_LITESDCARD : boolean := false
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
ext_clk : in std_ulogic;
|
|
||||||
ext_rst_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
uart_main_tx : out std_ulogic;
|
|
||||||
uart_main_rx : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0 : out std_ulogic;
|
|
||||||
led1 : out std_ulogic;
|
|
||||||
led2 : out std_ulogic;
|
|
||||||
led3 : out std_ulogic;
|
|
||||||
led4 : out std_ulogic;
|
|
||||||
led5 : out std_ulogic;
|
|
||||||
led6 : out std_ulogic;
|
|
||||||
led7 : out std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- Ethernet
|
|
||||||
eth_clocks_tx : out std_ulogic;
|
|
||||||
eth_clocks_rx : in std_ulogic;
|
|
||||||
eth_rst_n : out std_ulogic;
|
|
||||||
eth_int_n : in std_ulogic;
|
|
||||||
eth_mdio : inout std_ulogic;
|
|
||||||
eth_mdc : out std_ulogic;
|
|
||||||
eth_rx_ctl : in std_ulogic;
|
|
||||||
eth_rx_data : in std_ulogic_vector(3 downto 0);
|
|
||||||
eth_tx_ctl : out std_ulogic;
|
|
||||||
eth_tx_data : out std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
sdcard_reset : out std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_logic_vector(14 downto 0);
|
|
||||||
ddram_ba : out std_logic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_logic;
|
|
||||||
ddram_cas_n : out std_logic;
|
|
||||||
ddram_we_n : out std_logic;
|
|
||||||
ddram_dm : out std_logic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_logic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_logic_vector(1 downto 0);
|
|
||||||
ddram_dqs_n : inout std_logic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_logic;
|
|
||||||
ddram_clk_n : out std_logic;
|
|
||||||
ddram_cke : out std_logic;
|
|
||||||
ddram_odt : out std_logic;
|
|
||||||
ddram_reset_n : out std_logic
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- External IOs from the SoC
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal wb_ext_is_eth : std_ulogic;
|
|
||||||
signal wb_ext_is_sdcard : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteEth connection
|
|
||||||
signal ext_irq_eth : std_ulogic;
|
|
||||||
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteSDCard connection
|
|
||||||
signal ext_irq_sdcard : std_ulogic := '0';
|
|
||||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
|
||||||
signal wb_sddma_in : wb_io_slave_out;
|
|
||||||
signal wb_sddma_nr : wb_io_master_out;
|
|
||||||
signal wb_sddma_ir : wb_io_slave_out;
|
|
||||||
-- for conversion from non-pipelined wishbone to pipelined
|
|
||||||
signal wb_sddma_stb_sent : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- ddram clock signals as vectors
|
|
||||||
signal ddram_clk_p_vec : std_logic_vector(0 downto 0);
|
|
||||||
signal ddram_clk_n_vec : std_logic_vector(0 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_FPU => HAS_FPU,
|
|
||||||
HAS_BTC => HAS_BTC,
|
|
||||||
HAS_SHORT_MULT=> HAS_SHORT_MULT,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 512 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
|
||||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
|
||||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
|
||||||
LOG_LENGTH => LOG_LENGTH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550,
|
|
||||||
HAS_LITEETH => USE_LITEETH,
|
|
||||||
HAS_SD_CARD => USE_LITESDCARD
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => uart_main_tx,
|
|
||||||
uart0_rxd => uart_main_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- External interrupts
|
|
||||||
ext_irq_eth => ext_irq_eth,
|
|
||||||
ext_irq_sdcard => ext_irq_sdcard,
|
|
||||||
|
|
||||||
-- IO wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
wb_ext_is_eth => wb_ext_is_eth,
|
|
||||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
|
||||||
|
|
||||||
-- DMA wishbone
|
|
||||||
wishbone_dma_in => wb_sddma_in,
|
|
||||||
wishbone_dma_out => wb_sddma_out,
|
|
||||||
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash. The SPI clk needs to be fed through the STARTUPE2
|
|
||||||
-- primitive of the FPGA as it's not a normal pin
|
|
||||||
--
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
STARTUPE2_INST: STARTUPE2
|
|
||||||
port map (
|
|
||||||
CLK => '0',
|
|
||||||
GSR => '0',
|
|
||||||
GTS => '0',
|
|
||||||
KEYCLEARB => '0',
|
|
||||||
PACK => '0',
|
|
||||||
USRCCLKO => spi_sck,
|
|
||||||
USRCCLKTS => '0',
|
|
||||||
USRDONEO => '1',
|
|
||||||
USRDONETS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => 100000000,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
led0 <= '1';
|
|
||||||
led1 <= not soc_rst;
|
|
||||||
led2 <= '0';
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
-- Vivado barfs on those differential signals if left
|
|
||||||
-- unconnected. So instanciate a diff. buffer and feed
|
|
||||||
-- it a constant '0'.
|
|
||||||
dummy_dram_clk: OBUFDS
|
|
||||||
port map (
|
|
||||||
O => ddram_clk_p,
|
|
||||||
OB => ddram_clk_n,
|
|
||||||
I => ddram_clk_dummy
|
|
||||||
);
|
|
||||||
ddram_clk_dummy <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from the generator
|
|
||||||
-- but for now, assert it's 100Mhz
|
|
||||||
assert CLK_FREQUENCY = 100000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => '1',
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => open
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Generate SoC reset
|
|
||||||
soc_rst_gen: process(system_clk)
|
|
||||||
begin
|
|
||||||
if ext_rst_n = '0' then
|
|
||||||
soc_rst <= '1';
|
|
||||||
elsif rising_edge(system_clk) then
|
|
||||||
soc_rst <= dram_sys_rst or not system_clk_locked;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
ddram_clk_p_vec <= (others => ddram_clk_p);
|
|
||||||
ddram_clk_n_vec <= (others => ddram_clk_n);
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 25,
|
|
||||||
DRAM_ALINES => 15,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => dram_sys_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_dram_ctrl_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => open,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_dqs_n => ddram_dqs_n,
|
|
||||||
ddram_clk_p => ddram_clk_p_vec,
|
|
||||||
ddram_clk_n => ddram_clk_n_vec,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
led0 <= not dram_init_done;
|
|
||||||
led1 <= dram_init_error; -- Make it blink ?
|
|
||||||
led2 <= dram_init_done and not dram_init_error;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_liteeth : if USE_LITEETH generate
|
|
||||||
|
|
||||||
component liteeth_core port (
|
|
||||||
sys_clock : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
rgmii_eth_clocks_tx : out std_ulogic;
|
|
||||||
rgmii_eth_clocks_rx : in std_ulogic;
|
|
||||||
rgmii_eth_rst_n : out std_ulogic;
|
|
||||||
rgmii_eth_int_n : in std_ulogic;
|
|
||||||
rgmii_eth_mdio : inout std_ulogic;
|
|
||||||
rgmii_eth_mdc : out std_ulogic;
|
|
||||||
rgmii_eth_rx_ctl : in std_ulogic;
|
|
||||||
rgmii_eth_rx_data : in std_ulogic_vector(3 downto 0);
|
|
||||||
rgmii_eth_tx_ctl : out std_ulogic;
|
|
||||||
rgmii_eth_tx_data : out std_ulogic_vector(3 downto 0);
|
|
||||||
wishbone_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wishbone_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wishbone_cyc : in std_ulogic;
|
|
||||||
wishbone_stb : in std_ulogic;
|
|
||||||
wishbone_ack : out std_ulogic;
|
|
||||||
wishbone_we : in std_ulogic;
|
|
||||||
wishbone_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wishbone_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wishbone_err : out std_ulogic;
|
|
||||||
interrupt : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_eth_cyc : std_ulogic;
|
|
||||||
signal wb_eth_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
liteeth : liteeth_core
|
|
||||||
port map(
|
|
||||||
sys_clock => system_clk,
|
|
||||||
sys_reset => soc_rst,
|
|
||||||
rgmii_eth_clocks_tx => eth_clocks_tx,
|
|
||||||
rgmii_eth_clocks_rx => eth_clocks_rx,
|
|
||||||
rgmii_eth_rst_n => eth_rst_n,
|
|
||||||
rgmii_eth_int_n => eth_int_n,
|
|
||||||
rgmii_eth_mdio => eth_mdio,
|
|
||||||
rgmii_eth_mdc => eth_mdc,
|
|
||||||
rgmii_eth_rx_ctl => eth_rx_ctl,
|
|
||||||
rgmii_eth_rx_data => eth_rx_data,
|
|
||||||
rgmii_eth_tx_ctl => eth_tx_ctl,
|
|
||||||
rgmii_eth_tx_data => eth_tx_data,
|
|
||||||
wishbone_adr => wb_eth_adr,
|
|
||||||
wishbone_dat_w => wb_ext_io_in.dat,
|
|
||||||
wishbone_dat_r => wb_eth_out.dat,
|
|
||||||
wishbone_sel => wb_ext_io_in.sel,
|
|
||||||
wishbone_cyc => wb_eth_cyc,
|
|
||||||
wishbone_stb => wb_ext_io_in.stb,
|
|
||||||
wishbone_ack => wb_eth_out.ack,
|
|
||||||
wishbone_we => wb_ext_io_in.we,
|
|
||||||
wishbone_cti => "000",
|
|
||||||
wishbone_bte => "00",
|
|
||||||
wishbone_err => open,
|
|
||||||
interrupt => ext_irq_eth
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with "chip select" from soc
|
|
||||||
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
|
|
||||||
|
|
||||||
-- Remove top address bits as liteeth decoder doesn't know about them
|
|
||||||
wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
|
|
||||||
|
|
||||||
-- LiteETH isn't pipelined
|
|
||||||
wb_eth_out.stall <= not wb_eth_out.ack;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
no_liteeth : if not USE_LITEETH generate
|
|
||||||
ext_irq_eth <= '0';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- SD card
|
|
||||||
has_sdcard : if USE_LITESDCARD generate
|
|
||||||
component litesdcard_core port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
-- wishbone for accessing control registers
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
-- wishbone for SD card core to use for DMA
|
|
||||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
|
||||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
|
||||||
wb_dma_cyc : out std_ulogic;
|
|
||||||
wb_dma_stb : out std_ulogic;
|
|
||||||
wb_dma_ack : in std_ulogic;
|
|
||||||
wb_dma_we : out std_ulogic;
|
|
||||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
|
||||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
|
||||||
wb_dma_err : in std_ulogic;
|
|
||||||
-- connections to SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
irq : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_sdcard_cyc : std_ulogic;
|
|
||||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
litesdcard : litesdcard_core
|
|
||||||
port map (
|
|
||||||
clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
wb_ctrl_adr => wb_sdcard_adr,
|
|
||||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
|
||||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
|
||||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
|
||||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
|
||||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
|
||||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
|
||||||
wb_ctrl_we => wb_ext_io_in.we,
|
|
||||||
wb_ctrl_cti => "000",
|
|
||||||
wb_ctrl_bte => "00",
|
|
||||||
wb_ctrl_err => open,
|
|
||||||
wb_dma_adr => wb_sddma_nr.adr,
|
|
||||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
|
||||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
|
||||||
wb_dma_sel => wb_sddma_nr.sel,
|
|
||||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
|
||||||
wb_dma_stb => wb_sddma_nr.stb,
|
|
||||||
wb_dma_ack => wb_sddma_ir.ack,
|
|
||||||
wb_dma_we => wb_sddma_nr.we,
|
|
||||||
wb_dma_cti => open,
|
|
||||||
wb_dma_bte => open,
|
|
||||||
wb_dma_err => '0',
|
|
||||||
sdcard_data => sdcard_data,
|
|
||||||
sdcard_cmd => sdcard_cmd,
|
|
||||||
sdcard_clk => sdcard_clk,
|
|
||||||
sdcard_cd => sdcard_cd,
|
|
||||||
irq => ext_irq_sdcard
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with chip select from SoC
|
|
||||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
|
||||||
|
|
||||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
|
|
||||||
|
|
||||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
|
||||||
|
|
||||||
sdcard_reset <= '0';
|
|
||||||
|
|
||||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
|
||||||
-- non-acknowledged strobes
|
|
||||||
process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
wb_sddma_out <= wb_sddma_nr;
|
|
||||||
if wb_sddma_stb_sent = '1' or
|
|
||||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
|
||||||
wb_sddma_out.stb <= '0';
|
|
||||||
end if;
|
|
||||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
|
||||||
wb_sddma_stb_sent <= '0';
|
|
||||||
elsif wb_sddma_in.stall = '0' then
|
|
||||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
|
||||||
end if;
|
|
||||||
wb_sddma_ir <= wb_sddma_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
no_sdcard : if not USE_LITESDCARD generate
|
|
||||||
sdcard_reset <= '1';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- Mux WB response on the IO bus
|
|
||||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
|
|
||||||
wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
|
||||||
wb_dram_ctrl_out;
|
|
||||||
|
|
||||||
led4 <= system_clk_locked;
|
|
||||||
led5 <= '1';
|
|
||||||
led6 <= not soc_rst;
|
|
||||||
led7 <= '0';
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,512 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_INPUT : positive := 100000000;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
HAS_FPU : boolean := true;
|
|
||||||
HAS_BTC : boolean := false;
|
|
||||||
USE_LITEDRAM : boolean := true;
|
|
||||||
NO_BRAM : boolean := true;
|
|
||||||
SCLK_STARTUPE2 : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 4194304;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 0;
|
|
||||||
UART_IS_16550 : boolean := true;
|
|
||||||
HAS_UART1 : boolean := false;
|
|
||||||
USE_LITESDCARD : boolean := true;
|
|
||||||
ICACHE_NUM_LINES : natural := 64;
|
|
||||||
NGPIO : natural := 0
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
ext_clk : in std_ulogic;
|
|
||||||
ext_rst_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
pin_gpio_0 : out std_ulogic;
|
|
||||||
pin_gpio_1 : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0_b : out std_ulogic;
|
|
||||||
led0_g : out std_ulogic;
|
|
||||||
led0_r : out std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- SD card wires
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
|
||||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_ulogic;
|
|
||||||
ddram_cas_n : out std_ulogic;
|
|
||||||
ddram_we_n : out std_ulogic;
|
|
||||||
ddram_cs_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_ulogic_vector(0 downto 0);
|
|
||||||
-- only the positive differential pin is instantiated
|
|
||||||
--ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
|
||||||
--ddram_clk_n : out std_ulogic_vector(0 downto 0);
|
|
||||||
ddram_cke : out std_ulogic;
|
|
||||||
ddram_odt : out std_ulogic;
|
|
||||||
ddram_reset_n : out std_ulogic;
|
|
||||||
|
|
||||||
ddram_gnd : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_vccio : out std_ulogic_vector(5 downto 0)
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- External IOs from the SoC
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal wb_ext_is_sdcard : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteSDCard connection
|
|
||||||
signal ext_irq_sdcard : std_ulogic := '0';
|
|
||||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
|
||||||
signal wb_sddma_in : wb_io_slave_out;
|
|
||||||
signal wb_sddma_nr : wb_io_master_out;
|
|
||||||
signal wb_sddma_ir : wb_io_slave_out;
|
|
||||||
-- for conversion from non-pipelined wishbone to pipelined
|
|
||||||
signal wb_sddma_stb_sent : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- Status LED
|
|
||||||
signal led0_b_pwm : std_ulogic;
|
|
||||||
signal led0_r_pwm : std_ulogic;
|
|
||||||
signal led0_g_pwm : std_ulogic;
|
|
||||||
|
|
||||||
-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
|
|
||||||
signal pwm_counter : std_ulogic_vector(8 downto 0);
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- GPIO
|
|
||||||
signal gpio_in : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal gpio_out : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal gpio_dir : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
|
|
||||||
COMPONENT USRMCLK
|
|
||||||
PORT(
|
|
||||||
USRMCLKI : IN STD_ULOGIC;
|
|
||||||
USRMCLKTS : IN STD_ULOGIC
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
attribute syn_noprune: boolean ;
|
|
||||||
attribute syn_noprune of USRMCLK: component is true;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_FPU => HAS_FPU,
|
|
||||||
HAS_BTC => HAS_BTC,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 256 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
|
||||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
|
||||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
|
||||||
LOG_LENGTH => LOG_LENGTH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550,
|
|
||||||
HAS_UART1 => HAS_UART1,
|
|
||||||
HAS_SD_CARD => USE_LITESDCARD,
|
|
||||||
ICACHE_NUM_LINES => ICACHE_NUM_LINES,
|
|
||||||
HAS_SHORT_MULT => true,
|
|
||||||
NGPIO => NGPIO
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => pin_gpio_0,
|
|
||||||
uart0_rxd => pin_gpio_1,
|
|
||||||
|
|
||||||
-- UART1 signals
|
|
||||||
--uart1_txd => uart_pmod_tx,
|
|
||||||
--uart1_rxd => uart_pmod_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- GPIO signals
|
|
||||||
gpio_in => gpio_in,
|
|
||||||
gpio_out => gpio_out,
|
|
||||||
gpio_dir => gpio_dir,
|
|
||||||
|
|
||||||
-- External interrupts
|
|
||||||
ext_irq_sdcard => ext_irq_sdcard,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
|
|
||||||
-- IO wishbone
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
|
||||||
|
|
||||||
-- DMA wishbone
|
|
||||||
wishbone_dma_in => wb_sddma_in,
|
|
||||||
wishbone_dma_out => wb_sddma_out,
|
|
||||||
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash
|
|
||||||
--
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
uclk: USRMCLK port map (
|
|
||||||
USRMCLKI => spi_sck,
|
|
||||||
USRMCLKTS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => CLK_INPUT,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
led0_b_pwm <= '1';
|
|
||||||
led0_r_pwm <= '1';
|
|
||||||
led0_g_pwm <= '0';
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
signal rst_gen_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from
|
|
||||||
-- litesdram generate.py sys_clk_freq
|
|
||||||
-- but for now, assert it's 48Mhz for orangecrab
|
|
||||||
assert CLK_FREQUENCY = 48000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => rst_gen_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Generate SoC reset
|
|
||||||
soc_rst_gen: process(system_clk)
|
|
||||||
begin
|
|
||||||
if ext_rst_n = '0' then
|
|
||||||
soc_rst <= '1';
|
|
||||||
elsif rising_edge(system_clk) then
|
|
||||||
soc_rst <= dram_sys_rst or not system_clk_locked;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 14,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
NUM_LINES => 8, -- reduce from default of 64 to make smaller/timing
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => dram_sys_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_dram_ctrl_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => ddram_cs_n,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_clk_p => ddram_clk_p,
|
|
||||||
-- only the positive differential pin is instantiated
|
|
||||||
--ddram_dqs_n => ddram_dqs_n,
|
|
||||||
--ddram_clk_n => ddram_clk_n,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
ddram_gnd <= "00";
|
|
||||||
-- for power consumption.
|
|
||||||
-- https://github.com/orangecrab-fpga/orangecrab-hardware/issues/19#issuecomment-683479378
|
|
||||||
ddram_vccio <= "111111";
|
|
||||||
|
|
||||||
led0_b_pwm <= not dram_init_done;
|
|
||||||
led0_r_pwm <= dram_init_error;
|
|
||||||
led0_g_pwm <= dram_init_done and not dram_init_error;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
|
|
||||||
-- SD card pmod
|
|
||||||
has_sdcard : if USE_LITESDCARD generate
|
|
||||||
component litesdcard_core port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
-- wishbone for accessing control registers
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
-- wishbone for SD card core to use for DMA
|
|
||||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
|
||||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
|
||||||
wb_dma_cyc : out std_ulogic;
|
|
||||||
wb_dma_stb : out std_ulogic;
|
|
||||||
wb_dma_ack : in std_ulogic;
|
|
||||||
wb_dma_we : out std_ulogic;
|
|
||||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
|
||||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
|
||||||
wb_dma_err : in std_ulogic;
|
|
||||||
-- connections to SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
irq : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_sdcard_cyc : std_ulogic;
|
|
||||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
litesdcard : litesdcard_core
|
|
||||||
port map (
|
|
||||||
clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
wb_ctrl_adr => wb_sdcard_adr,
|
|
||||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
|
||||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
|
||||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
|
||||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
|
||||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
|
||||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
|
||||||
wb_ctrl_we => wb_ext_io_in.we,
|
|
||||||
wb_ctrl_cti => "000",
|
|
||||||
wb_ctrl_bte => "00",
|
|
||||||
wb_ctrl_err => open,
|
|
||||||
wb_dma_adr => wb_sddma_nr.adr,
|
|
||||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
|
||||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
|
||||||
wb_dma_sel => wb_sddma_nr.sel,
|
|
||||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
|
||||||
wb_dma_stb => wb_sddma_nr.stb,
|
|
||||||
wb_dma_ack => wb_sddma_ir.ack,
|
|
||||||
wb_dma_we => wb_sddma_nr.we,
|
|
||||||
wb_dma_cti => open,
|
|
||||||
wb_dma_bte => open,
|
|
||||||
wb_dma_err => '0',
|
|
||||||
sdcard_data => sdcard_data,
|
|
||||||
sdcard_cmd => sdcard_cmd,
|
|
||||||
sdcard_clk => sdcard_clk,
|
|
||||||
sdcard_cd => sdcard_cd,
|
|
||||||
irq => ext_irq_sdcard
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with chip select from SoC
|
|
||||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
|
||||||
|
|
||||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
|
|
||||||
|
|
||||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
|
||||||
|
|
||||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
|
||||||
-- non-acknowledged strobes
|
|
||||||
process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
wb_sddma_out <= wb_sddma_nr;
|
|
||||||
if wb_sddma_stb_sent = '1' or
|
|
||||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
|
||||||
wb_sddma_out.stb <= '0';
|
|
||||||
end if;
|
|
||||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
|
||||||
wb_sddma_stb_sent <= '0';
|
|
||||||
elsif wb_sddma_in.stall = '0' then
|
|
||||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
|
||||||
end if;
|
|
||||||
wb_sddma_ir <= wb_sddma_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- Mux WB response on the IO bus
|
|
||||||
wb_ext_io_out <= wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
|
||||||
wb_dram_ctrl_out;
|
|
||||||
|
|
||||||
leds_pwm : process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
|
|
||||||
if pwm_counter(8 downto 4) = "00000" then
|
|
||||||
led0_b <= led0_b_pwm;
|
|
||||||
led0_r <= led0_r_pwm;
|
|
||||||
led0_g <= led0_g_pwm;
|
|
||||||
else
|
|
||||||
led0_b <= '0';
|
|
||||||
led0_r <= '0';
|
|
||||||
led0_g <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,587 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
HAS_FPU : boolean := true;
|
|
||||||
HAS_BTC : boolean := true;
|
|
||||||
HAS_SHORT_MULT : boolean := false;
|
|
||||||
USE_LITEDRAM : boolean := false;
|
|
||||||
NO_BRAM : boolean := false;
|
|
||||||
DISABLE_FLATTEN_CORE : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 4194304;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 512;
|
|
||||||
USE_LITEETH : boolean := false;
|
|
||||||
UART_IS_16550 : boolean := true;
|
|
||||||
HAS_UART1 : boolean := false;
|
|
||||||
USE_LITESDCARD : boolean := false;
|
|
||||||
HAS_GPIO : boolean := false;
|
|
||||||
NGPIO : natural := 32
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
ext_clk : in std_ulogic;
|
|
||||||
ext_rst_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
uart_main_tx : out std_ulogic;
|
|
||||||
uart_main_rx : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0_n : out std_ulogic;
|
|
||||||
led1_n : out std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- Ethernet
|
|
||||||
eth_clocks_tx : in std_ulogic;
|
|
||||||
eth_clocks_gtx : out std_ulogic;
|
|
||||||
eth_clocks_rx : in std_ulogic;
|
|
||||||
eth_rst_n : out std_ulogic;
|
|
||||||
eth_mdio : inout std_ulogic;
|
|
||||||
eth_mdc : out std_ulogic;
|
|
||||||
eth_rx_dv : in std_ulogic;
|
|
||||||
eth_rx_er : in std_ulogic;
|
|
||||||
eth_rx_data : in std_ulogic_vector(7 downto 0);
|
|
||||||
eth_tx_en : out std_ulogic;
|
|
||||||
eth_tx_er : out std_ulogic;
|
|
||||||
eth_tx_data : out std_ulogic_vector(7 downto 0);
|
|
||||||
eth_col : in std_ulogic;
|
|
||||||
eth_crs : in std_ulogic;
|
|
||||||
|
|
||||||
-- SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
|
||||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_ulogic;
|
|
||||||
ddram_cas_n : out std_ulogic;
|
|
||||||
ddram_we_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_ulogic;
|
|
||||||
ddram_clk_n : out std_ulogic;
|
|
||||||
ddram_cke : out std_ulogic;
|
|
||||||
ddram_odt : out std_ulogic;
|
|
||||||
ddram_reset_n : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- External IOs from the SoC
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal wb_ext_is_eth : std_ulogic;
|
|
||||||
signal wb_ext_is_sdcard : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteEth connection
|
|
||||||
signal ext_irq_eth : std_ulogic;
|
|
||||||
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteSDCard connection
|
|
||||||
signal ext_irq_sdcard : std_ulogic := '0';
|
|
||||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
|
||||||
signal wb_sddma_in : wb_io_slave_out;
|
|
||||||
signal wb_sddma_nr : wb_io_master_out;
|
|
||||||
signal wb_sddma_ir : wb_io_slave_out;
|
|
||||||
-- for conversion from non-pipelined wishbone to pipelined
|
|
||||||
signal wb_sddma_stb_sent : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- ddram clock signals as vectors
|
|
||||||
signal ddram_clk_p_vec : std_ulogic_vector(0 downto 0);
|
|
||||||
signal ddram_clk_n_vec : std_ulogic_vector(0 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_FPU => HAS_FPU,
|
|
||||||
HAS_BTC => HAS_BTC,
|
|
||||||
HAS_SHORT_MULT => HAS_SHORT_MULT,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 256 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
|
||||||
HAS_SPI_FLASH => true,
|
|
||||||
SPI_FLASH_DLINES => 4,
|
|
||||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
|
||||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
|
||||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
|
||||||
LOG_LENGTH => LOG_LENGTH,
|
|
||||||
HAS_LITEETH => USE_LITEETH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550,
|
|
||||||
HAS_UART1 => HAS_UART1,
|
|
||||||
HAS_SD_CARD => USE_LITESDCARD,
|
|
||||||
HAS_GPIO => HAS_GPIO,
|
|
||||||
NGPIO => NGPIO
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => uart_main_tx,
|
|
||||||
uart0_rxd => uart_main_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- External interrupts
|
|
||||||
ext_irq_eth => ext_irq_eth,
|
|
||||||
ext_irq_sdcard => ext_irq_sdcard,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
|
|
||||||
-- IO wishbone
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
wb_ext_is_eth => wb_ext_is_eth,
|
|
||||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
|
||||||
|
|
||||||
-- DMA wishbone
|
|
||||||
wishbone_dma_in => wb_sddma_in,
|
|
||||||
wishbone_dma_out => wb_sddma_out,
|
|
||||||
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
STARTUPE2_INST: STARTUPE2
|
|
||||||
port map (
|
|
||||||
CLK => '0',
|
|
||||||
GSR => '0',
|
|
||||||
GTS => '0',
|
|
||||||
KEYCLEARB => '0',
|
|
||||||
PACK => '0',
|
|
||||||
USRCCLKO => spi_sck,
|
|
||||||
USRCCLKTS => '0',
|
|
||||||
USRDONEO => '1',
|
|
||||||
USRDONETS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => 50000000,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
-- Vivado barfs on those differential signals if left
|
|
||||||
-- unconnected. So instanciate a diff. buffer and feed
|
|
||||||
-- it a constant '0'.
|
|
||||||
dummy_dram_clk: OBUFDS
|
|
||||||
port map (
|
|
||||||
O => ddram_clk_p,
|
|
||||||
OB => ddram_clk_n,
|
|
||||||
I => ddram_clk_dummy
|
|
||||||
);
|
|
||||||
ddram_clk_dummy <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
signal rst_gen_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from the generator
|
|
||||||
-- but for now, assert it's 100Mhz
|
|
||||||
assert CLK_FREQUENCY = 100000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => rst_gen_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Generate SoC reset
|
|
||||||
soc_rst_gen: process(system_clk)
|
|
||||||
begin
|
|
||||||
if ext_rst_n = '0' then
|
|
||||||
soc_rst <= '1';
|
|
||||||
elsif rising_edge(system_clk) then
|
|
||||||
soc_rst <= dram_sys_rst or not system_clk_locked;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
ddram_clk_p_vec <= (others => ddram_clk_p);
|
|
||||||
ddram_clk_n_vec <= (others => ddram_clk_n);
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 14,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => dram_sys_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_dram_ctrl_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => open,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_dqs_n => ddram_dqs_n,
|
|
||||||
ddram_clk_p => ddram_clk_p_vec,
|
|
||||||
ddram_clk_n => ddram_clk_n_vec,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_liteeth : if USE_LITEETH generate
|
|
||||||
|
|
||||||
component liteeth_core port (
|
|
||||||
sys_clock : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
gmii_eth_clocks_tx : in std_ulogic;
|
|
||||||
gmii_eth_clocks_gtx : out std_ulogic;
|
|
||||||
gmii_eth_clocks_rx : in std_ulogic;
|
|
||||||
gmii_eth_rst_n : out std_ulogic;
|
|
||||||
gmii_eth_mdio : inout std_ulogic;
|
|
||||||
gmii_eth_mdc : out std_ulogic;
|
|
||||||
gmii_eth_rx_dv : in std_ulogic;
|
|
||||||
gmii_eth_rx_er : in std_ulogic;
|
|
||||||
gmii_eth_rx_data : in std_ulogic_vector(7 downto 0);
|
|
||||||
gmii_eth_tx_en : out std_ulogic;
|
|
||||||
gmii_eth_tx_er : out std_ulogic;
|
|
||||||
gmii_eth_tx_data : out std_ulogic_vector(7 downto 0);
|
|
||||||
gmii_eth_col : in std_ulogic;
|
|
||||||
gmii_eth_crs : in std_ulogic;
|
|
||||||
wishbone_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wishbone_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wishbone_cyc : in std_ulogic;
|
|
||||||
wishbone_stb : in std_ulogic;
|
|
||||||
wishbone_ack : out std_ulogic;
|
|
||||||
wishbone_we : in std_ulogic;
|
|
||||||
wishbone_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wishbone_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wishbone_err : out std_ulogic;
|
|
||||||
interrupt : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_eth_cyc : std_ulogic;
|
|
||||||
signal wb_eth_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
-- Change this to use a PLL instead of a BUFR to generate the 25Mhz
|
|
||||||
-- reference clock to the PHY.
|
|
||||||
constant USE_PLL : boolean := false;
|
|
||||||
begin
|
|
||||||
liteeth : liteeth_core
|
|
||||||
port map(
|
|
||||||
sys_clock => system_clk,
|
|
||||||
sys_reset => soc_rst,
|
|
||||||
gmii_eth_clocks_tx => eth_clocks_tx,
|
|
||||||
gmii_eth_clocks_gtx => eth_clocks_gtx,
|
|
||||||
gmii_eth_clocks_rx => eth_clocks_rx,
|
|
||||||
gmii_eth_rst_n => eth_rst_n,
|
|
||||||
gmii_eth_mdio => eth_mdio,
|
|
||||||
gmii_eth_mdc => eth_mdc,
|
|
||||||
gmii_eth_rx_dv => eth_rx_dv,
|
|
||||||
gmii_eth_rx_er => eth_rx_er,
|
|
||||||
gmii_eth_rx_data => eth_rx_data,
|
|
||||||
gmii_eth_tx_en => eth_tx_en,
|
|
||||||
gmii_eth_tx_er => eth_tx_er,
|
|
||||||
gmii_eth_tx_data => eth_tx_data,
|
|
||||||
gmii_eth_col => eth_col,
|
|
||||||
gmii_eth_crs => eth_crs,
|
|
||||||
wishbone_adr => wb_eth_adr,
|
|
||||||
wishbone_dat_w => wb_ext_io_in.dat,
|
|
||||||
wishbone_dat_r => wb_eth_out.dat,
|
|
||||||
wishbone_sel => wb_ext_io_in.sel,
|
|
||||||
wishbone_cyc => wb_eth_cyc,
|
|
||||||
wishbone_stb => wb_ext_io_in.stb,
|
|
||||||
wishbone_ack => wb_eth_out.ack,
|
|
||||||
wishbone_we => wb_ext_io_in.we,
|
|
||||||
wishbone_cti => "000",
|
|
||||||
wishbone_bte => "00",
|
|
||||||
wishbone_err => open,
|
|
||||||
interrupt => ext_irq_eth
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with "chip select" from soc
|
|
||||||
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
|
|
||||||
|
|
||||||
-- Remove top address bits as liteeth decoder doesn't know about them
|
|
||||||
wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
|
|
||||||
|
|
||||||
-- LiteETH isn't pipelined
|
|
||||||
wb_eth_out.stall <= not wb_eth_out.ack;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
no_liteeth : if not USE_LITEETH generate
|
|
||||||
ext_irq_eth <= '0';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- SD card pmod
|
|
||||||
has_sdcard : if USE_LITESDCARD generate
|
|
||||||
component litesdcard_core port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
-- wishbone for accessing control registers
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
-- wishbone for SD card core to use for DMA
|
|
||||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
|
||||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
|
||||||
wb_dma_cyc : out std_ulogic;
|
|
||||||
wb_dma_stb : out std_ulogic;
|
|
||||||
wb_dma_ack : in std_ulogic;
|
|
||||||
wb_dma_we : out std_ulogic;
|
|
||||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
|
||||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
|
||||||
wb_dma_err : in std_ulogic;
|
|
||||||
-- connections to SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
irq : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_sdcard_cyc : std_ulogic;
|
|
||||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
litesdcard : litesdcard_core
|
|
||||||
port map (
|
|
||||||
clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
wb_ctrl_adr => wb_sdcard_adr,
|
|
||||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
|
||||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
|
||||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
|
||||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
|
||||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
|
||||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
|
||||||
wb_ctrl_we => wb_ext_io_in.we,
|
|
||||||
wb_ctrl_cti => "000",
|
|
||||||
wb_ctrl_bte => "00",
|
|
||||||
wb_ctrl_err => open,
|
|
||||||
wb_dma_adr => wb_sddma_nr.adr,
|
|
||||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
|
||||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
|
||||||
wb_dma_sel => wb_sddma_nr.sel,
|
|
||||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
|
||||||
wb_dma_stb => wb_sddma_nr.stb,
|
|
||||||
wb_dma_ack => wb_sddma_ir.ack,
|
|
||||||
wb_dma_we => wb_sddma_nr.we,
|
|
||||||
wb_dma_cti => open,
|
|
||||||
wb_dma_bte => open,
|
|
||||||
wb_dma_err => '0',
|
|
||||||
sdcard_data => sdcard_data,
|
|
||||||
sdcard_cmd => sdcard_cmd,
|
|
||||||
sdcard_clk => sdcard_clk,
|
|
||||||
sdcard_cd => sdcard_cd,
|
|
||||||
irq => ext_irq_sdcard
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with chip select from SoC
|
|
||||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
|
||||||
|
|
||||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
|
|
||||||
|
|
||||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
|
||||||
|
|
||||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
|
||||||
-- non-acknowledged strobes
|
|
||||||
process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
wb_sddma_out <= wb_sddma_nr;
|
|
||||||
if wb_sddma_stb_sent = '1' or
|
|
||||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
|
||||||
wb_sddma_out.stb <= '0';
|
|
||||||
end if;
|
|
||||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
|
||||||
wb_sddma_stb_sent <= '0';
|
|
||||||
elsif wb_sddma_in.stall = '0' then
|
|
||||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
|
||||||
end if;
|
|
||||||
wb_sddma_ir <= wb_sddma_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- Mux WB response on the IO bus
|
|
||||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
|
|
||||||
wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
|
||||||
wb_dram_ctrl_out;
|
|
||||||
|
|
||||||
led0_n <= system_clk_locked;
|
|
||||||
led1_n <= not soc_rst;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,487 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
# clkin, reset, uart pins...
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN M21 IOSTANDARD LVCMOS33 } [get_ports { ext_clk }];
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN H7 IOSTANDARD LVCMOS33 } [get_ports { ext_rst_n }];
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { uart_main_tx }];
|
|
||||||
set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { uart_main_rx }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# LEDs
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led0_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led1_n }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# SPI Flash
|
|
||||||
################################################################################ema
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }];
|
|
||||||
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }];
|
|
||||||
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Micro SD
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN M5 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[0] }];
|
|
||||||
set_property -dict { PACKAGE_PIN M7 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[1] }];
|
|
||||||
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[2] }];
|
|
||||||
set_property -dict { PACKAGE_PIN J6 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[3] }];
|
|
||||||
set_property -dict { PACKAGE_PIN J8 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_cmd }];
|
|
||||||
set_property -dict { PACKAGE_PIN L4 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
|
||||||
set_property -dict { PACKAGE_PIN N6 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
|
||||||
|
|
||||||
# Put registers into IOBs to improve timing
|
|
||||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdcard_*}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header J10 (high-speed, no protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G7 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G8 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D6 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_10 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header J11 (high-speed, no protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN B5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_10 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# HDR 20X2 connector
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Ethernet (generated by LiteX)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# eth_clocks:0.tx
|
|
||||||
set_property LOC M2 [get_ports {eth_clocks_tx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_tx}]
|
|
||||||
|
|
||||||
# eth_clocks:0.gtx
|
|
||||||
set_property LOC U1 [get_ports {eth_clocks_gtx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_gtx}]
|
|
||||||
|
|
||||||
# eth_clocks:0.rx
|
|
||||||
set_property LOC P4 [get_ports {eth_clocks_rx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_rx}]
|
|
||||||
|
|
||||||
# eth:0.rst_n
|
|
||||||
set_property LOC R1 [get_ports {eth_rst_n}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rst_n}]
|
|
||||||
|
|
||||||
# eth:0.mdio
|
|
||||||
set_property LOC H1 [get_ports {eth_mdio}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdio}]
|
|
||||||
|
|
||||||
# eth:0.mdc
|
|
||||||
set_property LOC H2 [get_ports {eth_mdc}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdc}]
|
|
||||||
|
|
||||||
# eth:0.rx_dv
|
|
||||||
set_property LOC L3 [get_ports {eth_rx_dv}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_dv}]
|
|
||||||
|
|
||||||
# eth:0.rx_er
|
|
||||||
set_property LOC U5 [get_ports {eth_rx_er}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_er}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC M4 [get_ports {eth_rx_data[0]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[0]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC N3 [get_ports {eth_rx_data[1]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[1]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC N4 [get_ports {eth_rx_data[2]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[2]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC P3 [get_ports {eth_rx_data[3]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[3]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC R3 [get_ports {eth_rx_data[4]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[4]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC T3 [get_ports {eth_rx_data[5]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[5]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC T4 [get_ports {eth_rx_data[6]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[6]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC T5 [get_ports {eth_rx_data[7]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[7]}]
|
|
||||||
|
|
||||||
# eth:0.tx_en
|
|
||||||
set_property LOC T2 [get_ports {eth_tx_en}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_en}]
|
|
||||||
|
|
||||||
# eth:0.tx_er
|
|
||||||
set_property LOC J1 [get_ports {eth_tx_er}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_er}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC R2 [get_ports {eth_tx_data[0]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[0]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC P1 [get_ports {eth_tx_data[1]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[1]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC N2 [get_ports {eth_tx_data[2]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[2]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC N1 [get_ports {eth_tx_data[3]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[3]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC M1 [get_ports {eth_tx_data[4]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[4]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC L2 [get_ports {eth_tx_data[5]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[5]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC K2 [get_ports {eth_tx_data[6]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[6]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC K1 [get_ports {eth_tx_data[7]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[7]}]
|
|
||||||
|
|
||||||
# eth:0.col
|
|
||||||
set_property LOC U4 [get_ports {eth_col}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_col}]
|
|
||||||
|
|
||||||
# eth:0.crs
|
|
||||||
set_property LOC U2 [get_ports {eth_crs}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_crs}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# DRAM (generated by LiteX)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC E17 [get_ports {ddram_a[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[0]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC G17 [get_ports {ddram_a[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[1]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC F17 [get_ports {ddram_a[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[2]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC C17 [get_ports {ddram_a[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[3]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[3]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC G16 [get_ports {ddram_a[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[4]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[4]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC D16 [get_ports {ddram_a[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[5]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[5]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC H16 [get_ports {ddram_a[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[6]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[6]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC E16 [get_ports {ddram_a[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[7]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[7]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC H14 [get_ports {ddram_a[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[8]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[8]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC F15 [get_ports {ddram_a[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[9]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[9]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC F20 [get_ports {ddram_a[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[10]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[10]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC H15 [get_ports {ddram_a[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[11]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[11]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC C18 [get_ports {ddram_a[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[12]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[12]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC G15 [get_ports {ddram_a[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[13]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[13]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC B17 [get_ports {ddram_ba[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[0]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC D18 [get_ports {ddram_ba[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[1]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC A17 [get_ports {ddram_ba[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[2]}]
|
|
||||||
|
|
||||||
# ddram:0.ras_n
|
|
||||||
set_property LOC A19 [get_ports {ddram_ras_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ras_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ras_n}]
|
|
||||||
|
|
||||||
# ddram:0.cas_n
|
|
||||||
set_property LOC B19 [get_ports {ddram_cas_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cas_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cas_n}]
|
|
||||||
|
|
||||||
# ddram:0.we_n
|
|
||||||
set_property LOC A18 [get_ports {ddram_we_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_we_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_we_n}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC A22 [get_ports {ddram_dm[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC C22 [get_ports {ddram_dm[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D21 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C21 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B22 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B21 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D19 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[4]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC E20 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[5]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C19 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[6]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D20 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[7]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C23 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[8]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D23 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[9]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B24 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[10]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B25 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[11]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C24 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[12]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C26 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[13]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC A25 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[14]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B26 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[15]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC B20 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC A23 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC A20 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC A24 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
|
|
||||||
# ddram:0.clk_p
|
|
||||||
set_property LOC F18 [get_ports {ddram_clk_p}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_p}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_clk_p}]
|
|
||||||
|
|
||||||
# ddram:0.clk_n
|
|
||||||
set_property LOC F19 [get_ports {ddram_clk_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_n}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_clk_n}]
|
|
||||||
|
|
||||||
# ddram:0.cke
|
|
||||||
set_property LOC E18 [get_ports {ddram_cke}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cke}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cke}]
|
|
||||||
|
|
||||||
# ddram:0.odt
|
|
||||||
set_property LOC G19 [get_ports {ddram_odt}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_odt}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_odt}]
|
|
||||||
|
|
||||||
# ddram:0.reset_n
|
|
||||||
set_property LOC H17 [get_ports {ddram_reset_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_reset_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_reset_n}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Design constraints and bitsteam attributes
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property INTERNAL_VREF 0.675 [get_iobanks 16]
|
|
||||||
|
|
||||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
|
||||||
set_property CFGBVS VCCO [current_design]
|
|
||||||
|
|
||||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
|
|
||||||
set_property CONFIG_MODE SPIx4 [current_design]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Clock constraints
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
create_clock -name sys_clk_pin -period 20.00 [get_ports { ext_clk }];
|
|
||||||
|
|
||||||
create_clock -name eth_rx_clk -period 8.0 [get_nets has_liteeth.liteeth/eth_rx_clk]
|
|
||||||
create_clock -name eth_tx_clk -period 8.0 [get_nets has_liteeth.liteeth/eth_tx_clk]
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_rx_clk]] -asynchronous
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_tx_clk]] -asynchronous
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_rx_clk]] -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_tx_clk]] -asynchronous
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# False path constraints (from LiteX as they relate to LiteDRAM and LiteEth)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
|
||||||
|
|
||||||
set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
|
||||||
|
|
||||||
set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
|
@ -1,99 +0,0 @@
|
|||||||
-- GPIO module for microwatt
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity gpio is
|
|
||||||
generic (
|
|
||||||
NGPIO : integer := 32
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
|
|
||||||
-- Wishbone
|
|
||||||
wb_in : in wb_io_master_out;
|
|
||||||
wb_out : out wb_io_slave_out;
|
|
||||||
|
|
||||||
-- GPIO lines
|
|
||||||
gpio_in : in std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
gpio_out : out std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
-- 1 = output, 0 = input
|
|
||||||
gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
-- Interrupt
|
|
||||||
intr : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity gpio;
|
|
||||||
|
|
||||||
architecture behaviour of gpio is
|
|
||||||
constant GPIO_REG_BITS : positive := 5;
|
|
||||||
|
|
||||||
-- Register addresses, matching addr downto 2, so 4 bytes per reg
|
|
||||||
constant GPIO_REG_DATA_OUT : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00000";
|
|
||||||
constant GPIO_REG_DATA_IN : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00001";
|
|
||||||
constant GPIO_REG_DIR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00010";
|
|
||||||
constant GPIO_REG_DATA_SET : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00100";
|
|
||||||
constant GPIO_REG_DATA_CLR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00101";
|
|
||||||
|
|
||||||
-- Current output value and direction
|
|
||||||
signal reg_data : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal reg_dirn : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal reg_in1 : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal reg_in2 : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
signal wb_rsp : wb_io_slave_out;
|
|
||||||
signal reg_out : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- No interrupt facility for now
|
|
||||||
intr <= '0';
|
|
||||||
|
|
||||||
gpio_out <= reg_data;
|
|
||||||
gpio_dir <= reg_dirn;
|
|
||||||
|
|
||||||
-- Wishbone response
|
|
||||||
wb_rsp.ack <= wb_in.cyc and wb_in.stb;
|
|
||||||
with wb_in.adr(GPIO_REG_BITS - 1 downto 0) select reg_out <=
|
|
||||||
reg_data when GPIO_REG_DATA_OUT,
|
|
||||||
reg_in2 when GPIO_REG_DATA_IN,
|
|
||||||
reg_dirn when GPIO_REG_DIR,
|
|
||||||
(others => '0') when others;
|
|
||||||
wb_rsp.dat(wb_rsp.dat'left downto NGPIO) <= (others => '0');
|
|
||||||
wb_rsp.dat(NGPIO - 1 downto 0) <= reg_out;
|
|
||||||
wb_rsp.stall <= '0';
|
|
||||||
|
|
||||||
regs_rw: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
wb_out <= wb_rsp;
|
|
||||||
reg_in2 <= reg_in1;
|
|
||||||
reg_in1 <= gpio_in;
|
|
||||||
if rst = '1' then
|
|
||||||
reg_data <= (others => '0');
|
|
||||||
reg_dirn <= (others => '0');
|
|
||||||
wb_out.ack <= '0';
|
|
||||||
else
|
|
||||||
if wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then
|
|
||||||
case wb_in.adr(GPIO_REG_BITS - 1 downto 0) is
|
|
||||||
when GPIO_REG_DATA_OUT =>
|
|
||||||
reg_data <= wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when GPIO_REG_DIR =>
|
|
||||||
reg_dirn <= wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when GPIO_REG_DATA_SET =>
|
|
||||||
reg_data <= reg_data or wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when GPIO_REG_DATA_CLR =>
|
|
||||||
reg_data <= reg_data and not wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when others =>
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
||||||
|
|
Binary file not shown.
@ -1,30 +1,146 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "console.h"
|
/*
|
||||||
|
* Core UART functions to implement for a port
|
||||||
|
*/
|
||||||
|
|
||||||
static char mw_logo[] =
|
static uint64_t potato_uart_base;
|
||||||
|
|
||||||
"\n"
|
#define PROC_FREQ 50000000
|
||||||
" .oOOo. \n"
|
#define UART_FREQ 115200
|
||||||
" .\" \". \n"
|
#define UART_BASE 0xc0002000
|
||||||
" ; .mw. ; Microwatt, it works.\n"
|
|
||||||
" . ' ' . \n"
|
#define POTATO_CONSOLE_TX 0x00
|
||||||
" \\ || / \n"
|
#define POTATO_CONSOLE_RX 0x08
|
||||||
" ;..; \n"
|
#define POTATO_CONSOLE_STATUS 0x10
|
||||||
" ;..; \n"
|
#define POTATO_CONSOLE_STATUS_RX_EMPTY 0x01
|
||||||
" `ww' \n";
|
#define POTATO_CONSOLE_STATUS_TX_EMPTY 0x02
|
||||||
|
#define POTATO_CONSOLE_STATUS_RX_FULL 0x04
|
||||||
|
#define POTATO_CONSOLE_STATUS_TX_FULL 0x08
|
||||||
|
#define POTATO_CONSOLE_CLOCK_DIV 0x18
|
||||||
|
#define POTATO_CONSOLE_IRQ_EN 0x20
|
||||||
|
|
||||||
|
static uint64_t potato_uart_reg_read(int offset)
|
||||||
|
{
|
||||||
|
uint64_t addr;
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
addr = potato_uart_base + offset;
|
||||||
|
|
||||||
|
val = *(volatile uint64_t *)addr;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void potato_uart_reg_write(int offset, uint64_t val)
|
||||||
|
{
|
||||||
|
uint64_t addr;
|
||||||
|
|
||||||
|
addr = potato_uart_base + offset;
|
||||||
|
|
||||||
|
*(volatile uint64_t *)addr = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int potato_uart_rx_empty(void)
|
||||||
|
{
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
|
||||||
|
|
||||||
|
if (val & POTATO_CONSOLE_STATUS_RX_EMPTY)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int potato_uart_tx_full(void)
|
||||||
|
{
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
|
||||||
|
|
||||||
|
if (val & POTATO_CONSOLE_STATUS_TX_FULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char potato_uart_read(void)
|
||||||
|
{
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
val = potato_uart_reg_read(POTATO_CONSOLE_RX);
|
||||||
|
|
||||||
|
return (char)(val & 0x000000ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void potato_uart_write(char c)
|
||||||
|
{
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
val = c;
|
||||||
|
|
||||||
|
potato_uart_reg_write(POTATO_CONSOLE_TX, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long potato_uart_divisor(unsigned long proc_freq, unsigned long uart_freq)
|
||||||
|
{
|
||||||
|
return proc_freq / (uart_freq * 16) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void potato_uart_init(void)
|
||||||
|
{
|
||||||
|
potato_uart_base = UART_BASE;
|
||||||
|
|
||||||
|
potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, potato_uart_divisor(PROC_FREQ, UART_FREQ));
|
||||||
|
}
|
||||||
|
|
||||||
|
int getchar(void)
|
||||||
|
{
|
||||||
|
while (potato_uart_rx_empty())
|
||||||
|
/* Do nothing */ ;
|
||||||
|
|
||||||
|
return potato_uart_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void putchar(unsigned char c)
|
||||||
|
{
|
||||||
|
while (potato_uart_tx_full())
|
||||||
|
/* Do Nothing */;
|
||||||
|
|
||||||
|
potato_uart_write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void putstr(const char *str, unsigned long len)
|
||||||
|
{
|
||||||
|
for (unsigned long i = 0; i < len; i++) {
|
||||||
|
putchar(str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen(const char *s)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
while (*s++)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HELLO_WORLD "Hello World\r\n"
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
console_init();
|
potato_uart_init();
|
||||||
|
|
||||||
puts(mw_logo);
|
putstr(HELLO_WORLD, strlen(HELLO_WORLD));
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
unsigned char c = getchar();
|
unsigned char c = getchar();
|
||||||
putchar(c);
|
putchar(c);
|
||||||
if (c == 13) // if CR send LF
|
|
||||||
putchar(10);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -1,785 +0,0 @@
|
|||||||
000000004800012c
|
|
||||||
0000000000000000
|
|
||||||
4800002408000048
|
|
||||||
01006b69a600607d
|
|
||||||
a602487d05009f42
|
|
||||||
a64b5a7d14004a39
|
|
||||||
2402004ca64b7b7d
|
|
||||||
00000000480000f4
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
4800002408000048
|
|
||||||
01006b69a600607d
|
|
||||||
a602487d05009f42
|
|
||||||
a64b5a7d14004a39
|
|
||||||
2402004ca64b7b7d
|
|
||||||
3d40000048000004
|
|
||||||
794a07c6614a0000
|
|
||||||
614a1900654a0000
|
|
||||||
616b00003d600000
|
|
||||||
656b0000796b07c6
|
|
||||||
7d6a5850616b1980
|
|
||||||
796bd183396b003f
|
|
||||||
7d6903a641820014
|
|
||||||
394a00407c0057ec
|
|
||||||
3c2000004200fff8
|
|
||||||
782107c660210000
|
|
||||||
6021398064210000
|
|
||||||
f801ffe138000000
|
|
||||||
3d8000007c1243a6
|
|
||||||
798c07c6618c0000
|
|
||||||
618c1000658c0000
|
|
||||||
4e8004217d8903a6
|
|
||||||
4800000000000200
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000048000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
384298003c400001
|
|
||||||
fbe1fff87c0802a6
|
|
||||||
f821ffd1f8010010
|
|
||||||
60000000480001ed
|
|
||||||
3862800060000000
|
|
||||||
6000000048000155
|
|
||||||
6000000048000049
|
|
||||||
5463063e7c7f1b78
|
|
||||||
480000b957ff063e
|
|
||||||
2c1f000d60000000
|
|
||||||
3860000a4082ffe0
|
|
||||||
60000000480000a5
|
|
||||||
000000004bffffd0
|
|
||||||
0000018001000000
|
|
||||||
384298003c400001
|
|
||||||
8922810860000000
|
|
||||||
3942810060000000
|
|
||||||
418200302c090000
|
|
||||||
39290014e92a0000
|
|
||||||
7d204eaa7c0004ac
|
|
||||||
4182ffec71290001
|
|
||||||
7c0004ace86a0000
|
|
||||||
5463063e7c601eaa
|
|
||||||
e92a00004e800020
|
|
||||||
7c0004ac39290010
|
|
||||||
712900017d204eea
|
|
||||||
e86a00004082ffec
|
|
||||||
7c0004ac38630008
|
|
||||||
4bffffd07c601eea
|
|
||||||
0000000000000000
|
|
||||||
3c40000100000000
|
|
||||||
6000000038429800
|
|
||||||
6000000089228108
|
|
||||||
2c09000039428100
|
|
||||||
e92a00004182002c
|
|
||||||
7c0004ac39290014
|
|
||||||
712900207d204eaa
|
|
||||||
e92a00004182ffec
|
|
||||||
7c604faa7c0004ac
|
|
||||||
e92a00004e800020
|
|
||||||
7c0004ac39290010
|
|
||||||
712900087d204eea
|
|
||||||
5469063e4082ffec
|
|
||||||
7c0004ace94a0000
|
|
||||||
4e8000207d2057ea
|
|
||||||
0000000000000000
|
|
||||||
3c40000100000000
|
|
||||||
7c0802a638429800
|
|
||||||
fbc1fff0fbe1fff8
|
|
||||||
f80100103be3ffff
|
|
||||||
8fdf0001f821ffd1
|
|
||||||
408200102c3e0000
|
|
||||||
3860000038210030
|
|
||||||
281e000a480001e8
|
|
||||||
3860000d4082000c
|
|
||||||
7fc3f3784bffff45
|
|
||||||
4bffffd04bffff3d
|
|
||||||
0100000000000000
|
|
||||||
7c691b7800000280
|
|
||||||
7d4918ae38600000
|
|
||||||
4d8200202c0a0000
|
|
||||||
4bfffff038630001
|
|
||||||
0000000000000000
|
|
||||||
3c40000100000000
|
|
||||||
3d40c00038429800
|
|
||||||
794a0020614a0020
|
|
||||||
7d4056ea7c0004ac
|
|
||||||
794a06003d20c000
|
|
||||||
7929002061290008
|
|
||||||
7d204eea7c0004ac
|
|
||||||
4182001871290020
|
|
||||||
612900403d20c000
|
|
||||||
7c0004ac79290020
|
|
||||||
7929f8047d204eea
|
|
||||||
79290fc33d00c000
|
|
||||||
7908002061082000
|
|
||||||
f902810060000000
|
|
||||||
610820003d00001c
|
|
||||||
418200847d4a4392
|
|
||||||
3920000160000000
|
|
||||||
3d00c00099228108
|
|
||||||
3920ff806108200c
|
|
||||||
7c0004ac79080020
|
|
||||||
e92281007d2047aa
|
|
||||||
7d404faa7c0004ac
|
|
||||||
794ac202e9228100
|
|
||||||
7c0004ac39290004
|
|
||||||
e92281007d404faa
|
|
||||||
3929000c39400003
|
|
||||||
7d404faa7c0004ac
|
|
||||||
39290010e9228100
|
|
||||||
7d404faa7c0004ac
|
|
||||||
39400007e9228100
|
|
||||||
7c0004ac39290008
|
|
||||||
4e8000207d404faa
|
|
||||||
394affff60000000
|
|
||||||
3d20c00099228108
|
|
||||||
7929002061292018
|
|
||||||
7d404fea7c0004ac
|
|
||||||
000000004e800020
|
|
||||||
0000000000000000
|
|
||||||
384298003c400001
|
|
||||||
8922810860000000
|
|
||||||
600000002c090000
|
|
||||||
41820024e9228100
|
|
||||||
78840e282c230000
|
|
||||||
6084000141820008
|
|
||||||
7c0004ac39290004
|
|
||||||
4e8000207c804faa
|
|
||||||
418200082c240000
|
|
||||||
3929002060630002
|
|
||||||
7c604fea7c0004ac
|
|
||||||
000000004e800020
|
|
||||||
0000000000000000
|
|
||||||
e8010010ebc1fff0
|
|
||||||
7c0803a6ebe1fff8
|
|
||||||
000000104e800020
|
|
||||||
00527a0100000000
|
|
||||||
00010c1b01417804
|
|
||||||
0000001800000018
|
|
||||||
00000070fffffc40
|
|
||||||
9f7e4111300e4600
|
|
||||||
0000001000000001
|
|
||||||
00527a0100000000
|
|
||||||
00010c1b01417804
|
|
||||||
0000001800000010
|
|
||||||
00000084fffffc80
|
|
||||||
0000001000000000
|
|
||||||
fffffcf00000002c
|
|
||||||
0000000000000080
|
|
||||||
0000004000000028
|
|
||||||
00000060fffffd5c
|
|
||||||
9e019f0041094500
|
|
||||||
447e4111300e4302
|
|
||||||
4106dedf42000e0a
|
|
||||||
000000100000000b
|
|
||||||
fffffd900000006c
|
|
||||||
0000000000000028
|
|
||||||
0000008000000010
|
|
||||||
0000012cfffffda4
|
|
||||||
0000001000000000
|
|
||||||
fffffebc00000094
|
|
||||||
0000000000000068
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
0000000000000000
|
|
||||||
4f4f6f2e2020200a
|
|
||||||
0a20202020202e6f
|
|
||||||
2020202020222e20
|
|
||||||
203b200a202e2220
|
|
||||||
3b20202e776d2e20
|
|
||||||
6f7263694d202020
|
|
||||||
7469202c74746177
|
|
||||||
0a2e736b726f7720
|
|
||||||
27202027202e2020
|
|
||||||
200a202020202e20
|
|
||||||
2f207c7c205c2020
|
|
||||||
2020200a20202020
|
|
||||||
2020203b2e2e3b20
|
|
||||||
202020200a202020
|
|
||||||
202020203b2e2e3b
|
|
||||||
60202020200a2020
|
|
||||||
000a202020277777
|
|
@ -1,27 +1,13 @@
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0;
|
|
||||||
_start = .;
|
_start = .;
|
||||||
|
. = 0;
|
||||||
.head : {
|
.head : {
|
||||||
KEEP(*(.head))
|
KEEP(*(.head))
|
||||||
}
|
}
|
||||||
. = 0x1000;
|
. = 0x1000;
|
||||||
.text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) }
|
.text : { *(.text) }
|
||||||
. = 0x1800;
|
. = 0x2000;
|
||||||
.data : { *(.data) *(.data.*) *(.got) *(.toc) }
|
.data : { *(.data) }
|
||||||
. = ALIGN(0x80);
|
.bss : { *(.bss) }
|
||||||
__bss_start = .;
|
|
||||||
.bss : {
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss)
|
|
||||||
*(.scommon)
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.common)
|
|
||||||
*(.bss.*)
|
|
||||||
}
|
|
||||||
. = ALIGN(0x80);
|
|
||||||
__bss_end = .;
|
|
||||||
. = . + 0x2000;
|
|
||||||
__stack_top = .;
|
|
||||||
}
|
}
|
||||||
|
@ -1,157 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity icache_tb is
|
|
||||||
end icache_tb;
|
|
||||||
|
|
||||||
architecture behave of icache_tb is
|
|
||||||
signal clk : std_ulogic;
|
|
||||||
signal rst : std_ulogic;
|
|
||||||
|
|
||||||
signal i_out : Fetch1ToIcacheType;
|
|
||||||
signal i_in : IcacheToDecode1Type;
|
|
||||||
|
|
||||||
signal m_out : MmuToIcacheType;
|
|
||||||
|
|
||||||
signal wb_bram_in : wishbone_master_out;
|
|
||||||
signal wb_bram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
constant clk_period : time := 10 ns;
|
|
||||||
begin
|
|
||||||
icache0: entity work.icache
|
|
||||||
generic map(
|
|
||||||
LINE_SIZE => 64,
|
|
||||||
NUM_LINES => 4
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
i_in => i_out,
|
|
||||||
i_out => i_in,
|
|
||||||
m_in => m_out,
|
|
||||||
stall_in => '0',
|
|
||||||
flush_in => '0',
|
|
||||||
inval_in => '0',
|
|
||||||
wishbone_out => wb_bram_in,
|
|
||||||
wishbone_in => wb_bram_out
|
|
||||||
);
|
|
||||||
|
|
||||||
-- BRAM Memory slave
|
|
||||||
bram0: entity work.wishbone_bram_wrapper
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => 1024,
|
|
||||||
RAM_INIT_FILE => "icache_test.bin"
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
wishbone_in => wb_bram_in,
|
|
||||||
wishbone_out => wb_bram_out
|
|
||||||
);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
rst_process: process
|
|
||||||
begin
|
|
||||||
rst <= '1';
|
|
||||||
wait for 2*clk_period;
|
|
||||||
rst <= '0';
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
stim: process
|
|
||||||
begin
|
|
||||||
i_out.req <= '0';
|
|
||||||
i_out.nia <= (others => '0');
|
|
||||||
i_out.stop_mark <= '0';
|
|
||||||
i_out.priv_mode <= '1';
|
|
||||||
i_out.virt_mode <= '0';
|
|
||||||
i_out.big_endian <= '0';
|
|
||||||
|
|
||||||
m_out.tlbld <= '0';
|
|
||||||
m_out.tlbie <= '0';
|
|
||||||
m_out.addr <= (others => '0');
|
|
||||||
m_out.pte <= (others => '0');
|
|
||||||
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
i_out.req <= '1';
|
|
||||||
i_out.nia <= x"0000000000000004";
|
|
||||||
|
|
||||||
wait for 30*clk_period;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
assert i_in.valid = '1' severity failure;
|
|
||||||
assert i_in.insn = x"00000001"
|
|
||||||
report "insn @" & to_hstring(i_out.nia) &
|
|
||||||
"=" & to_hstring(i_in.insn) &
|
|
||||||
" expected 00000001"
|
|
||||||
severity failure;
|
|
||||||
|
|
||||||
i_out.req <= '0';
|
|
||||||
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
-- hit
|
|
||||||
i_out.req <= '1';
|
|
||||||
i_out.nia <= x"0000000000000008";
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
assert i_in.valid = '1' severity failure;
|
|
||||||
assert i_in.insn = x"00000002"
|
|
||||||
report "insn @" & to_hstring(i_out.nia) &
|
|
||||||
"=" & to_hstring(i_in.insn) &
|
|
||||||
" expected 00000002"
|
|
||||||
severity failure;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
-- another miss
|
|
||||||
i_out.req <= '1';
|
|
||||||
i_out.nia <= x"0000000000000040";
|
|
||||||
|
|
||||||
wait for 30*clk_period;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
assert i_in.valid = '1' severity failure;
|
|
||||||
assert i_in.insn = x"00000010"
|
|
||||||
report "insn @" & to_hstring(i_out.nia) &
|
|
||||||
"=" & to_hstring(i_in.insn) &
|
|
||||||
" expected 00000010"
|
|
||||||
severity failure;
|
|
||||||
|
|
||||||
-- test something that aliases
|
|
||||||
i_out.req <= '1';
|
|
||||||
i_out.nia <= x"0000000000000100";
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
assert i_in.valid = '0' severity failure;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
wait for 30*clk_period;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
assert i_in.valid = '1' severity failure;
|
|
||||||
assert i_in.insn = x"00000040"
|
|
||||||
report "insn @" & to_hstring(i_out.nia) &
|
|
||||||
"=" & to_hstring(i_in.insn) &
|
|
||||||
" expected 00000040"
|
|
||||||
severity failure;
|
|
||||||
|
|
||||||
i_out.req <= '0';
|
|
||||||
|
|
||||||
std.env.finish;
|
|
||||||
end process;
|
|
||||||
end;
|
|
Binary file not shown.
@ -1,11 +0,0 @@
|
|||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
void console_init(void);
|
|
||||||
void console_set_irq_en(bool rx_irq, bool tx_irq);
|
|
||||||
int getchar(void);
|
|
||||||
int putchar(int c);
|
|
||||||
int puts(const char *str);
|
|
||||||
|
|
||||||
#ifndef __USE_LIBC
|
|
||||||
size_t strlen(const char *s);
|
|
||||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||||||
#ifndef __IO_H
|
|
||||||
#define __IO_H
|
|
||||||
|
|
||||||
static inline uint8_t readb(unsigned long addr)
|
|
||||||
{
|
|
||||||
uint8_t val;
|
|
||||||
__asm__ volatile("sync; lbzcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t readw(unsigned long addr)
|
|
||||||
{
|
|
||||||
uint16_t val;
|
|
||||||
__asm__ volatile("sync; lhzcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t readl(unsigned long addr)
|
|
||||||
{
|
|
||||||
uint32_t val;
|
|
||||||
__asm__ volatile("sync; lwzcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t readq(unsigned long addr)
|
|
||||||
{
|
|
||||||
uint64_t val;
|
|
||||||
__asm__ volatile("sync; ldcix %0,0,%1" : "=r" (val) : "r" (addr) : "memory");
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writeb(uint8_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
__asm__ volatile("sync; stbcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writew(uint16_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
__asm__ volatile("sync; sthcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writel(uint32_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
__asm__ volatile("sync; stwcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writeq(uint64_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
__asm__ volatile("sync; stdcix %0,0,%1" : : "r" (val), "r" (addr) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __IO_H */
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
|||||||
#ifndef __MICROWATT_SOC_H
|
|
||||||
#define __MICROWATT_SOC_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Microwatt SoC memory map
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MEMORY_BASE 0x00000000 /* "Main" memory alias, either BRAM or DRAM */
|
|
||||||
#define DRAM_BASE 0x40000000 /* DRAM if present */
|
|
||||||
#define BRAM_BASE 0x80000000 /* Internal BRAM */
|
|
||||||
|
|
||||||
#define SYSCON_BASE 0xc0000000 /* System control regs */
|
|
||||||
#define UART_BASE 0xc0002000 /* UART */
|
|
||||||
#define XICS_ICP_BASE 0xc0004000 /* Interrupt controller */
|
|
||||||
#define XICS_ICS_BASE 0xc0005000 /* Interrupt controller */
|
|
||||||
#define SPI_FCTRL_BASE 0xc0006000 /* SPI flash controller registers */
|
|
||||||
#define DRAM_CTRL_BASE 0xc8000000 /* LiteDRAM control registers */
|
|
||||||
#define LETH_CSR_BASE 0xc8020000 /* LiteEth CSR registers */
|
|
||||||
#define LETH_SRAM_BASE 0xc8030000 /* LiteEth MMIO space */
|
|
||||||
#define LSDC_CSR_BASE 0xc8040000 /* LiteSDCard MMIO space */
|
|
||||||
#define SPI_FLASH_BASE 0xf0000000 /* SPI Flash memory map */
|
|
||||||
#define DRAM_INIT_BASE 0xff000000 /* Internal DRAM init firmware */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interrupt numbers
|
|
||||||
*/
|
|
||||||
#define IRQ_UART0 0
|
|
||||||
#define IRQ_ETHERNET 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register definitions for the syscon registers
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SYS_REG_SIGNATURE 0x00
|
|
||||||
#define SYS_REG_INFO 0x08
|
|
||||||
#define SYS_REG_INFO_HAS_UART (1ull << 0)
|
|
||||||
#define SYS_REG_INFO_HAS_DRAM (1ull << 1)
|
|
||||||
#define SYS_REG_INFO_HAS_BRAM (1ull << 2)
|
|
||||||
#define SYS_REG_INFO_HAS_SPI_FLASH (1ull << 3)
|
|
||||||
#define SYS_REG_INFO_HAS_LITEETH (1ull << 4)
|
|
||||||
#define SYS_REG_INFO_HAS_LARGE_SYSCON (1ull << 5)
|
|
||||||
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
|
|
||||||
#define SYS_REG_INFO_HAS_ARTB (1ull << 7)
|
|
||||||
#define SYS_REG_INFO_HAS_LITESDCARD (1ull << 8)
|
|
||||||
#define SYS_REG_BRAMINFO 0x10
|
|
||||||
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
|
|
||||||
#define SYS_REG_DRAMINFO 0x18
|
|
||||||
#define SYS_REG_DRAMINFO_SIZE_MASK 0xfffffffffffffull
|
|
||||||
#define SYS_REG_CLKINFO 0x20
|
|
||||||
#define SYS_REG_CLKINFO_FREQ_MASK 0xffffffffffull
|
|
||||||
#define SYS_REG_CTRL 0x28
|
|
||||||
#define SYS_REG_CTRL_DRAM_AT_0 (1ull << 0)
|
|
||||||
#define SYS_REG_CTRL_CORE_RESET (1ull << 1)
|
|
||||||
#define SYS_REG_CTRL_SOC_RESET (1ull << 2)
|
|
||||||
#define SYS_REG_DRAMINITINFO 0x30
|
|
||||||
#define SYS_REG_SPI_INFO 0x38
|
|
||||||
#define SYS_REG_SPI_INFO_FLASH_OFF_MASK 0xffffffff
|
|
||||||
#define SYS_REG_UART0_INFO 0x40
|
|
||||||
#define SYS_REG_UART1_INFO 0x48
|
|
||||||
#define SYS_REG_UART_IS_16550 (1ull << 32)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register definitions for the potato UART
|
|
||||||
*/
|
|
||||||
#define POTATO_CONSOLE_TX 0x00
|
|
||||||
#define POTATO_CONSOLE_RX 0x08
|
|
||||||
#define POTATO_CONSOLE_STATUS 0x10
|
|
||||||
#define POTATO_CONSOLE_STATUS_RX_EMPTY 0x01
|
|
||||||
#define POTATO_CONSOLE_STATUS_TX_EMPTY 0x02
|
|
||||||
#define POTATO_CONSOLE_STATUS_RX_FULL 0x04
|
|
||||||
#define POTATO_CONSOLE_STATUS_TX_FULL 0x08
|
|
||||||
#define POTATO_CONSOLE_CLOCK_DIV 0x18
|
|
||||||
#define POTATO_CONSOLE_IRQ_EN 0x20
|
|
||||||
#define POTATO_CONSOLE_IRQ_RX 0x01
|
|
||||||
#define POTATO_CONSOLE_IRQ_TX 0x02
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register definitionss for our standard (16550 style) UART
|
|
||||||
*/
|
|
||||||
#define UART_REG_RX 0x00
|
|
||||||
#define UART_REG_TX 0x00
|
|
||||||
#define UART_REG_DLL 0x00
|
|
||||||
#define UART_REG_IER 0x04
|
|
||||||
#define UART_REG_IER_RDI 0x01
|
|
||||||
#define UART_REG_IER_THRI 0x02
|
|
||||||
#define UART_REG_IER_RLSI 0x04
|
|
||||||
#define UART_REG_IER_MSI 0x08
|
|
||||||
#define UART_REG_DLM 0x04
|
|
||||||
#define UART_REG_IIR 0x08
|
|
||||||
#define UART_REG_FCR 0x08
|
|
||||||
#define UART_REG_FCR_EN_FIFO 0x01
|
|
||||||
#define UART_REG_FCR_CLR_RCVR 0x02
|
|
||||||
#define UART_REG_FCR_CLR_XMIT 0x04
|
|
||||||
#define UART_REG_FCR_TRIG1 0x00
|
|
||||||
#define UART_REG_FCR_TRIG4 0x40
|
|
||||||
#define UART_REG_FCR_TRIG8 0x80
|
|
||||||
#define UART_REG_FCR_TRIG14 0xc0
|
|
||||||
#define UART_REG_LCR 0x0c
|
|
||||||
#define UART_REG_LCR_5BIT 0x00
|
|
||||||
#define UART_REG_LCR_6BIT 0x01
|
|
||||||
#define UART_REG_LCR_7BIT 0x02
|
|
||||||
#define UART_REG_LCR_8BIT 0x03
|
|
||||||
#define UART_REG_LCR_STOP 0x04
|
|
||||||
#define UART_REG_LCR_PAR 0x08
|
|
||||||
#define UART_REG_LCR_EVEN_PAR 0x10
|
|
||||||
#define UART_REG_LCR_STIC_PAR 0x20
|
|
||||||
#define UART_REG_LCR_BREAK 0x40
|
|
||||||
#define UART_REG_LCR_DLAB 0x80
|
|
||||||
#define UART_REG_MCR 0x10
|
|
||||||
#define UART_REG_MCR_DTR 0x01
|
|
||||||
#define UART_REG_MCR_RTS 0x02
|
|
||||||
#define UART_REG_MCR_OUT1 0x04
|
|
||||||
#define UART_REG_MCR_OUT2 0x08
|
|
||||||
#define UART_REG_MCR_LOOP 0x10
|
|
||||||
#define UART_REG_LSR 0x14
|
|
||||||
#define UART_REG_LSR_DR 0x01
|
|
||||||
#define UART_REG_LSR_OE 0x02
|
|
||||||
#define UART_REG_LSR_PE 0x04
|
|
||||||
#define UART_REG_LSR_FE 0x08
|
|
||||||
#define UART_REG_LSR_BI 0x10
|
|
||||||
#define UART_REG_LSR_THRE 0x20
|
|
||||||
#define UART_REG_LSR_TEMT 0x40
|
|
||||||
#define UART_REG_LSR_FIFOE 0x80
|
|
||||||
#define UART_REG_MSR 0x18
|
|
||||||
#define UART_REG_SCR 0x1c
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register definitions for the SPI controller
|
|
||||||
*/
|
|
||||||
#define SPI_REG_DATA 0x00 /* Byte access: single wire transfer */
|
|
||||||
#define SPI_REG_DATA_DUAL 0x01 /* Byte access: dual wire transfer */
|
|
||||||
#define SPI_REG_DATA_QUAD 0x02 /* Byte access: quad wire transfer */
|
|
||||||
#define SPI_REG_CTRL 0x04 /* Reset and manual mode control */
|
|
||||||
#define SPI_REG_CTRL_RESET 0x01 /* reset all registers */
|
|
||||||
#define SPI_REG_CTRL_MANUAL_CS 0x02 /* assert CS, enable manual mode */
|
|
||||||
#define SPI_REG_CTRL_CKDIV_SHIFT 8 /* clock div */
|
|
||||||
#define SPI_REG_CTRL_CKDIV_MASK (0xff << SPI_REG_CTRL_CKDIV_SHIFT)
|
|
||||||
#define SPI_REG_AUTO_CFG 0x08 /* Automatic map configuration */
|
|
||||||
#define SPI_REG_AUTO_CFG_CMD_SHIFT 0 /* Command to use for reads */
|
|
||||||
#define SPI_REG_AUTO_CFG_CMD_MASK (0xff << SPI_REG_AUTO_CFG_CMD_SHIFT)
|
|
||||||
#define SPI_REG_AUTO_CFG_DUMMIES_SHIFT 8 /* # dummy cycles */
|
|
||||||
#define SPI_REG_AUTO_CFG_DUMMIES_MASK (0x7 << SPI_REG_AUTO_CFG_DUMMIES_SHIFT)
|
|
||||||
#define SPI_REG_AUTO_CFG_MODE_SHIFT 11 /* SPI wire mode */
|
|
||||||
#define SPI_REG_AUTO_CFG_MODE_MASK (0x3 << SPI_REG_AUTO_CFG_MODE_SHIFT)
|
|
||||||
#define SPI_REG_AUT_CFG_MODE_SINGLE (0 << 11)
|
|
||||||
#define SPI_REG_AUT_CFG_MODE_DUAL (2 << 11)
|
|
||||||
#define SPI_REG_AUT_CFG_MODE_QUAD (3 << 11)
|
|
||||||
#define SPI_REG_AUTO_CFG_ADDR4 (1u << 13) /* 3 or 4 addr bytes */
|
|
||||||
#define SPI_REG_AUTO_CFG_CKDIV_SHIFT 16 /* clock div */
|
|
||||||
#define SPI_REG_AUTO_CFG_CKDIV_MASK (0xff << SPI_REG_AUTO_CFG_CKDIV_SHIFT)
|
|
||||||
#define SPI_REG_AUTO_CFG_CSTOUT_SHIFT 24 /* CS timeout */
|
|
||||||
#define SPI_REG_AUTO_CFG_CSTOUT_MASK (0x3f << SPI_REG_AUTO_CFG_CSTOUT_SHIFT)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __MICROWATT_SOC_H */
|
|
@ -1,223 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "console.h"
|
|
||||||
#include "microwatt_soc.h"
|
|
||||||
#include "io.h"
|
|
||||||
|
|
||||||
#define UART_BAUDS 115200
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Core UART functions to implement for a port
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool uart_is_std;
|
|
||||||
|
|
||||||
static uint64_t uart_base;
|
|
||||||
|
|
||||||
static unsigned long uart_divisor(unsigned long uart_freq, unsigned long bauds)
|
|
||||||
{
|
|
||||||
return uart_freq / (bauds * 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t potato_uart_reg_read(int offset)
|
|
||||||
{
|
|
||||||
return readq(uart_base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void potato_uart_reg_write(int offset, uint64_t val)
|
|
||||||
{
|
|
||||||
writeq(val, uart_base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int potato_uart_rx_empty(void)
|
|
||||||
{
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
|
|
||||||
|
|
||||||
if (val & POTATO_CONSOLE_STATUS_RX_EMPTY)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int potato_uart_tx_full(void)
|
|
||||||
{
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
|
|
||||||
|
|
||||||
if (val & POTATO_CONSOLE_STATUS_TX_FULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char potato_uart_read(void)
|
|
||||||
{
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
val = potato_uart_reg_read(POTATO_CONSOLE_RX);
|
|
||||||
|
|
||||||
return (char)(val & 0x000000ff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void potato_uart_write(char c)
|
|
||||||
{
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
val = c;
|
|
||||||
|
|
||||||
potato_uart_reg_write(POTATO_CONSOLE_TX, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void potato_uart_init(uint64_t uart_freq)
|
|
||||||
{
|
|
||||||
unsigned long div = uart_divisor(uart_freq, UART_BAUDS) - 1;
|
|
||||||
potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, div);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void potato_uart_set_irq_en(bool rx_irq, bool tx_irq)
|
|
||||||
{
|
|
||||||
uint64_t en = 0;
|
|
||||||
|
|
||||||
if (rx_irq)
|
|
||||||
en |= POTATO_CONSOLE_IRQ_RX;
|
|
||||||
if (tx_irq)
|
|
||||||
en |= POTATO_CONSOLE_IRQ_TX;
|
|
||||||
potato_uart_reg_write(POTATO_CONSOLE_IRQ_EN, en);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool std_uart_rx_empty(void)
|
|
||||||
{
|
|
||||||
return !(readb(uart_base + UART_REG_LSR) & UART_REG_LSR_DR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t std_uart_read(void)
|
|
||||||
{
|
|
||||||
return readb(uart_base + UART_REG_RX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool std_uart_tx_full(void)
|
|
||||||
{
|
|
||||||
return !(readb(uart_base + UART_REG_LSR) & UART_REG_LSR_THRE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void std_uart_write(uint8_t c)
|
|
||||||
{
|
|
||||||
writeb(c, uart_base + UART_REG_TX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void std_uart_set_irq_en(bool rx_irq, bool tx_irq)
|
|
||||||
{
|
|
||||||
uint8_t ier = 0;
|
|
||||||
|
|
||||||
if (tx_irq)
|
|
||||||
ier |= UART_REG_IER_THRI;
|
|
||||||
if (rx_irq)
|
|
||||||
ier |= UART_REG_IER_RDI;
|
|
||||||
writeb(ier, uart_base + UART_REG_IER);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void std_uart_init(uint64_t uart_freq)
|
|
||||||
{
|
|
||||||
unsigned long div = uart_divisor(uart_freq, UART_BAUDS);
|
|
||||||
|
|
||||||
writeb(UART_REG_LCR_DLAB, uart_base + UART_REG_LCR);
|
|
||||||
writeb(div & 0xff, uart_base + UART_REG_DLL);
|
|
||||||
writeb(div >> 8, uart_base + UART_REG_DLM);
|
|
||||||
writeb(UART_REG_LCR_8BIT, uart_base + UART_REG_LCR);
|
|
||||||
writeb(UART_REG_MCR_DTR |
|
|
||||||
UART_REG_MCR_RTS, uart_base + UART_REG_MCR);
|
|
||||||
writeb(UART_REG_FCR_EN_FIFO |
|
|
||||||
UART_REG_FCR_CLR_RCVR |
|
|
||||||
UART_REG_FCR_CLR_XMIT, uart_base + UART_REG_FCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getchar(void)
|
|
||||||
{
|
|
||||||
if (uart_is_std) {
|
|
||||||
while (std_uart_rx_empty())
|
|
||||||
/* Do nothing */ ;
|
|
||||||
return std_uart_read();
|
|
||||||
} else {
|
|
||||||
while (potato_uart_rx_empty())
|
|
||||||
/* Do nothing */ ;
|
|
||||||
return potato_uart_read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int putchar(int c)
|
|
||||||
{
|
|
||||||
if (uart_is_std) {
|
|
||||||
while(std_uart_tx_full())
|
|
||||||
/* Do Nothing */;
|
|
||||||
std_uart_write(c);
|
|
||||||
} else {
|
|
||||||
while (potato_uart_tx_full())
|
|
||||||
/* Do Nothing */;
|
|
||||||
potato_uart_write(c);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
int puts(const char *str)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; *str; i++) {
|
|
||||||
char c = *(str++);
|
|
||||||
if (c == 10)
|
|
||||||
putchar(13);
|
|
||||||
putchar(c);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef __USE_LIBC
|
|
||||||
size_t strlen(const char *s)
|
|
||||||
{
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
while (*s++)
|
|
||||||
len++;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void console_init(void)
|
|
||||||
{
|
|
||||||
uint64_t sys_info;
|
|
||||||
uint64_t proc_freq;
|
|
||||||
uint64_t uart_info = 0;
|
|
||||||
uint64_t uart_freq = 0;
|
|
||||||
|
|
||||||
proc_freq = readq(SYSCON_BASE + SYS_REG_CLKINFO) & SYS_REG_CLKINFO_FREQ_MASK;
|
|
||||||
sys_info = readq(SYSCON_BASE + SYS_REG_INFO);
|
|
||||||
|
|
||||||
if (sys_info & SYS_REG_INFO_HAS_LARGE_SYSCON) {
|
|
||||||
uart_info = readq(SYSCON_BASE + SYS_REG_UART0_INFO);
|
|
||||||
uart_freq = uart_info & 0xffffffff;
|
|
||||||
}
|
|
||||||
if (uart_freq == 0)
|
|
||||||
uart_freq = proc_freq;
|
|
||||||
|
|
||||||
uart_base = UART_BASE;
|
|
||||||
if (uart_info & SYS_REG_UART_IS_16550) {
|
|
||||||
uart_is_std = true;
|
|
||||||
std_uart_init(proc_freq);
|
|
||||||
} else {
|
|
||||||
uart_is_std = false;
|
|
||||||
potato_uart_init(proc_freq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void console_set_irq_en(bool rx_irq, bool tx_irq)
|
|
||||||
{
|
|
||||||
if (uart_is_std)
|
|
||||||
std_uart_set_irq_en(rx_irq, tx_irq);
|
|
||||||
else
|
|
||||||
potato_uart_set_irq_en(rx_irq, tx_irq);
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
from fusesoc.capi2.generator import Generator
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import pathlib
|
|
||||||
|
|
||||||
class LiteDRAMGenerator(Generator):
|
|
||||||
def run(self):
|
|
||||||
board = self.config.get('board')
|
|
||||||
payload = self.config.get('payload')
|
|
||||||
|
|
||||||
# Collect a bunch of directory path
|
|
||||||
script_dir = os.path.dirname(sys.argv[0])
|
|
||||||
base_dir = os.path.join(script_dir, os.pardir)
|
|
||||||
gen_dir = os.path.join(base_dir, "generated", board)
|
|
||||||
extras_dir = os.path.join(base_dir, "extras")
|
|
||||||
|
|
||||||
print("Adding LiteDRAM for board... ", board)
|
|
||||||
|
|
||||||
# Add files to fusesoc
|
|
||||||
files = []
|
|
||||||
f = os.path.join(gen_dir, "litedram_core.v")
|
|
||||||
files.append({f : {'file_type' : 'verilogSource'}})
|
|
||||||
f = os.path.join(gen_dir, "litedram-initmem.vhdl")
|
|
||||||
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
|
||||||
f = os.path.join(gen_dir, "litedram_core.init")
|
|
||||||
files.append({f : {'file_type' : 'user'}})
|
|
||||||
f = os.path.join(extras_dir, "litedram-wrapper-l2.vhdl")
|
|
||||||
files.append({f : {'file_type' : 'vhdlSource-2008'}})
|
|
||||||
|
|
||||||
self.add_files(files)
|
|
||||||
|
|
||||||
g = LiteDRAMGenerator()
|
|
||||||
g.run()
|
|
||||||
g.write()
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +0,0 @@
|
|||||||
OPT_FAST=-O3 -fstrict-aliasing
|
|
||||||
OPT_SLOW=-O3 -fstrict-aliasing
|
|
||||||
|
|
||||||
top_all: top_all2
|
|
||||||
|
|
||||||
include Vlitedram_core.mk
|
|
||||||
|
|
||||||
top_all2: default $(VK_GLOBAL_OBJS)
|
|
||||||
|
|
||||||
.PHONY: top_all top_all2
|
|
@ -1,214 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
package sim_litedram is
|
|
||||||
-- WB req format:
|
|
||||||
-- 73 .. 71 : cti(2..0)
|
|
||||||
-- 70 .. 69 : bte(1..0)
|
|
||||||
-- 68 .. 65 : sel(3..0)
|
|
||||||
-- 64 : we
|
|
||||||
-- 63 : stb
|
|
||||||
-- 62 : cyc
|
|
||||||
-- 61 .. 32 : addr(29..0)
|
|
||||||
-- 31 .. 0 : write_data(31..0)
|
|
||||||
--
|
|
||||||
procedure litedram_set_wb(req : in std_ulogic_vector(73 downto 0));
|
|
||||||
attribute foreign of litedram_set_wb : procedure is "VHPIDIRECT litedram_set_wb";
|
|
||||||
|
|
||||||
-- WB rsp format:
|
|
||||||
-- 35 : init_error;
|
|
||||||
-- 34 : init_done;
|
|
||||||
-- 33 : err
|
|
||||||
-- 32 : ack
|
|
||||||
-- 31 .. 0 : read_data(31..0)
|
|
||||||
--
|
|
||||||
procedure litedram_get_wb(rsp : out std_ulogic_vector(35 downto 0));
|
|
||||||
attribute foreign of litedram_get_wb : procedure is "VHPIDIRECT litedram_get_wb";
|
|
||||||
|
|
||||||
-- User req format:
|
|
||||||
-- 171 : cmd_valid
|
|
||||||
-- 170 : cmd_we
|
|
||||||
-- 169 : wdata_valid
|
|
||||||
-- 168 : rdata_ready
|
|
||||||
-- 167 .. 144 : cmd_addr(23..0)
|
|
||||||
-- 143 .. 128 : wdata_we(15..0)
|
|
||||||
-- 127 .. 0 : wdata_data(127..0)
|
|
||||||
--
|
|
||||||
procedure litedram_set_user(req: in std_ulogic_vector(171 downto 0));
|
|
||||||
attribute foreign of litedram_set_user : procedure is "VHPIDIRECT litedram_set_user";
|
|
||||||
|
|
||||||
-- User rsp format:
|
|
||||||
-- 130 : cmd_ready
|
|
||||||
-- 129 : wdata_ready
|
|
||||||
-- 128 : rdata_valid
|
|
||||||
-- 127 .. 0 : rdata_data(127..0)
|
|
||||||
|
|
||||||
procedure litedram_get_user(req: in std_ulogic_vector(130 downto 0));
|
|
||||||
attribute foreign of litedram_get_user : procedure is "VHPIDIRECT litedram_get_user";
|
|
||||||
|
|
||||||
procedure litedram_clock;
|
|
||||||
attribute foreign of litedram_clock : procedure is "VHPIDIRECT litedram_clock";
|
|
||||||
|
|
||||||
procedure litedram_init(trace: integer);
|
|
||||||
attribute foreign of litedram_init : procedure is "VHPIDIRECT litedram_init";
|
|
||||||
end sim_litedram;
|
|
||||||
|
|
||||||
package body sim_litedram is
|
|
||||||
procedure litedram_set_wb(req : in std_ulogic_vector(73 downto 0)) is
|
|
||||||
begin
|
|
||||||
assert false report "VHPI" severity failure;
|
|
||||||
end procedure;
|
|
||||||
procedure litedram_get_wb(rsp : out std_ulogic_vector(35 downto 0)) is
|
|
||||||
begin
|
|
||||||
assert false report "VHPI" severity failure;
|
|
||||||
end procedure;
|
|
||||||
procedure litedram_set_user(req: in std_ulogic_vector(171 downto 0)) is
|
|
||||||
begin
|
|
||||||
assert false report "VHPI" severity failure;
|
|
||||||
end procedure;
|
|
||||||
procedure litedram_get_user(req: in std_ulogic_vector(130 downto 0)) is
|
|
||||||
begin
|
|
||||||
assert false report "VHPI" severity failure;
|
|
||||||
end procedure;
|
|
||||||
procedure litedram_clock is
|
|
||||||
begin
|
|
||||||
assert false report "VHPI" severity failure;
|
|
||||||
end procedure;
|
|
||||||
procedure litedram_init(trace: integer) is
|
|
||||||
begin
|
|
||||||
assert false report "VHPI" severity failure;
|
|
||||||
end procedure;
|
|
||||||
end sim_litedram;
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.sim_litedram.all;
|
|
||||||
|
|
||||||
entity litedram_core is
|
|
||||||
port(
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
pll_locked : out std_ulogic;
|
|
||||||
ddram_a : out std_ulogic_vector(0 downto 0);
|
|
||||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_ulogic;
|
|
||||||
ddram_cas_n : out std_ulogic;
|
|
||||||
ddram_we_n : out std_ulogic;
|
|
||||||
ddram_cs_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_ulogic_vector(0 downto 0);
|
|
||||||
ddram_clk_n : out std_ulogic_vector(0 downto 0);
|
|
||||||
ddram_cke : out std_ulogic;
|
|
||||||
ddram_odt : out std_ulogic;
|
|
||||||
ddram_reset_n : out std_ulogic;
|
|
||||||
init_done : out std_ulogic;
|
|
||||||
init_error : out std_ulogic;
|
|
||||||
user_clk : out std_ulogic;
|
|
||||||
user_rst : out std_ulogic;
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
user_port_native_0_cmd_valid : in std_ulogic;
|
|
||||||
user_port_native_0_cmd_ready : out std_ulogic;
|
|
||||||
user_port_native_0_cmd_we : in std_ulogic;
|
|
||||||
user_port_native_0_cmd_addr : in std_ulogic_vector(23 downto 0);
|
|
||||||
user_port_native_0_wdata_valid : in std_ulogic;
|
|
||||||
user_port_native_0_wdata_ready : out std_ulogic;
|
|
||||||
user_port_native_0_wdata_we : in std_ulogic_vector(15 downto 0);
|
|
||||||
user_port_native_0_wdata_data : in std_ulogic_vector(127 downto 0);
|
|
||||||
user_port_native_0_rdata_valid : out std_ulogic;
|
|
||||||
user_port_native_0_rdata_ready : in std_ulogic;
|
|
||||||
user_port_native_0_rdata_data : out std_ulogic_vector(127 downto 0)
|
|
||||||
);
|
|
||||||
end entity litedram_core;
|
|
||||||
|
|
||||||
architecture behaviour of litedram_core is
|
|
||||||
signal idone : std_ulogic := '0';
|
|
||||||
signal ierr : std_ulogic := '0';
|
|
||||||
signal old_wb_cyc : std_ulogic := '1';
|
|
||||||
begin
|
|
||||||
user_rst <= rst;
|
|
||||||
user_clk <= clk;
|
|
||||||
pll_locked <= '1';
|
|
||||||
init_done <= idone;
|
|
||||||
init_error <= ierr;
|
|
||||||
|
|
||||||
poll: process(user_clk)
|
|
||||||
procedure send_signals is
|
|
||||||
begin
|
|
||||||
litedram_set_wb(wb_ctrl_cti & wb_ctrl_bte &
|
|
||||||
wb_ctrl_sel & wb_ctrl_we &
|
|
||||||
wb_ctrl_stb & wb_ctrl_cyc &
|
|
||||||
wb_ctrl_adr & wb_ctrl_dat_w);
|
|
||||||
litedram_set_user(user_port_native_0_cmd_valid &
|
|
||||||
user_port_native_0_cmd_we &
|
|
||||||
user_port_native_0_wdata_valid &
|
|
||||||
user_port_native_0_rdata_ready &
|
|
||||||
user_port_native_0_cmd_addr &
|
|
||||||
user_port_native_0_wdata_we &
|
|
||||||
user_port_native_0_wdata_data);
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
procedure recv_signals is
|
|
||||||
variable wb_response : std_ulogic_vector(35 downto 0);
|
|
||||||
variable ur_response : std_ulogic_vector(130 downto 0);
|
|
||||||
begin
|
|
||||||
litedram_get_wb(wb_response);
|
|
||||||
wb_ctrl_dat_r <= wb_response(31 downto 0);
|
|
||||||
wb_ctrl_ack <= wb_response(32);
|
|
||||||
wb_ctrl_err <= wb_response(33);
|
|
||||||
idone <= wb_response(34);
|
|
||||||
ierr <= wb_response(35);
|
|
||||||
litedram_get_user(ur_response);
|
|
||||||
user_port_native_0_cmd_ready <= ur_response(130);
|
|
||||||
user_port_native_0_wdata_ready <= ur_response(129);
|
|
||||||
user_port_native_0_rdata_valid <= ur_response(128);
|
|
||||||
user_port_native_0_rdata_data <= ur_response(127 downto 0);
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if rising_edge(user_clk) then
|
|
||||||
|
|
||||||
send_signals;
|
|
||||||
recv_signals;
|
|
||||||
-- Then generate a clock cycle ( 0->1 then 1->0 )
|
|
||||||
litedram_clock;
|
|
||||||
recv_signals;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
if falling_edge(user_clk) then
|
|
||||||
send_signals;
|
|
||||||
recv_signals;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.sim_litedram.all;
|
|
||||||
|
|
||||||
entity litedram_trace_stub is
|
|
||||||
end entity;
|
|
||||||
|
|
||||||
architecture behaviour of litedram_trace_stub is
|
|
||||||
begin
|
|
||||||
process
|
|
||||||
begin
|
|
||||||
litedram_init(1);
|
|
||||||
wait;
|
|
||||||
end process;
|
|
||||||
end architecture;
|
|
@ -1,198 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <poll.h>
|
|
||||||
|
|
||||||
#include "sim_vhpi_c.h"
|
|
||||||
#include "Vlitedram_core.h"
|
|
||||||
#include "verilated_vcd_c.h"
|
|
||||||
|
|
||||||
static Vlitedram_core *v;
|
|
||||||
vluint64_t main_time = 0;
|
|
||||||
|
|
||||||
#if VM_TRACE
|
|
||||||
VerilatedVcdC *tfp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void cleanup(void)
|
|
||||||
{
|
|
||||||
#if VM_TRACE
|
|
||||||
if (tfp) {
|
|
||||||
tfp->flush();
|
|
||||||
tfp->close();
|
|
||||||
delete tfp;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void check_init(bool traces)
|
|
||||||
{
|
|
||||||
if (v)
|
|
||||||
return;
|
|
||||||
// XX Catch exceptions ?
|
|
||||||
v = new Vlitedram_core;
|
|
||||||
if (!v) {
|
|
||||||
fprintf(stderr, "Failure allocating litedram core\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
#if VM_TRACE
|
|
||||||
if (traces) {
|
|
||||||
// init trace dump
|
|
||||||
Verilated::traceEverOn(true);
|
|
||||||
tfp = new VerilatedVcdC;
|
|
||||||
v->trace(tfp, 99);
|
|
||||||
tfp->open("litedram.vcd");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
atexit(cleanup);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char get_bit(unsigned char **p)
|
|
||||||
{
|
|
||||||
unsigned char b = **p;
|
|
||||||
|
|
||||||
*p = *p + 1;
|
|
||||||
|
|
||||||
return b == vhpi1 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t get_bits(unsigned char **p, int len)
|
|
||||||
{
|
|
||||||
uint64_t r = 0;
|
|
||||||
|
|
||||||
while(len--)
|
|
||||||
r = (r << 1) | get_bit(p);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_bit(unsigned char **p, int bit)
|
|
||||||
{
|
|
||||||
**p = bit ? vhpi1 : vhpi0;
|
|
||||||
*p = *p + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_bits(unsigned char **p, uint64_t val, int len)
|
|
||||||
{
|
|
||||||
while(len--)
|
|
||||||
set_bit(p, (val >> len) & 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
double sc_time_stamp(void)
|
|
||||||
{
|
|
||||||
return main_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define check_size(s, exp) \
|
|
||||||
do { \
|
|
||||||
int __s = (s); \
|
|
||||||
int __e = (exp); \
|
|
||||||
if (__s != __e) \
|
|
||||||
fprintf(stderr, "WARNING: %s exp %d got %d\n", __func__, __e, __s); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
static void do_eval(void)
|
|
||||||
{
|
|
||||||
v->eval();
|
|
||||||
#if VM_TRACE
|
|
||||||
if (tfp)
|
|
||||||
tfp->dump((double) main_time);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void litedram_set_wb(unsigned char *req)
|
|
||||||
{
|
|
||||||
unsigned char *orig = req;
|
|
||||||
|
|
||||||
check_init(false);
|
|
||||||
|
|
||||||
v->wb_ctrl_cti = get_bits(&req, 3);
|
|
||||||
v->wb_ctrl_bte = get_bits(&req, 2);
|
|
||||||
v->wb_ctrl_sel = get_bits(&req, 4);
|
|
||||||
v->wb_ctrl_we = get_bit(&req);
|
|
||||||
v->wb_ctrl_stb = get_bit(&req);
|
|
||||||
v->wb_ctrl_cyc = get_bit(&req);
|
|
||||||
v->wb_ctrl_adr = get_bits(&req, 30);
|
|
||||||
v->wb_ctrl_dat_w = get_bits(&req, 32);
|
|
||||||
|
|
||||||
check_size(req - orig, 74);
|
|
||||||
|
|
||||||
do_eval();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void litedram_get_wb(unsigned char *req)
|
|
||||||
{
|
|
||||||
unsigned char *orig = req;
|
|
||||||
|
|
||||||
check_init(false);
|
|
||||||
|
|
||||||
set_bit(&req, v->init_error);
|
|
||||||
set_bit(&req, v->init_done);
|
|
||||||
set_bit(&req, v->wb_ctrl_err);
|
|
||||||
set_bit(&req, v->wb_ctrl_ack);
|
|
||||||
set_bits(&req, v->wb_ctrl_dat_r, 32);
|
|
||||||
|
|
||||||
check_size(req - orig, 36);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void litedram_set_user(unsigned char *req)
|
|
||||||
{
|
|
||||||
unsigned char *orig = req;
|
|
||||||
|
|
||||||
check_init(false);
|
|
||||||
|
|
||||||
v->user_port_native_0_cmd_valid = get_bit(&req);
|
|
||||||
v->user_port_native_0_cmd_we = get_bit(&req);
|
|
||||||
v->user_port_native_0_wdata_valid = get_bit(&req);
|
|
||||||
v->user_port_native_0_rdata_ready = get_bit(&req);
|
|
||||||
v->user_port_native_0_cmd_addr = get_bits(&req, 24);
|
|
||||||
v->user_port_native_0_wdata_we = get_bits(&req, 16);
|
|
||||||
v->user_port_native_0_wdata_data[3] = get_bits(&req, 32);
|
|
||||||
v->user_port_native_0_wdata_data[2] = get_bits(&req, 32);
|
|
||||||
v->user_port_native_0_wdata_data[1] = get_bits(&req, 32);
|
|
||||||
v->user_port_native_0_wdata_data[0] = get_bits(&req, 32);
|
|
||||||
|
|
||||||
check_size(req - orig, 172);
|
|
||||||
|
|
||||||
do_eval();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void litedram_get_user(unsigned char *req)
|
|
||||||
{
|
|
||||||
unsigned char *orig = req;
|
|
||||||
|
|
||||||
check_init(false);
|
|
||||||
|
|
||||||
set_bit(&req, v->user_port_native_0_cmd_ready);
|
|
||||||
set_bit(&req, v->user_port_native_0_wdata_ready);
|
|
||||||
set_bit(&req, v->user_port_native_0_rdata_valid);
|
|
||||||
set_bits(&req, v->user_port_native_0_rdata_data[3], 32);
|
|
||||||
set_bits(&req, v->user_port_native_0_rdata_data[2], 32);
|
|
||||||
set_bits(&req, v->user_port_native_0_rdata_data[1], 32);
|
|
||||||
set_bits(&req, v->user_port_native_0_rdata_data[0], 32);
|
|
||||||
|
|
||||||
check_size(req - orig, 131);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void litedram_clock(void)
|
|
||||||
{
|
|
||||||
check_init(false);
|
|
||||||
|
|
||||||
v->clk = 1;
|
|
||||||
do_eval();
|
|
||||||
main_time++;
|
|
||||||
v->clk = 0;
|
|
||||||
do_eval();
|
|
||||||
main_time++;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void litedram_init(int trace_on)
|
|
||||||
{
|
|
||||||
check_init(!!trace_on);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
@ -1,84 +0,0 @@
|
|||||||
$ version 1.1
|
|
||||||
|
|
||||||
# Signals in entities :
|
|
||||||
/core_dram_tb/dram/rst
|
|
||||||
/core_dram_tb/dram/system_clk
|
|
||||||
/core_dram_tb/dram/system_reset
|
|
||||||
/core_dram_tb/dram/wb_in
|
|
||||||
/core_dram_tb/dram/wb_out
|
|
||||||
/core_dram_tb/dram/user_port0_cmd_valid
|
|
||||||
/core_dram_tb/dram/user_port0_cmd_ready
|
|
||||||
/core_dram_tb/dram/user_port0_cmd_we
|
|
||||||
/core_dram_tb/dram/user_port0_cmd_addr
|
|
||||||
/core_dram_tb/dram/user_port0_wdata_valid
|
|
||||||
/core_dram_tb/dram/user_port0_wdata_ready
|
|
||||||
/core_dram_tb/dram/user_port0_wdata_we
|
|
||||||
/core_dram_tb/dram/user_port0_wdata_data
|
|
||||||
/core_dram_tb/dram/user_port0_rdata_valid
|
|
||||||
/core_dram_tb/dram/user_port0_rdata_ready
|
|
||||||
/core_dram_tb/dram/user_port0_rdata_data
|
|
||||||
/core_dram_tb/dram/cache_tags
|
|
||||||
/core_dram_tb/dram/cache_valids
|
|
||||||
/core_dram_tb/dram/storeq_rd_ready
|
|
||||||
/core_dram_tb/dram/storeq_rd_valid
|
|
||||||
/core_dram_tb/dram/storeq_rd_data
|
|
||||||
/core_dram_tb/dram/storeq_wr_ready
|
|
||||||
/core_dram_tb/dram/storeq_wr_valid
|
|
||||||
/core_dram_tb/dram/storeq_wr_data
|
|
||||||
/core_dram_tb/dram/accept_store
|
|
||||||
/core_dram_tb/dram/state
|
|
||||||
/core_dram_tb/dram/wb_req
|
|
||||||
/core_dram_tb/dram/store_queued
|
|
||||||
/core_dram_tb/dram/read_ack_0
|
|
||||||
/core_dram_tb/dram/read_ack_1
|
|
||||||
/core_dram_tb/dram/read_ad3_0
|
|
||||||
/core_dram_tb/dram/read_ad3_1
|
|
||||||
/core_dram_tb/dram/read_way_0
|
|
||||||
/core_dram_tb/dram/read_way_1
|
|
||||||
/core_dram_tb/dram/req_index
|
|
||||||
/core_dram_tb/dram/req_row
|
|
||||||
/core_dram_tb/dram/req_hit_way
|
|
||||||
/core_dram_tb/dram/req_tag
|
|
||||||
/core_dram_tb/dram/req_op
|
|
||||||
/core_dram_tb/dram/req_laddr
|
|
||||||
/core_dram_tb/dram/req_ad3
|
|
||||||
/core_dram_tb/dram/req_we
|
|
||||||
/core_dram_tb/dram/req_wdata
|
|
||||||
/core_dram_tb/dram/store_way
|
|
||||||
/core_dram_tb/dram/store_index
|
|
||||||
/core_dram_tb/dram/store_row
|
|
||||||
/core_dram_tb/dram/cache_out
|
|
||||||
/core_dram_tb/dram/plru_victim
|
|
||||||
/core_dram_tb/dram/replace_way
|
|
||||||
/core_dram_tb/dram/rams/do_read
|
|
||||||
/core_dram_tb/dram/rams/do_write
|
|
||||||
/core_dram_tb/dram/rams/rd_addr
|
|
||||||
/core_dram_tb/dram/rams/wr_addr
|
|
||||||
/core_dram_tb/dram/rams/wr_data
|
|
||||||
/core_dram_tb/dram/rams/wr_sel
|
|
||||||
/core_dram_tb/dram/rams/wr_sel_m
|
|
||||||
/core_dram_tb/dram/rams/dout
|
|
||||||
/core_dram_tb/dram/rams/way/clk
|
|
||||||
/core_dram_tb/dram/rams/way/rd_en
|
|
||||||
/core_dram_tb/dram/rams/way/rd_addr
|
|
||||||
/core_dram_tb/dram/rams/way/rd_data
|
|
||||||
/core_dram_tb/dram/rams/way/wr_sel
|
|
||||||
/core_dram_tb/dram/rams/way/wr_addr
|
|
||||||
/core_dram_tb/dram/rams/way/wr_data
|
|
||||||
/core_dram_tb/dram/rams/way/rd_data0
|
|
||||||
/core_dram_tb/dram/store_queue/wr_ready
|
|
||||||
/core_dram_tb/dram/store_queue/wr_valid
|
|
||||||
/core_dram_tb/dram/store_queue/wr_data
|
|
||||||
/core_dram_tb/dram/store_queue/rd_ready
|
|
||||||
/core_dram_tb/dram/store_queue/rd_valid
|
|
||||||
/core_dram_tb/dram/store_queue/rd_data
|
|
||||||
/core_dram_tb/dram/store_queue/rd_idx
|
|
||||||
/core_dram_tb/dram/store_queue/rd_next
|
|
||||||
/core_dram_tb/dram/store_queue/wr_idx
|
|
||||||
/core_dram_tb/dram/store_queue/wr_next
|
|
||||||
/core_dram_tb/dram/store_queue/op_prev
|
|
||||||
/core_dram_tb/dram/store_queue/op_next
|
|
||||||
/core_dram_tb/dram/store_queue/full
|
|
||||||
/core_dram_tb/dram/store_queue/empty
|
|
||||||
/core_dram_tb/dram/store_queue/push
|
|
||||||
/core_dram_tb/dram/store_queue/pop
|
|
@ -1,83 +0,0 @@
|
|||||||
[*]
|
|
||||||
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
|
|
||||||
[*] Mon Jun 22 06:32:16 2020
|
|
||||||
[*]
|
|
||||||
[dumpfile] "/home/ANT.AMAZON.COM/benh/hackplace/microwatt/foo.ghw"
|
|
||||||
[dumpfile_mtime] "Mon Jun 22 06:28:35 2020"
|
|
||||||
[dumpfile_size] 1680014
|
|
||||||
[savefile] "/home/ANT.AMAZON.COM/benh/hackplace/microwatt/litedram/extras/wave_tb.gtkw"
|
|
||||||
[timestart] 1920580000
|
|
||||||
[size] 2509 1371
|
|
||||||
[pos] -1 -1
|
|
||||||
*-24.248457 1935000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
|
||||||
[treeopen] top.
|
|
||||||
[treeopen] top.dram_tb.
|
|
||||||
[treeopen] top.dram_tb.dram.
|
|
||||||
[sst_width] 301
|
|
||||||
[signals_width] 433
|
|
||||||
[sst_expanded] 1
|
|
||||||
[sst_vpaned_height] 410
|
|
||||||
@28
|
|
||||||
top.dram_tb.reset_acks
|
|
||||||
@420
|
|
||||||
top.dram_tb.acks
|
|
||||||
@28
|
|
||||||
top.dram_tb.rst
|
|
||||||
top.dram_tb.clk
|
|
||||||
@22
|
|
||||||
#{top.dram_tb.wb_in.dat[63:0]} top.dram_tb.wb_in.dat[63] top.dram_tb.wb_in.dat[62] top.dram_tb.wb_in.dat[61] top.dram_tb.wb_in.dat[60] top.dram_tb.wb_in.dat[59] top.dram_tb.wb_in.dat[58] top.dram_tb.wb_in.dat[57] top.dram_tb.wb_in.dat[56] top.dram_tb.wb_in.dat[55] top.dram_tb.wb_in.dat[54] top.dram_tb.wb_in.dat[53] top.dram_tb.wb_in.dat[52] top.dram_tb.wb_in.dat[51] top.dram_tb.wb_in.dat[50] top.dram_tb.wb_in.dat[49] top.dram_tb.wb_in.dat[48] top.dram_tb.wb_in.dat[47] top.dram_tb.wb_in.dat[46] top.dram_tb.wb_in.dat[45] top.dram_tb.wb_in.dat[44] top.dram_tb.wb_in.dat[43] top.dram_tb.wb_in.dat[42] top.dram_tb.wb_in.dat[41] top.dram_tb.wb_in.dat[40] top.dram_tb.wb_in.dat[39] top.dram_tb.wb_in.dat[38] top.dram_tb.wb_in.dat[37] top.dram_tb.wb_in.dat[36] top.dram_tb.wb_in.dat[35] top.dram_tb.wb_in.dat[34] top.dram_tb.wb_in.dat[33] top.dram_tb.wb_in.dat[32] top.dram_tb.wb_in.dat[31] top.dram_tb.wb_in.dat[30] top.dram_tb.wb_in.dat[29] top.dram_tb.wb_in.dat[28] top.dram_tb.wb_in.dat[27] top.dram_tb.wb_in.dat[26] top.dram_tb.wb_in.dat[25] top.dram_tb.wb_in.dat[24] top.dram_tb.wb_in.dat[23] top.dram_tb.wb_in.dat[22] top.dram_tb.wb_in.dat[21] top.dram_tb.wb_in.dat[20] top.dram_tb.wb_in.dat[19] top.dram_tb.wb_in.dat[18] top.dram_tb.wb_in.dat[17] top.dram_tb.wb_in.dat[16] top.dram_tb.wb_in.dat[15] top.dram_tb.wb_in.dat[14] top.dram_tb.wb_in.dat[13] top.dram_tb.wb_in.dat[12] top.dram_tb.wb_in.dat[11] top.dram_tb.wb_in.dat[10] top.dram_tb.wb_in.dat[9] top.dram_tb.wb_in.dat[8] top.dram_tb.wb_in.dat[7] top.dram_tb.wb_in.dat[6] top.dram_tb.wb_in.dat[5] top.dram_tb.wb_in.dat[4] top.dram_tb.wb_in.dat[3] top.dram_tb.wb_in.dat[2] top.dram_tb.wb_in.dat[1] top.dram_tb.wb_in.dat[0]
|
|
||||||
#{top.dram_tb.wb_in.adr[31:0]} top.dram_tb.wb_in.adr[31] top.dram_tb.wb_in.adr[30] top.dram_tb.wb_in.adr[29] top.dram_tb.wb_in.adr[28] top.dram_tb.wb_in.adr[27] top.dram_tb.wb_in.adr[26] top.dram_tb.wb_in.adr[25] top.dram_tb.wb_in.adr[24] top.dram_tb.wb_in.adr[23] top.dram_tb.wb_in.adr[22] top.dram_tb.wb_in.adr[21] top.dram_tb.wb_in.adr[20] top.dram_tb.wb_in.adr[19] top.dram_tb.wb_in.adr[18] top.dram_tb.wb_in.adr[17] top.dram_tb.wb_in.adr[16] top.dram_tb.wb_in.adr[15] top.dram_tb.wb_in.adr[14] top.dram_tb.wb_in.adr[13] top.dram_tb.wb_in.adr[12] top.dram_tb.wb_in.adr[11] top.dram_tb.wb_in.adr[10] top.dram_tb.wb_in.adr[9] top.dram_tb.wb_in.adr[8] top.dram_tb.wb_in.adr[7] top.dram_tb.wb_in.adr[6] top.dram_tb.wb_in.adr[5] top.dram_tb.wb_in.adr[4] top.dram_tb.wb_in.adr[3] top.dram_tb.wb_in.adr[2] top.dram_tb.wb_in.adr[1] top.dram_tb.wb_in.adr[0]
|
|
||||||
#{top.dram_tb.wb_in.sel[7:0]} top.dram_tb.wb_in.sel[7] top.dram_tb.wb_in.sel[6] top.dram_tb.wb_in.sel[5] top.dram_tb.wb_in.sel[4] top.dram_tb.wb_in.sel[3] top.dram_tb.wb_in.sel[2] top.dram_tb.wb_in.sel[1] top.dram_tb.wb_in.sel[0]
|
|
||||||
@28
|
|
||||||
top.dram_tb.wb_in.cyc
|
|
||||||
top.dram_tb.wb_in.stb
|
|
||||||
top.dram_tb.wb_in.we
|
|
||||||
top.dram_tb.wb_out.ack
|
|
||||||
top.dram_tb.wb_out.stall
|
|
||||||
@22
|
|
||||||
#{top.dram_tb.wb_out.dat[63:0]} top.dram_tb.wb_out.dat[63] top.dram_tb.wb_out.dat[62] top.dram_tb.wb_out.dat[61] top.dram_tb.wb_out.dat[60] top.dram_tb.wb_out.dat[59] top.dram_tb.wb_out.dat[58] top.dram_tb.wb_out.dat[57] top.dram_tb.wb_out.dat[56] top.dram_tb.wb_out.dat[55] top.dram_tb.wb_out.dat[54] top.dram_tb.wb_out.dat[53] top.dram_tb.wb_out.dat[52] top.dram_tb.wb_out.dat[51] top.dram_tb.wb_out.dat[50] top.dram_tb.wb_out.dat[49] top.dram_tb.wb_out.dat[48] top.dram_tb.wb_out.dat[47] top.dram_tb.wb_out.dat[46] top.dram_tb.wb_out.dat[45] top.dram_tb.wb_out.dat[44] top.dram_tb.wb_out.dat[43] top.dram_tb.wb_out.dat[42] top.dram_tb.wb_out.dat[41] top.dram_tb.wb_out.dat[40] top.dram_tb.wb_out.dat[39] top.dram_tb.wb_out.dat[38] top.dram_tb.wb_out.dat[37] top.dram_tb.wb_out.dat[36] top.dram_tb.wb_out.dat[35] top.dram_tb.wb_out.dat[34] top.dram_tb.wb_out.dat[33] top.dram_tb.wb_out.dat[32] top.dram_tb.wb_out.dat[31] top.dram_tb.wb_out.dat[30] top.dram_tb.wb_out.dat[29] top.dram_tb.wb_out.dat[28] top.dram_tb.wb_out.dat[27] top.dram_tb.wb_out.dat[26] top.dram_tb.wb_out.dat[25] top.dram_tb.wb_out.dat[24] top.dram_tb.wb_out.dat[23] top.dram_tb.wb_out.dat[22] top.dram_tb.wb_out.dat[21] top.dram_tb.wb_out.dat[20] top.dram_tb.wb_out.dat[19] top.dram_tb.wb_out.dat[18] top.dram_tb.wb_out.dat[17] top.dram_tb.wb_out.dat[16] top.dram_tb.wb_out.dat[15] top.dram_tb.wb_out.dat[14] top.dram_tb.wb_out.dat[13] top.dram_tb.wb_out.dat[12] top.dram_tb.wb_out.dat[11] top.dram_tb.wb_out.dat[10] top.dram_tb.wb_out.dat[9] top.dram_tb.wb_out.dat[8] top.dram_tb.wb_out.dat[7] top.dram_tb.wb_out.dat[6] top.dram_tb.wb_out.dat[5] top.dram_tb.wb_out.dat[4] top.dram_tb.wb_out.dat[3] top.dram_tb.wb_out.dat[2] top.dram_tb.wb_out.dat[1] top.dram_tb.wb_out.dat[0]
|
|
||||||
@28
|
|
||||||
top.dram_tb.rd_valid
|
|
||||||
top.dram_tb.rd_ready
|
|
||||||
@22
|
|
||||||
#{top.dram_tb.rd_data[63:0]} top.dram_tb.rd_data[63] top.dram_tb.rd_data[62] top.dram_tb.rd_data[61] top.dram_tb.rd_data[60] top.dram_tb.rd_data[59] top.dram_tb.rd_data[58] top.dram_tb.rd_data[57] top.dram_tb.rd_data[56] top.dram_tb.rd_data[55] top.dram_tb.rd_data[54] top.dram_tb.rd_data[53] top.dram_tb.rd_data[52] top.dram_tb.rd_data[51] top.dram_tb.rd_data[50] top.dram_tb.rd_data[49] top.dram_tb.rd_data[48] top.dram_tb.rd_data[47] top.dram_tb.rd_data[46] top.dram_tb.rd_data[45] top.dram_tb.rd_data[44] top.dram_tb.rd_data[43] top.dram_tb.rd_data[42] top.dram_tb.rd_data[41] top.dram_tb.rd_data[40] top.dram_tb.rd_data[39] top.dram_tb.rd_data[38] top.dram_tb.rd_data[37] top.dram_tb.rd_data[36] top.dram_tb.rd_data[35] top.dram_tb.rd_data[34] top.dram_tb.rd_data[33] top.dram_tb.rd_data[32] top.dram_tb.rd_data[31] top.dram_tb.rd_data[30] top.dram_tb.rd_data[29] top.dram_tb.rd_data[28] top.dram_tb.rd_data[27] top.dram_tb.rd_data[26] top.dram_tb.rd_data[25] top.dram_tb.rd_data[24] top.dram_tb.rd_data[23] top.dram_tb.rd_data[22] top.dram_tb.rd_data[21] top.dram_tb.rd_data[20] top.dram_tb.rd_data[19] top.dram_tb.rd_data[18] top.dram_tb.rd_data[17] top.dram_tb.rd_data[16] top.dram_tb.rd_data[15] top.dram_tb.rd_data[14] top.dram_tb.rd_data[13] top.dram_tb.rd_data[12] top.dram_tb.rd_data[11] top.dram_tb.rd_data[10] top.dram_tb.rd_data[9] top.dram_tb.rd_data[8] top.dram_tb.rd_data[7] top.dram_tb.rd_data[6] top.dram_tb.rd_data[5] top.dram_tb.rd_data[4] top.dram_tb.rd_data[3] top.dram_tb.rd_data[2] top.dram_tb.rd_data[1] top.dram_tb.rd_data[0]
|
|
||||||
@200
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-wrapper
|
|
||||||
@28
|
|
||||||
top.dram_tb.dram.accept_store
|
|
||||||
@420
|
|
||||||
top.dram_tb.dram.req_op
|
|
||||||
top.dram_tb.dram.state
|
|
||||||
@28
|
|
||||||
top.dram_tb.dram.read_ack_1
|
|
||||||
top.dram_tb.dram.read_ack_0
|
|
||||||
top.dram_tb.dram.storeq_wr_valid
|
|
||||||
top.dram_tb.dram.storeq_wr_ready
|
|
||||||
top.dram_tb.dram.storeq_rd_valid
|
|
||||||
top.dram_tb.dram.storeq_rd_ready
|
|
||||||
top.dram_tb.dram.user_port0_rdata_ready
|
|
||||||
top.dram_tb.dram.user_port0_rdata_valid
|
|
||||||
top.dram_tb.dram.user_port0_wdata_ready
|
|
||||||
top.dram_tb.dram.user_port0_wdata_valid
|
|
||||||
top.dram_tb.dram.user_port0_cmd_we
|
|
||||||
top.dram_tb.dram.user_port0_cmd_ready
|
|
||||||
top.dram_tb.dram.user_port0_cmd_valid
|
|
||||||
top.dram_tb.dram.refill_cmd_valid
|
|
||||||
@420
|
|
||||||
top.dram_tb.dram.req_index
|
|
||||||
@421
|
|
||||||
top.dram_tb.dram.req_row
|
|
||||||
@420
|
|
||||||
top.dram_tb.dram.req_hit_way
|
|
||||||
@28
|
|
||||||
top.dram_tb.dram.req_ad3
|
|
||||||
@420
|
|
||||||
top.dram_tb.dram.refill_row
|
|
||||||
top.dram_tb.dram.refill_index
|
|
||||||
top.dram_tb.dram.refill_way
|
|
||||||
@28
|
|
||||||
top.dram_tb.dram.system_clk
|
|
||||||
[pattern_trace] 1
|
|
||||||
[pattern_trace] 0
|
|
@ -1,37 +0,0 @@
|
|||||||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
||||||
# License: BSD
|
|
||||||
|
|
||||||
{
|
|
||||||
# General ------------------------------------------------------------------
|
|
||||||
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
|
||||||
"speedgrade": -2, # FPGA speedgrade
|
|
||||||
"memtype": "DDR3", # DRAM type
|
|
||||||
|
|
||||||
# PHY ----------------------------------------------------------------------
|
|
||||||
"cmd_latency": 0, # Command additional latency
|
|
||||||
"sdram_module": "MT41K512M16", # SDRAM modules of the board or SO-DIMM
|
|
||||||
"sdram_module_nb": 2, # Number of byte groups
|
|
||||||
"sdram_rank_nb": 1, # Number of ranks
|
|
||||||
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
|
||||||
|
|
||||||
# Electrical ---------------------------------------------------------------
|
|
||||||
"rtt_nom": "60ohm", # Nominal termination
|
|
||||||
"rtt_wr": "60ohm", # Write termination
|
|
||||||
"ron": "34ohm", # Output driver impedance
|
|
||||||
|
|
||||||
# Frequency ----------------------------------------------------------------
|
|
||||||
"input_clk_freq": 200e6, # Input clock frequency
|
|
||||||
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
|
||||||
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
|
||||||
|
|
||||||
# Core ---------------------------------------------------------------------
|
|
||||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
|
||||||
|
|
||||||
# User Ports ---------------------------------------------------------------
|
|
||||||
"user_ports": {
|
|
||||||
"native_0": {
|
|
||||||
"type": "native",
|
|
||||||
"block_until_ready": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
||||||
# License: BSD
|
|
||||||
|
|
||||||
{
|
|
||||||
# General ------------------------------------------------------------------
|
|
||||||
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
|
||||||
"speedgrade": -1, # FPGA speedgrade
|
|
||||||
"memtype": "DDR3", # DRAM type
|
|
||||||
|
|
||||||
# PHY ----------------------------------------------------------------------
|
|
||||||
"cmd_latency": 0, # Command additional latency
|
|
||||||
"sdram_module": "MT41K128M16", # SDRAM modules of the board or SO-DIMM
|
|
||||||
"sdram_module_nb": 2, # Number of byte groups
|
|
||||||
"sdram_rank_nb": 1, # Number of ranks
|
|
||||||
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
|
||||||
|
|
||||||
# Electrical ---------------------------------------------------------------
|
|
||||||
"rtt_nom": "60ohm", # Nominal termination
|
|
||||||
"rtt_wr": "60ohm", # Write termination
|
|
||||||
"ron": "34ohm", # Output driver impedance
|
|
||||||
|
|
||||||
# Frequency ----------------------------------------------------------------
|
|
||||||
"input_clk_freq": 100e6, # Input clock frequency
|
|
||||||
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
|
||||||
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
|
||||||
|
|
||||||
# Core ---------------------------------------------------------------------
|
|
||||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
|
||||||
|
|
||||||
# User Ports ---------------------------------------------------------------
|
|
||||||
"user_ports": {
|
|
||||||
"native_0": {
|
|
||||||
"type": "native",
|
|
||||||
"block_until_ready": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
use work.utils.all;
|
|
||||||
|
|
||||||
entity dram_init_mem is
|
|
||||||
generic (
|
|
||||||
EXTRA_PAYLOAD_FILE : string := "";
|
|
||||||
EXTRA_PAYLOAD_SIZE : integer := 0
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
wb_in : in wb_io_master_out;
|
|
||||||
wb_out : out wb_io_slave_out
|
|
||||||
);
|
|
||||||
end entity dram_init_mem;
|
|
||||||
|
|
||||||
architecture rtl of dram_init_mem is
|
|
||||||
|
|
||||||
constant INIT_RAM_SIZE : integer := 24576;
|
|
||||||
constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
|
|
||||||
constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
|
|
||||||
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE-1);
|
|
||||||
constant INIT_RAM_FILE : string := "litedram_core.init";
|
|
||||||
|
|
||||||
type ram_t is array(0 to (TOTAL_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0);
|
|
||||||
|
|
||||||
-- XXX FIXME: Have a single init function called twice with
|
|
||||||
-- an offset as argument
|
|
||||||
procedure init_load_payload(ram: inout ram_t; filename: string) is
|
|
||||||
file payload_file : text open read_mode is filename;
|
|
||||||
variable ram_line : line;
|
|
||||||
variable temp_word : std_logic_vector(63 downto 0);
|
|
||||||
begin
|
|
||||||
for i in 0 to RND_PAYLOAD_SIZE-1 loop
|
|
||||||
exit when endfile(payload_file);
|
|
||||||
readline(payload_file, ram_line);
|
|
||||||
hread(ram_line, temp_word);
|
|
||||||
ram((INIT_RAM_SIZE/4) + i*2) := temp_word(31 downto 0);
|
|
||||||
ram((INIT_RAM_SIZE/4) + i*2+1) := temp_word(63 downto 32);
|
|
||||||
end loop;
|
|
||||||
assert endfile(payload_file) report "Payload too big !" severity failure;
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
impure function init_load_ram(name : string) return ram_t is
|
|
||||||
file ram_file : text open read_mode is name;
|
|
||||||
variable temp_word : std_logic_vector(63 downto 0);
|
|
||||||
variable temp_ram : ram_t := (others => (others => '0'));
|
|
||||||
variable ram_line : line;
|
|
||||||
begin
|
|
||||||
report "Payload size:" & integer'image(EXTRA_PAYLOAD_SIZE) &
|
|
||||||
" rounded to:" & integer'image(RND_PAYLOAD_SIZE);
|
|
||||||
report "Total RAM size:" & integer'image(TOTAL_RAM_SIZE) &
|
|
||||||
" bytes using " & integer'image(INIT_RAM_ABITS) &
|
|
||||||
" address bits";
|
|
||||||
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
|
|
||||||
exit when endfile(ram_file);
|
|
||||||
readline(ram_file, ram_line);
|
|
||||||
hread(ram_line, temp_word);
|
|
||||||
temp_ram(i*2) := temp_word(31 downto 0);
|
|
||||||
temp_ram(i*2+1) := temp_word(63 downto 32);
|
|
||||||
end loop;
|
|
||||||
if RND_PAYLOAD_SIZE /= 0 then
|
|
||||||
init_load_payload(temp_ram, EXTRA_PAYLOAD_FILE);
|
|
||||||
end if;
|
|
||||||
return temp_ram;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
impure function init_zero return ram_t is
|
|
||||||
variable temp_ram : ram_t := (others => (others => '0'));
|
|
||||||
begin
|
|
||||||
return temp_ram;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
impure function initialize_ram(filename: string) return ram_t is
|
|
||||||
begin
|
|
||||||
report "Opening file " & filename;
|
|
||||||
if filename'length = 0 then
|
|
||||||
return init_zero;
|
|
||||||
else
|
|
||||||
return init_load_ram(filename);
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
signal init_ram : ram_t := initialize_ram(INIT_RAM_FILE);
|
|
||||||
|
|
||||||
attribute ram_style : string;
|
|
||||||
attribute ram_style of init_ram: signal is "block";
|
|
||||||
|
|
||||||
signal obuf : std_ulogic_vector(31 downto 0);
|
|
||||||
signal oack : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
init_ram_0: process(clk)
|
|
||||||
variable adr : integer;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
oack <= '0';
|
|
||||||
if (wb_in.cyc and wb_in.stb) = '1' then
|
|
||||||
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
|
|
||||||
if wb_in.we = '0' then
|
|
||||||
obuf <= init_ram(adr);
|
|
||||||
else
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
if wb_in.sel(i) = '1' then
|
|
||||||
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
|
|
||||||
wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
oack <= '1';
|
|
||||||
end if;
|
|
||||||
wb_out.ack <= oack;
|
|
||||||
wb_out.dat <= obuf;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
wb_out.stall <= '0';
|
|
||||||
|
|
||||||
end architecture rtl;
|
|
@ -1,108 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
from litex.build.tools import write_to_file
|
|
||||||
from litex.build.tools import replace_in_file
|
|
||||||
from litedram.gen import *
|
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
def make_new_dir(base, added):
|
|
||||||
r = os.path.join(base, added)
|
|
||||||
if os.path.exists(r):
|
|
||||||
shutil.rmtree(r)
|
|
||||||
os.mkdir(r)
|
|
||||||
return r
|
|
||||||
|
|
||||||
gen_src_dir = os.path.dirname(os.path.realpath(__file__))
|
|
||||||
base_dir = os.path.normpath(os.path.join(gen_src_dir, os.pardir))
|
|
||||||
build_top_dir = make_new_dir(base_dir, "build")
|
|
||||||
gen_src_dir = os.path.join(base_dir, "gen-src")
|
|
||||||
gen_dir = make_new_dir(base_dir, "generated")
|
|
||||||
|
|
||||||
# Build the init code for microwatt-initialized DRAM
|
|
||||||
def build_init_code(build_dir, is_sim):
|
|
||||||
|
|
||||||
# More path fudging
|
|
||||||
sw_dir = os.path.join(build_dir, "software");
|
|
||||||
sw_inc_dir = os.path.join(sw_dir, "include")
|
|
||||||
gen_inc_dir = os.path.join(sw_inc_dir, "generated")
|
|
||||||
src_dir = os.path.join(gen_src_dir, "sdram_init")
|
|
||||||
lxbios_src_dir = os.path.join(soc_directory, "software")
|
|
||||||
print(" sw dir:", sw_dir)
|
|
||||||
print("gen_inc_dir:", gen_inc_dir)
|
|
||||||
print(" src dir:", src_dir)
|
|
||||||
print(" lx src dir:", lxbios_src_dir)
|
|
||||||
|
|
||||||
# Generate mem.h (hard wire size, it's not important)
|
|
||||||
mem_h = "#define MAIN_RAM_BASE 0x40000000UL\n#define MAIN_RAM_SIZE 0x10000000UL\n"
|
|
||||||
write_to_file(os.path.join(gen_inc_dir, "mem.h"), mem_h)
|
|
||||||
|
|
||||||
# Environment
|
|
||||||
env_vars = []
|
|
||||||
def _makefile_escape(s): # From LiteX
|
|
||||||
return s.replace("\\", "\\\\")
|
|
||||||
def add_var(k, v):
|
|
||||||
env_vars.append("{}={}\n".format(k, _makefile_escape(v)))
|
|
||||||
|
|
||||||
makefile = os.path.join(src_dir, "Makefile")
|
|
||||||
cmd = ["make", "-C", build_dir, "-f", makefile]
|
|
||||||
cmd.append("BUILD_DIR=%s" % sw_dir)
|
|
||||||
cmd.append("SRC_DIR=%s" % src_dir)
|
|
||||||
cmd.append("GENINC_DIR=%s" % sw_inc_dir)
|
|
||||||
cmd.append("LXSRC_DIR=%s" % lxbios_src_dir)
|
|
||||||
|
|
||||||
if is_sim:
|
|
||||||
cmd.append("EXTRA_CFLAGS=%s" % "-D__SIM__")
|
|
||||||
|
|
||||||
# Build init code
|
|
||||||
print(" Generating init software...")
|
|
||||||
r = subprocess.check_call(cmd)
|
|
||||||
print("Make result:", r)
|
|
||||||
|
|
||||||
return os.path.join(sw_dir, "obj", "sdram_init.hex")
|
|
||||||
|
|
||||||
def generate_one(t):
|
|
||||||
|
|
||||||
print("Generating target:", t)
|
|
||||||
|
|
||||||
# Is it a simulation ?
|
|
||||||
is_sim = "sim" in t
|
|
||||||
|
|
||||||
# Muck with directory path
|
|
||||||
build_dir = make_new_dir(build_top_dir, t)
|
|
||||||
t_dir = make_new_dir(gen_dir, t)
|
|
||||||
|
|
||||||
cmd = ["litedram_gen", "--output-dir=%s" % build_dir]
|
|
||||||
if is_sim:
|
|
||||||
cmd.append("--sim")
|
|
||||||
cmd.append("%s.yml" % t)
|
|
||||||
subprocess.check_call(cmd)
|
|
||||||
|
|
||||||
# Grab generated gatewar dir
|
|
||||||
gw_dir = os.path.join(build_dir, "gateware")
|
|
||||||
|
|
||||||
# Generate init code
|
|
||||||
src_init_file = build_init_code(build_dir, is_sim)
|
|
||||||
src_initram_file = os.path.join(gen_src_dir, "dram-init-mem.vhdl")
|
|
||||||
|
|
||||||
# Copy generated files to target dir, amend them if necessary
|
|
||||||
initfile_name = "litedram_core.init"
|
|
||||||
core_file = os.path.join(gw_dir, "litedram_core.v")
|
|
||||||
dst_init_file = os.path.join(t_dir, initfile_name)
|
|
||||||
dst_initram_file = os.path.join(t_dir, "litedram-initmem.vhdl")
|
|
||||||
shutil.copyfile(src_init_file, dst_init_file)
|
|
||||||
shutil.copyfile(src_initram_file, dst_initram_file)
|
|
||||||
if is_sim:
|
|
||||||
initfile_path = os.path.join("litedram", "generated", "sim", initfile_name)
|
|
||||||
replace_in_file(dst_initram_file, initfile_name, initfile_path)
|
|
||||||
shutil.copy(core_file, t_dir)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
targets = ['arty','nexys-video', 'genesys2', 'acorn-cle-215', 'wukong-v2', 'orangecrab-85-0.2', 'sim']
|
|
||||||
for t in targets:
|
|
||||||
generate_one(t)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,37 +0,0 @@
|
|||||||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
||||||
# License: BSD
|
|
||||||
|
|
||||||
{
|
|
||||||
# General ------------------------------------------------------------------
|
|
||||||
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
|
||||||
"speedgrade": -2, # FPGA speedgrade
|
|
||||||
"memtype": "DDR3", # DRAM type
|
|
||||||
|
|
||||||
# PHY ----------------------------------------------------------------------
|
|
||||||
"cmd_latency": 1, # Command additional latency
|
|
||||||
"sdram_module": "MT41J256M16", # SDRAM modules of the board or SO-DIMM
|
|
||||||
"sdram_module_nb": 4, # Number of byte groups
|
|
||||||
"sdram_rank_nb": 1, # Number of ranks
|
|
||||||
"sdram_phy": "K7DDRPHY", # Type of FPGA PHY
|
|
||||||
|
|
||||||
# Electrical ---------------------------------------------------------------
|
|
||||||
"rtt_nom": "60ohm", # Nominal termination
|
|
||||||
"rtt_wr": "60ohm", # Write termination
|
|
||||||
"ron": "34ohm", # Output driver impedance
|
|
||||||
|
|
||||||
# Frequency ----------------------------------------------------------------
|
|
||||||
"input_clk_freq": 200e6, # Input clock frequency
|
|
||||||
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
|
||||||
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
|
||||||
|
|
||||||
# Core ---------------------------------------------------------------------
|
|
||||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
|
||||||
|
|
||||||
# User Ports ---------------------------------------------------------------
|
|
||||||
"user_ports": {
|
|
||||||
"native_0": {
|
|
||||||
"type": "native",
|
|
||||||
"block_until_ready": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
||||||
# License: BSD
|
|
||||||
|
|
||||||
{
|
|
||||||
# General ------------------------------------------------------------------
|
|
||||||
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
|
||||||
"speedgrade": -1, # FPGA speedgrade
|
|
||||||
"memtype": "DDR3", # DRAM type
|
|
||||||
|
|
||||||
# PHY ----------------------------------------------------------------------
|
|
||||||
"cmd_latency": 0, # Command additional latency
|
|
||||||
"sdram_module": "MT41K256M16", # SDRAM modules of the board or SO-DIMM
|
|
||||||
"sdram_module_nb": 2, # Number of byte groups
|
|
||||||
"sdram_rank_nb": 1, # Number of ranks
|
|
||||||
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
|
||||||
|
|
||||||
# Electrical ---------------------------------------------------------------
|
|
||||||
"rtt_nom": "60ohm", # Nominal termination
|
|
||||||
"rtt_wr": "60ohm", # Write termination
|
|
||||||
"ron": "34ohm", # Output driver impedance
|
|
||||||
|
|
||||||
# Frequency ----------------------------------------------------------------
|
|
||||||
"input_clk_freq": 100e6, # Input clock frequency
|
|
||||||
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
|
||||||
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
|
||||||
|
|
||||||
# Core ---------------------------------------------------------------------
|
|
||||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
|
||||||
|
|
||||||
# User Ports ---------------------------------------------------------------
|
|
||||||
"user_ports": {
|
|
||||||
"native_0": {
|
|
||||||
"type": "native",
|
|
||||||
"block_until_ready": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity dram_init_mem is
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
wb_in : in wb_io_master_out;
|
|
||||||
wb_out : out wb_io_slave_out
|
|
||||||
);
|
|
||||||
end entity dram_init_mem;
|
|
||||||
|
|
||||||
architecture rtl of dram_init_mem is
|
|
||||||
|
|
||||||
wb_out.dat <= (others => '0');
|
|
||||||
wb_out.stall <= '0';
|
|
||||||
wb_out.ack <= wb_in.stb and wb_in.cyc;
|
|
||||||
|
|
||||||
end architecture rtl;
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue