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
|
||||
CFLAGS=-O3 -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
|
||||
CFLAGS=-O2 -Wall
|
||||
|
||||
# some yosys builds have ghdl plugin built in, otherwise need "-m ghdl"
|
||||
GHDLSYNTH ?= $(shell ($(YOSYS) -H | grep -q ghdl) || echo -m ghdl)
|
||||
YOSYS ?= yosys
|
||||
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 = core_tb simple_ram_behavioural_tb soc_reset_tb
|
||||
# XXX
|
||||
# loadstore_tb fetch_tb
|
||||
|
||||
all: $(all)
|
||||
|
||||
core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \
|
||||
utils.vhdl plru.vhdl cache_ram.vhdl icache.vhdl \
|
||||
decode1.vhdl helpers.vhdl insn_helpers.vhdl \
|
||||
control.vhdl decode2.vhdl register_file.vhdl \
|
||||
cr_file.vhdl crhelpers.vhdl ppc_fx_insns.vhdl rotator.vhdl \
|
||||
logical.vhdl countbits.vhdl multiply.vhdl divider.vhdl execute1.vhdl \
|
||||
loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \
|
||||
core.vhdl fpu.vhdl pmu.vhdl
|
||||
|
||||
soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
|
||||
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl gpio.vhdl soc.vhdl \
|
||||
spi_rxtx.vhdl spi_flash_ctrl.vhdl
|
||||
|
||||
uart_files = $(wildcard uart16550/*.v)
|
||||
|
||||
soc_sim_files = $(core_files) $(soc_files) sim_console.vhdl sim_pp_uart.vhdl sim_bram_helpers.vhdl \
|
||||
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl \
|
||||
sim_16550_uart.vhdl \
|
||||
foreign_random.vhdl glibc_random.vhdl glibc_random_helpers.vhdl
|
||||
|
||||
soc_sim_c_files = sim_vhpi_c.c sim_bram_helpers_c.c sim_console_c.c \
|
||||
sim_jtag_socket_c.c
|
||||
|
||||
soc_sim_obj_files=$(soc_sim_c_files:.c=.o)
|
||||
comma := ,
|
||||
soc_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_sim_obj_files))
|
||||
|
||||
unisim_dir = sim-unisim
|
||||
unisim_lib = $(unisim_dir)/unisim-obj08.cf
|
||||
unisim_lib_files = $(unisim_dir)/BSCANE2.vhdl $(unisim_dir)/BUFG.vhdl \
|
||||
$(unisim_dir)/unisim_vcomponents.vhdl
|
||||
$(unisim_lib): $(unisim_lib_files)
|
||||
$(GHDL) -i --std=08 --work=unisim --workdir=$(unisim_dir) $^
|
||||
GHDLFLAGS += -P$(unisim_dir)
|
||||
|
||||
soc_tbs = core_tb icache_tb dcache_tb dmi_dtm_tb wishbone_bram_tb
|
||||
soc_flash_tbs = core_flash_tb
|
||||
soc_dram_tbs = dram_tb core_dram_tb
|
||||
|
||||
ifneq ($(FLASH_MODEL_PATH),)
|
||||
fmf_dir = $(FLASH_MODEL_PATH)/fmf
|
||||
fmf_lib = $(fmf_dir)/fmf-obj08.cf
|
||||
fmf_lib_files = $(wildcard $(fmf_dir)/*.vhd)
|
||||
GHDLFLAGS += -P$(fmf_dir)
|
||||
$(fmf_lib): $(fmf_lib_files)
|
||||
$(GHDL) -i --std=08 --work=fmf --workdir=$(fmf_dir) $^
|
||||
|
||||
flash_model_files=$(FLASH_MODEL_PATH)/s25fl128s.vhd
|
||||
flash_model_files: $(fmf_lib)
|
||||
else
|
||||
flash_model_files=sim_no_flash.vhdl
|
||||
fmf_lib=
|
||||
endif
|
||||
|
||||
$(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) $<
|
||||
%.o : %.vhdl
|
||||
$(GHDL) -a $(GHDLFLAGS) $<
|
||||
|
||||
common.o: decode_types.o
|
||||
core_tb.o: common.o core.o soc.o
|
||||
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
|
||||
cr_file.o: common.o
|
||||
crhelpers.o: common.o
|
||||
decode1.o: common.o decode_types.o
|
||||
decode2.o: decode_types.o common.o helpers.o insn_helpers.o
|
||||
decode_types.o:
|
||||
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
|
||||
fetch1.o: common.o
|
||||
fetch2.o: common.o wishbone_types.o
|
||||
glibc_random_helpers.o:
|
||||
glibc_random.o: glibc_random_helpers.o
|
||||
helpers.o:
|
||||
icache.o: common.o wishbone_types.o
|
||||
insn_helpers.o:
|
||||
loadstore1.o: common.o
|
||||
loadstore2.o: common.o helpers.o wishbone_types.o
|
||||
multiply_tb.o: common.o glibc_random.o ppc_fx_insns.o multiply.o
|
||||
multiply.o: common.o decode_types.o ppc_fx_insns.o crhelpers.o
|
||||
ppc_fx_insns.o: helpers.o
|
||||
register_file.o: common.o
|
||||
sim_console.o:
|
||||
simple_ram_behavioural_helpers.o:
|
||||
simple_ram_behavioural_tb.o: wishbone_types.o simple_ram_behavioural.o
|
||||
simple_ram_behavioural.o: wishbone_types.o simple_ram_behavioural_helpers.o
|
||||
sim_uart.o: wishbone_types.o sim_console.o
|
||||
soc.o: common.o wishbone_types.o core.o wishbone_arbiter.o sim_uart.o simple_ram_behavioural.o
|
||||
wishbone_arbiter.o: wishbone_types.o
|
||||
wishbone_types.o:
|
||||
writeback.o: common.o
|
||||
fpga/soc_reset_tb.o: fpga/soc_reset.o
|
||||
|
||||
soc_reset_tb: fpga/soc_reset_tb.o fpga/soc_reset.o
|
||||
$(GHDL) -e $(GHDLFLAGS) soc_reset_tb
|
||||
|
||||
core_tb: core_tb.o simple_ram_behavioural_helpers_c.o sim_console_c.o
|
||||
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o -Wl,sim_console_c.o $@
|
||||
|
||||
fetch_tb: fetch_tb.o
|
||||
$(GHDL) -e $(GHDLFLAGS) $@
|
||||
|
||||
loadstore_tb: loadstore_tb.o
|
||||
$(GHDL) -e $(GHDLFLAGS) $@
|
||||
|
||||
simple_ram_tb: simple_ram_tb.o
|
||||
$(GHDL) -e $(GHDLFLAGS) $@
|
||||
|
||||
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 $@
|
||||
|
||||
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:
|
||||
$(VUNITRUN) $(VUNITARGS)
|
||||
check: $(tests) test_micropython test_micropython_long
|
||||
|
||||
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 tests_console 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
|
||||
|
||||
$(tests): core_tb
|
||||
@./scripts/run_test.sh $@
|
||||
|
||||
$(tests_console): core_tb
|
||||
@./scripts/run_test_console.sh $@
|
||||
|
||||
test_micropython: core_tb
|
||||
@./scripts/test_micropython.py
|
||||
|
||||
test_micropython_verilator: microwatt-verilator
|
||||
@./scripts/test_micropython_verilator.py
|
||||
|
||||
test_micropython_long: core_tb
|
||||
@./scripts/test_micropython_long.py
|
||||
|
||||
test_micropython_verilator_long: microwatt-verilator
|
||||
@./scripts/test_micropython_verilator_long.py
|
||||
|
||||
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
|
||||
clean:
|
||||
rm -f *.o work-*cf $(all)
|
||||
|
@ -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,792 +1,196 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.utils.all;
|
||||
use work.decode_types.all;
|
||||
|
||||
package common is
|
||||
-- Processor Version Number
|
||||
constant PVR_MICROWATT : std_ulogic_vector(31 downto 0) := x"00630000";
|
||||
|
||||
-- MSR bit numbers
|
||||
constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode
|
||||
constant MSR_EE : integer := (63 - 48); -- External interrupt Enable
|
||||
constant MSR_PR : integer := (63 - 49); -- PRoblem state
|
||||
constant MSR_FP : integer := (63 - 50); -- Floating Point available
|
||||
constant MSR_FE0 : integer := (63 - 52); -- Floating Exception mode
|
||||
constant MSR_SE : integer := (63 - 53); -- Single-step bit of TE field
|
||||
constant MSR_BE : integer := (63 - 54); -- Branch trace bit of TE field
|
||||
constant MSR_FE1 : integer := (63 - 55); -- Floating Exception mode
|
||||
constant MSR_IR : integer := (63 - 58); -- Instruction Relocation
|
||||
constant MSR_DR : integer := (63 - 59); -- Data Relocation
|
||||
constant MSR_PMM : integer := (63 - 61); -- Performance Monitor Mark
|
||||
constant MSR_RI : integer := (63 - 62); -- Recoverable Interrupt
|
||||
constant MSR_LE : integer := (63 - 63); -- Little Endian
|
||||
|
||||
-- SPR numbers
|
||||
subtype spr_num_t is integer range 0 to 1023;
|
||||
|
||||
function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t;
|
||||
|
||||
constant SPR_XER : spr_num_t := 1;
|
||||
constant SPR_LR : spr_num_t := 8;
|
||||
constant SPR_CTR : spr_num_t := 9;
|
||||
constant SPR_TAR : spr_num_t := 815;
|
||||
constant SPR_DSISR : spr_num_t := 18;
|
||||
constant SPR_DAR : spr_num_t := 19;
|
||||
constant SPR_TB : spr_num_t := 268;
|
||||
constant SPR_TBU : spr_num_t := 269;
|
||||
constant SPR_DEC : spr_num_t := 22;
|
||||
constant SPR_SRR0 : spr_num_t := 26;
|
||||
constant SPR_SRR1 : spr_num_t := 27;
|
||||
constant SPR_CFAR : spr_num_t := 28;
|
||||
constant SPR_HSRR0 : spr_num_t := 314;
|
||||
constant SPR_HSRR1 : spr_num_t := 315;
|
||||
constant SPR_SPRG0 : spr_num_t := 272;
|
||||
constant SPR_SPRG1 : spr_num_t := 273;
|
||||
constant SPR_SPRG2 : spr_num_t := 274;
|
||||
constant SPR_SPRG3 : spr_num_t := 275;
|
||||
constant SPR_SPRG3U : spr_num_t := 259;
|
||||
constant SPR_HSPRG0 : spr_num_t := 304;
|
||||
constant SPR_HSPRG1 : spr_num_t := 305;
|
||||
constant SPR_PID : spr_num_t := 48;
|
||||
constant SPR_PTCR : spr_num_t := 464;
|
||||
constant SPR_PVR : spr_num_t := 287;
|
||||
|
||||
-- PMU registers
|
||||
constant SPR_UPMC1 : spr_num_t := 771;
|
||||
constant SPR_UPMC2 : spr_num_t := 772;
|
||||
constant SPR_UPMC3 : spr_num_t := 773;
|
||||
constant SPR_UPMC4 : spr_num_t := 774;
|
||||
constant SPR_UPMC5 : spr_num_t := 775;
|
||||
constant SPR_UPMC6 : spr_num_t := 776;
|
||||
constant SPR_UMMCR0 : spr_num_t := 779;
|
||||
constant SPR_UMMCR1 : spr_num_t := 782;
|
||||
constant SPR_UMMCR2 : spr_num_t := 769;
|
||||
constant SPR_UMMCRA : spr_num_t := 770;
|
||||
constant SPR_USIER : spr_num_t := 768;
|
||||
constant SPR_USIAR : spr_num_t := 780;
|
||||
constant SPR_USDAR : spr_num_t := 781;
|
||||
constant SPR_PMC1 : spr_num_t := 787;
|
||||
constant SPR_PMC2 : spr_num_t := 788;
|
||||
constant SPR_PMC3 : spr_num_t := 789;
|
||||
constant SPR_PMC4 : spr_num_t := 790;
|
||||
constant SPR_PMC5 : spr_num_t := 791;
|
||||
constant SPR_PMC6 : spr_num_t := 792;
|
||||
constant SPR_MMCR0 : spr_num_t := 795;
|
||||
constant SPR_MMCR1 : spr_num_t := 798;
|
||||
constant SPR_MMCR2 : spr_num_t := 785;
|
||||
constant SPR_MMCRA : spr_num_t := 786;
|
||||
constant SPR_SIER : spr_num_t := 784;
|
||||
constant SPR_SIAR : spr_num_t := 796;
|
||||
constant SPR_SDAR : spr_num_t := 797;
|
||||
|
||||
-- GPR indices in the register file (GPR only)
|
||||
subtype gpr_index_t is std_ulogic_vector(4 downto 0);
|
||||
|
||||
-- Extended GPR index (can hold an SPR or a FPR)
|
||||
subtype gspr_index_t is std_ulogic_vector(6 downto 0);
|
||||
|
||||
-- FPR indices
|
||||
subtype fpr_index_t is std_ulogic_vector(4 downto 0);
|
||||
|
||||
-- Some SPRs are stored in the register file, they use the magic
|
||||
-- GPR numbers above 31.
|
||||
--
|
||||
-- The function fast_spr_num() returns the corresponding fast
|
||||
-- pseudo-GPR number for a given SPR number. The result MSB
|
||||
-- indicates if this is indeed a fast SPR. If clear, then
|
||||
-- the SPR is not stored in the GPR file.
|
||||
--
|
||||
-- FPRs are also stored in the register file, using GSPR
|
||||
-- numbers from 64 to 95.
|
||||
--
|
||||
function fast_spr_num(spr: spr_num_t) return gspr_index_t;
|
||||
|
||||
-- Indices conversion functions
|
||||
function gspr_to_gpr(i: gspr_index_t) return gpr_index_t;
|
||||
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t;
|
||||
function gpr_or_spr_to_gspr(g: gpr_index_t; s: gspr_index_t) return gspr_index_t;
|
||||
function is_fast_spr(s: gspr_index_t) return std_ulogic;
|
||||
function fpr_to_gspr(f: fpr_index_t) return gspr_index_t;
|
||||
|
||||
-- The XER is split: the common bits (CA, OV, SO, OV32 and CA32) are
|
||||
-- in the CR file as a kind of CR extension (with a separate write
|
||||
-- control). The rest is stored as a fast SPR.
|
||||
type xer_common_t is record
|
||||
ca : std_ulogic;
|
||||
ca32 : std_ulogic;
|
||||
ov : std_ulogic;
|
||||
ov32 : std_ulogic;
|
||||
so : std_ulogic;
|
||||
end record;
|
||||
constant xerc_init : xer_common_t := (others => '0');
|
||||
|
||||
-- FPSCR bit numbers
|
||||
constant FPSCR_FX : integer := 63 - 32;
|
||||
constant FPSCR_FEX : integer := 63 - 33;
|
||||
constant FPSCR_VX : integer := 63 - 34;
|
||||
constant FPSCR_OX : integer := 63 - 35;
|
||||
constant FPSCR_UX : integer := 63 - 36;
|
||||
constant FPSCR_ZX : integer := 63 - 37;
|
||||
constant FPSCR_XX : integer := 63 - 38;
|
||||
constant FPSCR_VXSNAN : integer := 63 - 39;
|
||||
constant FPSCR_VXISI : integer := 63 - 40;
|
||||
constant FPSCR_VXIDI : integer := 63 - 41;
|
||||
constant FPSCR_VXZDZ : integer := 63 - 42;
|
||||
constant FPSCR_VXIMZ : integer := 63 - 43;
|
||||
constant FPSCR_VXVC : integer := 63 - 44;
|
||||
constant FPSCR_FR : integer := 63 - 45;
|
||||
constant FPSCR_FI : integer := 63 - 46;
|
||||
constant FPSCR_C : integer := 63 - 47;
|
||||
constant FPSCR_FL : integer := 63 - 48;
|
||||
constant FPSCR_FG : integer := 63 - 49;
|
||||
constant FPSCR_FE : integer := 63 - 50;
|
||||
constant FPSCR_FU : integer := 63 - 51;
|
||||
constant FPSCR_VXSOFT : integer := 63 - 53;
|
||||
constant FPSCR_VXSQRT : integer := 63 - 54;
|
||||
constant FPSCR_VXCVI : integer := 63 - 55;
|
||||
constant FPSCR_VE : integer := 63 - 56;
|
||||
constant FPSCR_OE : integer := 63 - 57;
|
||||
constant FPSCR_UE : integer := 63 - 58;
|
||||
constant FPSCR_ZE : integer := 63 - 59;
|
||||
constant FPSCR_XE : integer := 63 - 60;
|
||||
constant FPSCR_NI : integer := 63 - 61;
|
||||
constant FPSCR_RN : integer := 63 - 63;
|
||||
|
||||
-- Real addresses
|
||||
-- REAL_ADDR_BITS is the number of real address bits that we store
|
||||
constant REAL_ADDR_BITS : positive := 56;
|
||||
subtype real_addr_t is std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0);
|
||||
function addr_to_real(addr: std_ulogic_vector(63 downto 0)) return real_addr_t;
|
||||
|
||||
-- Used for tracking instruction completion and pending register writes
|
||||
constant TAG_COUNT : positive := 4;
|
||||
constant TAG_NUMBER_BITS : natural := log2(TAG_COUNT);
|
||||
subtype tag_number_t is integer range 0 to TAG_COUNT - 1;
|
||||
subtype tag_index_t is unsigned(TAG_NUMBER_BITS - 1 downto 0);
|
||||
type instr_tag_t is record
|
||||
tag : tag_number_t;
|
||||
valid : std_ulogic;
|
||||
end record;
|
||||
constant instr_tag_init : instr_tag_t := (tag => 0, valid => '0');
|
||||
function tag_match(tag1 : instr_tag_t; tag2 : instr_tag_t) return boolean;
|
||||
|
||||
subtype intr_vector_t is integer range 0 to 16#fff#;
|
||||
|
||||
-- For now, fixed 16 sources, make this either a parametric
|
||||
-- package of some sort or an unconstrainted array.
|
||||
type ics_to_icp_t is record
|
||||
-- Level interrupts only, ICS just keeps prsenting the
|
||||
-- highest priority interrupt. Once handling edge, something
|
||||
-- smarter involving handshake & reject support will be needed
|
||||
src : std_ulogic_vector(3 downto 0);
|
||||
pri : std_ulogic_vector(7 downto 0);
|
||||
end record;
|
||||
|
||||
-- This needs to die...
|
||||
type ctrl_t is record
|
||||
tb: std_ulogic_vector(63 downto 0);
|
||||
dec: std_ulogic_vector(63 downto 0);
|
||||
msr: std_ulogic_vector(63 downto 0);
|
||||
cfar: std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type Fetch1ToIcacheType is record
|
||||
req: std_ulogic;
|
||||
virt_mode : std_ulogic;
|
||||
priv_mode : std_ulogic;
|
||||
big_endian : std_ulogic;
|
||||
stop_mark: std_ulogic;
|
||||
predicted : std_ulogic;
|
||||
pred_ntaken : std_ulogic;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type IcacheToDecode1Type is record
|
||||
valid: std_ulogic;
|
||||
stop_mark: std_ulogic;
|
||||
fetch_failed: std_ulogic;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
insn: std_ulogic_vector(31 downto 0);
|
||||
big_endian: std_ulogic;
|
||||
next_predicted: std_ulogic;
|
||||
next_pred_ntaken: std_ulogic;
|
||||
end record;
|
||||
|
||||
type IcacheEventType is record
|
||||
icache_miss : std_ulogic;
|
||||
itlb_miss_resolved : std_ulogic;
|
||||
end record;
|
||||
|
||||
type Decode1ToDecode2Type is record
|
||||
valid: std_ulogic;
|
||||
stop_mark : std_ulogic;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
insn: std_ulogic_vector(31 downto 0);
|
||||
ispr1: gspr_index_t; -- (G)SPR used for branch condition (CTR) or mfspr
|
||||
ispr2: gspr_index_t; -- (G)SPR used for branch target (CTR, LR, TAR)
|
||||
ispro: gspr_index_t; -- (G)SPR written with LR or CTR
|
||||
decode: decode_rom_t;
|
||||
br_pred: std_ulogic; -- Branch was predicted to be taken
|
||||
big_endian: std_ulogic;
|
||||
end record;
|
||||
constant Decode1ToDecode2Init : Decode1ToDecode2Type :=
|
||||
(valid => '0', stop_mark => '0', nia => (others => '0'), insn => (others => '0'),
|
||||
ispr1 => (others => '0'), ispr2 => (others => '0'), ispro => (others => '0'),
|
||||
decode => decode_rom_init, br_pred => '0', big_endian => '0');
|
||||
|
||||
type Decode1ToFetch1Type is record
|
||||
redirect : std_ulogic;
|
||||
redirect_nia : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type bypass_data_t is record
|
||||
tag : instr_tag_t;
|
||||
data : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
constant bypass_data_init : bypass_data_t := (tag => instr_tag_init, data => (others => '0'));
|
||||
|
||||
type cr_bypass_data_t is record
|
||||
tag : instr_tag_t;
|
||||
data : std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
constant cr_bypass_data_init : cr_bypass_data_t := (tag => instr_tag_init, data => (others => '0'));
|
||||
|
||||
type Decode2ToExecute1Type is record
|
||||
valid: std_ulogic;
|
||||
unit : unit_t;
|
||||
fac : facility_t;
|
||||
insn_type: insn_type_t;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
instr_tag : instr_tag_t;
|
||||
write_reg: gspr_index_t;
|
||||
write_reg_enable: std_ulogic;
|
||||
read_reg1: gspr_index_t;
|
||||
read_reg2: gspr_index_t;
|
||||
read_data1: std_ulogic_vector(63 downto 0);
|
||||
read_data2: std_ulogic_vector(63 downto 0);
|
||||
read_data3: std_ulogic_vector(63 downto 0);
|
||||
cr: std_ulogic_vector(31 downto 0);
|
||||
xerc: xer_common_t;
|
||||
lr: std_ulogic;
|
||||
br_abs: std_ulogic;
|
||||
rc: std_ulogic;
|
||||
oe: std_ulogic;
|
||||
invert_a: std_ulogic;
|
||||
addm1 : std_ulogic;
|
||||
invert_out: std_ulogic;
|
||||
input_carry: carry_in_t;
|
||||
output_carry: std_ulogic;
|
||||
input_cr: std_ulogic;
|
||||
output_cr: std_ulogic;
|
||||
output_xer: std_ulogic;
|
||||
is_32bit: std_ulogic;
|
||||
is_signed: std_ulogic;
|
||||
insn: std_ulogic_vector(31 downto 0);
|
||||
data_len: std_ulogic_vector(3 downto 0);
|
||||
byte_reverse : std_ulogic;
|
||||
sign_extend : std_ulogic; -- do we need to sign extend?
|
||||
update : std_ulogic; -- is this an update instruction?
|
||||
reserve : std_ulogic; -- set for larx/stcx
|
||||
br_pred : std_ulogic;
|
||||
result_sel : std_ulogic_vector(2 downto 0); -- select source of result
|
||||
sub_select : std_ulogic_vector(2 downto 0); -- sub-result selection
|
||||
repeat : std_ulogic; -- set if instruction is cracked into two ops
|
||||
second : std_ulogic; -- set if this is the second op
|
||||
end record;
|
||||
constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
|
||||
(valid => '0', unit => NONE, fac => NONE, insn_type => OP_ILLEGAL, instr_tag => instr_tag_init,
|
||||
write_reg_enable => '0',
|
||||
lr => '0', br_abs => '0', rc => '0', oe => '0', invert_a => '0', addm1 => '0',
|
||||
invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0',
|
||||
output_cr => '0', output_xer => '0',
|
||||
is_32bit => '0', is_signed => '0', xerc => xerc_init, reserve => '0', br_pred => '0',
|
||||
byte_reverse => '0', sign_extend => '0', update => '0', nia => (others => '0'),
|
||||
read_data1 => (others => '0'), read_data2 => (others => '0'), read_data3 => (others => '0'),
|
||||
cr => (others => '0'), insn => (others => '0'), data_len => (others => '0'),
|
||||
result_sel => "000", sub_select => "000",
|
||||
repeat => '0', second => '0', others => (others => '0'));
|
||||
|
||||
type MultiplyInputType is record
|
||||
valid: std_ulogic;
|
||||
data1: std_ulogic_vector(63 downto 0);
|
||||
data2: std_ulogic_vector(63 downto 0);
|
||||
addend: std_ulogic_vector(127 downto 0);
|
||||
is_32bit: std_ulogic;
|
||||
not_result: std_ulogic;
|
||||
end record;
|
||||
constant MultiplyInputInit : MultiplyInputType := (valid => '0',
|
||||
is_32bit => '0', not_result => '0',
|
||||
others => (others => '0'));
|
||||
|
||||
type MultiplyOutputType is record
|
||||
valid: std_ulogic;
|
||||
result: std_ulogic_vector(127 downto 0);
|
||||
overflow : std_ulogic;
|
||||
end record;
|
||||
constant MultiplyOutputInit : MultiplyOutputType := (valid => '0', overflow => '0',
|
||||
others => (others => '0'));
|
||||
|
||||
type Execute1ToDividerType is record
|
||||
valid: std_ulogic;
|
||||
dividend: std_ulogic_vector(63 downto 0);
|
||||
divisor: std_ulogic_vector(63 downto 0);
|
||||
is_signed: std_ulogic;
|
||||
is_32bit: std_ulogic;
|
||||
is_extended: std_ulogic;
|
||||
is_modulus: std_ulogic;
|
||||
neg_result: std_ulogic;
|
||||
end record;
|
||||
constant Execute1ToDividerInit: Execute1ToDividerType := (valid => '0', is_signed => '0', is_32bit => '0',
|
||||
is_extended => '0', is_modulus => '0',
|
||||
neg_result => '0', others => (others => '0'));
|
||||
|
||||
type PMUEventType is record
|
||||
no_instr_avail : std_ulogic;
|
||||
dispatch : std_ulogic;
|
||||
ext_interrupt : std_ulogic;
|
||||
instr_complete : std_ulogic;
|
||||
fp_complete : std_ulogic;
|
||||
ld_complete : std_ulogic;
|
||||
st_complete : std_ulogic;
|
||||
br_taken_complete : std_ulogic;
|
||||
br_mispredict : std_ulogic;
|
||||
ipref_discard : std_ulogic;
|
||||
itlb_miss : std_ulogic;
|
||||
itlb_miss_resolved : std_ulogic;
|
||||
icache_miss : std_ulogic;
|
||||
dc_miss_resolved : std_ulogic;
|
||||
dc_load_miss : std_ulogic;
|
||||
dc_ld_miss_resolved : std_ulogic;
|
||||
dc_store_miss : std_ulogic;
|
||||
dtlb_miss : std_ulogic;
|
||||
dtlb_miss_resolved : std_ulogic;
|
||||
ld_miss_nocache : std_ulogic;
|
||||
ld_fill_nocache : std_ulogic;
|
||||
end record;
|
||||
constant PMUEventInit : PMUEventType := (others => '0');
|
||||
|
||||
type Execute1ToPMUType is record
|
||||
mfspr : std_ulogic;
|
||||
mtspr : std_ulogic;
|
||||
spr_num : std_ulogic_vector(4 downto 0);
|
||||
spr_val : std_ulogic_vector(63 downto 0);
|
||||
tbbits : std_ulogic_vector(3 downto 0); -- event bits from timebase
|
||||
pmm_msr : std_ulogic; -- PMM bit from MSR
|
||||
pr_msr : std_ulogic; -- PR bit from MSR
|
||||
run : std_ulogic;
|
||||
nia : std_ulogic_vector(63 downto 0);
|
||||
addr : std_ulogic_vector(63 downto 0);
|
||||
addr_v : std_ulogic;
|
||||
occur : PMUEventType;
|
||||
end record;
|
||||
|
||||
type PMUToExecute1Type is record
|
||||
spr_val : std_ulogic_vector(63 downto 0);
|
||||
intr : std_ulogic;
|
||||
end record;
|
||||
|
||||
type Decode2ToRegisterFileType is record
|
||||
read1_enable : std_ulogic;
|
||||
read1_reg : gspr_index_t;
|
||||
read2_enable : std_ulogic;
|
||||
read2_reg : gspr_index_t;
|
||||
read3_enable : std_ulogic;
|
||||
read3_reg : gspr_index_t;
|
||||
end record;
|
||||
|
||||
type RegisterFileToDecode2Type is record
|
||||
read1_data : std_ulogic_vector(63 downto 0);
|
||||
read2_data : std_ulogic_vector(63 downto 0);
|
||||
read3_data : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type Decode2ToCrFileType is record
|
||||
read : std_ulogic;
|
||||
end record;
|
||||
|
||||
type CrFileToDecode2Type is record
|
||||
read_cr_data : std_ulogic_vector(31 downto 0);
|
||||
read_xerc_data : xer_common_t;
|
||||
end record;
|
||||
|
||||
type Execute1ToLoadstore1Type is record
|
||||
valid : std_ulogic;
|
||||
op : insn_type_t; -- what ld/st or m[tf]spr or TLB op to do
|
||||
nia : std_ulogic_vector(63 downto 0);
|
||||
insn : std_ulogic_vector(31 downto 0);
|
||||
instr_tag : instr_tag_t;
|
||||
addr1 : std_ulogic_vector(63 downto 0);
|
||||
addr2 : std_ulogic_vector(63 downto 0);
|
||||
data : std_ulogic_vector(63 downto 0); -- data to write, unused for read
|
||||
write_reg : gspr_index_t;
|
||||
length : std_ulogic_vector(3 downto 0);
|
||||
ci : std_ulogic; -- cache-inhibited load/store
|
||||
byte_reverse : std_ulogic;
|
||||
sign_extend : std_ulogic; -- do we need to sign extend?
|
||||
update : std_ulogic; -- is this an update instruction?
|
||||
xerc : xer_common_t;
|
||||
reserve : std_ulogic; -- set for larx/stcx.
|
||||
rc : std_ulogic; -- set for stcx.
|
||||
virt_mode : std_ulogic; -- do translation through TLB
|
||||
priv_mode : std_ulogic; -- privileged mode (MSR[PR] = 0)
|
||||
mode_32bit : std_ulogic; -- trim addresses to 32 bits
|
||||
is_32bit : std_ulogic;
|
||||
repeat : std_ulogic;
|
||||
second : std_ulogic;
|
||||
msr : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type :=
|
||||
(valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
|
||||
sign_extend => '0', update => '0', xerc => xerc_init,
|
||||
reserve => '0', rc => '0', virt_mode => '0', priv_mode => '0',
|
||||
nia => (others => '0'), insn => (others => '0'),
|
||||
instr_tag => instr_tag_init,
|
||||
addr1 => (others => '0'), addr2 => (others => '0'), data => (others => '0'),
|
||||
write_reg => (others => '0'),
|
||||
length => (others => '0'),
|
||||
mode_32bit => '0', is_32bit => '0',
|
||||
repeat => '0', second => '0',
|
||||
msr => (others => '0'));
|
||||
|
||||
type Loadstore1ToExecute1Type is record
|
||||
busy : std_ulogic;
|
||||
in_progress : std_ulogic;
|
||||
interrupt : std_ulogic;
|
||||
end record;
|
||||
|
||||
type Loadstore1ToDcacheType is record
|
||||
valid : std_ulogic;
|
||||
hold : std_ulogic;
|
||||
load : std_ulogic; -- is this a load
|
||||
dcbz : std_ulogic;
|
||||
nc : std_ulogic;
|
||||
reserve : std_ulogic;
|
||||
atomic : std_ulogic; -- part of a multi-transfer atomic op
|
||||
atomic_last : std_ulogic;
|
||||
virt_mode : std_ulogic;
|
||||
priv_mode : std_ulogic;
|
||||
addr : std_ulogic_vector(63 downto 0);
|
||||
data : std_ulogic_vector(63 downto 0); -- valid the cycle after .valid = 1
|
||||
byte_sel : std_ulogic_vector(7 downto 0);
|
||||
end record;
|
||||
|
||||
type DcacheToLoadstore1Type is record
|
||||
valid : std_ulogic;
|
||||
data : std_ulogic_vector(63 downto 0);
|
||||
store_done : std_ulogic;
|
||||
error : std_ulogic;
|
||||
cache_paradox : std_ulogic;
|
||||
end record;
|
||||
|
||||
type DcacheEventType is record
|
||||
load_miss : std_ulogic;
|
||||
store_miss : std_ulogic;
|
||||
dcache_refill : std_ulogic;
|
||||
dtlb_miss : std_ulogic;
|
||||
dtlb_miss_resolved : std_ulogic;
|
||||
end record;
|
||||
|
||||
type Loadstore1ToMmuType is record
|
||||
valid : std_ulogic;
|
||||
tlbie : std_ulogic;
|
||||
slbia : std_ulogic;
|
||||
mtspr : std_ulogic;
|
||||
iside : std_ulogic;
|
||||
load : std_ulogic;
|
||||
priv : std_ulogic;
|
||||
sprn : std_ulogic_vector(9 downto 0);
|
||||
addr : std_ulogic_vector(63 downto 0);
|
||||
rs : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type MmuToLoadstore1Type is record
|
||||
done : std_ulogic;
|
||||
err : std_ulogic;
|
||||
invalid : std_ulogic;
|
||||
badtree : std_ulogic;
|
||||
segerr : std_ulogic;
|
||||
perm_error : std_ulogic;
|
||||
rc_error : std_ulogic;
|
||||
sprval : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type MmuToDcacheType is record
|
||||
valid : std_ulogic;
|
||||
tlbie : std_ulogic;
|
||||
doall : std_ulogic;
|
||||
tlbld : std_ulogic;
|
||||
addr : std_ulogic_vector(63 downto 0);
|
||||
pte : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type DcacheToMmuType is record
|
||||
stall : std_ulogic;
|
||||
done : std_ulogic;
|
||||
err : std_ulogic;
|
||||
data : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type MmuToIcacheType is record
|
||||
tlbld : std_ulogic;
|
||||
tlbie : std_ulogic;
|
||||
doall : std_ulogic;
|
||||
addr : std_ulogic_vector(63 downto 0);
|
||||
pte : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type Loadstore1ToWritebackType is record
|
||||
valid : std_ulogic;
|
||||
instr_tag : instr_tag_t;
|
||||
write_enable: std_ulogic;
|
||||
write_reg : gspr_index_t;
|
||||
write_data : std_ulogic_vector(63 downto 0);
|
||||
xerc : xer_common_t;
|
||||
rc : std_ulogic;
|
||||
store_done : std_ulogic;
|
||||
interrupt : std_ulogic;
|
||||
intr_vec : intr_vector_t;
|
||||
srr0: std_ulogic_vector(63 downto 0);
|
||||
srr1: std_ulogic_vector(15 downto 0);
|
||||
end record;
|
||||
constant Loadstore1ToWritebackInit : Loadstore1ToWritebackType :=
|
||||
(valid => '0', instr_tag => instr_tag_init, write_enable => '0',
|
||||
write_reg => (others => '0'), write_data => (others => '0'),
|
||||
xerc => xerc_init, rc => '0', store_done => '0',
|
||||
interrupt => '0', intr_vec => 0,
|
||||
srr0 => (others => '0'), srr1 => (others => '0'));
|
||||
|
||||
type Loadstore1EventType is record
|
||||
load_complete : std_ulogic;
|
||||
store_complete : std_ulogic;
|
||||
itlb_miss : std_ulogic;
|
||||
end record;
|
||||
|
||||
type Execute1ToWritebackType is record
|
||||
valid: std_ulogic;
|
||||
instr_tag : instr_tag_t;
|
||||
rc : std_ulogic;
|
||||
mode_32bit : std_ulogic;
|
||||
write_enable : std_ulogic;
|
||||
write_reg: gspr_index_t;
|
||||
write_data: std_ulogic_vector(63 downto 0);
|
||||
write_cr_enable : std_ulogic;
|
||||
write_cr_mask : std_ulogic_vector(7 downto 0);
|
||||
write_cr_data : std_ulogic_vector(31 downto 0);
|
||||
write_xerc_enable : std_ulogic;
|
||||
xerc : xer_common_t;
|
||||
interrupt : std_ulogic;
|
||||
intr_vec : intr_vector_t;
|
||||
redirect: std_ulogic;
|
||||
redir_mode: std_ulogic_vector(3 downto 0);
|
||||
last_nia: std_ulogic_vector(63 downto 0);
|
||||
br_offset: std_ulogic_vector(63 downto 0);
|
||||
br_last: std_ulogic;
|
||||
br_taken: std_ulogic;
|
||||
abs_br: std_ulogic;
|
||||
srr1: std_ulogic_vector(15 downto 0);
|
||||
msr: std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
constant Execute1ToWritebackInit : Execute1ToWritebackType :=
|
||||
(valid => '0', instr_tag => instr_tag_init, rc => '0', mode_32bit => '0',
|
||||
write_enable => '0', write_cr_enable => '0',
|
||||
write_xerc_enable => '0', xerc => xerc_init,
|
||||
write_data => (others => '0'), write_cr_mask => (others => '0'),
|
||||
write_cr_data => (others => '0'), write_reg => (others => '0'),
|
||||
interrupt => '0', intr_vec => 0, redirect => '0', redir_mode => "0000",
|
||||
last_nia => (others => '0'), br_offset => (others => '0'),
|
||||
br_last => '0', br_taken => '0', abs_br => '0',
|
||||
srr1 => (others => '0'), msr => (others => '0'));
|
||||
|
||||
type Execute1ToFPUType is record
|
||||
valid : std_ulogic;
|
||||
op : insn_type_t;
|
||||
nia : std_ulogic_vector(63 downto 0);
|
||||
itag : instr_tag_t;
|
||||
insn : std_ulogic_vector(31 downto 0);
|
||||
single : std_ulogic;
|
||||
fe_mode : std_ulogic_vector(1 downto 0);
|
||||
fra : std_ulogic_vector(63 downto 0);
|
||||
frb : std_ulogic_vector(63 downto 0);
|
||||
frc : std_ulogic_vector(63 downto 0);
|
||||
frt : gspr_index_t;
|
||||
rc : std_ulogic;
|
||||
out_cr : std_ulogic;
|
||||
end record;
|
||||
constant Execute1ToFPUInit : Execute1ToFPUType := (valid => '0', op => OP_ILLEGAL, nia => (others => '0'),
|
||||
itag => instr_tag_init,
|
||||
insn => (others => '0'), fe_mode => "00", rc => '0',
|
||||
fra => (others => '0'), frb => (others => '0'),
|
||||
frc => (others => '0'), frt => (others => '0'),
|
||||
single => '0', out_cr => '0');
|
||||
|
||||
type FPUToExecute1Type is record
|
||||
busy : std_ulogic;
|
||||
exception : std_ulogic;
|
||||
end record;
|
||||
constant FPUToExecute1Init : FPUToExecute1Type := (others => '0');
|
||||
|
||||
type FPUToWritebackType is record
|
||||
valid : std_ulogic;
|
||||
interrupt : std_ulogic;
|
||||
instr_tag : instr_tag_t;
|
||||
write_enable : std_ulogic;
|
||||
write_reg : gspr_index_t;
|
||||
write_data : std_ulogic_vector(63 downto 0);
|
||||
write_cr_enable : std_ulogic;
|
||||
write_cr_mask : std_ulogic_vector(7 downto 0);
|
||||
write_cr_data : std_ulogic_vector(31 downto 0);
|
||||
intr_vec : intr_vector_t;
|
||||
srr0 : std_ulogic_vector(63 downto 0);
|
||||
srr1 : std_ulogic_vector(15 downto 0);
|
||||
end record;
|
||||
constant FPUToWritebackInit : FPUToWritebackType :=
|
||||
(valid => '0', interrupt => '0', instr_tag => instr_tag_init,
|
||||
write_enable => '0', write_reg => (others => '0'),
|
||||
write_cr_enable => '0', write_cr_mask => (others => '0'),
|
||||
write_cr_data => (others => '0'),
|
||||
intr_vec => 0, srr1 => (others => '0'),
|
||||
others => (others => '0'));
|
||||
|
||||
type DividerToExecute1Type is record
|
||||
valid: std_ulogic;
|
||||
write_reg_data: std_ulogic_vector(63 downto 0);
|
||||
overflow : std_ulogic;
|
||||
end record;
|
||||
constant DividerToExecute1Init : DividerToExecute1Type := (valid => '0', overflow => '0',
|
||||
others => (others => '0'));
|
||||
|
||||
type WritebackToFetch1Type is record
|
||||
redirect: std_ulogic;
|
||||
virt_mode: std_ulogic;
|
||||
priv_mode: std_ulogic;
|
||||
big_endian: std_ulogic;
|
||||
mode_32bit: std_ulogic;
|
||||
redirect_nia: std_ulogic_vector(63 downto 0);
|
||||
br_nia : std_ulogic_vector(63 downto 0);
|
||||
br_last : std_ulogic;
|
||||
br_taken : std_ulogic;
|
||||
end record;
|
||||
constant WritebackToFetch1Init : WritebackToFetch1Type :=
|
||||
(redirect => '0', virt_mode => '0', priv_mode => '0', big_endian => '0',
|
||||
mode_32bit => '0', redirect_nia => (others => '0'),
|
||||
br_last => '0', br_taken => '0', br_nia => (others => '0'));
|
||||
|
||||
type WritebackToRegisterFileType is record
|
||||
write_reg : gspr_index_t;
|
||||
write_data : std_ulogic_vector(63 downto 0);
|
||||
write_enable : std_ulogic;
|
||||
end record;
|
||||
constant WritebackToRegisterFileInit : WritebackToRegisterFileType :=
|
||||
(write_enable => '0', write_data => (others => '0'), others => (others => '0'));
|
||||
|
||||
type WritebackToCrFileType is record
|
||||
write_cr_enable : std_ulogic;
|
||||
write_cr_mask : std_ulogic_vector(7 downto 0);
|
||||
write_cr_data : std_ulogic_vector(31 downto 0);
|
||||
write_xerc_enable : std_ulogic;
|
||||
write_xerc_data : xer_common_t;
|
||||
end record;
|
||||
constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', write_xerc_enable => '0',
|
||||
write_xerc_data => xerc_init,
|
||||
write_cr_mask => (others => '0'),
|
||||
write_cr_data => (others => '0'));
|
||||
|
||||
type WritebackEventType is record
|
||||
instr_complete : std_ulogic;
|
||||
fp_complete : std_ulogic;
|
||||
end record;
|
||||
|
||||
type ctrl_t is record
|
||||
lr: std_ulogic_vector(63 downto 0);
|
||||
ctr: std_ulogic_vector(63 downto 0);
|
||||
tb: std_ulogic_vector(63 downto 0);
|
||||
carry: std_ulogic;
|
||||
end record;
|
||||
|
||||
type Fetch1ToFetch2Type is record
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type Fetch2ToDecode1Type is record
|
||||
valid: std_ulogic;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
insn: std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
constant Fetch2ToDecode1Init : Fetch2ToDecode1Type := (valid => '0', others => (others => '0'));
|
||||
|
||||
type Decode1ToDecode2Type is record
|
||||
valid: std_ulogic;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
insn: std_ulogic_vector(31 downto 0);
|
||||
decode: decode_rom_t;
|
||||
end record;
|
||||
constant Decode1ToDecode2Init : Decode1ToDecode2Type := (valid => '0', decode => decode_rom_init, others => (others => '0'));
|
||||
|
||||
type Fetch2ToIcacheType is record
|
||||
req: std_ulogic;
|
||||
addr: std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type IcacheToFetch2Type is record
|
||||
ack: std_ulogic;
|
||||
insn: std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
|
||||
type Decode2ToExecute1Type is record
|
||||
valid: std_ulogic;
|
||||
insn_type: insn_type_t;
|
||||
nia: std_ulogic_vector(63 downto 0);
|
||||
write_reg: std_ulogic_vector(4 downto 0);
|
||||
read_reg1: std_ulogic_vector(4 downto 0);
|
||||
read_reg2: std_ulogic_vector(4 downto 0);
|
||||
read_data1: std_ulogic_vector(63 downto 0);
|
||||
read_data2: std_ulogic_vector(63 downto 0);
|
||||
const1: std_ulogic_vector(7 downto 0);
|
||||
const2: std_ulogic_vector(5 downto 0);
|
||||
const3: std_ulogic_vector(4 downto 0);
|
||||
cr: std_ulogic_vector(31 downto 0);
|
||||
lr: std_ulogic;
|
||||
rc: std_ulogic;
|
||||
input_carry: std_ulogic;
|
||||
output_carry: std_ulogic;
|
||||
input_cr: std_ulogic;
|
||||
output_cr: std_ulogic;
|
||||
end record;
|
||||
constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0'));
|
||||
|
||||
type Decode2ToMultiplyType is record
|
||||
valid: std_ulogic;
|
||||
insn_type: insn_type_t;
|
||||
write_reg: std_ulogic_vector(4 downto 0);
|
||||
data1: std_ulogic_vector(64 downto 0);
|
||||
data2: std_ulogic_vector(64 downto 0);
|
||||
rc: std_ulogic;
|
||||
end record;
|
||||
constant Decode2ToMultiplyInit : Decode2ToMultiplyType := (valid => '0', insn_type => OP_ILLEGAL, rc => '0', others => (others => '0'));
|
||||
|
||||
type Decode2ToRegisterFileType is record
|
||||
read1_enable : std_ulogic;
|
||||
read1_reg : std_ulogic_vector(4 downto 0);
|
||||
read2_enable : std_ulogic;
|
||||
read2_reg : std_ulogic_vector(4 downto 0);
|
||||
read3_enable : std_ulogic;
|
||||
read3_reg : std_ulogic_vector(4 downto 0);
|
||||
end record;
|
||||
|
||||
type RegisterFileToDecode2Type is record
|
||||
read1_data : std_ulogic_vector(63 downto 0);
|
||||
read2_data : std_ulogic_vector(63 downto 0);
|
||||
read3_data : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type Decode2ToCrFileType is record
|
||||
read : std_ulogic;
|
||||
end record;
|
||||
|
||||
type CrFileToDecode2Type is record
|
||||
read_cr_data : std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
|
||||
type Execute1ToFetch1Type is record
|
||||
redirect: std_ulogic;
|
||||
redirect_nia: std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0'));
|
||||
|
||||
type Decode2ToLoadstore1Type is record
|
||||
valid : std_ulogic;
|
||||
load : std_ulogic; -- is this a load or store
|
||||
addr1 : std_ulogic_vector(63 downto 0);
|
||||
addr2 : std_ulogic_vector(63 downto 0);
|
||||
data : std_ulogic_vector(63 downto 0); -- data to write, unused for read
|
||||
write_reg : std_ulogic_vector(4 downto 0); -- read data goes to this register
|
||||
length : std_ulogic_vector(3 downto 0);
|
||||
byte_reverse : std_ulogic;
|
||||
sign_extend : std_ulogic; -- do we need to sign extend?
|
||||
update : std_ulogic; -- is this an update instruction?
|
||||
update_reg : std_ulogic_vector(4 downto 0); -- if so, the register to update
|
||||
end record;
|
||||
constant Decode2ToLoadstore1Init : Decode2ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0'));
|
||||
|
||||
type Loadstore1ToLoadstore2Type is record
|
||||
valid : std_ulogic;
|
||||
load : std_ulogic;
|
||||
addr : std_ulogic_vector(63 downto 0);
|
||||
data : std_ulogic_vector(63 downto 0);
|
||||
write_reg : std_ulogic_vector(4 downto 0);
|
||||
length : std_ulogic_vector(3 downto 0);
|
||||
byte_reverse : std_ulogic;
|
||||
sign_extend : std_ulogic;
|
||||
update : std_ulogic;
|
||||
update_reg : std_ulogic_vector(4 downto 0);
|
||||
end record;
|
||||
|
||||
type Loadstore2ToWritebackType is record
|
||||
valid : std_ulogic;
|
||||
write_enable: std_ulogic;
|
||||
write_reg : std_ulogic_vector(4 downto 0);
|
||||
write_data : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', others => (others => '0'));
|
||||
|
||||
type Execute1ToExecute2Type is record
|
||||
valid: std_ulogic;
|
||||
write_enable : std_ulogic;
|
||||
write_reg: std_ulogic_vector(4 downto 0);
|
||||
write_data: std_ulogic_vector(63 downto 0);
|
||||
write_cr_enable : std_ulogic;
|
||||
write_cr_mask : std_ulogic_vector(7 downto 0);
|
||||
write_cr_data : std_ulogic_vector(31 downto 0);
|
||||
rc : std_ulogic;
|
||||
end record;
|
||||
constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', others => (others => '0'));
|
||||
|
||||
type Execute2ToWritebackType is record
|
||||
valid: std_ulogic;
|
||||
write_enable : std_ulogic;
|
||||
write_reg: std_ulogic_vector(4 downto 0);
|
||||
write_data: std_ulogic_vector(63 downto 0);
|
||||
write_cr_enable : std_ulogic;
|
||||
write_cr_mask : std_ulogic_vector(7 downto 0);
|
||||
write_cr_data : std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', write_enable => '0', write_cr_enable => '0', others => (others => '0'));
|
||||
|
||||
type MultiplyToWritebackType is record
|
||||
valid: std_ulogic;
|
||||
|
||||
write_reg_enable : std_ulogic;
|
||||
write_reg_nr: std_ulogic_vector(4 downto 0);
|
||||
write_reg_data: std_ulogic_vector(63 downto 0);
|
||||
write_cr_enable: std_ulogic;
|
||||
write_cr_mask: std_ulogic_vector(7 downto 0);
|
||||
write_cr_data: std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
constant MultiplyToWritebackInit : MultiplyToWritebackType := (valid => '0', write_reg_enable => '0', write_cr_enable => '0', others => (others => '0'));
|
||||
|
||||
type WritebackToRegisterFileType is record
|
||||
write_reg : std_ulogic_vector(4 downto 0);
|
||||
write_data : std_ulogic_vector(63 downto 0);
|
||||
write_enable : std_ulogic;
|
||||
end record;
|
||||
constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', others => (others => '0'));
|
||||
|
||||
type WritebackToCrFileType is record
|
||||
write_cr_enable : std_ulogic;
|
||||
write_cr_mask : std_ulogic_vector(7 downto 0);
|
||||
write_cr_data : std_ulogic_vector(31 downto 0);
|
||||
end record;
|
||||
constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', others => (others => '0'));
|
||||
|
||||
-- Would prefer not to expose this outside the register file, but ghdl
|
||||
-- doesn't support external names
|
||||
type regfile is array(0 to 32) of std_ulogic_vector(63 downto 0);
|
||||
end common;
|
||||
|
||||
package body common is
|
||||
function decode_spr_num(insn: std_ulogic_vector(31 downto 0)) return spr_num_t is
|
||||
begin
|
||||
return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
|
||||
end;
|
||||
function fast_spr_num(spr: spr_num_t) return gspr_index_t is
|
||||
variable n : integer range 0 to 31;
|
||||
-- tmp variable introduced as workaround for VCS compilation
|
||||
-- simulation was failing with subtype constraint mismatch error
|
||||
-- see GitHub PR #173
|
||||
variable tmp : std_ulogic_vector(4 downto 0);
|
||||
begin
|
||||
case spr is
|
||||
when SPR_LR =>
|
||||
n := 0; -- N.B. decode2 relies on this specific value
|
||||
when SPR_CTR =>
|
||||
n := 1; -- N.B. decode2 relies on this specific value
|
||||
when SPR_SRR0 =>
|
||||
n := 2;
|
||||
when SPR_SRR1 =>
|
||||
n := 3;
|
||||
when SPR_HSRR0 =>
|
||||
n := 4;
|
||||
when SPR_HSRR1 =>
|
||||
n := 5;
|
||||
when SPR_SPRG0 =>
|
||||
n := 6;
|
||||
when SPR_SPRG1 =>
|
||||
n := 7;
|
||||
when SPR_SPRG2 =>
|
||||
n := 8;
|
||||
when SPR_SPRG3 | SPR_SPRG3U =>
|
||||
n := 9;
|
||||
when SPR_HSPRG0 =>
|
||||
n := 10;
|
||||
when SPR_HSPRG1 =>
|
||||
n := 11;
|
||||
when SPR_XER =>
|
||||
n := 12;
|
||||
when SPR_TAR =>
|
||||
n := 13;
|
||||
when others =>
|
||||
n := 0;
|
||||
return "0000000";
|
||||
end case;
|
||||
tmp := std_ulogic_vector(to_unsigned(n, 5));
|
||||
return "01" & tmp;
|
||||
end;
|
||||
|
||||
function gspr_to_gpr(i: gspr_index_t) return gpr_index_t is
|
||||
begin
|
||||
return i(4 downto 0);
|
||||
end;
|
||||
|
||||
function gpr_to_gspr(i: gpr_index_t) return gspr_index_t is
|
||||
begin
|
||||
return "00" & i;
|
||||
end;
|
||||
|
||||
function gpr_or_spr_to_gspr(g: gpr_index_t; s: gspr_index_t) return gspr_index_t is
|
||||
begin
|
||||
if s(5) = '1' then
|
||||
return s;
|
||||
else
|
||||
return gpr_to_gspr(g);
|
||||
end if;
|
||||
end;
|
||||
|
||||
function is_fast_spr(s: gspr_index_t) return std_ulogic is
|
||||
begin
|
||||
return s(5);
|
||||
end;
|
||||
|
||||
function fpr_to_gspr(f: fpr_index_t) return gspr_index_t is
|
||||
begin
|
||||
return "10" & f;
|
||||
end;
|
||||
|
||||
function tag_match(tag1 : instr_tag_t; tag2 : instr_tag_t) return boolean is
|
||||
begin
|
||||
return tag1.valid = '1' and tag2.valid = '1' and tag1.tag = tag2.tag;
|
||||
end;
|
||||
|
||||
function addr_to_real(addr: std_ulogic_vector(63 downto 0)) return real_addr_t is
|
||||
begin
|
||||
return addr(real_addr_t'range);
|
||||
end;
|
||||
end common;
|
||||
|
@ -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,19 +1,19 @@
|
||||
package glibc_random_helpers is
|
||||
procedure srand (v : integer);
|
||||
attribute foreign of srand : procedure is "VHPIDIRECT srand";
|
||||
procedure srand (v : integer);
|
||||
attribute foreign of srand : procedure is "VHPIDIRECT srand";
|
||||
|
||||
function random return integer;
|
||||
attribute foreign of random : function is "VHPIDIRECT random";
|
||||
function random return integer;
|
||||
attribute foreign of random : function is "VHPIDIRECT random";
|
||||
end glibc_random_helpers;
|
||||
|
||||
package body glibc_random_helpers is
|
||||
procedure srand (v : integer) is
|
||||
begin
|
||||
assert false severity failure;
|
||||
end srand;
|
||||
procedure srand (v : integer) is
|
||||
begin
|
||||
assert false severity failure;
|
||||
end srand;
|
||||
|
||||
function random return integer is
|
||||
begin
|
||||
assert false severity failure;
|
||||
end random;
|
||||
function random return integer is
|
||||
begin
|
||||
assert false severity failure;
|
||||
end random;
|
||||
end glibc_random_helpers;
|
||||
|
@ -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 <stdbool.h>
|
||||
|
||||
#include "console.h"
|
||||
/*
|
||||
* Core UART functions to implement for a port
|
||||
*/
|
||||
|
||||
static char mw_logo[] =
|
||||
static uint64_t potato_uart_base;
|
||||
|
||||
"\n"
|
||||
" .oOOo. \n"
|
||||
" .\" \". \n"
|
||||
" ; .mw. ; Microwatt, it works.\n"
|
||||
" . ' ' . \n"
|
||||
" \\ || / \n"
|
||||
" ;..; \n"
|
||||
" ;..; \n"
|
||||
" `ww' \n";
|
||||
#define PROC_FREQ 50000000
|
||||
#define UART_FREQ 115200
|
||||
#define UART_BASE 0xc0002000
|
||||
|
||||
#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
|
||||
|
||||
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)
|
||||
{
|
||||
console_init();
|
||||
potato_uart_init();
|
||||
|
||||
puts(mw_logo);
|
||||
putstr(HELLO_WORLD, strlen(HELLO_WORLD));
|
||||
|
||||
while (1) {
|
||||
unsigned char c = getchar();
|
||||
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
|
||||
{
|
||||
. = 0;
|
||||
_start = .;
|
||||
. = 0;
|
||||
.head : {
|
||||
KEEP(*(.head))
|
||||
}
|
||||
}
|
||||
. = 0x1000;
|
||||
.text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) }
|
||||
. = 0x1800;
|
||||
.data : { *(.data) *(.data.*) *(.got) *(.toc) }
|
||||
. = ALIGN(0x80);
|
||||
__bss_start = .;
|
||||
.bss : {
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.common)
|
||||
*(.bss.*)
|
||||
}
|
||||
. = ALIGN(0x80);
|
||||
__bss_end = .;
|
||||
. = . + 0x2000;
|
||||
__stack_top = .;
|
||||
.text : { *(.text) }
|
||||
. = 0x2000;
|
||||
.data : { *(.data) }
|
||||
.bss : { *(.bss) }
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
},
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue