Compare commits

..

2 Commits

Author SHA1 Message Date
Anton Blanchard ceb15d3ca8 Hack to test under verilator 3 years ago
Michael Neuling 376ad8da3d boxarty rebased
Build with
  fusesoc run --target=arty_a7-100 microwatt --memory_size=0 --no_bram --use_litesdcard --has_lpc
3 years ago

@ -72,7 +72,7 @@ jobs:
fail-fast: false fail-fast: false
max-parallel: 2 max-parallel: 2
matrix: matrix:
task: [ ECP5-EVN, ORANGE-CRAB, ORANGE-CRAB-0.21 ] task: [ ECP5-EVN, ORANGE-CRAB ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
DOCKER: 1 DOCKER: 1

@ -6,17 +6,13 @@ VERILATOR_FLAGS=-O3 -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT #--trace
# It takes forever to build with optimisation, so disable by default # It takes forever to build with optimisation, so disable by default
#VERILATOR_CFLAGS=-O3 #VERILATOR_CFLAGS=-O3


# some yosys builds have ghdl plugin built in, otherwise need "-m ghdl" GHDLSYNTH ?= ghdl.so
GHDLSYNTH ?= $(shell ($(YOSYS) -H | grep -q ghdl) || echo -m ghdl)
YOSYS ?= yosys YOSYS ?= yosys
NEXTPNR ?= nextpnr-ecp5 NEXTPNR ?= nextpnr-ecp5
ECPPACK ?= ecppack ECPPACK ?= ecppack
ECPPROG ?= ecpprog
OPENOCD ?= openocd OPENOCD ?= openocd
VUNITRUN ?= python3 ./run.py VUNITRUN ?= python3 ./run.py
VERILATOR ?= verilator VERILATOR ?= verilator
DFUUTIL ?= dfu-util
DFUSUFFIX ?= dfu-suffix


# We need a version of GHDL built with either the LLVM or gcc backend. # 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 # Fedora provides this, but other distros may not. Another option is to use
@ -39,7 +35,7 @@ PWD = $(shell pwd)
DOCKERARGS = run --rm -v $(PWD):/src:z -w /src DOCKERARGS = run --rm -v $(PWD):/src:z -w /src
GHDL = $(DOCKERBIN) $(DOCKERARGS) ghdl/ghdl:buster-llvm-7 ghdl GHDL = $(DOCKERBIN) $(DOCKERARGS) ghdl/ghdl:buster-llvm-7 ghdl
CC = $(DOCKERBIN) $(DOCKERARGS) ghdl/ghdl:buster-llvm-7 gcc CC = $(DOCKERBIN) $(DOCKERARGS) ghdl/ghdl:buster-llvm-7 gcc
GHDLSYNTH = -m ghdl GHDLSYNTH = ghdl
YOSYS = $(DOCKERBIN) $(DOCKERARGS) hdlc/ghdl:yosys yosys YOSYS = $(DOCKERBIN) $(DOCKERARGS) hdlc/ghdl:yosys yosys
NEXTPNR = $(DOCKERBIN) $(DOCKERARGS) hdlc/nextpnr:ecp5 nextpnr-ecp5 NEXTPNR = $(DOCKERBIN) $(DOCKERARGS) hdlc/nextpnr:ecp5 nextpnr-ecp5
ECPPACK = $(DOCKERBIN) $(DOCKERARGS) hdlc/prjtrellis ecppack ECPPACK = $(DOCKERBIN) $(DOCKERARGS) hdlc/prjtrellis ecppack
@ -60,7 +56,7 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \
decode1.vhdl helpers.vhdl insn_helpers.vhdl \ decode1.vhdl helpers.vhdl insn_helpers.vhdl \
control.vhdl decode2.vhdl register_file.vhdl \ control.vhdl decode2.vhdl register_file.vhdl \
cr_file.vhdl crhelpers.vhdl ppc_fx_insns.vhdl rotator.vhdl \ cr_file.vhdl crhelpers.vhdl ppc_fx_insns.vhdl rotator.vhdl \
logical.vhdl countbits.vhdl multiply.vhdl divider.vhdl execute1.vhdl \ logical.vhdl countzero.vhdl multiply.vhdl divider.vhdl execute1.vhdl \
loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \ loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \
core.vhdl fpu.vhdl pmu.vhdl core.vhdl fpu.vhdl pmu.vhdl


@ -152,18 +148,13 @@ RAM_INIT_FILE ?=hello_world/hello_world.hex
#MEMORY_SIZE=393216 #MEMORY_SIZE=393216
#RAM_INIT_FILE=micropython/firmware.hex #RAM_INIT_FILE=micropython/firmware.hex


FPGA_TARGET ?= ORANGE-CRAB-0.21 FPGA_TARGET ?= ORANGE-CRAB


# FIXME: icache RAMs aren't being inferrenced as block RAMs on ECP5 # FIXME: icache RAMs aren't being inferrenced as block RAMs on ECP5
# with yosys, so make it smaller for now as a workaround. # with yosys, so make it smaller for now as a workaround.
ICACHE_NUM_LINES=4 ICACHE_NUM_LINES=4


clkgen=fpga/clk_gen_ecp5.vhd # OrangeCrab with ECP85
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) ifeq ($(FPGA_TARGET), ORANGE-CRAB)
RESET_LOW=true RESET_LOW=true
CLK_INPUT=48000000 CLK_INPUT=48000000
@ -173,26 +164,6 @@ PACKAGE=CSFBGA285
NEXTPNR_FLAGS=--um5g-85k --freq 48 NEXTPNR_FLAGS=--um5g-85k --freq 48
OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.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 endif


# ECP5-EVN # ECP5-EVN
@ -207,17 +178,12 @@ OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
endif 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) \ 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) \ -gRESET_LOW=$(RESET_LOW) -gCLK_INPUT=$(CLK_INPUT) -gCLK_FREQUENCY=$(CLK_FREQUENCY) -gICACHE_NUM_LINES=$(ICACHE_NUM_LINES)
$(LITEDRAM_GHDL_ARG)


clkgen=fpga/clk_gen_ecp5.vhd
toplevel=fpga/top-generic.vhdl
dmi_dtm=dmi_dtm_dummy.vhdl


ifeq ($(FPGA_TARGET), verilator) ifeq ($(FPGA_TARGET), verilator)
RESET_LOW=true RESET_LOW=true
@ -230,16 +196,16 @@ fpga_files = fpga/soc_reset.vhdl \
fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram.vhdl \ fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram.vhdl \
nonrandom.vhdl nonrandom.vhdl


synth_files = $(core_files) $(soc_files) $(soc_extra_synth) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm) synth_files = $(core_files) $(soc_files) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm)


microwatt.json: $(synth_files) $(RAM_INIT_FILE) 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)" $(YOSYS) -m $(GHDLSYNTH) -p "ghdl --std=08 --no-formal $(GHDL_IMAGE_GENERICS) $(synth_files) -e toplevel; synth_ecp5 -abc9 -nowidelut -json $@ $(SYNTH_ECP5_FLAGS)" $(uart_files)


microwatt.v: $(synth_files) $(RAM_INIT_FILE) microwatt.v: $(synth_files) $(RAM_INIT_FILE)
$(YOSYS) $(GHDLSYNTH) -p "ghdl --std=08 --no-formal $(GHDL_IMAGE_GENERICS) $(synth_files) -e toplevel; write_verilog $@" $(YOSYS) -m $(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 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 $(VERILATOR) $(VERILATOR_FLAGS) -CFLAGS "$(VERILATOR_CFLAGS) -DCLK_FREQUENCY=$(CLK_FREQUENCY)" -Iuart16550 --assert --cc --exe --build $^ -o $@ -top-module toplevel lpc/lpc.v -Ilpc
@cp -f obj_dir/microwatt-verilator microwatt-verilator @cp -f obj_dir/microwatt-verilator microwatt-verilator


microwatt_out.config: microwatt.json $(LPF) microwatt_out.config: microwatt.json $(LPF)
@ -247,28 +213,13 @@ microwatt_out.config: microwatt.json $(LPF)
mv -f $@.tmp $@ mv -f $@.tmp $@


microwatt.bit: microwatt_out.config microwatt.bit: microwatt_out.config
$(ECPPACK) --compress --freq 38.8 --svf microwatt.svf $< $@ $(ECPPACK) --svf microwatt.svf $< $@


microwatt.svf: microwatt.bit microwatt.svf: microwatt.bit


prog: microwatt.svf prog: microwatt.svf
$(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit" $(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit"


microwatt.dfu: microwatt.bit
cp $< $@.tmp
$(DFUSUFFIX) -v $(DFU_VENDOR) -p $(DFU_PRODUCT) -a $@.tmp
mv $@.tmp $@

dfuprog: microwatt.dfu
$(DFUUTIL) -a 0 -D $<

ecpprog: microwatt.bit
$(ECPPROG) -S $<

ecpflash: microwatt.bit
test -n "$(ECP_FLASH_OFFSET)" || (echo Error: No ECP_FLASH_OFFSET defined for target; exit 1)
$(ECPPROG) -o $(ECP_FLASH_OFFSET) $<

tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out))) tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out)))
tests_console = $(sort $(patsubst tests/%.console_out,%,$(wildcard tests/*.console_out))) tests_console = $(sort $(patsubst tests/%.console_out,%,$(wildcard tests/*.console_out)))



@ -103,8 +103,14 @@ sudo dnf install fusesoc


``` ```
fusesoc init fusesoc init
fusesoc fetch uart16550 ```
fusesoc library add microwatt /path/to/microwatt
- Create a working directory and point FuseSoC at microwatt:

```
mkdir microwatt-fusesoc
cd microwatt-fusesoc
fusesoc library add microwatt /path/to/microwatt/
``` ```


- Build using FuseSoC. For hello world (Replace nexys_video with your FPGA board such as --target=arty_a7-100): - Build using FuseSoC. For hello world (Replace nexys_video with your FPGA board such as --target=arty_a7-100):
@ -122,68 +128,6 @@ You should then be able to see output via the serial port of the board (/dev/tty
fusesoc run --target=nexys_video microwatt fusesoc run --target=nexys_video microwatt
``` ```


## Linux on Microwatt

Mainline Linux supports Microwatt as of v5.14. The Arty A7 is the best tested
platform, but it's also been tested on the OrangeCrab and ButterStick.

1. Use buildroot to create a userspace

A small change is required to glibc in order to support the VMX/AltiVec-less
Microwatt, as float128 support is mandiatory and for this in GCC requires
VSX/AltiVec. This change is included in Joel's buildroot fork, along with a
defconfig:
```
git clone -b microwatt https://github.com/shenki/buildroot
cd buildroot
make ppc64le_microwatt_defconfig
make
```

The output is `output/images/rootfs.cpio`.

2. Build the Linux kernel
```
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
make ARCH=powerpc microwatt_defconfig
make ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- \
CONFIG_INITRAMFS_SOURCE=/buildroot/output/images/rootfs.cpio -j`nproc`
```

The output is `arch/powerpc/boot/dtbImage.microwatt.elf`.

3. Build gateware using FuseSoC

First configure FuseSoC as above.
```
fusesoc run --build --target=arty_a7-100 microwatt --no_bram --memory_size=0
```

The output is `build/microwatt_0/arty_a7-100-vivado/microwatt_0.bit`.

4. Program the flash

This operation will overwrite the contents of your flash.

For the Arty A7 A100, set `FLASH_ADDRESS` to `0x400000` and pass `-f a100`.

For the Arty A7 A35, set `FLASH_ADDRESS` to `0x300000` and pass `-f a35`.
```
microwatt/openocd/flash-arty -f a100 build/microwatt_0/arty_a7-100-vivado/microwatt_0.bit
microwatt/openocd/flash-arty -f a100 dtbImage.microwatt.elf -t bin -a $FLASH_ADDRESS
```

5. Connect to the second USB TTY device exposed by the FPGA

```
minicom -D /dev/ttyUSB1
```

The gateware has firmware that will look at `FLASH_ADDRESS` and attempt to
parse an ELF there, loading it to the address specified in the ELF header
and jumping to it.

## Testing ## Testing


- A simple test suite containing random execution test cases and a couple of - A simple test suite containing random execution test cases and a couple of
@ -195,5 +139,8 @@ make -j$(nproc) check


## Issues ## Issues


- There are a few instructions still to be implemented: This is functional, but very simple. We still have quite a lot to do:
- Vector/VMX/VSX
- There are a few instructions still to be implemented
- Need to add caches and bypassing (in progress)
- Need to add supervisor state (in progress)

@ -200,6 +200,7 @@ package common is
priv_mode : std_ulogic; priv_mode : std_ulogic;
big_endian : std_ulogic; big_endian : std_ulogic;
stop_mark: std_ulogic; stop_mark: std_ulogic;
sequential: std_ulogic;
predicted : std_ulogic; predicted : std_ulogic;
pred_ntaken : std_ulogic; pred_ntaken : std_ulogic;
nia: std_ulogic_vector(63 downto 0); nia: std_ulogic_vector(63 downto 0);

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

@ -64,8 +64,8 @@ architecture rtl of control is


signal r_int, rin_int : reg_internal_type := reg_internal_init; signal r_int, rin_int : reg_internal_type := reg_internal_init;


signal gpr_write_valid : std_ulogic; signal gpr_write_valid : std_ulogic := '0';
signal cr_write_valid : std_ulogic; signal cr_write_valid : std_ulogic := '0';


type tag_register is record type tag_register is record
wr_gpr : std_ulogic; wr_gpr : std_ulogic;
@ -245,8 +245,6 @@ begin
end if; end if;


if rst = '1' then if rst = '1' then
gpr_write_valid <= '0';
cr_write_valid <= '0';
v_int := reg_internal_init; v_int := reg_internal_init;
valid_tmp := '0'; valid_tmp := '0';
end if; end if;

@ -117,20 +117,21 @@ architecture behave of core is
signal complete: instr_tag_t; signal complete: instr_tag_t;
signal terminate: std_ulogic; signal terminate: std_ulogic;
signal core_rst: std_ulogic; signal core_rst: std_ulogic;
signal icache_inv: std_ulogic;
signal do_interrupt: std_ulogic; signal do_interrupt: std_ulogic;


-- Delayed/Latched resets and alt_reset -- Delayed/Latched resets and alt_reset
signal rst_fetch1 : std_ulogic; signal rst_fetch1 : std_ulogic := '1';
signal rst_fetch2 : std_ulogic; signal rst_fetch2 : std_ulogic := '1';
signal rst_icache : std_ulogic; signal rst_icache : std_ulogic := '1';
signal rst_dcache : std_ulogic; signal rst_dcache : std_ulogic := '1';
signal rst_dec1 : std_ulogic; signal rst_dec1 : std_ulogic := '1';
signal rst_dec2 : std_ulogic; signal rst_dec2 : std_ulogic := '1';
signal rst_ex1 : std_ulogic; signal rst_ex1 : std_ulogic := '1';
signal rst_fpu : std_ulogic; signal rst_fpu : std_ulogic := '1';
signal rst_ls1 : std_ulogic; signal rst_ls1 : std_ulogic := '1';
signal rst_wback : std_ulogic; signal rst_wback : std_ulogic := '1';
signal rst_dbg : std_ulogic; signal rst_dbg : std_ulogic := '1';
signal alt_reset_d : std_ulogic; signal alt_reset_d : std_ulogic;


signal sim_cr_dump: std_ulogic; signal sim_cr_dump: std_ulogic;

@ -154,7 +154,6 @@ begin
stopping <= '0'; stopping <= '0';
terminated <= '0'; terminated <= '0';
log_trigger_delay <= 0; log_trigger_delay <= 0;
gspr_index <= (others => '0');
else else
if do_log_trigger = '1' or log_trigger_delay /= 0 then if do_log_trigger = '1' or log_trigger_delay /= 0 then
if log_trigger_delay = 255 then if log_trigger_delay = 255 then

@ -121,7 +121,6 @@ begin
DRAM_ABITS => 24, DRAM_ABITS => 24,
DRAM_ALINES => 1, DRAM_ALINES => 1,
DRAM_DLINES => 16, DRAM_DLINES => 16,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 128, DRAM_PORT_WIDTH => 128,
PAYLOAD_FILE => DRAM_INIT_FILE, PAYLOAD_FILE => DRAM_INIT_FILE,
PAYLOAD_SIZE => ROM_SIZE PAYLOAD_SIZE => ROM_SIZE

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

@ -0,0 +1,60 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.helpers.all;

entity zero_counter is
port (
clk : in std_logic;
rs : in std_ulogic_vector(63 downto 0);
count_right : in std_ulogic;
is_32bit : in std_ulogic;
result : out std_ulogic_vector(63 downto 0)
);
end entity zero_counter;

architecture behaviour of zero_counter is
signal inp : std_ulogic_vector(63 downto 0);
signal sum : std_ulogic_vector(64 downto 0);
signal msb_r : std_ulogic;
signal onehot : std_ulogic_vector(63 downto 0);
signal onehot_r : std_ulogic_vector(63 downto 0);
signal bitnum : std_ulogic_vector(5 downto 0);

begin
countzero_r: process(clk)
begin
if rising_edge(clk) then
msb_r <= sum(64);
onehot_r <= onehot;
end if;
end process;

countzero: process(all)
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);
onehot <= sum(63 downto 0) and inp;

-- The following occurs after a clock edge
bitnum <= bit_number(onehot_r);

result <= x"00000000000000" & "0" & msb_r & bitnum;
end process;
end behaviour;

@ -11,11 +11,11 @@ use work.common.all;
library osvvm; library osvvm;
use osvvm.RandomPkg.all; use osvvm.RandomPkg.all;


entity countbits_tb is entity countzero_tb is
generic (runner_cfg : string := runner_cfg_default); generic (runner_cfg : string := runner_cfg_default);
end countbits_tb; end countzero_tb;


architecture behave of countbits_tb is architecture behave of countzero_tb is
constant clk_period: time := 10 ns; constant clk_period: time := 10 ns;
signal rs: std_ulogic_vector(63 downto 0); signal rs: std_ulogic_vector(63 downto 0);
signal is_32bit, count_right: std_ulogic := '0'; signal is_32bit, count_right: std_ulogic := '0';
@ -23,15 +23,13 @@ architecture behave of countbits_tb is
signal clk: std_ulogic; signal clk: std_ulogic;


begin begin
bitcounter_0: entity work.bit_counter zerocounter_0: entity work.zero_counter
port map ( port map (
clk => clk, clk => clk,
rs => rs, rs => rs,
result => res, result => res,
count_right => count_right, count_right => count_right,
is_32bit => is_32bit, is_32bit => is_32bit
do_popcnt => '0',
datalen => "0000"
); );


clk_process: process clk_process: process

@ -1121,6 +1121,7 @@ begin
rams: for i in 0 to NUM_WAYS-1 generate rams: for i in 0 to NUM_WAYS-1 generate
signal do_read : std_ulogic; signal do_read : std_ulogic;
signal rd_addr : std_ulogic_vector(ROW_BITS-1 downto 0); signal rd_addr : std_ulogic_vector(ROW_BITS-1 downto 0);
signal do_write : std_ulogic;
signal wr_addr : std_ulogic_vector(ROW_BITS-1 downto 0); signal wr_addr : std_ulogic_vector(ROW_BITS-1 downto 0);
signal wr_data : std_ulogic_vector(wishbone_data_bits-1 downto 0); signal wr_data : std_ulogic_vector(wishbone_data_bits-1 downto 0);
signal wr_sel : std_ulogic_vector(ROW_SIZE-1 downto 0); signal wr_sel : std_ulogic_vector(ROW_SIZE-1 downto 0);

@ -215,6 +215,7 @@ architecture behaviour of decode2 is
OP_AND => "001", -- logical_result OP_AND => "001", -- logical_result
OP_OR => "001", OP_OR => "001",
OP_XOR => "001", OP_XOR => "001",
OP_POPCNT => "001",
OP_PRTY => "001", OP_PRTY => "001",
OP_CMPB => "001", OP_CMPB => "001",
OP_EXTS => "001", OP_EXTS => "001",
@ -233,8 +234,7 @@ architecture behaviour of decode2 is
OP_DIV => "011", OP_DIV => "011",
OP_DIVE => "011", OP_DIVE => "011",
OP_MOD => "011", OP_MOD => "011",
OP_CNTZ => "100", -- countbits_result OP_CNTZ => "100", -- countzero_result
OP_POPCNT => "100",
OP_MFSPR => "101", -- spr_result OP_MFSPR => "101", -- spr_result
OP_B => "110", -- next_nia OP_B => "110", -- next_nia
OP_BC => "110", OP_BC => "110",

@ -42,8 +42,6 @@ begin
quot <= (others => '0'); quot <= (others => '0');
running <= '0'; running <= '0';
count <= "0000000"; count <= "0000000";
is_32bit <= '0';
overflow <= '0';
elsif d_in.valid = '1' then elsif d_in.valid = '1' then
if d_in.is_extended = '1' then if d_in.is_extended = '1' then
dend <= '0' & d_in.dividend & x"0000000000000000"; dend <= '0' & d_in.dividend & x"0000000000000000";

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

@ -44,7 +44,6 @@ begin
DRAM_ABITS => 24, DRAM_ABITS => 24,
DRAM_ALINES => 1, DRAM_ALINES => 1,
DRAM_DLINES => 16, DRAM_DLINES => 16,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 128, DRAM_PORT_WIDTH => 128,
PAYLOAD_FILE => DRAM_INIT_FILE, PAYLOAD_FILE => DRAM_INIT_FILE,
PAYLOAD_SIZE => DRAM_INIT_SIZE PAYLOAD_SIZE => DRAM_INIT_SIZE

@ -99,20 +99,21 @@ architecture behaviour of execute1 is
signal mshort_p : std_ulogic_vector(31 downto 0) := (others => '0'); signal mshort_p : std_ulogic_vector(31 downto 0) := (others => '0');


signal valid_in : std_ulogic; signal valid_in : std_ulogic;
signal ctrl: ctrl_t; signal ctrl: ctrl_t := (others => (others => '0'));
signal ctrl_tmp: ctrl_t; signal ctrl_tmp: ctrl_t := (others => (others => '0'));
signal right_shift, rot_clear_left, rot_clear_right: std_ulogic; signal right_shift, rot_clear_left, rot_clear_right: std_ulogic;
signal rot_sign_ext: std_ulogic; signal rot_sign_ext: std_ulogic;
signal rotator_result: std_ulogic_vector(63 downto 0); signal rotator_result: std_ulogic_vector(63 downto 0);
signal rotator_carry: std_ulogic; signal rotator_carry: std_ulogic;
signal logical_result: std_ulogic_vector(63 downto 0); signal logical_result: std_ulogic_vector(63 downto 0);
signal do_popcnt: std_ulogic; signal countzero_result: std_ulogic_vector(63 downto 0);
signal countbits_result: std_ulogic_vector(63 downto 0);
signal alu_result: std_ulogic_vector(63 downto 0); signal alu_result: std_ulogic_vector(63 downto 0);
signal adder_result: std_ulogic_vector(63 downto 0); signal adder_result: std_ulogic_vector(63 downto 0);
signal misc_result: std_ulogic_vector(63 downto 0); signal misc_result: std_ulogic_vector(63 downto 0);
signal muldiv_result: std_ulogic_vector(63 downto 0); signal muldiv_result: std_ulogic_vector(63 downto 0);
signal spr_result: std_ulogic_vector(63 downto 0); signal spr_result: std_ulogic_vector(63 downto 0);
signal result_mux_sel: std_ulogic_vector(2 downto 0);
signal sub_mux_sel: std_ulogic_vector(2 downto 0);
signal next_nia : std_ulogic_vector(63 downto 0); signal next_nia : std_ulogic_vector(63 downto 0);
signal current: Decode2ToExecute1Type; signal current: Decode2ToExecute1Type;


@ -283,15 +284,13 @@ begin
datalen => e_in.data_len datalen => e_in.data_len
); );


countbits_0: entity work.bit_counter countzero_0: entity work.zero_counter
port map ( port map (
clk => clk, clk => clk,
rs => c_in, rs => c_in,
count_right => e_in.insn(10), count_right => e_in.insn(10),
is_32bit => e_in.is_32bit, is_32bit => e_in.is_32bit,
do_popcnt => do_popcnt, result => countzero_result
datalen => e_in.data_len,
result => countbits_result
); );


multiply_0: entity work.multiply multiply_0: entity work.multiply
@ -392,7 +391,7 @@ begin
logical_result when "001", logical_result when "001",
rotator_result when "010", rotator_result when "010",
muldiv_result when "011", muldiv_result when "011",
countbits_result when "100", countzero_result when "100",
spr_result when "101", spr_result when "101",
next_nia when "110", next_nia when "110",
misc_result when others; misc_result when others;
@ -404,7 +403,6 @@ begin
r <= reg_type_init; r <= reg_type_init;
ctrl.tb <= (others => '0'); ctrl.tb <= (others => '0');
ctrl.dec <= (others => '0'); ctrl.dec <= (others => '0');
ctrl.cfar <= (others => '0');
ctrl.msr <= (MSR_SF => '1', MSR_LE => '1', others => '0'); ctrl.msr <= (MSR_SF => '1', MSR_LE => '1', others => '0');
else else
r <= rin; r <= rin;
@ -815,8 +813,6 @@ begin
rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0'; rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0';
rot_sign_ext <= '1' when e_in.insn_type = OP_EXTSWSLI else '0'; rot_sign_ext <= '1' when e_in.insn_type = OP_EXTSWSLI else '0';


do_popcnt <= '1' when e_in.insn_type = OP_POPCNT else '0';

illegal := '0'; illegal := '0';
if r.intr_pending = '1' then if r.intr_pending = '1' then
v.e.srr1 := r.e.srr1; v.e.srr1 := r.e.srr1;
@ -967,7 +963,7 @@ begin
when OP_ADDG6S => when OP_ADDG6S =>
when OP_CMPRB => when OP_CMPRB =>
when OP_CMPEQB => when OP_CMPEQB =>
when OP_AND | OP_OR | OP_XOR | OP_PRTY | OP_CMPB | OP_EXTS | when OP_AND | OP_OR | OP_XOR | OP_POPCNT | OP_PRTY | OP_CMPB | OP_EXTS |
OP_BPERM | OP_BCD => OP_BPERM | OP_BCD =>


when OP_B => when OP_B =>
@ -1029,7 +1025,7 @@ begin
end if; end if;
do_trace := '0'; do_trace := '0';


when OP_CNTZ | OP_POPCNT => when OP_CNTZ =>
v.e.valid := '0'; v.e.valid := '0';
v.cntz_in_progress := '1'; v.cntz_in_progress := '1';
v.busy := '1'; v.busy := '1';
@ -1224,7 +1220,7 @@ begin
-- valid_in = 0. Hence they don't happen in the same cycle as any of -- valid_in = 0. Hence they don't happen in the same cycle as any of
-- the cases above which depend on valid_in = 1. -- the cases above which depend on valid_in = 1.
if r.cntz_in_progress = '1' then if r.cntz_in_progress = '1' then
-- cnt[lt]z and popcnt* always take two cycles -- cnt[lt]z always takes two cycles
v.e.valid := '1'; v.e.valid := '1';
elsif r.mul_in_progress = '1' or r.div_in_progress = '1' then elsif r.mul_in_progress = '1' or r.div_in_progress = '1' then
if (r.mul_in_progress = '1' and multiply_to_x.valid = '1') or if (r.mul_in_progress = '1' and multiply_to_x.valid = '1') or

@ -89,8 +89,9 @@ begin
r_int.predicted_taken <= r_next_int.predicted_taken; r_int.predicted_taken <= r_next_int.predicted_taken;
r_int.pred_not_taken <= r_next_int.pred_not_taken; r_int.pred_not_taken <= r_next_int.pred_not_taken;
r_int.predicted_nia <= r_next_int.predicted_nia; r_int.predicted_nia <= r_next_int.predicted_nia;
r_int.rd_is_niap4 <= r_next_int.rd_is_niap4; r_int.rd_is_niap4 <= r_next.sequential;
end if; end if;
r.sequential <= r_next.sequential and advance_nia;
-- always send the up-to-date stop mark and req -- always send the up-to-date stop mark and req
r.stop_mark <= stop_in; r.stop_mark <= stop_in;
r.req <= not rst; r.req <= not rst;
@ -144,11 +145,11 @@ begin
begin begin
v := r; v := r;
v_int := r_int; v_int := r_int;
v.sequential := '0';
v.predicted := '0'; v.predicted := '0';
v.pred_ntaken := '0'; v.pred_ntaken := '0';
v_int.predicted_taken := '0'; v_int.predicted_taken := '0';
v_int.pred_not_taken := '0'; v_int.pred_not_taken := '0';
v_int.rd_is_niap4 := '0';


if rst = '1' then if rst = '1' then
if alt_reset_in = '1' then if alt_reset_in = '1' then
@ -179,7 +180,7 @@ begin
v.nia := r_int.predicted_nia; v.nia := r_int.predicted_nia;
v.predicted := '1'; v.predicted := '1';
else else
v_int.rd_is_niap4 := '1'; v.sequential := '1';
v.pred_ntaken := r_int.pred_not_taken; v.pred_ntaken := r_int.pred_not_taken;
v.nia := std_ulogic_vector(unsigned(r.nia) + 4); v.nia := std_ulogic_vector(unsigned(r.nia) + 4);
if r_int.mode_32bit = '1' then if r_int.mode_32bit = '1' then

@ -80,14 +80,14 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdca
# PMOD header JB (high-speed, no protection resisters) # 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 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 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 D15 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { pmod_jb[3] }];
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_4 }]; set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[6] }];
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_7 }]; set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { pmod_jb[7] }];
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_8 }]; set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[7] }];
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb_9 }]; 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 }]; set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb[10] }];


# connection to Digilent PmodSD on JB # 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 E15 IOSTANDARD LVCMOS33 SLEW FAST PULLUP TRUE } [get_ports { sdcard_data[3] }];
@ -103,14 +103,14 @@ set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdca
# PMOD header JC (high-speed, no protection resisters) # 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 U12 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { pmod_jc[1] }];
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_2 }]; 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 V10 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { pmod_jc[3] }];
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_4 }]; 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 U14 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { pmod_jc[7] }];
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_8 }]; 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 T13 IOSTANDARD LVCMOS33 PULLUP TRUE } [get_ports { pmod_jc[9] }];
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc_10 }]; set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { pmod_jc[10] }];


################################################################################ ################################################################################
# PMOD header JD (standard, 200 ohm protection resisters) # PMOD header JD (standard, 200 ohm protection resisters)
@ -135,8 +135,8 @@ set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_po
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[3] }]; 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 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 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 T15 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb[4] }];
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[7] }]; set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { pmod_jb[8] }];
set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[8] }]; 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 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 V17 IOSTANDARD LVCMOS33 PULLDOWN TRUE } [get_ports { shield_io[10] }];
@ -552,3 +552,4 @@ 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_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}]] 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}]]


@ -82,42 +82,33 @@ architecture bypass of clock_generator is
CLKINTFB : out std_logic ); CLKINTFB : out std_logic );
end component; end component;


signal clkos : std_ulogic;
signal clkop : std_logic; signal clkop : std_logic;
signal lock : std_logic; signal lock : std_logic;


-- PLL constants -- PLL constants based on prjtrellis example
-- According to the datasheet, PLL_IN needs to be between 10 and 400 MHz constant PLL_IN : natural := 2000000;
-- PLL_OUT needs to be between 400 and 800 MHz constant PLL_OUT : natural := 600000000;
-- 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 -- Configration for ECP5 PLL
constant PLL_CLKOP_DIV : natural := PLL_OUT/CLK_OUTPUT_HZ; constant PLL_CLKOP_DIV : natural := PLL_OUT/CLK_OUTPUT_HZ;
constant PLL_CLKOS_DIV : natural := 2; constant PLL_CLKFB_DIV : natural := CLK_OUTPUT_HZ/PLL_IN;
constant PLL_CLKFB_DIV : natural := PLL_OUT/PLL_CLKOS_DIV/PLL_IN;
constant PLL_CLKI_DIV : natural := CLK_INPUT_HZ/PLL_IN; constant PLL_CLKI_DIV : natural := CLK_INPUT_HZ/PLL_IN;


begin begin
pll_clk_out <= clkop; pll_clk_out <= clkop;
pll_locked_out <= lock; pll_locked_out <= not lock; -- FIXME: EHXPLLL lock signal active low?!?


clkgen: EHXPLLL clkgen: EHXPLLL
generic map( generic map(
CLKOP_CPHASE => 11, -- FIXME: Copied from prjtrells.
CLKOP_DIV => PLL_CLKOP_DIV, CLKOP_DIV => PLL_CLKOP_DIV,
CLKOS_ENABLE => "ENABLED",
CLKOS_DIV => PLL_CLKOS_DIV,
CLKFB_DIV => PLL_CLKFB_DIV, CLKFB_DIV => PLL_CLKFB_DIV,
CLKI_DIV => PLL_CLKI_DIV, CLKI_DIV => PLL_CLKI_DIV
FEEDBK_PATH => "CLKOS"
) )
port map ( port map (
CLKI => ext_clk, CLKI => ext_clk,
CLKOP => clkop, CLKOP => clkop,
CLKOS => clkos, CLKFB => clkop,
CLKFB => clkos,
LOCK => lock, LOCK => lock,
RST => pll_rst_in, RST => pll_rst_in,
PHASESEL1 => '0', PHASESEL1 => '0',
@ -127,8 +118,8 @@ begin
PHASELOADREG => '0', PHASELOADREG => '0',
STDBY => '0', STDBY => '0',
PLLWAKESYNC => '0', PLLWAKESYNC => '0',
ENCLKOP => '1', ENCLKOP => '0',
ENCLKOS => '1', ENCLKOS => '0',
ENCLKOS2 => '0', ENCLKOS2 => '0',
ENCLKOS3 => '0' ENCLKOS3 => '0'
); );

@ -94,10 +94,6 @@ architecture behaviour of toplevel is
signal spi_sdat_oe : 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 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 -- Fixup various memory sizes based on generics
function get_bram_size return natural is function get_bram_size return natural is
begin begin
@ -256,9 +252,6 @@ begin
-- but for now, assert it's 100Mhz -- but for now, assert it's 100Mhz
assert CLK_FREQUENCY = 100000000; 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 reset_controller: entity work.soc_reset
generic map( generic map(
RESET_LOW => false, RESET_LOW => false,
@ -279,7 +272,6 @@ begin
DRAM_ABITS => 26, DRAM_ABITS => 26,
DRAM_ALINES => 16, DRAM_ALINES => 16,
DRAM_DLINES => 16, DRAM_DLINES => 16,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 128, DRAM_PORT_WIDTH => 128,
PAYLOAD_FILE => RAM_INIT_FILE, PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE PAYLOAD_SIZE => PAYLOAD_SIZE
@ -312,8 +304,8 @@ begin
ddram_dq => ddram_dq, ddram_dq => ddram_dq,
ddram_dqs_p => ddram_dqs_p, ddram_dqs_p => ddram_dqs_p,
ddram_dqs_n => ddram_dqs_n, ddram_dqs_n => ddram_dqs_n,
ddram_clk_p => ddram_clk_p_vec, ddram_clk_p => ddram_clk_p,
ddram_clk_n => ddram_clk_n_vec, ddram_clk_n => ddram_clk_n,
ddram_cke => ddram_cke, ddram_cke => ddram_cke,
ddram_odt => ddram_odt, ddram_odt => ddram_odt,
ddram_reset_n => ddram_reset_n ddram_reset_n => ddram_reset_n

@ -17,6 +17,7 @@ entity toplevel is
HAS_FPU : boolean := true; HAS_FPU : boolean := true;
HAS_BTC : boolean := true; HAS_BTC : boolean := true;
HAS_SHORT_MULT : boolean := false; HAS_SHORT_MULT : boolean := false;
HAS_LPC : boolean := true;
USE_LITEDRAM : boolean := false; USE_LITEDRAM : boolean := false;
NO_BRAM : boolean := false; NO_BRAM : boolean := false;
DISABLE_FLATTEN_CORE : boolean := false; DISABLE_FLATTEN_CORE : boolean := false;
@ -60,6 +61,10 @@ entity toplevel is
-- GPIO -- GPIO
shield_io : inout std_ulogic_vector(44 downto 0); shield_io : inout std_ulogic_vector(44 downto 0);


-- LPC
pmod_jb : inout std_ulogic_vector(10 downto 1);
pmod_jc : inout std_ulogic_vector(10 downto 1);

-- Ethernet -- Ethernet
eth_ref_clk : out std_ulogic; eth_ref_clk : out std_ulogic;
eth_clocks_tx : in std_ulogic; eth_clocks_tx : in std_ulogic;
@ -163,9 +168,17 @@ architecture behaviour of toplevel is
signal gpio_out : 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); signal gpio_dir : std_ulogic_vector(NGPIO - 1 downto 0);


-- ddram clock signals as vectors -- LPC
signal ddram_clk_p_vec : std_logic_vector(0 downto 0); signal lpc_data_o : std_ulogic_vector(3 downto 0);
signal ddram_clk_n_vec : std_logic_vector(0 downto 0); signal lpc_data_o_reg : std_ulogic_vector(3 downto 0);
signal lpc_data_oe : std_ulogic;
signal lpc_data_i : std_ulogic_vector(3 downto 0);
signal lpc_irq_o : std_ulogic;
signal lpc_irq_oe : std_ulogic;
signal lpc_irq_i : std_ulogic;
signal lpc_frame_n : std_ulogic;
signal lpc_reset_n : std_ulogic;
signal lpc_clock : std_ulogic;


-- Fixup various memory sizes based on generics -- Fixup various memory sizes based on generics
function get_bram_size return natural is function get_bram_size return natural is
@ -200,6 +213,7 @@ begin
HAS_FPU => HAS_FPU, HAS_FPU => HAS_FPU,
HAS_BTC => HAS_BTC, HAS_BTC => HAS_BTC,
HAS_SHORT_MULT => HAS_SHORT_MULT, HAS_SHORT_MULT => HAS_SHORT_MULT,
HAS_LPC => HAS_LPC,
HAS_DRAM => USE_LITEDRAM, HAS_DRAM => USE_LITEDRAM,
DRAM_SIZE => 256 * 1024 * 1024, DRAM_SIZE => 256 * 1024 * 1024,
DRAM_INIT_SIZE => PAYLOAD_SIZE, DRAM_INIT_SIZE => PAYLOAD_SIZE,
@ -242,6 +256,17 @@ begin
gpio_out => gpio_out, gpio_out => gpio_out,
gpio_dir => gpio_dir, gpio_dir => gpio_dir,


-- LPC
lpc_data_o => lpc_data_o,
lpc_data_oe => lpc_data_oe,
lpc_data_i => lpc_data_i,
lpc_frame_n => lpc_frame_n,
lpc_reset_n => lpc_reset_n,
lpc_clock => lpc_clock,
lpc_irq_o => lpc_irq_o,
lpc_irq_oe => lpc_irq_oe,
lpc_irq_i => lpc_irq_i,

-- External interrupts -- External interrupts
ext_irq_eth => ext_irq_eth, ext_irq_eth => ext_irq_eth,
ext_irq_sdcard => ext_irq_sdcard, ext_irq_sdcard => ext_irq_sdcard,
@ -267,6 +292,35 @@ begin


--uart_pmod_rts_n <= '0'; --uart_pmod_rts_n <= '0';


-- LPC inout/bidir pins (assignments requested by paulus)
lpc_clock <= pmod_jb(1);
pmod_jb(2) <= '0';

lpc_data_i(0) <= pmod_jc(1);
lpc_data_i(1) <= pmod_jc(3);
lpc_data_i(2) <= pmod_jc(7);
lpc_data_i(3) <= pmod_jc(9);
lpc_data_o_reg <= lpc_data_o;

pmod_jc(1) <= lpc_data_o_reg(0) when lpc_data_oe = '1' and ext_rst_n = '1' else 'Z';
pmod_jc(2) <= '0';
pmod_jc(3) <= lpc_data_o_reg(1) when lpc_data_oe = '1' and ext_rst_n = '1' else 'Z';
pmod_jc(4) <= '0';
pmod_jc(7) <= lpc_data_o_reg(2) when lpc_data_oe = '1' and ext_rst_n = '1' else 'Z';
pmod_jc(8) <= '0';
pmod_jc(9) <= lpc_data_o_reg(3) when lpc_data_oe = '1' and ext_rst_n = '1' else 'Z';
pmod_jc(10) <= '0';

lpc_reset_n <= pmod_jb(3);
pmod_jb(4) <= 'Z'; -- actually comes out on 40-pin connector
lpc_frame_n <= pmod_jb(7);
pmod_jb(7) <= 'Z';
pmod_jb(8) <= 'Z'; -- actually comes out on 40-pin connector
pmod_jb(9) <= lpc_irq_o when lpc_irq_oe = '1' and ext_rst_n = '1' else 'Z';
lpc_irq_i <= pmod_jb(9);
pmod_jb(10) <= lpc_data_oe;


-- SPI Flash -- SPI Flash
-- --
-- Note: Unlike many other boards, the SPI flash on the Arty has -- Note: Unlike many other boards, the SPI flash on the Arty has
@ -386,15 +440,11 @@ begin
end if; end if;
end process; end process;


ddram_clk_p_vec <= (others => ddram_clk_p);
ddram_clk_n_vec <= (others => ddram_clk_n);

dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 24, DRAM_ABITS => 24,
DRAM_ALINES => 14, DRAM_ALINES => 14,
DRAM_DLINES => 16, DRAM_DLINES => 16,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 128, DRAM_PORT_WIDTH => 128,
PAYLOAD_FILE => RAM_INIT_FILE, PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE PAYLOAD_SIZE => PAYLOAD_SIZE
@ -427,8 +477,8 @@ begin
ddram_dq => ddram_dq, ddram_dq => ddram_dq,
ddram_dqs_p => ddram_dqs_p, ddram_dqs_p => ddram_dqs_p,
ddram_dqs_n => ddram_dqs_n, ddram_dqs_n => ddram_dqs_n,
ddram_clk_p => ddram_clk_p_vec, ddram_clk_p => ddram_clk_p,
ddram_clk_n => ddram_clk_n_vec, ddram_clk_n => ddram_clk_n,
ddram_cke => ddram_cke, ddram_cke => ddram_cke,
ddram_odt => ddram_odt, ddram_odt => ddram_odt,
ddram_reset_n => ddram_reset_n ddram_reset_n => ddram_reset_n
@ -707,8 +757,8 @@ begin
gpio_in(3) <= shield_io(3); gpio_in(3) <= shield_io(3);
gpio_in(4) <= shield_io(4); gpio_in(4) <= shield_io(4);
gpio_in(5) <= shield_io(5); gpio_in(5) <= shield_io(5);
gpio_in(6) <= shield_io(6); gpio_in(6) <= shield_io(6); -- actually comes out on JB4
gpio_in(7) <= shield_io(7); gpio_in(7) <= shield_io(7); -- actually comes out on JB8
gpio_in(8) <= shield_io(8); gpio_in(8) <= shield_io(8);
gpio_in(9) <= shield_io(9); gpio_in(9) <= shield_io(9);
gpio_in(10) <= shield_io(10); gpio_in(10) <= shield_io(10);

@ -17,7 +17,8 @@ entity toplevel is
ICACHE_NUM_LINES : natural := 64; ICACHE_NUM_LINES : natural := 64;
LOG_LENGTH : natural := 512; LOG_LENGTH : natural := 512;
DISABLE_FLATTEN_CORE : boolean := false; DISABLE_FLATTEN_CORE : boolean := false;
UART_IS_16550 : boolean := true UART_IS_16550 : boolean := true;
HAS_LPC : boolean := true
); );
port( port(
ext_clk : in std_ulogic; ext_clk : in std_ulogic;
@ -25,7 +26,19 @@ entity toplevel is


-- UART0 signals: -- UART0 signals:
uart0_txd : out std_ulogic; uart0_txd : out std_ulogic;
uart0_rxd : in std_ulogic uart0_rxd : in std_ulogic;

-- LPC
lpc_clock : in std_ulogic;

lpc_frame_n : in std_ulogic;
lpc_reset_n : in std_ulogic;
lpc_data_i : in std_ulogic_vector(3 downto 0);
lpc_irq_i : in std_ulogic;

lpc_data_oe : out std_ulogic;
lpc_data_o_reg : out std_ulogic_vector(3 downto 0);
lpc_irq_o2 : out std_ulogic
); );
end entity toplevel; end entity toplevel;


@ -39,6 +52,11 @@ architecture behaviour of toplevel is
signal system_clk : std_ulogic; signal system_clk : std_ulogic;
signal system_clk_locked : std_ulogic; signal system_clk_locked : std_ulogic;


-- LPC
signal lpc_data_i_reg : std_ulogic_vector(3 downto 0);
signal lpc_data_o : std_ulogic_vector(3 downto 0);
signal lpc_irq_o : std_ulogic;
signal lpc_irq_oe : std_ulogic;
begin begin


reset_controller: entity work.soc_reset reset_controller: entity work.soc_reset
@ -79,13 +97,35 @@ begin
ICACHE_NUM_LINES => ICACHE_NUM_LINES, ICACHE_NUM_LINES => ICACHE_NUM_LINES,
LOG_LENGTH => LOG_LENGTH, LOG_LENGTH => LOG_LENGTH,
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE, DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
UART0_IS_16550 => UART_IS_16550 UART0_IS_16550 => UART_IS_16550,
HAS_LPC => HAS_LPC
) )
port map ( port map (
system_clk => system_clk, system_clk => system_clk,
rst => soc_rst, rst => soc_rst,
uart0_txd => uart0_txd, uart0_txd => uart0_txd,
uart0_rxd => uart0_rxd uart0_rxd => uart0_rxd,

-- LPC
lpc_data_o => lpc_data_o,
lpc_data_oe => lpc_data_oe,
lpc_data_i => lpc_data_i,
lpc_frame_n => lpc_frame_n,
lpc_reset_n => lpc_reset_n,
lpc_clock => lpc_clock,
lpc_irq_o => lpc_irq_o,
lpc_irq_oe => lpc_irq_oe,
lpc_irq_i => lpc_irq_i
); );


process(lpc_clock)
begin
if rising_edge(lpc_clock) then
lpc_data_i_reg <= lpc_data_i;
lpc_data_o_reg <= lpc_data_o when lpc_data_oe = '1' and ext_rst = '1' else "ZZZZ";
end if;
end process;

lpc_irq_o2 <= lpc_irq_o when lpc_irq_oe = '1' and ext_rst = '1' else 'Z';

end architecture behaviour; end architecture behaviour;

@ -97,10 +97,6 @@ architecture behaviour of toplevel is
signal spi_sdat_oe : 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 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 -- Fixup various memory sizes based on generics
function get_bram_size return natural is function get_bram_size return natural is
begin begin
@ -274,15 +270,11 @@ begin
rst_out => open rst_out => open
); );


ddram_clk_p_vec <= (others => ddram_clk_p);
ddram_clk_n_vec <= (others => ddram_clk_n);

dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 25, DRAM_ABITS => 25,
DRAM_ALINES => 15, DRAM_ALINES => 15,
DRAM_DLINES => 32, DRAM_DLINES => 32,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 256, DRAM_PORT_WIDTH => 256,
PAYLOAD_FILE => RAM_INIT_FILE, PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE PAYLOAD_SIZE => PAYLOAD_SIZE
@ -315,8 +307,8 @@ begin
ddram_dq => ddram_dq, ddram_dq => ddram_dq,
ddram_dqs_p => ddram_dqs_p, ddram_dqs_p => ddram_dqs_p,
ddram_dqs_n => ddram_dqs_n, ddram_dqs_n => ddram_dqs_n,
ddram_clk_p => ddram_clk_p_vec, ddram_clk_p => ddram_clk_p,
ddram_clk_n => ddram_clk_n_vec, ddram_clk_n => ddram_clk_n,
ddram_cke => ddram_cke, ddram_cke => ddram_cke,
ddram_odt => ddram_odt, ddram_odt => ddram_odt,
ddram_reset_n => ddram_reset_n ddram_reset_n => ddram_reset_n

@ -139,10 +139,6 @@ architecture behaviour of toplevel is
signal spi_sdat_oe : 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 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 -- Fixup various memory sizes based on generics
function get_bram_size return natural is function get_bram_size return natural is
begin begin
@ -334,15 +330,11 @@ begin
end if; end if;
end process; end process;


ddram_clk_p_vec <= (others => ddram_clk_p);
ddram_clk_n_vec <= (others => ddram_clk_n);

dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 25, DRAM_ABITS => 25,
DRAM_ALINES => 15, DRAM_ALINES => 15,
DRAM_DLINES => 16, DRAM_DLINES => 16,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 128, DRAM_PORT_WIDTH => 128,
PAYLOAD_FILE => RAM_INIT_FILE, PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE PAYLOAD_SIZE => PAYLOAD_SIZE
@ -375,8 +367,8 @@ begin
ddram_dq => ddram_dq, ddram_dq => ddram_dq,
ddram_dqs_p => ddram_dqs_p, ddram_dqs_p => ddram_dqs_p,
ddram_dqs_n => ddram_dqs_n, ddram_dqs_n => ddram_dqs_n,
ddram_clk_p => ddram_clk_p_vec, ddram_clk_p => ddram_clk_p,
ddram_clk_n => ddram_clk_n_vec, ddram_clk_n => ddram_clk_n,
ddram_cke => ddram_cke, ddram_cke => ddram_cke,
ddram_odt => ddram_odt, ddram_odt => ddram_odt,
ddram_reset_n => ddram_reset_n ddram_reset_n => ddram_reset_n

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

@ -139,10 +139,6 @@ architecture behaviour of toplevel is
signal spi_sdat_oe : 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 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 -- Fixup various memory sizes based on generics
function get_bram_size return natural is function get_bram_size return natural is
begin begin
@ -335,15 +331,11 @@ begin
end if; end if;
end process; end process;


ddram_clk_p_vec <= (others => ddram_clk_p);
ddram_clk_n_vec <= (others => ddram_clk_n);

dram: entity work.litedram_wrapper dram: entity work.litedram_wrapper
generic map( generic map(
DRAM_ABITS => 24, DRAM_ABITS => 24,
DRAM_ALINES => 14, DRAM_ALINES => 14,
DRAM_DLINES => 16, DRAM_DLINES => 16,
DRAM_CKLINES => 1,
DRAM_PORT_WIDTH => 128, DRAM_PORT_WIDTH => 128,
PAYLOAD_FILE => RAM_INIT_FILE, PAYLOAD_FILE => RAM_INIT_FILE,
PAYLOAD_SIZE => PAYLOAD_SIZE PAYLOAD_SIZE => PAYLOAD_SIZE
@ -376,8 +368,8 @@ begin
ddram_dq => ddram_dq, ddram_dq => ddram_dq,
ddram_dqs_p => ddram_dqs_p, ddram_dqs_p => ddram_dqs_p,
ddram_dqs_n => ddram_dqs_n, ddram_dqs_n => ddram_dqs_n,
ddram_clk_p => ddram_clk_p_vec, ddram_clk_p => ddram_clk_p,
ddram_clk_n => ddram_clk_n_vec, ddram_clk_n => ddram_clk_n,
ddram_cke => ddram_cke, ddram_cke => ddram_cke,
ddram_odt => ddram_odt, ddram_odt => ddram_odt,
ddram_reset_n => ddram_reset_n ddram_reset_n => ddram_reset_n

@ -16,7 +16,7 @@ entity fpu is
clk : in std_ulogic; clk : in std_ulogic;
rst : in std_ulogic; rst : in std_ulogic;


e_in : in Execute1ToFPUType; e_in : in Execute1toFPUType;
e_out : out FPUToExecute1Type; e_out : out FPUToExecute1Type;


w_out : out FPUToWritebackType w_out : out FPUToWritebackType
@ -197,7 +197,7 @@ architecture behaviour of fpu is
-- Each output value is the inverse of the center of the input -- Each output value is the inverse of the center of the input
-- range for the value, i.e. entry 0 is 1 / (1 + 1/512), -- range for the value, i.e. entry 0 is 1 / (1 + 1/512),
-- entry 1 is 1 / (1 + 3/512), etc. -- entry 1 is 1 / (1 + 3/512), etc.
constant inverse_table : lookup_table := ( signal inverse_table : lookup_table := (
-- 1/x lookup table -- 1/x lookup table
-- Unit bit is assumed to be 1, so input range is [1, 2) -- Unit bit is assumed to be 1, so input range is [1, 2)
18x"3fc01", 18x"3f411", 18x"3ec31", 18x"3e460", 18x"3dc9f", 18x"3d4ec", 18x"3cd49", 18x"3c5b5", 18x"3fc01", 18x"3f411", 18x"3ec31", 18x"3e460", 18x"3dc9f", 18x"3d4ec", 18x"3cd49", 18x"3c5b5",
@ -549,10 +549,6 @@ begin
r.do_intr <= '0'; r.do_intr <= '0';
r.fpscr <= (others => '0'); r.fpscr <= (others => '0');
r.writing_back <= '0'; r.writing_back <= '0';
r.dest_fpr <= (others =>'0');
r.cr_mask <= (others =>'0');
r.cr_result <= (others =>'0');
r.instr_tag.valid <= '0';
else else
assert not (r.state /= IDLE and e_in.valid = '1') severity failure; assert not (r.state /= IDLE and e_in.valid = '1') severity failure;
r <= rin; r <= rin;

@ -40,8 +40,8 @@ architecture behaviour of gpio is
constant GPIO_REG_DATA_CLR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00101"; constant GPIO_REG_DATA_CLR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00101";


-- Current output value and direction -- Current output value and direction
signal reg_data : std_ulogic_vector(NGPIO - 1 downto 0); signal reg_data : std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0');
signal reg_dirn : std_ulogic_vector(NGPIO - 1 downto 0); signal reg_dirn : std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0');
signal reg_in1 : 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 reg_in2 : std_ulogic_vector(NGPIO - 1 downto 0);



@ -60,25 +60,11 @@ _start:


.global boot_entry .global boot_entry
boot_entry: boot_entry:
LOAD_IMM64(%r10,__bss_start)
LOAD_IMM64(%r11,__bss_end)
subf %r11,%r10,%r11
addi %r11,%r11,63
srdi. %r11,%r11,6
beq 2f
mtctr %r11
1: dcbz 0,%r10
addi %r10,%r10,64
bdnz 1b

/* setup stack */ /* setup stack */
2: LOAD_IMM64(%r1,__stack_top) LOAD_IMM64(%r1, STACK_TOP - 0x100)
li %r0,0
stdu %r0,-32(%r1)
LOAD_IMM64(%r12, main) LOAD_IMM64(%r12, main)
mtctr %r12 mtctr %r12,
bctrl bctrl
attn // terminate on exit
b . b .


#define EXCEPTION(nr) \ #define EXCEPTION(nr) \

Binary file not shown.

Binary file not shown.

@ -35,24 +35,24 @@ a64b5a7d14004a39
a602487d05009f42 a602487d05009f42
a64b5a7d14004a39 a64b5a7d14004a39
2402004ca64b7b7d 2402004ca64b7b7d
3d40000048000004 3c20000048000004
794a07c6614a0000
614a1900654a0000
616b00003d600000
656b0000796b07c6
7d6a5850616b1980
796bd183396b003f
7d6903a641820014
394a00407c0057ec
3c2000004200fff8
782107c660210000 782107c660210000
6021398064210000 60211f0064210000
f801ffe138000000 618c00003d800000
3d8000007c1243a6 658c0000798c07c6
798c07c6618c0000 7d8903a6618c1014
618c1000658c0000 480000004e800421
4e8004217d8903a6 0000000000000000
4800000000000200 0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
@ -510,150 +510,150 @@ f801ffe138000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
384298003c400001 e8010010ebc1fff0
fbe1fff87c0802a6 7c0803a6ebe1fff8
f821ffd1f8010010 3c4000014e800020
60000000480001ed 7c0802a638429800
3862800060000000 f8010010fbe1fff8
6000000048000155 480001edf821ffd1
6000000048000049 6000000060000000
5463063e7c7f1b78 4800015538628000
480000b957ff063e 4800004960000000
2c1f000d60000000 7c7f1b7860000000
3860000a4082ffe0 57ff063e5463063e
60000000480000a5 60000000480000b9
4082ffe02c1f000d
480000a53860000a
4bffffd060000000
0100000000000000
3c40000100000180
6000000038429800
6000000089228090
2c09000039428088
e92a000041820030
7c0004ac39290014
712900017d204eaa
e86a00004182ffec
7c601eaa7c0004ac
4e8000205463063e
39290010e92a0000
7d204eea7c0004ac
4082ffec71290001
38630008e86a0000
7c601eea7c0004ac
000000004bffffd0 000000004bffffd0
0000018001000000 0000000000000000
384298003c400001 384298003c400001
8922810860000000 8922809060000000
3942810060000000 3942808860000000
418200302c090000 4182002c2c090000
39290014e92a0000 39290014e92a0000
7d204eaa7c0004ac 7d204eaa7c0004ac
4182ffec71290001 4182ffec71290020
7c0004ace86a0000 7c0004ace92a0000
5463063e7c601eaa 4e8000207c604faa
e92a00004e800020 39290010e92a0000
7c0004ac39290010 7d204eea7c0004ac
712900017d204eea 4082ffec71290008
e86a00004082ffec e94a00005469063e
7c0004ac38630008 7d2057ea7c0004ac
4bffffd07c601eea 000000004e800020
0000000000000000
3c40000100000000
6000000038429800
6000000089228108
2c09000039428100
e92a00004182002c
7c0004ac39290014
712900207d204eaa
e92a00004182ffec
7c604faa7c0004ac
e92a00004e800020
7c0004ac39290010
712900087d204eea
5469063e4082ffec
7c0004ace94a0000
4e8000207d2057ea
0000000000000000 0000000000000000
3c40000100000000 384298003c400001
7c0802a638429800 fbe1fff87c0802a6
fbc1fff0fbe1fff8 3be3fffffbc1fff0
f80100103be3ffff f821ffd1f8010010
8fdf0001f821ffd1 2c3e00008fdf0001
408200102c3e0000 3821003040820010
3860000038210030 4bfffe4438600000
281e000a480001e8 4082000c281e000a
3860000d4082000c 4bffff453860000d
7fc3f3784bffff45 4bffff3d7fc3f378
4bffffd04bffff3d 000000004bffffd0
0100000000000000 0000028001000000
7c691b7800000280 386000007c691b78
7d4918ae38600000 2c0a00007d4918ae
4d8200202c0a0000 386300014d820020
4bfffff038630001 000000004bfffff0
0000000000000000 0000000000000000
3c40000100000000 384298003c400001
3d40c00038429800 614a00203d40c000
794a0020614a0020 7c0004ac794a0020
7d4056ea7c0004ac 3d20c0007d4056ea
794a06003d20c000 61290008794a0600
7929002061290008
7d204eea7c0004ac
4182001871290020
612900403d20c000
7c0004ac79290020 7c0004ac79290020
7929f8047d204eea 712900207d204eea
79290fc33d00c000 3d20c00041820018
7908002061082000 7929002061290040
f902810060000000 7d204eea7c0004ac
610820003d00001c 3d00c0007929f804
418200847d4a4392 6108200079290fc3
3920000160000000 6000000079080020
3d00c00099228108 3d00001cf9028088
3920ff806108200c 7d4a439261082000
7c0004ac79080020 6000000041820084
e92281007d2047aa 9922809039200001
7d404faa7c0004ac 6108200c3d00c000
794ac202e9228100 790800203920ff80
7c0004ac39290004 7d2047aa7c0004ac
e92281007d404faa 7c0004ace9228088
3929000c39400003 e92280887d404faa
39290004794ac202
7d404faa7c0004ac 7d404faa7c0004ac
39290010e9228100 39400003e9228088
7c0004ac3929000c
e92280887d404faa
7c0004ac39290010
e92280887d404faa
3929000839400007
7d404faa7c0004ac 7d404faa7c0004ac
39400007e9228100 600000004e800020
7c0004ac39290008 99228090394affff
4e8000207d404faa 612920183d20c000
394affff60000000 7c0004ac79290020
3d20c00099228108 4e8000207d404fea
7929002061292018
7d404fea7c0004ac
000000004e800020
0000000000000000 0000000000000000
384298003c400001 3c40000100000000
8922810860000000 6000000038429800
600000002c090000 2c24000089228090
41820024e9228100 600000002f890000
78840e282c230000 419e0030e9228088
6084000141820008 3940000241820024
7c0004ac39290004 418200082c230000
4e8000207c804faa 39290004614a0001
418200082c240000 7d404faa7c0004ac
394000004e800020
418200084bffffe0
3929002060630002 3929002060630002
7c604fea7c0004ac 7c604fea7c0004ac
000000004e800020 000000004e800020
0000000000000000 0000000000000000
e8010010ebc1fff0 0000000000000010
7c0803a6ebe1fff8 0141780400527a01
000000104e800020 0000001800010c1b
00527a0100000000 fffffc4800000018
00010c1b01417804 300e460000000070
0000001800000018 000000019f7e4111
00000070fffffc40 0000000000000010
9f7e4111300e4600 0141780400527a01
0000001000000001 0000001000010c1b
00527a0100000000 fffffc8800000018
00010c1b01417804 0000000000000084
0000001800000010 0000002c00000010
00000084fffffc80 00000080fffffcf8
0000001000000000 0000002800000000
fffffcf00000002c fffffd6400000040
0000000000000080 4109450000000060
0000004000000028 300e43029e019f00
00000060fffffd5c 42000e0a447e4111
9e019f0041094500 0000000b4106dedf
447e4111300e4302 0000006c00000010
4106dedf42000e0a 00000028fffffd98
000000100000000b
fffffd900000006c
0000000000000028
0000008000000010
0000012cfffffda4
0000001000000000 0000001000000000
fffffebc00000094 fffffdac00000080
0000000000000068 000000000000012c
0000000000000000 0000009400000010
00000074fffffec4
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000

@ -1,27 +1,13 @@
SECTIONS SECTIONS
{ {
. = 0;
_start = .; _start = .;
. = 0;
.head : { .head : {
KEEP(*(.head)) KEEP(*(.head))
} }
. = 0x1000; . = 0x1000;
.text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) } .text : { *(.text) }
. = 0x1800; . = 0x1800;
.data : { *(.data) *(.data.*) *(.got) *(.toc) } .data : { *(.data) }
. = ALIGN(0x80); .bss : { *(.bss) }
__bss_start = .;
.bss : {
*(.dynsbss)
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(.common)
*(.bss.*)
}
. = ALIGN(0x80);
__bss_end = .;
. = . + 0x2000;
__stack_top = .;
} }

@ -28,9 +28,7 @@ package helpers is


function bit_reverse(a: std_ulogic_vector) return std_ulogic_vector; function bit_reverse(a: std_ulogic_vector) return std_ulogic_vector;
function bit_number(a: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; function bit_number(a: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
function edgelocation(v: std_ulogic_vector; nbits: natural) return std_ulogic_vector;
function count_left_zeroes(val: std_ulogic_vector) return std_ulogic_vector; function count_left_zeroes(val: std_ulogic_vector) return std_ulogic_vector;
function count_right_zeroes(val: std_ulogic_vector) return std_ulogic_vector;
end package helpers; end package helpers;


package body helpers is package body helpers is
@ -249,50 +247,16 @@ package body helpers is
return ret; return ret;
end; end;


-- Assuming the input 'v' is a value of the form 1...10...0, -- Count leading zeroes operation
-- the output is the bit number of the rightmost 1 bit in v.
-- If v is zero, the result is zero.
function edgelocation(v: std_ulogic_vector; nbits: natural) return std_ulogic_vector is
variable p: std_ulogic_vector(nbits - 1 downto 0);
variable stride: natural;
variable b: std_ulogic;
variable k: natural;
begin
stride := 2;
for i in 0 to nbits - 1 loop
b := '0';
for j in 0 to (2**nbits / stride) - 1 loop
k := j * stride;
b := b or (v(k + stride - 1) and not v(k + (stride/2) - 1));
end loop;
p(i) := b;
stride := stride * 2;
end loop;
return p;
end function;

-- Count leading zeroes operations
-- Assumes the value passed in is not zero (if it is, zero is returned) -- Assumes the value passed in is not zero (if it is, zero is returned)
function count_right_zeroes(val: std_ulogic_vector) return std_ulogic_vector is
variable sum: std_ulogic_vector(val'left downto val'right);
variable onehot: std_ulogic_vector(val'left downto val'right);
variable edge: std_ulogic_vector(val'left downto val'right);
variable bn, bn_e, bn_o: std_ulogic_vector(5 downto 0);
begin
sum := std_ulogic_vector(- signed(val));
onehot := sum and val;
edge := sum or val;
bn_e := edgelocation(std_ulogic_vector(resize(signed(edge), 64)), 6);
bn_o := bit_number(std_ulogic_vector(resize(unsigned(onehot), 64)));
bn := bn_e(5 downto 2) & bn_o(1 downto 0);
return bn;
end;

function count_left_zeroes(val: std_ulogic_vector) return std_ulogic_vector is function count_left_zeroes(val: std_ulogic_vector) return std_ulogic_vector is
variable rev: std_ulogic_vector(val'left downto val'right); variable rev: std_ulogic_vector(val'left downto val'right);
variable sum: std_ulogic_vector(val'left downto val'right);
variable onehot: std_ulogic_vector(val'left downto val'right);
begin begin
rev := bit_reverse(val); rev := bit_reverse(val);
return count_right_zeroes(rev); sum := std_ulogic_vector(- signed(rev));
onehot := sum and rev;
return bit_number(std_ulogic_vector(resize(unsigned(onehot), 64)));
end; end;

end package body helpers; end package body helpers;

@ -212,6 +212,7 @@ architecture rtl of icache is
signal ra_valid : std_ulogic; signal ra_valid : std_ulogic;
signal priv_fault : std_ulogic; signal priv_fault : std_ulogic;
signal access_ok : std_ulogic; signal access_ok : std_ulogic;
signal use_previous : std_ulogic;


-- Cache RAM interface -- Cache RAM interface
type cache_ram_out_t is array(way_t) of cache_row_t; type cache_ram_out_t is array(way_t) of cache_row_t;
@ -396,7 +397,7 @@ begin
wr_dat(ii * 8 + 7 downto ii * 8) <= wishbone_in.dat(j * 8 + 7 downto j * 8); wr_dat(ii * 8 + 7 downto ii * 8) <= wishbone_in.dat(j * 8 + 7 downto j * 8);
end loop; end loop;
end if; end if;
do_read <= not stall_in; do_read <= not (stall_in or use_previous);
do_write <= '0'; do_write <= '0';
if wishbone_in.ack = '1' and replace_way = i then if wishbone_in.ack = '1' and replace_way = i then
do_write <= '1'; do_write <= '1';
@ -502,6 +503,16 @@ begin
variable is_hit : std_ulogic; variable is_hit : std_ulogic;
variable hit_way : way_t; variable hit_way : way_t;
begin begin
-- i_in.sequential means that i_in.nia this cycle is 4 more than
-- last cycle. If we read more than 32 bits at a time, had a cache hit
-- last cycle, and we don't want the first 32-bit chunk, then we can
-- keep the data we read last cycle and just use that.
if unsigned(i_in.nia(INSN_BITS+2-1 downto 2)) /= 0 then
use_previous <= i_in.req and i_in.sequential and r.hit_valid;
else
use_previous <= '0';
end if;

-- Extract line, row and tag from request -- Extract line, row and tag from request
req_index <= get_index(i_in.nia); req_index <= get_index(i_in.nia);
req_row <= get_row(i_in.nia); req_row <= get_row(i_in.nia);
@ -531,7 +542,7 @@ begin
end loop; end loop;


-- Generate the "hit" and "miss" signals for the synchronous blocks -- Generate the "hit" and "miss" signals for the synchronous blocks
if i_in.req = '1' and access_ok = '1' and flush_in = '0' and rst = '0' then if i_in.req = '1' and access_ok = '1' and flush_in = '0' and rst = '0' and use_previous = '0' then
req_is_hit <= is_hit; req_is_hit <= is_hit;
req_is_miss <= not is_hit; req_is_miss <= not is_hit;
else else
@ -555,11 +566,7 @@ begin
-- I prefer not to do just yet as it would force fetch2 to know about -- I prefer not to do just yet as it would force fetch2 to know about
-- some of the cache geometry information. -- some of the cache geometry information.
-- --
if r.hit_valid = '1' then
i_out.insn <= read_insn_word(r.hit_nia, cache_out(r.hit_way)); i_out.insn <= read_insn_word(r.hit_nia, cache_out(r.hit_way));
else
i_out.insn <= (others => '0');
end if;
i_out.valid <= r.hit_valid; i_out.valid <= r.hit_valid;
i_out.nia <= r.hit_nia; i_out.nia <= r.hit_nia;
i_out.stop_mark <= r.hit_smark; i_out.stop_mark <= r.hit_smark;
@ -569,7 +576,7 @@ begin
i_out.next_pred_ntaken <= i_in.pred_ntaken; i_out.next_pred_ntaken <= i_in.pred_ntaken;


-- Stall fetch1 if we have a miss on cache or TLB or a protection fault -- Stall fetch1 if we have a miss on cache or TLB or a protection fault
stall_out <= not (is_hit and access_ok); stall_out <= not (is_hit and access_ok) and not use_previous;


-- Wishbone requests output (from the cache miss reload machine) -- Wishbone requests output (from the cache miss reload machine)
wishbone_out <= r.wb; wishbone_out <= r.wb;
@ -581,7 +588,8 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
-- keep outputs to fetch2 unchanged on a stall -- keep outputs to fetch2 unchanged on a stall
-- except that flush or reset sets valid to 0 -- except that flush or reset sets valid to 0
if stall_in = '1' then -- If use_previous, keep the same data as last cycle and use the second half
if stall_in = '1' or use_previous = '1' then
if rst = '1' or flush_in = '1' then if rst = '1' or flush_in = '1' then
r.hit_valid <= '0'; r.hit_valid <= '0';
end if; end if;
@ -824,7 +832,4 @@ begin
end process; end process;
log_out <= log_data; log_out <= log_data;
end generate; end generate;

events <= ev;

end; end;

@ -74,9 +74,6 @@ begin
i_out.req <= '0'; i_out.req <= '0';
i_out.nia <= (others => '0'); i_out.nia <= (others => '0');
i_out.stop_mark <= '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.tlbld <= '0';
m_out.tlbie <= '0'; m_out.tlbie <= '0';

@ -13,7 +13,6 @@ entity litedram_wrapper is
DRAM_ABITS : positive; DRAM_ABITS : positive;
DRAM_ALINES : natural; DRAM_ALINES : natural;
DRAM_DLINES : natural; DRAM_DLINES : natural;
DRAM_CKLINES : natural;
DRAM_PORT_WIDTH : positive; DRAM_PORT_WIDTH : positive;


-- Pseudo-ROM payload -- Pseudo-ROM payload
@ -70,8 +69,8 @@ entity litedram_wrapper is
ddram_dq : inout std_ulogic_vector(DRAM_DLINES-1 downto 0); ddram_dq : inout std_ulogic_vector(DRAM_DLINES-1 downto 0);
ddram_dqs_p : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0); ddram_dqs_p : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0); ddram_dqs_n : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0);
ddram_clk_p : out std_ulogic_vector(DRAM_CKLINES-1 downto 0); ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic_vector(DRAM_CKLINES-1 downto 0); ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic; ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic; ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic ddram_reset_n : out std_ulogic
@ -94,8 +93,8 @@ architecture behaviour of litedram_wrapper is
ddram_dq : inout std_ulogic_vector(DRAM_DLINES-1 downto 0); ddram_dq : inout std_ulogic_vector(DRAM_DLINES-1 downto 0);
ddram_dqs_p : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0); ddram_dqs_p : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0);
ddram_dqs_n : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0); ddram_dqs_n : inout std_ulogic_vector(DRAM_DLINES/8-1 downto 0);
ddram_clk_p : out std_ulogic_vector(DRAM_CKLINES-1 downto 0); ddram_clk_p : out std_ulogic;
ddram_clk_n : out std_ulogic_vector(DRAM_CKLINES-1 downto 0); ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic; ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic; ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic; ddram_reset_n : out std_ulogic;

@ -102,8 +102,8 @@ entity litedram_core is
ddram_dq : inout std_ulogic_vector(15 downto 0); ddram_dq : inout std_ulogic_vector(15 downto 0);
ddram_dqs_p : inout std_ulogic_vector(1 downto 0); ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
ddram_dqs_n : 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_p : out std_ulogic;
ddram_clk_n : out std_ulogic_vector(0 downto 0); ddram_clk_n : out std_ulogic;
ddram_cke : out std_ulogic; ddram_cke : out std_ulogic;
ddram_odt : out std_ulogic; ddram_odt : out std_ulogic;
ddram_reset_n : out std_ulogic; ddram_reset_n : out std_ulogic;

@ -31,7 +31,6 @@
"user_ports": { "user_ports": {
"native_0": { "native_0": {
"type": "native", "type": "native",
"block_until_ready": False,
}, },
}, },
} }

@ -31,7 +31,6 @@
"user_ports": { "user_ports": {
"native_0": { "native_0": {
"type": "native", "type": "native",
"block_until_ready": False,
}, },
}, },
} }

@ -100,7 +100,7 @@ def generate_one(t):


def main(): def main():


targets = ['arty','nexys-video', 'genesys2', 'acorn-cle-215', 'wukong-v2', 'orangecrab-85-0.2', 'sim'] targets = ['arty','nexys-video', 'genesys2', 'acorn-cle-215', 'wukong-v2', 'sim']
for t in targets: for t in targets:
generate_one(t) generate_one(t)

@ -31,7 +31,6 @@
"user_ports": { "user_ports": {
"native_0": { "native_0": {
"type": "native", "type": "native",
"block_until_ready": False,
}, },
}, },
} }

@ -31,7 +31,6 @@
"user_ports": { "user_ports": {
"native_0": { "native_0": {
"type": "native", "type": "native",
"block_until_ready": False,
}, },
}, },
} }

@ -1,39 +0,0 @@
# Matt Johnston 2021
# Based on parameters from Greg Davill's Orangecrab-test-sw

{
"cpu": "None", # CPU type (ex vexriscv, serv, None)
"device": "LFE5U-85F-8MG285C",
"memtype": "DDR3", # DRAM type

"sdram_module": "MT41K256M16", # SDRAM modules of the board or SO-DIMM
"sdram_module_nb": 2, # Number of byte groups
"sdram_rank_nb": 1, # Number of ranks
"sdram_phy": "ECP5DDRPHY", # Type of FPGA PHY

# Electrical ---------------------------------------------------------------
"rtt_nom": "disabled", # Nominal termination. ("disabled" from orangecrab)
"rtt_wr": "60ohm", # Write termination. (Default)
"ron": "34ohm", # Output driver impedance. (Default)

# Frequency ----------------------------------------------------------------
"init_clk_freq": 24e6,
"input_clk_freq": 48e6, # Input clock frequency
"sys_clk_freq": 48e6, # System clock frequency (DDR_clk = 4 x sys_clk)

# 0 if freq >64e6 else 100. https://github.com/enjoy-digital/litedram/issues/130
"cmd_delay": 100,

# Core ---------------------------------------------------------------------
"cmd_buffer_depth": 16, # Depth of the command buffer

"dm_swap": true,

# User Ports ---------------------------------------------------------------
"user_ports": {
"native_0": {
"type": "native",
"block_until_ready": False,
},
},
}

@ -32,7 +32,6 @@ CPPFLAGS += -I$(LXSRC_DIR) -I$(LXINC_DIR) -I$(LXINC_DIR)/base -I$(LXSRC_DIR)/lib


CPPFLAGS += -isystem $(shell $(CC) -print-file-name=include) CPPFLAGS += -isystem $(shell $(CC) -print-file-name=include)
CFLAGS = -Os -g -Wall -std=c99 -m64 -mabi=elfv2 -msoft-float -mno-string -mno-multiple -mno-vsx -mno-altivec -mlittle-endian -fno-stack-protector -mstrict-align -ffreestanding -fdata-sections -ffunction-sections -fno-delete-null-pointer-checks CFLAGS = -Os -g -Wall -std=c99 -m64 -mabi=elfv2 -msoft-float -mno-string -mno-multiple -mno-vsx -mno-altivec -mlittle-endian -fno-stack-protector -mstrict-align -ffreestanding -fdata-sections -ffunction-sections -fno-delete-null-pointer-checks
CFLAGS += -Werror
ASFLAGS = $(CPPFLAGS) $(CFLAGS) ASFLAGS = $(CPPFLAGS) $(CFLAGS)
LDFLAGS = -static -nostdlib -T $(OBJ)/$(PROGRAM).lds --gc-sections LDFLAGS = -static -nostdlib -T $(OBJ)/$(PROGRAM).lds --gc-sections



@ -31,7 +31,6 @@
"user_ports": { "user_ports": {
"native_0": { "native_0": {
"type": "native", "type": "native",
"block_until_ready": False,
}, },
}, },
} }

@ -31,7 +31,6 @@
"user_ports": { "user_ports": {
"native_0": { "native_0": {
"type": "native", "type": "native",
"block_until_ready": False,
}, },
}, },
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

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

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -100,7 +100,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
oack <= '0'; oack <= '0';
if (wb_in.cyc and wb_in.stb) = '1' then if (wb_in.cyc and wb_in.stb) = '1' then
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0)))); adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS-1 downto 2))));
if wb_in.we = '0' then if wb_in.we = '0' then
obuf <= init_ram(adr); obuf <= init_ram(adr);
else else

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash


# vendor:sysclk VENDORS="xilinx"
VENDORS="xilinx:100 lattice:48"


ME=$(realpath $0) ME=$(realpath $0)
echo ME=$ME echo ME=$ME
@ -14,10 +13,8 @@ mkdir -p $BUILD_PATH
GEN_PATH=$PARENT_PATH/generated GEN_PATH=$PARENT_PATH/generated
mkdir -p $GEN_PATH mkdir -p $GEN_PATH


for i_clk in $VENDORS for i in $VENDORS
do do
i=$(echo $i_clk | cut -d : -f 1)
clk=$(echo $i_clk | cut -d : -f 2)
TARGET_BUILD_PATH=$BUILD_PATH/$i TARGET_BUILD_PATH=$BUILD_PATH/$i
TARGET_GEN_PATH=$GEN_PATH/$i TARGET_GEN_PATH=$GEN_PATH/$i
rm -rf $TARGET_BUILD_PATH rm -rf $TARGET_BUILD_PATH
@ -26,7 +23,7 @@ do
mkdir -p $TARGET_GEN_PATH mkdir -p $TARGET_GEN_PATH


echo "Generating $i in $TARGET_BUILD_PATH" echo "Generating $i in $TARGET_BUILD_PATH"
(cd $TARGET_BUILD_PATH && litesdcard_gen --vendor $i --clk-freq $clk) (cd $TARGET_BUILD_PATH && litesdcard_gen --vendor $i)


cp $TARGET_BUILD_PATH/build/gateware/litesdcard_core.v $TARGET_GEN_PATH/ cp $TARGET_BUILD_PATH/build/gateware/litesdcard_core.v $TARGET_GEN_PATH/
done done

File diff suppressed because it is too large Load Diff

@ -1,23 +1,7 @@
// ----------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-Generated by: __ _ __ _ __ // Auto-generated by Migen (35203d6) & LiteX (79ac0931) on 2021-08-10 08:40:47
// / / (_) /____ | |/_/ //--------------------------------------------------------------------------------
// / /__/ / __/ -_)> < module litesdcard_core(
// /____/_/\__/\__/_/|_|
// Build your hardware, easily!
// https://github.com/enjoy-digital/litex
//
// Filename : litesdcard_core.v
// Device :
// LiteX sha1 : --------
// Date : 2022-01-14 07:30:19
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// Module
//------------------------------------------------------------------------------

module litesdcard_core (
input wire clk, input wire clk,
input wire rst, input wire rst,
input wire [29:0] wb_ctrl_adr, input wire [29:0] wb_ctrl_adr,
@ -49,11 +33,6 @@ module litesdcard_core (
output wire irq output wire irq
); );



//------------------------------------------------------------------------------
// Signals
//------------------------------------------------------------------------------

wire sys_clk; wire sys_clk;
wire sys_rst; wire sys_rst;
wire por_clk; wire por_clk;
@ -163,7 +142,7 @@ reg cmdr_source_ready = 1'd0;
reg cmdr_source_last = 1'd0; reg cmdr_source_last = 1'd0;
reg [7:0] cmdr_source_payload_data = 8'd0; reg [7:0] cmdr_source_payload_data = 8'd0;
reg [2:0] cmdr_source_payload_status = 3'd0; reg [2:0] cmdr_source_payload_status = 3'd0;
reg [31:0] cmdr_timeout = 32'd100; reg [31:0] cmdr_timeout = 32'd100000000;
reg [7:0] cmdr_count = 8'd0; reg [7:0] cmdr_count = 8'd0;
reg cmdr_busy = 1'd0; reg cmdr_busy = 1'd0;
wire cmdr_cmdr_pads_in_valid; wire cmdr_cmdr_pads_in_valid;
@ -327,7 +306,7 @@ reg datar_source_last = 1'd0;
reg [7:0] datar_source_payload_data = 8'd0; reg [7:0] datar_source_payload_data = 8'd0;
reg [2:0] datar_source_payload_status = 3'd0; reg [2:0] datar_source_payload_status = 3'd0;
reg datar_stop = 1'd0; reg datar_stop = 1'd0;
reg [31:0] datar_timeout = 32'd100; reg [31:0] datar_timeout = 32'd100000000;
reg [9:0] datar_count = 10'd0; reg [9:0] datar_count = 10'd0;
wire datar_datar_pads_in_valid; wire datar_datar_pads_in_valid;
reg datar_datar_pads_in_ready = 1'd0; reg datar_datar_pads_in_ready = 1'd0;
@ -1131,10 +1110,6 @@ wire sdrio_clk_13;
wire sdrio_clk_14; wire sdrio_clk_14;
wire sdrio_clk_15; wire sdrio_clk_15;


//------------------------------------------------------------------------------
// Combinatorial Logic
//------------------------------------------------------------------------------

assign wb_ctrl_adr_1 = wb_ctrl_adr; assign wb_ctrl_adr_1 = wb_ctrl_adr;
assign wb_ctrl_dat_w_1 = wb_ctrl_dat_w; assign wb_ctrl_dat_w_1 = wb_ctrl_dat_w;
assign wb_ctrl_dat_r = wb_ctrl_dat_r_1; assign wb_ctrl_dat_r = wb_ctrl_dat_r_1;
@ -1436,7 +1411,7 @@ always @(*) begin
cmdr_sink_ready <= 1'd1; cmdr_sink_ready <= 1'd1;
if ((cmdr_sink_payload_cmd_type == 2'd3)) begin if ((cmdr_sink_payload_cmd_type == 2'd3)) begin
cmdr_source_valid <= 1'd0; cmdr_source_valid <= 1'd0;
cmdr_timeout_sdphycmdr_next_value0 <= 7'd100; cmdr_timeout_sdphycmdr_next_value0 <= 27'd100000000;
cmdr_timeout_sdphycmdr_next_value_ce0 <= 1'd1; cmdr_timeout_sdphycmdr_next_value_ce0 <= 1'd1;
subfragments_sdphycmdr_next_state <= 2'd3; subfragments_sdphycmdr_next_state <= 2'd3;
end else begin end else begin
@ -1500,7 +1475,7 @@ always @(*) begin
end end
end end
default: begin default: begin
cmdr_timeout_sdphycmdr_next_value0 <= 7'd100; cmdr_timeout_sdphycmdr_next_value0 <= 27'd100000000;
cmdr_timeout_sdphycmdr_next_value_ce0 <= 1'd1; cmdr_timeout_sdphycmdr_next_value_ce0 <= 1'd1;
cmdr_count_sdphycmdr_next_value1 <= 1'd0; cmdr_count_sdphycmdr_next_value1 <= 1'd0;
cmdr_count_sdphycmdr_next_value_ce1 <= 1'd1; cmdr_count_sdphycmdr_next_value_ce1 <= 1'd1;
@ -1787,7 +1762,7 @@ always @(*) begin
datar_count_sdphydatar_next_value_ce0 <= 1'd1; datar_count_sdphydatar_next_value_ce0 <= 1'd1;
if ((datar_sink_valid & datar_pads_out_ready)) begin if ((datar_sink_valid & datar_pads_out_ready)) begin
datar_pads_out_payload_clk <= 1'd1; datar_pads_out_payload_clk <= 1'd1;
datar_timeout_sdphydatar_next_value1 <= 32'd100; datar_timeout_sdphydatar_next_value1 <= 32'd100000000;
datar_timeout_sdphydatar_next_value_ce1 <= 1'd1; datar_timeout_sdphydatar_next_value_ce1 <= 1'd1;
datar_count_sdphydatar_next_value0 <= 1'd0; datar_count_sdphydatar_next_value0 <= 1'd0;
datar_count_sdphydatar_next_value_ce0 <= 1'd1; datar_count_sdphydatar_next_value_ce0 <= 1'd1;
@ -2287,11 +2262,11 @@ always @(*) begin
end end
assign sdblock2mem_start = (sdblock2mem_sink_sink_valid0 & sdblock2mem_sink_sink_first); assign sdblock2mem_start = (sdblock2mem_sink_sink_valid0 & sdblock2mem_sink_sink_first);
always @(*) begin always @(*) begin
sdblock2mem_fifo_sink_first <= 1'd0;
sdblock2mem_fifo_sink_last <= 1'd0; sdblock2mem_fifo_sink_last <= 1'd0;
sdblock2mem_sink_sink_ready0 <= 1'd0; sdblock2mem_sink_sink_ready0 <= 1'd0;
sdblock2mem_fifo_sink_payload_data <= 8'd0; sdblock2mem_fifo_sink_payload_data <= 8'd0;
sdblock2mem_fifo_sink_valid <= 1'd0; sdblock2mem_fifo_sink_valid <= 1'd0;
sdblock2mem_fifo_sink_first <= 1'd0;
if ((sdblock2mem_wishbonedmawriter_enable_storage & (sdblock2mem_start | sdblock2mem_connect))) begin if ((sdblock2mem_wishbonedmawriter_enable_storage & (sdblock2mem_start | sdblock2mem_connect))) begin
sdblock2mem_fifo_sink_valid <= sdblock2mem_sink_sink_valid0; sdblock2mem_fifo_sink_valid <= sdblock2mem_sink_sink_valid0;
sdblock2mem_sink_sink_ready0 <= sdblock2mem_fifo_sink_ready; sdblock2mem_sink_sink_ready0 <= sdblock2mem_fifo_sink_ready;
@ -2467,13 +2442,13 @@ always @(*) begin
endcase endcase
end end
always @(*) begin always @(*) begin
subfragments_sdmem2blockdma_resetinserter_next_state <= 2'd0;
sdmem2block_dma_sink_last <= 1'd0; sdmem2block_dma_sink_last <= 1'd0;
sdmem2block_dma_offset_sdmem2blockdma_resetinserter_next_value <= 32'd0; sdmem2block_dma_offset_sdmem2blockdma_resetinserter_next_value <= 32'd0;
sdmem2block_dma_sink_payload_address <= 32'd0; sdmem2block_dma_sink_payload_address <= 32'd0;
sdmem2block_dma_offset_sdmem2blockdma_resetinserter_next_value_ce <= 1'd0; sdmem2block_dma_offset_sdmem2blockdma_resetinserter_next_value_ce <= 1'd0;
sdmem2block_dma_sink_valid <= 1'd0;
sdmem2block_dma_done_status <= 1'd0; sdmem2block_dma_done_status <= 1'd0;
sdmem2block_dma_sink_valid <= 1'd0;
subfragments_sdmem2blockdma_resetinserter_next_state <= 2'd0;
subfragments_sdmem2blockdma_resetinserter_next_state <= subfragments_sdmem2blockdma_resetinserter_state; subfragments_sdmem2blockdma_resetinserter_next_state <= subfragments_sdmem2blockdma_resetinserter_state;
case (subfragments_sdmem2blockdma_resetinserter_state) case (subfragments_sdmem2blockdma_resetinserter_state)
1'd1: begin 1'd1: begin
@ -2605,8 +2580,8 @@ always @(*) begin
litesdcardcore_next_state <= 1'd0; litesdcardcore_next_state <= 1'd0;
litesdcardcore_litesdcardcore_adr <= 14'd0; litesdcardcore_litesdcardcore_adr <= 14'd0;
litesdcardcore_litesdcardcore_we <= 1'd0; litesdcardcore_litesdcardcore_we <= 1'd0;
litesdcardcore_litesdcardcore_wishbone_ack <= 1'd0;
litesdcardcore_litesdcardcore_dat_w <= 32'd0; litesdcardcore_litesdcardcore_dat_w <= 32'd0;
litesdcardcore_litesdcardcore_wishbone_ack <= 1'd0;
litesdcardcore_next_state <= litesdcardcore_state; litesdcardcore_next_state <= litesdcardcore_state;
case (litesdcardcore_state) case (litesdcardcore_state)
1'd1: begin 1'd1: begin
@ -2663,8 +2638,8 @@ assign litesdcardcore_shared_err = wb_dma_err_1;
assign litesdcardcore_wait = ((litesdcardcore_shared_stb & litesdcardcore_shared_cyc) & (~litesdcardcore_shared_ack)); assign litesdcardcore_wait = ((litesdcardcore_shared_stb & litesdcardcore_shared_cyc) & (~litesdcardcore_shared_ack));
always @(*) begin always @(*) begin
litesdcardcore_error <= 1'd0; litesdcardcore_error <= 1'd0;
litesdcardcore_shared_ack <= 1'd0;
litesdcardcore_shared_dat_r <= 32'd0; litesdcardcore_shared_dat_r <= 32'd0;
litesdcardcore_shared_ack <= 1'd0;
litesdcardcore_shared_ack <= wb_dma_ack_1; litesdcardcore_shared_ack <= wb_dma_ack_1;
litesdcardcore_shared_dat_r <= ({32{litesdcardcore_slave_sel_r}} & wb_dma_dat_r_1); litesdcardcore_shared_dat_r <= ({32{litesdcardcore_slave_sel_r}} & wb_dma_dat_r_1);
if (litesdcardcore_done) begin if (litesdcardcore_done) begin
@ -2686,8 +2661,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank0_scratch0_r = litesdcardcore_interface0_bank_bus_dat_w[31:0]; assign litesdcardcore_csrbank0_scratch0_r = litesdcardcore_interface0_bank_bus_dat_w[31:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank0_scratch0_we <= 1'd0;
litesdcardcore_csrbank0_scratch0_re <= 1'd0; litesdcardcore_csrbank0_scratch0_re <= 1'd0;
litesdcardcore_csrbank0_scratch0_we <= 1'd0;
if ((litesdcardcore_csrbank0_sel & (litesdcardcore_interface0_bank_bus_adr[8:0] == 1'd1))) begin if ((litesdcardcore_csrbank0_sel & (litesdcardcore_interface0_bank_bus_adr[8:0] == 1'd1))) begin
litesdcardcore_csrbank0_scratch0_re <= litesdcardcore_interface0_bank_bus_we; litesdcardcore_csrbank0_scratch0_re <= litesdcardcore_interface0_bank_bus_we;
litesdcardcore_csrbank0_scratch0_we <= (~litesdcardcore_interface0_bank_bus_we); litesdcardcore_csrbank0_scratch0_we <= (~litesdcardcore_interface0_bank_bus_we);
@ -2725,8 +2700,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank1_dma_base0_r = litesdcardcore_interface1_bank_bus_dat_w[31:0]; assign litesdcardcore_csrbank1_dma_base0_r = litesdcardcore_interface1_bank_bus_dat_w[31:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank1_dma_base0_re <= 1'd0;
litesdcardcore_csrbank1_dma_base0_we <= 1'd0; litesdcardcore_csrbank1_dma_base0_we <= 1'd0;
litesdcardcore_csrbank1_dma_base0_re <= 1'd0;
if ((litesdcardcore_csrbank1_sel & (litesdcardcore_interface1_bank_bus_adr[8:0] == 1'd1))) begin if ((litesdcardcore_csrbank1_sel & (litesdcardcore_interface1_bank_bus_adr[8:0] == 1'd1))) begin
litesdcardcore_csrbank1_dma_base0_re <= litesdcardcore_interface1_bank_bus_we; litesdcardcore_csrbank1_dma_base0_re <= litesdcardcore_interface1_bank_bus_we;
litesdcardcore_csrbank1_dma_base0_we <= (~litesdcardcore_interface1_bank_bus_we); litesdcardcore_csrbank1_dma_base0_we <= (~litesdcardcore_interface1_bank_bus_we);
@ -2789,8 +2764,8 @@ assign sdblock2mem_wishbonedmawriter_offset_we = litesdcardcore_csrbank1_dma_off
assign litesdcardcore_csrbank2_sel = (litesdcardcore_interface2_bank_bus_adr[13:9] == 2'd2); assign litesdcardcore_csrbank2_sel = (litesdcardcore_interface2_bank_bus_adr[13:9] == 2'd2);
assign litesdcardcore_csrbank2_cmd_argument0_r = litesdcardcore_interface2_bank_bus_dat_w[31:0]; assign litesdcardcore_csrbank2_cmd_argument0_r = litesdcardcore_interface2_bank_bus_dat_w[31:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank2_cmd_argument0_re <= 1'd0;
litesdcardcore_csrbank2_cmd_argument0_we <= 1'd0; litesdcardcore_csrbank2_cmd_argument0_we <= 1'd0;
litesdcardcore_csrbank2_cmd_argument0_re <= 1'd0;
if ((litesdcardcore_csrbank2_sel & (litesdcardcore_interface2_bank_bus_adr[8:0] == 1'd0))) begin if ((litesdcardcore_csrbank2_sel & (litesdcardcore_interface2_bank_bus_adr[8:0] == 1'd0))) begin
litesdcardcore_csrbank2_cmd_argument0_re <= litesdcardcore_interface2_bank_bus_we; litesdcardcore_csrbank2_cmd_argument0_re <= litesdcardcore_interface2_bank_bus_we;
litesdcardcore_csrbank2_cmd_argument0_we <= (~litesdcardcore_interface2_bank_bus_we); litesdcardcore_csrbank2_cmd_argument0_we <= (~litesdcardcore_interface2_bank_bus_we);
@ -2879,8 +2854,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank2_block_count0_r = litesdcardcore_interface2_bank_bus_dat_w[31:0]; assign litesdcardcore_csrbank2_block_count0_r = litesdcardcore_interface2_bank_bus_dat_w[31:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank2_block_count0_re <= 1'd0;
litesdcardcore_csrbank2_block_count0_we <= 1'd0; litesdcardcore_csrbank2_block_count0_we <= 1'd0;
litesdcardcore_csrbank2_block_count0_re <= 1'd0;
if ((litesdcardcore_csrbank2_sel & (litesdcardcore_interface2_bank_bus_adr[8:0] == 4'd10))) begin if ((litesdcardcore_csrbank2_sel & (litesdcardcore_interface2_bank_bus_adr[8:0] == 4'd10))) begin
litesdcardcore_csrbank2_block_count0_re <= litesdcardcore_interface2_bank_bus_we; litesdcardcore_csrbank2_block_count0_re <= litesdcardcore_interface2_bank_bus_we;
litesdcardcore_csrbank2_block_count0_we <= (~litesdcardcore_interface2_bank_bus_we); litesdcardcore_csrbank2_block_count0_we <= (~litesdcardcore_interface2_bank_bus_we);
@ -2938,8 +2913,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank3_enable0_r = litesdcardcore_interface3_bank_bus_dat_w[3:0]; assign litesdcardcore_csrbank3_enable0_r = litesdcardcore_interface3_bank_bus_dat_w[3:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank3_enable0_we <= 1'd0;
litesdcardcore_csrbank3_enable0_re <= 1'd0; litesdcardcore_csrbank3_enable0_re <= 1'd0;
litesdcardcore_csrbank3_enable0_we <= 1'd0;
if ((litesdcardcore_csrbank3_sel & (litesdcardcore_interface3_bank_bus_adr[8:0] == 2'd2))) begin if ((litesdcardcore_csrbank3_sel & (litesdcardcore_interface3_bank_bus_adr[8:0] == 2'd2))) begin
litesdcardcore_csrbank3_enable0_re <= litesdcardcore_interface3_bank_bus_we; litesdcardcore_csrbank3_enable0_re <= litesdcardcore_interface3_bank_bus_we;
litesdcardcore_csrbank3_enable0_we <= (~litesdcardcore_interface3_bank_bus_we); litesdcardcore_csrbank3_enable0_we <= (~litesdcardcore_interface3_bank_bus_we);
@ -2998,8 +2973,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank4_dma_enable0_r = litesdcardcore_interface4_bank_bus_dat_w[0]; assign litesdcardcore_csrbank4_dma_enable0_r = litesdcardcore_interface4_bank_bus_dat_w[0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank4_dma_enable0_we <= 1'd0;
litesdcardcore_csrbank4_dma_enable0_re <= 1'd0; litesdcardcore_csrbank4_dma_enable0_re <= 1'd0;
litesdcardcore_csrbank4_dma_enable0_we <= 1'd0;
if ((litesdcardcore_csrbank4_sel & (litesdcardcore_interface4_bank_bus_adr[8:0] == 2'd3))) begin if ((litesdcardcore_csrbank4_sel & (litesdcardcore_interface4_bank_bus_adr[8:0] == 2'd3))) begin
litesdcardcore_csrbank4_dma_enable0_re <= litesdcardcore_interface4_bank_bus_we; litesdcardcore_csrbank4_dma_enable0_re <= litesdcardcore_interface4_bank_bus_we;
litesdcardcore_csrbank4_dma_enable0_we <= (~litesdcardcore_interface4_bank_bus_we); litesdcardcore_csrbank4_dma_enable0_we <= (~litesdcardcore_interface4_bank_bus_we);
@ -3025,8 +3000,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank4_dma_offset_r = litesdcardcore_interface4_bank_bus_dat_w[31:0]; assign litesdcardcore_csrbank4_dma_offset_r = litesdcardcore_interface4_bank_bus_dat_w[31:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank4_dma_offset_we <= 1'd0;
litesdcardcore_csrbank4_dma_offset_re <= 1'd0; litesdcardcore_csrbank4_dma_offset_re <= 1'd0;
litesdcardcore_csrbank4_dma_offset_we <= 1'd0;
if ((litesdcardcore_csrbank4_sel & (litesdcardcore_interface4_bank_bus_adr[8:0] == 3'd6))) begin if ((litesdcardcore_csrbank4_sel & (litesdcardcore_interface4_bank_bus_adr[8:0] == 3'd6))) begin
litesdcardcore_csrbank4_dma_offset_re <= litesdcardcore_interface4_bank_bus_we; litesdcardcore_csrbank4_dma_offset_re <= litesdcardcore_interface4_bank_bus_we;
litesdcardcore_csrbank4_dma_offset_we <= (~litesdcardcore_interface4_bank_bus_we); litesdcardcore_csrbank4_dma_offset_we <= (~litesdcardcore_interface4_bank_bus_we);
@ -3053,8 +3028,8 @@ always @(*) begin
end end
assign litesdcardcore_csrbank5_clocker_divider0_r = litesdcardcore_interface5_bank_bus_dat_w[8:0]; assign litesdcardcore_csrbank5_clocker_divider0_r = litesdcardcore_interface5_bank_bus_dat_w[8:0];
always @(*) begin always @(*) begin
litesdcardcore_csrbank5_clocker_divider0_re <= 1'd0;
litesdcardcore_csrbank5_clocker_divider0_we <= 1'd0; litesdcardcore_csrbank5_clocker_divider0_we <= 1'd0;
litesdcardcore_csrbank5_clocker_divider0_re <= 1'd0;
if ((litesdcardcore_csrbank5_sel & (litesdcardcore_interface5_bank_bus_adr[8:0] == 1'd1))) begin if ((litesdcardcore_csrbank5_sel & (litesdcardcore_interface5_bank_bus_adr[8:0] == 1'd1))) begin
litesdcardcore_csrbank5_clocker_divider0_re <= litesdcardcore_interface5_bank_bus_we; litesdcardcore_csrbank5_clocker_divider0_re <= litesdcardcore_interface5_bank_bus_we;
litesdcardcore_csrbank5_clocker_divider0_we <= (~litesdcardcore_interface5_bank_bus_we); litesdcardcore_csrbank5_clocker_divider0_we <= (~litesdcardcore_interface5_bank_bus_we);
@ -3217,11 +3192,6 @@ assign sdrio_clk_13 = sys_clk;
assign sdrio_clk_14 = sys_clk; assign sdrio_clk_14 = sys_clk;
assign sdrio_clk_15 = sys_clk; assign sdrio_clk_15 = sys_clk;



//------------------------------------------------------------------------------
// Synchronous Logic
//------------------------------------------------------------------------------

always @(posedge por_clk) begin always @(posedge por_clk) begin
int_rst <= rst; int_rst <= rst;
end end
@ -4011,7 +3981,7 @@ always @(posedge sys_clk) begin
clocker_ce_delayed <= 1'd0; clocker_ce_delayed <= 1'd0;
init_count <= 8'd0; init_count <= 8'd0;
cmdw_count <= 8'd0; cmdw_count <= 8'd0;
cmdr_timeout <= 32'd100; cmdr_timeout <= 32'd100000000;
cmdr_count <= 8'd0; cmdr_count <= 8'd0;
cmdr_busy <= 1'd0; cmdr_busy <= 1'd0;
cmdr_cmdr_run <= 1'd0; cmdr_cmdr_run <= 1'd0;
@ -4034,7 +4004,7 @@ always @(posedge sys_clk) begin
dataw_crc_converter_strobe_all <= 1'd0; dataw_crc_converter_strobe_all <= 1'd0;
dataw_crc_buf_source_valid <= 1'd0; dataw_crc_buf_source_valid <= 1'd0;
dataw_crc_buf_source_payload_data <= 8'd0; dataw_crc_buf_source_payload_data <= 8'd0;
datar_timeout <= 32'd100; datar_timeout <= 32'd100000000;
datar_count <= 10'd0; datar_count <= 10'd0;
datar_datar_run <= 1'd0; datar_datar_run <= 1'd0;
datar_datar_converter_source_payload_data <= 8'd0; datar_datar_converter_source_payload_data <= 8'd0;
@ -4146,70 +4116,53 @@ always @(posedge sys_clk) begin
end end
end end



//------------------------------------------------------------------------------
// Specialized Logic
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Memory storage: 8-words x 10-bit
//------------------------------------------------------------------------------
// Port 0 | Read: Sync | Write: Sync | Mode: Read-First | Write-Granularity: 10
// Port 1 | Read: Async | Write: ---- |
reg [9:0] storage[0:7]; reg [9:0] storage[0:7];
reg [9:0] storage_dat0; reg [9:0] memdat;
always @(posedge sys_clk) begin always @(posedge sys_clk) begin
if (sdcore_fifo_wrport_we) if (sdcore_fifo_wrport_we)
storage[sdcore_fifo_wrport_adr] <= sdcore_fifo_wrport_dat_w; storage[sdcore_fifo_wrport_adr] <= sdcore_fifo_wrport_dat_w;
storage_dat0 <= storage[sdcore_fifo_wrport_adr]; memdat <= storage[sdcore_fifo_wrport_adr];
end end

always @(posedge sys_clk) begin always @(posedge sys_clk) begin
end end
assign sdcore_fifo_wrport_dat_r = storage_dat0;
assign sdcore_fifo_rdport_dat_r = storage[sdcore_fifo_rdport_adr];


assign sdcore_fifo_wrport_dat_r = memdat;
assign sdcore_fifo_rdport_dat_r = storage[sdcore_fifo_rdport_adr];


//------------------------------------------------------------------------------
// Memory storage_1: 512-words x 10-bit
//------------------------------------------------------------------------------
// Port 0 | Read: Sync | Write: Sync | Mode: Read-First | Write-Granularity: 10
// Port 1 | Read: Sync | Write: ---- |
reg [9:0] storage_1[0:511]; reg [9:0] storage_1[0:511];
reg [9:0] storage_1_dat0; reg [9:0] memdat_1;
reg [9:0] storage_1_dat1; reg [9:0] memdat_2;
always @(posedge sys_clk) begin always @(posedge sys_clk) begin
if (sdblock2mem_fifo_wrport_we) if (sdblock2mem_fifo_wrport_we)
storage_1[sdblock2mem_fifo_wrport_adr] <= sdblock2mem_fifo_wrport_dat_w; storage_1[sdblock2mem_fifo_wrport_adr] <= sdblock2mem_fifo_wrport_dat_w;
storage_1_dat0 <= storage_1[sdblock2mem_fifo_wrport_adr]; memdat_1 <= storage_1[sdblock2mem_fifo_wrport_adr];
end end

always @(posedge sys_clk) begin always @(posedge sys_clk) begin
if (sdblock2mem_fifo_rdport_re) if (sdblock2mem_fifo_rdport_re)
storage_1_dat1 <= storage_1[sdblock2mem_fifo_rdport_adr]; memdat_2 <= storage_1[sdblock2mem_fifo_rdport_adr];
end end
assign sdblock2mem_fifo_wrport_dat_r = storage_1_dat0;
assign sdblock2mem_fifo_rdport_dat_r = storage_1_dat1;


assign sdblock2mem_fifo_wrport_dat_r = memdat_1;
assign sdblock2mem_fifo_rdport_dat_r = memdat_2;


//------------------------------------------------------------------------------
// Memory storage_2: 512-words x 10-bit
//------------------------------------------------------------------------------
// Port 0 | Read: Sync | Write: Sync | Mode: Read-First | Write-Granularity: 10
// Port 1 | Read: Sync | Write: ---- |
reg [9:0] storage_2[0:511]; reg [9:0] storage_2[0:511];
reg [9:0] storage_2_dat0; reg [9:0] memdat_3;
reg [9:0] storage_2_dat1; reg [9:0] memdat_4;
always @(posedge sys_clk) begin always @(posedge sys_clk) begin
if (sdmem2block_fifo_wrport_we) if (sdmem2block_fifo_wrport_we)
storage_2[sdmem2block_fifo_wrport_adr] <= sdmem2block_fifo_wrport_dat_w; storage_2[sdmem2block_fifo_wrport_adr] <= sdmem2block_fifo_wrport_dat_w;
storage_2_dat0 <= storage_2[sdmem2block_fifo_wrport_adr]; memdat_3 <= storage_2[sdmem2block_fifo_wrport_adr];
end end

always @(posedge sys_clk) begin always @(posedge sys_clk) begin
if (sdmem2block_fifo_rdport_re) if (sdmem2block_fifo_rdport_re)
storage_2_dat1 <= storage_2[sdmem2block_fifo_rdport_adr]; memdat_4 <= storage_2[sdmem2block_fifo_rdport_adr];
end end
assign sdmem2block_fifo_wrport_dat_r = storage_2_dat0;
assign sdmem2block_fifo_rdport_dat_r = storage_2_dat1;


assign sdmem2block_fifo_wrport_dat_r = memdat_3;
assign sdmem2block_fifo_rdport_dat_r = memdat_4;


IOBUF IOBUF( IOBUF IOBUF(
.I(xilinxsdrtristateimpl0__o), .I(xilinxsdrtristateimpl0__o),
@ -4247,7 +4200,3 @@ IOBUF IOBUF_4(
); );


endmodule endmodule

// -----------------------------------------------------------------------------
// Auto-Generated by LiteX on 2022-01-14 07:30:20.
//------------------------------------------------------------------------------

@ -275,27 +275,10 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if rst = '1' then
r1.req.valid <= '0'; r1.req.valid <= '0';
r1.req.tlbie <= '0';
r1.req.is_slbia <= '0';
r1.req.instr_fault <= '0';
r1.req.load <= '0';
r1.req.priv_mode <= '0';
r1.req.sprn <= (others => '0');
r1.req.xerc <= xerc_init;

r2.req.valid <= '0'; r2.req.valid <= '0';
r2.req.tlbie <= '0';
r2.req.is_slbia <= '0';
r2.req.instr_fault <= '0';
r2.req.load <= '0';
r2.req.priv_mode <= '0';
r2.req.sprn <= (others => '0');
r2.req.xerc <= xerc_init;

r2.wait_dc <= '0'; r2.wait_dc <= '0';
r2.wait_mmu <= '0'; r2.wait_mmu <= '0';
r2.one_cycle <= '0'; r2.one_cycle <= '0';

r3.dar <= (others => '0'); r3.dar <= (others => '0');
r3.dsisr <= (others => '0'); r3.dsisr <= (others => '0');
r3.state <= IDLE; r3.state <= IDLE;
@ -303,8 +286,6 @@ begin
r3.interrupt <= '0'; r3.interrupt <= '0';
r3.stage1_en <= '1'; r3.stage1_en <= '1';
r3.convert_lfs <= '0'; r3.convert_lfs <= '0';
r3.events.load_complete <= '0';
r3.events.store_complete <= '0';
flushing <= '0'; flushing <= '0';
else else
r1 <= r1in; r1 <= r1in;

@ -20,7 +20,20 @@ end entity logical;


architecture behaviour of logical is architecture behaviour of logical is


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;
subtype sixbit is unsigned(5 downto 0);
type sixbit2 is array(0 to 1) of sixbit;
signal pc32 : sixbit2;
signal par0, par1 : std_ulogic; signal par0, par1 : std_ulogic;
signal popcnt : std_ulogic_vector(63 downto 0);
signal parity : std_ulogic_vector(63 downto 0); signal parity : std_ulogic_vector(63 downto 0);
signal permute : std_ulogic_vector(7 downto 0); signal permute : std_ulogic_vector(7 downto 0);


@ -96,6 +109,35 @@ begin
variable negative : std_ulogic; variable negative : std_ulogic;
variable j : integer; variable j : integer;
begin begin
-- population counts
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;
for i in 0 to 1 loop
pc32(i) <= ("00" & pc8(i * 4)) + ("00" & pc8(i * 4 + 1)) +
("00" & pc8(i * 4 + 2)) + ("00" & pc8(i * 4 + 3));
end loop;
popcnt <= (others => '0');
if datalen(3 downto 2) = "00" then
-- popcntb
for i in 0 to 7 loop
popcnt(i * 8 + 3 downto i * 8) <= std_ulogic_vector(pc8(i));
end loop;
elsif datalen(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;

-- parity calculations -- parity calculations
par0 <= rs(0) xor rs(8) xor rs(16) xor rs(24); par0 <= rs(0) xor rs(8) xor rs(16) xor rs(24);
par1 <= rs(32) xor rs(40) xor rs(48) xor rs(56); par1 <= rs(32) xor rs(40) xor rs(48) xor rs(56);
@ -136,6 +178,8 @@ begin
tmp := not tmp; tmp := not tmp;
end if; end if;


when OP_POPCNT =>
tmp := popcnt;
when OP_PRTY => when OP_PRTY =>
tmp := parity; tmp := parity;
when OP_CMPB => when OP_CMPB =>

13153
lpc/lpc.v

File diff suppressed because it is too large Load Diff

@ -18,7 +18,7 @@ filesets:
- ppc_fx_insns.vhdl - ppc_fx_insns.vhdl
- sim_console.vhdl - sim_console.vhdl
- logical.vhdl - logical.vhdl
- countbits.vhdl - countzero.vhdl
- control.vhdl - control.vhdl
- execute1.vhdl - execute1.vhdl
- fpu.vhdl - fpu.vhdl
@ -50,6 +50,7 @@ filesets:
- sync_fifo.vhdl - sync_fifo.vhdl
- spi_rxtx.vhdl - spi_rxtx.vhdl
- spi_flash_ctrl.vhdl - spi_flash_ctrl.vhdl
- lpc/lpc.v : {file_type : verilogSource}
file_type : vhdlSource-2008 file_type : vhdlSource-2008


fpga: fpga:
@ -339,6 +340,7 @@ targets:
- has_fpu - has_fpu
- has_btc - has_btc
- has_short_mult - has_short_mult
- has_lpc
generate: [litedram_arty, liteeth_arty, litesdcard_arty] generate: [litedram_arty, liteeth_arty, litesdcard_arty]
tools: tools:
vivado: {part : xc7a100ticsg324-1L} vivado: {part : xc7a100ticsg324-1L}
@ -504,6 +506,12 @@ parameters:
paramtype : generic paramtype : generic
default : false default : false


has_lpc:
datatype : bool
description : Include an LPC slave in the SOC
paramtype : generic
default : false

disable_flatten_core: disable_flatten_core:
datatype : bool datatype : bool
description : Prevent Vivado from flattening the main core components description : Prevent Vivado from flattening the main core components

@ -1,16 +1,10 @@
CFLAGS = -O2 -g -Wall -std=c99 CFLAGS = -O2 -g -Wall -std=c99
# CFLAGS += -I urjtag/urjtag/include/ -L urjtag/urjtag/src/.libs/ # CFLAGS += -I urjtag/urjtag/include/ -L urjtag/urjtag/src/.libs/
#
ifeq ($(STATIC_URJTAG), 1)
LIBURJTAG=-Wl,-Bstatic -lurjtag -Wl,-Bdynamic -lftdi1 -lusb-1.0 -lreadline
else
LIBURJTAG=-lurjtag
endif


all: mw_debug all: mw_debug


mw_debug: mw_debug.c mw_debug: mw_debug.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBURJTAG) $(CC) -o $@ $^ $(CFLAGS) -lurjtag


clean: clean:
rm -f mw_debug rm -f mw_debug

@ -49,7 +49,7 @@
static bool debug; static bool debug;


struct backend { struct backend {
int (*init)(const char *target, int freq); int (*init)(const char *target);
int (*reset)(void); int (*reset)(void);
int (*command)(uint8_t op, uint8_t addr, uint64_t *data); int (*command)(uint8_t op, uint8_t addr, uint64_t *data);
}; };
@ -67,15 +67,13 @@ static void check(int r, const char *failstr)


static int sim_fd = -1; static int sim_fd = -1;


static int sim_init(const char *target, int freq) static int sim_init(const char *target)
{ {
struct sockaddr_in saddr; struct sockaddr_in saddr;
struct hostent *hp; struct hostent *hp;
const char *p, *host; const char *p, *host;
int port, rc; int port, rc;


(void)freq;

if (!target) if (!target)
target = "localhost:13245"; target = "localhost:13245";
p = strchr(target, ':'); p = strchr(target, ':');
@ -212,34 +210,23 @@ static struct backend sim_backend = {


static urj_chain_t *jc; static urj_chain_t *jc;


static int common_jtag_init(const char *target, int freq) static int jtag_init(const char *target)
{ {
const char *sep; const char *sep;
const char *cable; const char *cable;
const int max_params = 20; char *params[] = { NULL, };
char *params[max_params+1]; urj_part_t *p;
int rc; uint32_t id;
int rc, part;


if (!target) if (!target)
target = "probe"; target = "probe";
memset(params, 0x0, sizeof(params)); sep = strchr(target, ':');
sep = strchr(target, ' ');
cable = strndup(target, sep - target); cable = strndup(target, sep - target);
if (sep && *sep) { if (sep && *sep) {
char *param_str = strdup(sep); fprintf(stderr, "jtag cable params not supported yet\n");
char *s = param_str;
for (int i = 0; *s; s++) {
if (*s == ' ') {
if (i >= max_params) {
fprintf(stderr, "Too many jtag cable params\n");
return -1; return -1;
} }
*s = '\0';
params[i] = s+1;
i++;
}
}
}
if (debug) if (debug)
printf("Opening jtag backend cable '%s'\n", cable); printf("Opening jtag backend cable '%s'\n", cable);


@ -254,35 +241,17 @@ static int common_jtag_init(const char *target, int freq)
char *cparams[] = { NULL, NULL,}; char *cparams[] = { NULL, NULL,};
rc = urj_tap_cable_usb_probe(cparams); rc = urj_tap_cable_usb_probe(cparams);
if (rc != URJ_STATUS_OK) { if (rc != URJ_STATUS_OK) {
fprintf(stderr, "JTAG cable probe failed: %s\n", urj_error_describe()); fprintf(stderr, "JTAG cable probe failed\n");
return -1; return -1;
} }
cable = strdup(cparams[1]); cable = strdup(cparams[1]);
} }
rc = urj_tap_chain_connect(jc, cable, params); rc = urj_tap_chain_connect(jc, cable, params);
if (rc != URJ_STATUS_OK) { if (rc != URJ_STATUS_OK) {
fprintf(stderr, "JTAG cable detect failed: %s\n", urj_error_describe()); fprintf(stderr, "JTAG cable detect failed\n");
return -1; return -1;
} }


if (freq) {
urj_tap_cable_set_frequency(jc->cable, freq);
}

return 0;
}

static int bscane2_init(const char *target, int freq)
{
urj_part_t *p;
uint32_t id;
int rc;

rc = common_jtag_init(target, freq);
if (rc < 0) {
return rc;
}

/* XXX Hard wire part 0, that might need to change (use params and detect !) */ /* XXX Hard wire part 0, that might need to change (use params and detect !) */
rc = urj_tap_manual_add(jc, 6); rc = urj_tap_manual_add(jc, 6);
if (rc < 0) { if (rc < 0) {
@ -295,7 +264,7 @@ static int bscane2_init(const char *target, int freq)
} }
urj_part_parts_set_instruction(jc->parts, "BYPASS"); urj_part_parts_set_instruction(jc->parts, "BYPASS");


jc->active_part = 0; jc->active_part = part = 0;


p = urj_tap_chain_active_part(jc); p = urj_tap_chain_active_part(jc);
if (!p) { if (!p) {
@ -331,69 +300,6 @@ static int bscane2_init(const char *target, int freq)
return 0; return 0;
} }


static int ecp5_init(const char *target, int freq)
{
urj_part_t *p;
uint32_t id;
int rc;

rc = common_jtag_init(target, freq);
if (rc < 0) {
return rc;
}

/* XXX Hard wire part 0, that might need to change (use params and detect !) */
rc = urj_tap_manual_add(jc, 8);
if (rc < 0) {
fprintf(stderr, "JTAG failed to add part! : %s\n", urj_error_describe());
return -1;
}
if (jc->parts == NULL || jc->parts->len == 0) {
fprintf(stderr, "JTAG Something's wrong after adding part! : %s\n", urj_error_describe());
return -1;
}
urj_part_parts_set_instruction(jc->parts, "BYPASS");

jc->active_part = 0;

p = urj_tap_chain_active_part(jc);
if (!p) {
fprintf(stderr, "Failed to get active JTAG part\n");
return -1;
}
rc = urj_part_data_register_define(p, "IDCODE_REG", 32);
if (rc != URJ_STATUS_OK) {
fprintf(stderr, "JTAG failed to add IDCODE_REG register! : %s\n",
urj_error_describe());
return -1;
}
// READ_ID = 0xE0 = 11100000, from Lattice TN1260 sysconfig guide
if (urj_part_instruction_define(p, "IDCODE", "11100000", "IDCODE_REG") == NULL) {
fprintf(stderr, "JTAG failed to add IDCODE instruction! : %s\n",
urj_error_describe());
return -1;
}
rc = urj_part_data_register_define(p, "USER2_REG", 74);
if (rc != URJ_STATUS_OK) {
fprintf(stderr, "JTAG failed to add USER2_REG register !\n");
return -1;
}
// ER1 = 0x32 = 00110010b
if (urj_part_instruction_define(p, "USER2", "00110010", "USER2_REG") == NULL) {
fprintf(stderr, "JTAG failed to add USER2 instruction !\n");
return -1;
}
urj_part_set_instruction(p, "IDCODE");
urj_tap_chain_shift_instructions(jc);
urj_tap_chain_shift_data_registers(jc, 1);
id = urj_tap_register_get_value(p->active_instruction->data_register->out);
printf("Found device ID: 0x%08x\n", id);
urj_part_set_instruction(p, "USER2");
urj_tap_chain_shift_instructions(jc);

return 0;
}

static int jtag_reset(void) static int jtag_reset(void)
{ {
return 0; return 0;
@ -433,14 +339,8 @@ static int jtag_command(uint8_t op, uint8_t addr, uint64_t *data)
return rc; return rc;
} }


static struct backend bscane2_backend = { static struct backend jtag_backend = {
.init = bscane2_init, .init = jtag_init,
.reset = jtag_reset,
.command = jtag_command,
};

static struct backend ecp5_backend = {
.init = ecp5_init,
.reset = jtag_reset, .reset = jtag_reset,
.command = jtag_command, .command = jtag_command,
}; };
@ -762,7 +662,7 @@ static void ltrig_set(uint64_t addr)


static void usage(const char *cmd) static void usage(const char *cmd)
{ {
fprintf(stderr, "Usage: %s -b <jtag|ecp5|sim> <command> <args>\n", cmd); fprintf(stderr, "Usage: %s -b <jtag|sim> <command> <args>\n", cmd);


fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, " CPU core:\n"); fprintf(stderr, " CPU core:\n");
@ -806,7 +706,7 @@ int main(int argc, char *argv[])
{ {
const char *progname = argv[0]; const char *progname = argv[0];
const char *target = NULL; const char *target = NULL;
int rc, i = 1, freq = 0; int rc, i = 1;


b = NULL; b = NULL;


@ -817,10 +717,9 @@ int main(int argc, char *argv[])
{ "backend", required_argument, 0, 'b' }, { "backend", required_argument, 0, 'b' },
{ "target", required_argument, 0, 't' }, { "target", required_argument, 0, 't' },
{ "debug", no_argument, 0, 'd' }, { "debug", no_argument, 0, 'd' },
{ "frequency", no_argument, 0, 's' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
c = getopt_long(argc, argv, "dhb:t:s:", lopts, &oindex); c = getopt_long(argc, argv, "dhb:t:", lopts, &oindex);
if (c < 0) if (c < 0)
break; break;
switch(c) { switch(c) {
@ -830,10 +729,8 @@ int main(int argc, char *argv[])
case 'b': case 'b':
if (strcmp(optarg, "sim") == 0) if (strcmp(optarg, "sim") == 0)
b = &sim_backend; b = &sim_backend;
else if (strcmp(optarg, "jtag") == 0 || strcmp(optarg, "bscane2") == 0) else if (strcmp(optarg, "jtag") == 0)
b = &bscane2_backend; b = &jtag_backend;
else if (strcmp(optarg, "ecp5") == 0)
b = &ecp5_backend;
else { else {
fprintf(stderr, "Unknown backend %s\n", optarg); fprintf(stderr, "Unknown backend %s\n", optarg);
exit(1); exit(1);
@ -842,22 +739,15 @@ int main(int argc, char *argv[])
case 't': case 't':
target = optarg; target = optarg;
break; break;
case 's':
freq = atoi(optarg);
if (freq == 0) {
fprintf(stderr, "Bad frequency %s\n", optarg);
exit(1);
}
break;
case 'd': case 'd':
debug = true; debug = true;
} }
} }


if (b == NULL) if (b == NULL)
b = &bscane2_backend; b = &jtag_backend;


rc = b->init(target, freq); rc = b->init(target);
if (rc < 0) if (rc < 0)
exit(1); exit(1);
for (i = optind; i < argc; i++) { for (i = optind; i < argc; i++) {
@ -899,7 +789,7 @@ int main(int argc, char *argv[])
if ((i+1) >= argc) if ((i+1) >= argc)
usage(argv[0]); usage(argv[0]);
addr = strtoul(argv[++i], NULL, 16); addr = strtoul(argv[++i], NULL, 16);
if (((i+1) < argc) && isxdigit(argv[i+1][0])) if (((i+1) < argc) && isdigit(argv[i+1][0]))
count = strtoul(argv[++i], NULL, 16); count = strtoul(argv[++i], NULL, 16);
mem_read(addr, count); mem_read(addr, count);
} else if (strcmp(argv[i], "mw") == 0) { } else if (strcmp(argv[i], "mw") == 0) {
@ -917,7 +807,7 @@ int main(int argc, char *argv[])
if ((i+1) >= argc) if ((i+1) >= argc)
usage(argv[0]); usage(argv[0]);
filename = argv[++i]; filename = argv[++i];
if (((i+1) < argc) && isxdigit(argv[i+1][0])) if (((i+1) < argc) && isdigit(argv[i+1][0]))
addr = strtoul(argv[++i], NULL, 16); addr = strtoul(argv[++i], NULL, 16);
load(filename, addr); load(filename, addr);
} else if (strcmp(argv[i], "save") == 0) { } else if (strcmp(argv[i], "save") == 0) {

@ -26,6 +26,7 @@ use work.wishbone_types.all;
-- 0xc0006000: SPI Flash controller -- 0xc0006000: SPI Flash controller
-- 0xc0007000: GPIO controller -- 0xc0007000: GPIO controller
-- 0xc8nnnnnn: External IO bus -- 0xc8nnnnnn: External IO bus
-- 0xcb000000: LPC slave (same addr as Kestral)
-- 0xf0000000: Flash "ROM" mapping -- 0xf0000000: Flash "ROM" mapping
-- 0xff000000: DRAM init code (if any) or flash ROM (**) -- 0xff000000: DRAM init code (if any) or flash ROM (**)


@ -50,6 +51,8 @@ use work.wishbone_types.all;
-- 2 : UART1 -- 2 : UART1
-- 3 : SD card -- 3 : SD card
-- 4 : GPIO -- 4 : GPIO
-- 5 : LPC UART
-- 6 : LPC IPMI


entity soc is entity soc is
generic ( generic (
@ -60,8 +63,8 @@ entity soc is
HAS_FPU : boolean := true; HAS_FPU : boolean := true;
HAS_BTC : boolean := true; HAS_BTC : boolean := true;
HAS_SHORT_MULT : boolean := false; HAS_SHORT_MULT : boolean := false;
HAS_LPC : boolean := false;
DISABLE_FLATTEN_CORE : boolean := false; DISABLE_FLATTEN_CORE : boolean := false;
ALT_RESET_ADDRESS : std_logic_vector(63 downto 0) := (23 downto 0 => '0', others => '1');
HAS_DRAM : boolean := false; HAS_DRAM : boolean := false;
DRAM_SIZE : integer := 0; DRAM_SIZE : integer := 0;
DRAM_INIT_SIZE : integer := 0; DRAM_INIT_SIZE : integer := 0;
@ -130,6 +133,17 @@ entity soc is
gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0); gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0);
gpio_in : in std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0'); gpio_in : in std_ulogic_vector(NGPIO - 1 downto 0) := (others => '0');


-- LPC signals
lpc_data_o : out std_ulogic_vector(3 downto 0);
lpc_data_oe : out std_ulogic;
lpc_data_i : in std_ulogic_vector(3 downto 0) := (others => '1');
lpc_frame_n : in std_ulogic := '1';
lpc_reset_n : in std_ulogic := '1';
lpc_clock : in std_ulogic := '1';
lpc_irq_o : out std_ulogic;
lpc_irq_oe : out std_ulogic;
lpc_irq_i : in std_ulogic := '0';

-- DRAM controller signals -- DRAM controller signals
alt_reset : in std_ulogic := '0' alt_reset : in std_ulogic := '0'
); );
@ -147,7 +161,7 @@ architecture behaviour of soc is


-- Arbiter array (ghdl doesnt' support assigning the array -- Arbiter array (ghdl doesnt' support assigning the array
-- elements in the entity instantiation) -- elements in the entity instantiation)
constant NUM_WB_MASTERS : positive := 4; constant NUM_WB_MASTERS : positive := 5;
signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1); signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1);
signal wb_masters_in : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1); signal wb_masters_in : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);


@ -188,6 +202,26 @@ architecture behaviour of soc is
signal wb_spiflash_is_reg : std_ulogic; signal wb_spiflash_is_reg : std_ulogic;
signal wb_spiflash_is_map : std_ulogic; signal wb_spiflash_is_map : std_ulogic;


-- LPC Flash controller signals:
signal wb_lpc_in : wb_io_master_out;
signal wb_lpc_out : wb_io_slave_out;
signal lpc_vuart_irq : std_ulogic;
signal lpc_ipmi_irq : std_ulogic;

-- LPC master wb
signal lpc_master_wb_cyc : std_ulogic;
signal lpc_master_wb_stb : std_ulogic;
signal lpc_master_wb_err : std_ulogic;
signal lpc_master_wb_addr : std_ulogic_vector(29 downto 0);

signal wb_lpc_dma_out : wb_io_master_out := wb_io_master_out_init;
signal wb_lpc_dma_in : wb_io_slave_out;
signal wb_lpc_dma_nr : wb_io_master_out;
signal wb_lpc_dma_ir : wb_io_slave_out;

-- for conversion from non-pipelined wishbone to pipelined
signal wb_lpc_dma_stb_sent : std_ulogic;

-- XICS signals: -- XICS signals:
signal wb_xics_icp_in : wb_io_master_out; signal wb_xics_icp_in : wb_io_master_out;
signal wb_xics_icp_out : wb_io_slave_out; signal wb_xics_icp_out : wb_io_slave_out;
@ -223,15 +257,16 @@ architecture behaviour of soc is
signal dmi_core_ack : std_ulogic; signal dmi_core_ack : std_ulogic;


-- Delayed/latched resets and alt_reset -- Delayed/latched resets and alt_reset
signal rst_core : std_ulogic; signal rst_core : std_ulogic := '1';
signal rst_uart : std_ulogic; signal rst_uart : std_ulogic := '1';
signal rst_xics : std_ulogic; signal rst_xics : std_ulogic := '1';
signal rst_spi : std_ulogic; signal rst_lpc : std_ulogic := '1';
signal rst_gpio : std_ulogic; signal rst_spi : std_ulogic := '1';
signal rst_bram : std_ulogic; signal rst_gpio : std_ulogic := '1';
signal rst_dtm : std_ulogic; signal rst_bram : std_ulogic := '1';
signal rst_wbar : std_ulogic; signal rst_dtm : std_ulogic := '1';
signal rst_wbdb : std_ulogic; signal rst_wbar : std_ulogic := '1';
signal rst_wbdb : std_ulogic := '1';
signal alt_reset_d : std_ulogic; signal alt_reset_d : std_ulogic;


-- IO branch split: -- IO branch split:
@ -240,20 +275,13 @@ architecture behaviour of soc is
SLAVE_IO_ICP, SLAVE_IO_ICP,
SLAVE_IO_ICS, SLAVE_IO_ICS,
SLAVE_IO_UART1, SLAVE_IO_UART1,
SLAVE_IO_SPI_FLASH, SLAVE_IO_SPI_FLASH_REG,
SLAVE_IO_SPI_FLASH_MAP,
SLAVE_IO_GPIO, SLAVE_IO_GPIO,
SLAVE_IO_EXTERNAL); SLAVE_IO_EXTERNAL,
signal current_io_decode : slave_io_type; SLAVE_IO_LPC,

SLAVE_IO_NONE);
signal io_cycle_none : std_ulogic; signal slave_io_dbg : slave_io_type;
signal io_cycle_syscon : std_ulogic;
signal io_cycle_uart : std_ulogic;
signal io_cycle_uart1 : std_ulogic;
signal io_cycle_icp : std_ulogic;
signal io_cycle_ics : std_ulogic;
signal io_cycle_spi_flash : std_ulogic;
signal io_cycle_gpio : std_ulogic;
signal io_cycle_external : std_ulogic;


function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is function wishbone_widen_data(wb : wb_io_master_out) return wishbone_master_out is
variable wwb : wishbone_master_out; variable wwb : wishbone_master_out;
@ -321,6 +349,7 @@ begin
rst_spi <= rst; rst_spi <= rst;
rst_xics <= rst; rst_xics <= rst;
rst_gpio <= rst; rst_gpio <= rst;
rst_lpc <= rst;
rst_bram <= rst; rst_bram <= rst;
rst_dtm <= rst; rst_dtm <= rst;
rst_wbar <= rst; rst_wbar <= rst;
@ -337,7 +366,7 @@ begin
HAS_BTC => HAS_BTC, HAS_BTC => HAS_BTC,
HAS_SHORT_MULT => HAS_SHORT_MULT, HAS_SHORT_MULT => HAS_SHORT_MULT,
DISABLE_FLATTEN => DISABLE_FLATTEN_CORE, DISABLE_FLATTEN => DISABLE_FLATTEN_CORE,
ALT_RESET_ADDRESS => ALT_RESET_ADDRESS, ALT_RESET_ADDRESS => (23 downto 0 => '0', others => '1'),
LOG_LENGTH => LOG_LENGTH, LOG_LENGTH => LOG_LENGTH,
ICACHE_NUM_LINES => ICACHE_NUM_LINES, ICACHE_NUM_LINES => ICACHE_NUM_LINES,
ICACHE_NUM_WAYS => ICACHE_NUM_WAYS, ICACHE_NUM_WAYS => ICACHE_NUM_WAYS,
@ -369,11 +398,13 @@ begin
wb_masters_out <= (0 => wishbone_dcore_out, wb_masters_out <= (0 => wishbone_dcore_out,
1 => wishbone_icore_out, 1 => wishbone_icore_out,
2 => wishbone_widen_data(wishbone_dma_out), 2 => wishbone_widen_data(wishbone_dma_out),
3 => wishbone_debug_out); 3 => wishbone_widen_data(wb_lpc_dma_out),
4 => wishbone_debug_out);
wishbone_dcore_in <= wb_masters_in(0); wishbone_dcore_in <= wb_masters_in(0);
wishbone_icore_in <= wb_masters_in(1); wishbone_icore_in <= wb_masters_in(1);
wishbone_dma_in <= wishbone_narrow_data(wb_masters_in(2), wishbone_dma_out.adr); wishbone_dma_in <= wishbone_narrow_data(wb_masters_in(2), wishbone_dma_out.adr);
wishbone_debug_in <= wb_masters_in(3); wb_lpc_dma_in <= wishbone_narrow_data(wb_masters_in(3), wb_lpc_dma_out.adr);
wishbone_debug_in <= wb_masters_in(4);
wishbone_arbiter_0: entity work.wishbone_arbiter wishbone_arbiter_0: entity work.wishbone_arbiter
generic map( generic map(
NUM_MASTERS => NUM_WB_MASTERS NUM_MASTERS => NUM_WB_MASTERS
@ -474,20 +505,14 @@ begin
-- Misc -- Misc
variable has_top : boolean; variable has_top : boolean;
variable has_bot : boolean; variable has_bot : boolean;
variable do_cyc : std_ulogic;
variable end_cyc : std_ulogic;
variable slave_io : slave_io_type;
variable match : std_ulogic_vector(31 downto 12);
begin begin
if rising_edge(system_clk) then if rising_edge(system_clk) then
do_cyc := '0';
end_cyc := '0';
if (rst) then if (rst) then
state := IDLE; state := IDLE;
wb_io_out.ack <= '0'; wb_io_out.ack <= '0';
wb_io_out.stall <= '0'; wb_io_out.stall <= '0';
wb_sio_out.cyc <= '0';
wb_sio_out.stb <= '0'; wb_sio_out.stb <= '0';
end_cyc := '1';
has_top := false; has_top := false;
has_bot := false; has_bot := false;
else else
@ -503,7 +528,7 @@ begin
wb_io_out.stall <= '1'; wb_io_out.stall <= '1';


-- Start cycle downstream -- Start cycle downstream
do_cyc := '1'; wb_sio_out.cyc <= '1';
wb_sio_out.stb <= '1'; wb_sio_out.stb <= '1';


-- Copy write enable to IO out, copy address as well -- Copy write enable to IO out, copy address as well
@ -566,8 +591,8 @@ begin
-- Wait for new ack -- Wait for new ack
state := WAIT_ACK_TOP; state := WAIT_ACK_TOP;
else else
-- We are done, ack up, clear cyc downstream -- We are done, ack up, clear cyc downstram
end_cyc := '1'; wb_sio_out.cyc <= '0';


-- And ack & unstall upstream -- And ack & unstall upstream
wb_io_out.ack <= '1'; wb_io_out.ack <= '1';
@ -591,7 +616,7 @@ begin
end if; end if;


-- We are done, ack up, clear cyc downstram -- We are done, ack up, clear cyc downstram
end_cyc := '1'; wb_sio_out.cyc <= '0';


-- And ack & unstall upstream -- And ack & unstall upstream
wb_io_out.ack <= '1'; wb_io_out.ack <= '1';
@ -602,149 +627,151 @@ begin
end if; end if;
end case; end case;
end if; end if;

-- Create individual registered cycle signals for the wishbones
-- going to the various peripherals
if do_cyc = '1' or end_cyc = '1' then
io_cycle_none <= '0';
io_cycle_syscon <= '0';
io_cycle_uart <= '0';
io_cycle_uart1 <= '0';
io_cycle_icp <= '0';
io_cycle_ics <= '0';
io_cycle_spi_flash <= '0';
io_cycle_gpio <= '0';
io_cycle_external <= '0';
wb_sio_out.cyc <= '0';
wb_ext_is_dram_init <= '0';
wb_spiflash_is_map <= '0';
wb_spiflash_is_reg <= '0';
wb_ext_is_dram_csr <= '0';
wb_ext_is_eth <= '0';
wb_ext_is_sdcard <= '0';
end if; end if;
if do_cyc = '1' then end process;
-- Decode I/O address
-- This is real address bits 29 downto 12 -- IO wishbone slave intercon.
match := "11" & wb_io_in.adr(26 downto 9); --
slave_io := SLAVE_IO_SYSCON; slave_io_intercon: process(wb_sio_out, wb_syscon_out, wb_uart0_out, wb_uart1_out,
wb_ext_io_out, wb_xics_icp_out, wb_xics_ics_out,
wb_spiflash_out)
variable slave_io : slave_io_type;

variable match : std_ulogic_vector(31 downto 12);
variable ext_valid : boolean;
begin

-- Simple address decoder.
slave_io := SLAVE_IO_NONE;
match := "11" & wb_sio_out.adr(27 downto 10);
if std_match(match, x"FF---") and HAS_DRAM then if std_match(match, x"FF---") and HAS_DRAM then
slave_io := SLAVE_IO_EXTERNAL; slave_io := SLAVE_IO_EXTERNAL;
io_cycle_external <= '1';
wb_ext_is_dram_init <= '1';
elsif std_match(match, x"F----") then elsif std_match(match, x"F----") then
slave_io := SLAVE_IO_SPI_FLASH; slave_io := SLAVE_IO_SPI_FLASH_MAP;
io_cycle_spi_flash <= '1';
wb_spiflash_is_map <= '1';
elsif std_match(match, x"C8---") then
-- Ext IO "chip selects"
if std_match(match, x"--00-") and HAS_DRAM then
slave_io := SLAVE_IO_EXTERNAL;
io_cycle_external <= '1';
wb_ext_is_dram_csr <= '1';
elsif (std_match(match, x"--02-") or std_match(match, x"--03-")) and
HAS_LITEETH then
slave_io := SLAVE_IO_EXTERNAL;
io_cycle_external <= '1';
wb_ext_is_eth <= '1';
elsif std_match(match, x"--04-") and HAS_SD_CARD then
slave_io := SLAVE_IO_EXTERNAL;
io_cycle_external <= '1';
wb_ext_is_sdcard <= '1';
else
io_cycle_none <= '1';
end if;
elsif std_match(match, x"C0000") then elsif std_match(match, x"C0000") then
slave_io := SLAVE_IO_SYSCON; slave_io := SLAVE_IO_SYSCON;
io_cycle_syscon <= '1';
elsif std_match(match, x"C0002") then elsif std_match(match, x"C0002") then
slave_io := SLAVE_IO_UART; slave_io := SLAVE_IO_UART;
io_cycle_uart <= '1';
elsif std_match(match, x"C0003") then elsif std_match(match, x"C0003") then
slave_io := SLAVE_IO_UART1; slave_io := SLAVE_IO_UART1;
io_cycle_uart1 <= '1'; elsif std_match(match, x"C8---") then
slave_io := SLAVE_IO_EXTERNAL;
elsif std_match(match, x"CB---") then
slave_io := SLAVE_IO_LPC;
elsif std_match(match, x"C0004") then elsif std_match(match, x"C0004") then
slave_io := SLAVE_IO_ICP; slave_io := SLAVE_IO_ICP;
io_cycle_icp <= '1';
elsif std_match(match, x"C0005") then elsif std_match(match, x"C0005") then
slave_io := SLAVE_IO_ICS; slave_io := SLAVE_IO_ICS;
io_cycle_ics <= '1';
elsif std_match(match, x"C0006") then elsif std_match(match, x"C0006") then
slave_io := SLAVE_IO_SPI_FLASH; slave_io := SLAVE_IO_SPI_FLASH_REG;
io_cycle_spi_flash <= '1';
wb_spiflash_is_reg <= '1';
elsif std_match(match, x"C0007") then elsif std_match(match, x"C0007") then
slave_io := SLAVE_IO_GPIO; slave_io := SLAVE_IO_GPIO;
io_cycle_gpio <= '1';
else
io_cycle_none <= '1';
end if;
current_io_decode <= slave_io;
wb_sio_out.cyc <= '1';
end if; end if;
end if; slave_io_dbg <= slave_io;
end process;
-- IO wishbone slave interconnect.
--
slave_io_intercon: process(all)
begin
wb_uart0_in <= wb_sio_out; wb_uart0_in <= wb_sio_out;
wb_uart0_in.cyc <= io_cycle_uart; wb_uart0_in.cyc <= '0';
wb_uart1_in <= wb_sio_out; wb_uart1_in <= wb_sio_out;
wb_uart1_in.cyc <= io_cycle_uart1; wb_uart1_in.cyc <= '0';

wb_spiflash_in <= wb_sio_out; wb_spiflash_in <= wb_sio_out;
wb_spiflash_in.cyc <= io_cycle_spi_flash; wb_spiflash_in.cyc <= '0';
-- Clear top bits so they don't make their way to the wb_spiflash_is_reg <= '0';
-- flash chip. wb_spiflash_is_map <= '0';
wb_spiflash_in.adr(27 downto 26) <= "00";

wb_gpio_in <= wb_sio_out; wb_gpio_in <= wb_sio_out;
wb_gpio_in.cyc <= io_cycle_gpio; wb_gpio_in.cyc <= '0';
wb_lpc_in <= wb_sio_out;
wb_lpc_in.cyc <= '0';


-- Only give xics 8 bits of wb addr (for now...) -- Only give xics 8 bits of wb addr (for now...)
wb_xics_icp_in <= wb_sio_out; wb_xics_icp_in <= wb_sio_out;
wb_xics_icp_in.adr <= (others => '0'); wb_xics_icp_in.adr <= (others => '0');
wb_xics_icp_in.adr(5 downto 0) <= wb_sio_out.adr(5 downto 0); wb_xics_icp_in.adr(5 downto 0) <= wb_sio_out.adr(5 downto 0);
wb_xics_icp_in.cyc <= io_cycle_icp; wb_xics_icp_in.cyc <= '0';
wb_xics_ics_in <= wb_sio_out; wb_xics_ics_in <= wb_sio_out;
wb_xics_ics_in.adr <= (others => '0'); wb_xics_ics_in.adr <= (others => '0');
wb_xics_ics_in.adr(9 downto 0) <= wb_sio_out.adr(9 downto 0); wb_xics_ics_in.adr(9 downto 0) <= wb_sio_out.adr(9 downto 0);
wb_xics_ics_in.cyc <= io_cycle_ics; wb_xics_ics_in.cyc <= '0';


wb_ext_io_in <= wb_sio_out; wb_ext_io_in <= wb_sio_out;
wb_ext_io_in.cyc <= io_cycle_external; wb_ext_io_in.cyc <= '0';


wb_syscon_in <= wb_sio_out; wb_syscon_in <= wb_sio_out;
wb_syscon_in.cyc <= io_cycle_syscon; wb_syscon_in.cyc <= '0';

wb_ext_is_dram_csr <= '0';
wb_ext_is_dram_init <= '0';
wb_ext_is_eth <= '0';
wb_ext_is_sdcard <= '0';


case current_io_decode is -- Default response, ack & return all 1's
wb_sio_in.dat <= (others => '1');
wb_sio_in.ack <= wb_sio_out.stb and wb_sio_out.cyc;
wb_sio_in.stall <= '0';

case slave_io is
when SLAVE_IO_EXTERNAL => when SLAVE_IO_EXTERNAL =>
-- Ext IO "chip selects"
--
-- DRAM init is special at 0xFF* so we just test the top
-- bit. Everything else is at 0xC8* so we test only bits
-- 23 downto 16 (21 downto 14 in the wishbone addr).
--
ext_valid := false;
if wb_sio_out.adr(27) = '1' and HAS_DRAM then -- DRAM init is special
wb_ext_is_dram_init <= '1';
ext_valid := true;
elsif wb_sio_out.adr(21 downto 14) = x"00" and HAS_DRAM then
wb_ext_is_dram_csr <= '1';
ext_valid := true;
elsif wb_sio_out.adr(21 downto 14) = x"02" and HAS_LITEETH then
wb_ext_is_eth <= '1';
ext_valid := true;
elsif wb_sio_out.adr(21 downto 14) = x"03" and HAS_LITEETH then
wb_ext_is_eth <= '1';
ext_valid := true;
elsif wb_sio_out.adr(21 downto 14) = x"04" and HAS_SD_CARD then
wb_ext_is_sdcard <= '1';
ext_valid := true;
end if;
if ext_valid then
wb_ext_io_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_ext_io_out; wb_sio_in <= wb_ext_io_out;
end if;

when SLAVE_IO_LPC =>
wb_lpc_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_lpc_out;
when SLAVE_IO_SYSCON => when SLAVE_IO_SYSCON =>
wb_syscon_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_syscon_out; wb_sio_in <= wb_syscon_out;
when SLAVE_IO_UART => when SLAVE_IO_UART =>
wb_uart0_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_uart0_out; wb_sio_in <= wb_uart0_out;
when SLAVE_IO_ICP => when SLAVE_IO_ICP =>
wb_xics_icp_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_xics_icp_out; wb_sio_in <= wb_xics_icp_out;
when SLAVE_IO_ICS => when SLAVE_IO_ICS =>
wb_xics_ics_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_xics_ics_out; wb_sio_in <= wb_xics_ics_out;
when SLAVE_IO_UART1 => when SLAVE_IO_UART1 =>
wb_uart1_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_uart1_out; wb_sio_in <= wb_uart1_out;
when SLAVE_IO_SPI_FLASH => when SLAVE_IO_SPI_FLASH_MAP =>
-- Clear top bits so they don't make their way to the
-- fash chip.
wb_spiflash_in.adr(27 downto 26) <= "00";
wb_spiflash_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_spiflash_out;
wb_spiflash_is_map <= '1';
when SLAVE_IO_SPI_FLASH_REG =>
wb_spiflash_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_spiflash_out; wb_sio_in <= wb_spiflash_out;
wb_spiflash_is_reg <= '1';
when SLAVE_IO_GPIO => when SLAVE_IO_GPIO =>
wb_gpio_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_gpio_out; wb_sio_in <= wb_gpio_out;
when others =>
end case; end case;


-- Default response, ack & return all 1's
if io_cycle_none = '1' then
wb_sio_in.dat <= (others => '1');
wb_sio_in.ack <= wb_sio_out.stb and wb_sio_out.cyc;
wb_sio_in.stall <= '0';
end if;

end process; end process;


-- Syscon slave -- Syscon slave
@ -912,6 +939,115 @@ begin
wb_spiflash_out.stall <= wb_spiflash_in.cyc and not wb_spiflash_out.ack; wb_spiflash_out.stall <= wb_spiflash_in.cyc and not wb_spiflash_out.ack;
end generate; end generate;


lpc_gen: if HAS_LPC generate
component lpc_top port (
clk : in std_ulogic;
rst : in std_ulogic;

lclk : in std_ulogic;
lframe : in std_ulogic;
lreset : in std_ulogic;
lad_en : out std_ulogic;
lad_out : out std_ulogic_vector(3 downto 0);
lad_in : in std_ulogic_vector(3 downto 0);

adr : in std_ulogic_vector(13 downto 0);
dat_w : in std_ulogic_vector(31 downto 0);
dat_r : out std_ulogic_vector(31 downto 0);
ack : out std_ulogic;
cyc : in std_ulogic;
sel : in std_ulogic;
stb : in std_ulogic;
we : in std_ulogic;

dma_adr : out std_ulogic_vector(29 downto 0);
dma_dat_w : out std_ulogic_vector(31 downto 0);
dma_dat_r : in std_ulogic_vector(31 downto 0);
dma_ack : in std_ulogic;
dma_cyc : out std_ulogic;
dma_sel : out std_ulogic_vector(3 downto 0);
dma_stb : out std_ulogic;
dma_we : out std_ulogic;

bmc_ipmi_irq : out std_ulogic;
bmc_vuart_irq : out std_ulogic;
target_ipmi_irq : out std_ulogic;
target_vuart_irq : out std_ulogic
);
end component;
begin
lpc0: lpc_top
port map(
rst => rst_lpc,
clk => system_clk,

adr => wb_lpc_in.adr(13 downto 0),
dat_w => wb_lpc_in.dat(31 downto 0),
dat_r => wb_lpc_out.dat(31 downto 0),
ack => wb_lpc_out.ack,
cyc => wb_lpc_in.cyc,
sel => wb_lpc_in.sel(0),
stb => wb_lpc_in.stb,
we => wb_lpc_in.we,

dma_adr => wb_lpc_dma_nr.adr(29 downto 0),
dma_dat_w => wb_lpc_dma_nr.dat(31 downto 0),
dma_dat_r => wb_lpc_dma_ir.dat(31 downto 0),
dma_sel => wb_lpc_dma_nr.sel,
dma_cyc => wb_lpc_dma_nr.cyc,
dma_stb => wb_lpc_dma_nr.stb,
dma_ack => wb_lpc_dma_ir.ack,
dma_we => wb_lpc_dma_nr.we,

lclk => lpc_clock,
lframe => lpc_frame_n,
lreset => lpc_reset_n,
lad_out => lpc_data_o,
lad_in => lpc_data_i,
lad_en => lpc_data_oe,

bmc_ipmi_irq => lpc_ipmi_irq,
bmc_vuart_irq => lpc_vuart_irq
);
lpc_master_wb_err <= '0';
lpc_irq_o <= '0';
lpc_irq_oe <= '0';
-- FIXME hook up irqs

wb_lpc_out.stall <= not wb_lpc_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_lpc_dma_out <= wb_lpc_dma_nr;
if wb_lpc_dma_stb_sent = '1' or
(wb_lpc_dma_out.stb = '1' and wb_lpc_dma_in.stall = '0') then
wb_lpc_dma_out.stb <= '0';
end if;
if wb_lpc_dma_nr.cyc = '0' or wb_lpc_dma_ir.ack = '1' then
wb_lpc_dma_stb_sent <= '0';
elsif wb_lpc_dma_in.stall = '0' then
wb_lpc_dma_stb_sent <= wb_lpc_dma_nr.stb;
end if;
wb_lpc_dma_ir <= wb_lpc_dma_in;
end if;
end process;

end generate;

no_lpc_gen: if not HAS_LPC generate
lpc_data_o <= (others => '0');
lpc_data_oe <= '0';
lpc_irq_o <= '0';
lpc_irq_oe <= '0';

wb_lpc_out.dat <= (others => '1');
wb_lpc_out.ack <= wb_lpc_in.cyc and wb_lpc_in.stb;
wb_lpc_out.stall <= wb_lpc_in.cyc and not wb_lpc_out.ack;
end generate;

xics_icp: entity work.xics_icp xics_icp: entity work.xics_icp
port map( port map(
clk => system_clk, clk => system_clk,
@ -962,6 +1098,8 @@ begin
int_level_in(2) <= uart1_irq; int_level_in(2) <= uart1_irq;
int_level_in(3) <= ext_irq_sdcard; int_level_in(3) <= ext_irq_sdcard;
int_level_in(4) <= gpio_intr; int_level_in(4) <= gpio_intr;
int_level_in(5) <= lpc_vuart_irq;
int_level_in(6) <= lpc_ipmi_irq;
end process; end process;


-- BRAM Memory slave -- BRAM Memory slave

@ -50,7 +50,7 @@ architecture rtl of spi_flash_ctrl is
constant SPI_REG_INVALID : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "111"; constant SPI_REG_INVALID : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "111";


-- Control register -- Control register
signal ctrl_reg : std_ulogic_vector(15 downto 0); signal ctrl_reg : std_ulogic_vector(15 downto 0) := (others => '0');
alias ctrl_reset : std_ulogic is ctrl_reg(0); alias ctrl_reset : std_ulogic is ctrl_reg(0);
alias ctrl_cs : std_ulogic is ctrl_reg(1); alias ctrl_cs : std_ulogic is ctrl_reg(1);
alias ctrl_rsrv1 : std_ulogic is ctrl_reg(2); alias ctrl_rsrv1 : std_ulogic is ctrl_reg(2);
@ -58,7 +58,7 @@ architecture rtl of spi_flash_ctrl is
alias ctrl_div : std_ulogic_vector(7 downto 0) is ctrl_reg(15 downto 8); alias ctrl_div : std_ulogic_vector(7 downto 0) is ctrl_reg(15 downto 8);


-- Auto mode config register -- Auto mode config register
signal auto_cfg_reg : std_ulogic_vector(29 downto 0); signal auto_cfg_reg : std_ulogic_vector(29 downto 0) := (others => '0');
alias auto_cfg_cmd : std_ulogic_vector(7 downto 0) is auto_cfg_reg(7 downto 0); alias auto_cfg_cmd : std_ulogic_vector(7 downto 0) is auto_cfg_reg(7 downto 0);
alias auto_cfg_dummies : std_ulogic_vector(2 downto 0) is auto_cfg_reg(10 downto 8); alias auto_cfg_dummies : std_ulogic_vector(2 downto 0) is auto_cfg_reg(10 downto 8);
alias auto_cfg_mode : std_ulogic_vector(1 downto 0) is auto_cfg_reg(12 downto 11); alias auto_cfg_mode : std_ulogic_vector(1 downto 0) is auto_cfg_reg(12 downto 11);
@ -126,9 +126,9 @@ architecture rtl of spi_flash_ctrl is
signal auto_latch_adr : std_ulogic; signal auto_latch_adr : std_ulogic;


-- Automatic mode latches -- Automatic mode latches
signal auto_data : std_ulogic_vector(wb_out.dat'left downto 0); signal auto_data : std_ulogic_vector(wb_out.dat'left downto 0) := (others => '0');
signal auto_cnt : integer range 0 to 63; signal auto_cnt : integer range 0 to 63 := 0;
signal auto_state : auto_state_t; signal auto_state : auto_state_t := AUTO_BOOT;
signal auto_last_addr : std_ulogic_vector(31 downto 0); signal auto_last_addr : std_ulogic_vector(31 downto 0);


begin begin
@ -351,8 +351,6 @@ begin
if rst = '1' then if rst = '1' then
auto_last_addr <= (others => '0'); auto_last_addr <= (others => '0');
auto_state <= AUTO_BOOT; auto_state <= AUTO_BOOT;
auto_cnt <= 0;
auto_data <= (others => '0');
else else
auto_state <= auto_next; auto_state <= auto_next;
auto_cnt <= auto_cnt_next; auto_cnt <= auto_cnt_next;

@ -126,10 +126,10 @@ architecture rtl of spi_rxtx is
signal dat_ack_l : std_ulogic; signal dat_ack_l : std_ulogic;


-- Delayed recv signal for the read machine -- Delayed recv signal for the read machine
signal sck_recv_d : std_ulogic; signal sck_recv_d : std_ulogic := '0';


-- Input shift register (use fifo ?) -- Input shift register (use fifo ?)
signal ireg : std_ulogic_vector(7 downto 0); signal ireg : std_ulogic_vector(7 downto 0) := (others => '0');


-- Bit counter -- Bit counter
signal bit_count : std_ulogic_vector(2 downto 0); signal bit_count : std_ulogic_vector(2 downto 0);
@ -157,7 +157,7 @@ architecture rtl of spi_rxtx is
end; end;


type state_t is (STANDBY, DATA); type state_t is (STANDBY, DATA);
signal state : state_t; signal state : state_t := STANDBY;
begin begin


-- We don't support multiple data lines at this point -- We don't support multiple data lines at this point
@ -349,9 +349,6 @@ begin
shift_in: process(clk) shift_in: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then
ireg <= (others => '0');
end if;


-- Delay the receive signal to match the input latch -- Delay the receive signal to match the input latch
if state = DATA then if state = DATA then

@ -24,7 +24,7 @@ entity wishbone_bram_wrapper is
end entity wishbone_bram_wrapper; end entity wishbone_bram_wrapper;


architecture behaviour of wishbone_bram_wrapper is architecture behaviour of wishbone_bram_wrapper is
constant ram_addr_bits : integer := log2ceil(MEMORY_SIZE-1) - 3; constant ram_addr_bits : integer := log2ceil(MEMORY_SIZE) - 3;


-- RAM interface -- RAM interface
signal ram_addr : std_logic_vector(ram_addr_bits - 1 downto 0); signal ram_addr : std_logic_vector(ram_addr_bits - 1 downto 0);

@ -54,6 +54,9 @@ architecture behaviour of xics_icp is


signal r, r_next : reg_internal_t; signal r, r_next : reg_internal_t;


-- hardwire the hardware IRQ priority
constant HW_PRIORITY : std_ulogic_vector(7 downto 0) := x"80";

-- 8 bit offsets for each presentation -- 8 bit offsets for each presentation
constant XIRR_POLL : std_ulogic_vector(7 downto 0) := x"00"; constant XIRR_POLL : std_ulogic_vector(7 downto 0) := x"00";
constant XIRR : std_ulogic_vector(7 downto 0) := x"04"; constant XIRR : std_ulogic_vector(7 downto 0) := x"04";
@ -204,14 +207,12 @@ use ieee.numeric_std.all;


library work; library work;
use work.common.all; use work.common.all;
use work.utils.all;
use work.wishbone_types.all; use work.wishbone_types.all;
use work.helpers.all;


entity xics_ics is entity xics_ics is
generic ( generic (
SRC_NUM : integer range 1 to 256 := 16; SRC_NUM : integer range 1 to 256 := 16;
PRIO_BITS : integer range 1 to 8 := 3 PRIO_BITS : integer range 1 to 8 := 8
); );
port ( port (
clk : in std_logic; clk : in std_logic;
@ -227,16 +228,12 @@ end xics_ics;


architecture rtl of xics_ics is architecture rtl of xics_ics is


constant SRC_NUM_BITS : natural := log2(SRC_NUM);

subtype pri_t is std_ulogic_vector(PRIO_BITS-1 downto 0); subtype pri_t is std_ulogic_vector(PRIO_BITS-1 downto 0);
type xive_t is record type xive_t is record
pri : pri_t; pri : pri_t;
end record; end record;
constant pri_masked : pri_t := (others => '1'); constant pri_masked : pri_t := (others => '1');


subtype pri_vector_t is std_ulogic_vector(2**PRIO_BITS - 1 downto 0);

type xive_array_t is array(0 to SRC_NUM-1) of xive_t; type xive_array_t is array(0 to SRC_NUM-1) of xive_t;
signal xives : xive_array_t; signal xives : xive_array_t;


@ -265,15 +262,8 @@ architecture rtl of xics_ics is
end function; end function;


function prio_pack(pri8: std_ulogic_vector(7 downto 0)) return pri_t is function prio_pack(pri8: std_ulogic_vector(7 downto 0)) return pri_t is
variable masked : std_ulogic_vector(7 downto 0);
begin begin
masked := x"00";
masked(PRIO_BITS - 1 downto 0) := (others => '1');
if unsigned(pri8) >= unsigned(masked) then
return pri_masked;
else
return pri8(PRIO_BITS-1 downto 0); return pri8(PRIO_BITS-1 downto 0);
end if;
end function; end function;


function prio_unpack(pri: pri_t) return std_ulogic_vector is function prio_unpack(pri: pri_t) return std_ulogic_vector is
@ -288,25 +278,6 @@ architecture rtl of xics_ics is
return r; return r;
end function; end function;


function prio_decode(pri: pri_t) return pri_vector_t is
variable v: pri_vector_t;
begin
v := (others => '0');
v(to_integer(unsigned(pri))) := '1';
return v;
end function;

-- Assumes nbits <= 6; v is 2^nbits wide
function priority_encoder(v: std_ulogic_vector; nbits: natural) return std_ulogic_vector is
variable h: std_ulogic_vector(2**nbits - 1 downto 0);
variable p: std_ulogic_vector(5 downto 0);
begin
-- Set the lowest-priority (highest-numbered) bit
h := v;
h(2**nbits - 1) := '1';
p := count_right_zeroes(h);
return p(nbits - 1 downto 0);
end function;


-- Register map -- Register map
-- 0 : Config -- 0 : Config
@ -420,33 +391,35 @@ begin
end process; end process;


irq_gen: process(all) irq_gen: process(all)
variable max_idx : std_ulogic_vector(SRC_NUM_BITS - 1 downto 0); variable max_idx : integer range 0 to SRC_NUM-1;
variable max_pri : pri_t; variable max_pri : pri_t;
variable pending_pri : pri_vector_t;
variable pending_at_pri : std_ulogic_vector(SRC_NUM - 1 downto 0);
begin
-- Work out the most-favoured (lowest) priority of the pending interrupts
pending_pri := (others => '0');
for i in 0 to SRC_NUM - 1 loop
if int_level_l(i) = '1' then
pending_pri := pending_pri or prio_decode(xives(i).pri);
end if;
end loop;
max_pri := priority_encoder(pending_pri, PRIO_BITS);


-- Work out which interrupts are pending at that priority -- A more favored than b ?
pending_at_pri := (others => '0'); function a_mf_b(a: pri_t; b: pri_t) return boolean is
variable a_i : unsigned(PRIO_BITS-1 downto 0);
variable b_i : unsigned(PRIO_BITS-1 downto 0);
begin
a_i := unsigned(a);
b_i := unsigned(b);
report "a_mf_b a=" & to_hstring(a) &
" b=" & to_hstring(b) &
" r=" & boolean'image(a < b);
return a_i < b_i;
end function;
begin
-- XXX FIXME: Use a tree
max_pri := pri_masked;
max_idx := 0;
for i in 0 to SRC_NUM - 1 loop for i in 0 to SRC_NUM - 1 loop
if int_level_l(i) = '1' and xives(i).pri = max_pri then if int_level_l(i) = '1' and a_mf_b(xives(i).pri, max_pri) then
pending_at_pri(i) := '1'; max_pri := xives(i).pri;
max_idx := i;
end if; end if;
end loop; end loop;
max_idx := priority_encoder(pending_at_pri, SRC_NUM_BITS);

if max_pri /= pri_masked then if max_pri /= pri_masked then
report "MFI: " & integer'image(to_integer(unsigned(max_idx))) & " pri=" & to_hstring(prio_unpack(max_pri)); report "MFI: " & integer'image(max_idx) & " pri=" & to_hstring(prio_unpack(max_pri));
end if; end if;
icp_out_next.src <= max_idx; icp_out_next.src <= std_ulogic_vector(to_unsigned(max_idx, 4));
icp_out_next.pri <= prio_unpack(max_pri); icp_out_next.pri <= prio_unpack(max_pri);
end process; end process;



Loading…
Cancel
Save