From 61d4408f2a001a7b516166853d7798226c099d78 Mon Sep 17 00:00:00 2001 From: Carlos Camargo Date: Tue, 25 May 2010 21:49:58 -0500 Subject: [PATCH] Adding lm32 demo to SAKC project --- Examples/sram/src/Makefile | 7 +- Examples/sram/src/enable_rx.c | 40 + Examples/sram/src/jz47xx_gpio.c | 3 + lm32/logic/sakc/Makefile | 131 + .../logic/sakc/firmware/boot0-serial/Makefile | 50 + .../sakc/firmware/boot0-serial/crt0ram.S | 85 + .../sakc/firmware/boot0-serial/crt0ram.d | 1 + .../sakc/firmware/boot0-serial/crt0ram.o | Bin 0 -> 1132 bytes lm32/logic/sakc/firmware/boot0-serial/image | Bin 0 -> 6169 bytes .../sakc/firmware/boot0-serial/image.bin | 44 + .../sakc/firmware/boot0-serial/image.lst | 454 ++++ .../sakc/firmware/boot0-serial/image.map | 127 + .../sakc/firmware/boot0-serial/image.ram | 1024 ++++++++ .../sakc/firmware/boot0-serial/image.srec | 44 + .../sakc/firmware/boot0-serial/linker.ld | 59 + lm32/logic/sakc/firmware/boot0-serial/main.c | 57 + lm32/logic/sakc/firmware/boot0-serial/main.d | 1 + lm32/logic/sakc/firmware/boot0-serial/main.o | Bin 0 -> 4568 bytes .../logic/sakc/firmware/boot0-serial/soc-hw.c | 69 + .../logic/sakc/firmware/boot0-serial/soc-hw.d | 1 + .../logic/sakc/firmware/boot0-serial/soc-hw.h | 108 + .../logic/sakc/firmware/boot0-serial/soc-hw.o | Bin 0 -> 5276 bytes lm32/logic/sakc/firmware/ddr-phaser/Makefile | 50 + lm32/logic/sakc/firmware/ddr-phaser/crt0ram.S | 166 ++ lm32/logic/sakc/firmware/ddr-phaser/image.ram | 1024 ++++++++ lm32/logic/sakc/firmware/ddr-phaser/linker.ld | 59 + lm32/logic/sakc/firmware/ddr-phaser/main.c | 105 + .../logic/sakc/firmware/ddr-phaser/spike_hw.c | 68 + .../logic/sakc/firmware/ddr-phaser/spike_hw.h | 108 + lm32/logic/sakc/firmware/gdb-test/Makefile | 43 + lm32/logic/sakc/firmware/gdb-test/crt0gdb.S | 290 +++ lm32/logic/sakc/firmware/gdb-test/gdb.c | 1214 +++++++++ lm32/logic/sakc/firmware/gdb-test/gdb.h | 37 + lm32/logic/sakc/firmware/gdb-test/gdb_uart.c | 23 + lm32/logic/sakc/firmware/gdb-test/gdb_uart.h | 5 + lm32/logic/sakc/firmware/gdb-test/linker.ld | 67 + lm32/logic/sakc/firmware/gdb-test/main.c | 20 + lm32/logic/sakc/firmware/gdb-test/soc-hw.c | 133 + lm32/logic/sakc/firmware/gdb-test/soc-hw.h | 108 + lm32/logic/sakc/firmware/gdb-test/start-gdb | 6 + lm32/logic/sakc/firmware/hw-test/Makefile | 46 + lm32/logic/sakc/firmware/hw-test/crt0ram.S | 249 ++ lm32/logic/sakc/firmware/hw-test/linker.ld | 59 + lm32/logic/sakc/firmware/hw-test/main.c | 151 ++ lm32/logic/sakc/firmware/hw-test/soc-hw.c | 133 + lm32/logic/sakc/firmware/hw-test/soc-hw.h | 108 + lm32/logic/sakc/rtl/lac/dp_ram.v | 43 + lm32/logic/sakc/rtl/lac/lac.v | 262 ++ lm32/logic/sakc/rtl/lac/uart.v | 155 ++ lm32/logic/sakc/rtl/lm32/JTAGB.v | 15 + lm32/logic/sakc/rtl/lm32/er1.v | 218 ++ lm32/logic/sakc/rtl/lm32/jtag_cores.v | 213 ++ lm32/logic/sakc/rtl/lm32/jtag_lm32.v | 195 ++ lm32/logic/sakc/rtl/lm32/lm32_adder.v | 110 + lm32/logic/sakc/rtl/lm32/lm32_addsub.v | 69 + lm32/logic/sakc/rtl/lm32/lm32_cpu.v | 2304 +++++++++++++++++ lm32/logic/sakc/rtl/lm32/lm32_dcache.v | 494 ++++ lm32/logic/sakc/rtl/lm32/lm32_debug.v | 340 +++ lm32/logic/sakc/rtl/lm32/lm32_decoder.v | 564 ++++ lm32/logic/sakc/rtl/lm32/lm32_functions.v | 29 + lm32/logic/sakc/rtl/lm32/lm32_icache.v | 428 +++ lm32/logic/sakc/rtl/lm32/lm32_include.v | 320 +++ lm32/logic/sakc/rtl/lm32/lm32_include_all.v | 32 + .../sakc/rtl/lm32/lm32_instruction_unit.v | 751 ++++++ lm32/logic/sakc/rtl/lm32/lm32_interrupt.v | 333 +++ lm32/logic/sakc/rtl/lm32/lm32_jtag.v | 491 ++++ .../sakc/rtl/lm32/lm32_load_store_unit.v | 588 +++++ lm32/logic/sakc/rtl/lm32/lm32_logic_op.v | 71 + lm32/logic/sakc/rtl/lm32/lm32_mc_arithmetic.v | 283 ++ lm32/logic/sakc/rtl/lm32/lm32_monitor.v | 164 ++ lm32/logic/sakc/rtl/lm32/lm32_monitor_ram.v | 1397 ++++++++++ lm32/logic/sakc/rtl/lm32/lm32_multiplier.v | 94 + lm32/logic/sakc/rtl/lm32/lm32_ram.v | 105 + lm32/logic/sakc/rtl/lm32/lm32_shifter.v | 129 + lm32/logic/sakc/rtl/lm32/lm32_simtrace.v | 165 ++ lm32/logic/sakc/rtl/lm32/lm32_top.v | 370 +++ lm32/logic/sakc/rtl/lm32/spiprog.v | 159 ++ lm32/logic/sakc/rtl/lm32/system.sdc | 58 + lm32/logic/sakc/rtl/lm32/typea.v | 74 + lm32/logic/sakc/rtl/lm32/typeb.v | 50 + lm32/logic/sakc/rtl/wb_bram/wb_bram.v | 62 + lm32/logic/sakc/rtl/wb_conbus/wb_conbus_arb.v | 252 ++ .../sakc/rtl/wb_conbus/wb_conbus_defines.v | 42 + lm32/logic/sakc/rtl/wb_conbus/wb_conbus_top.v | 655 +++++ lm32/logic/sakc/rtl/wb_ddr/async_fifo.v | 116 + lm32/logic/sakc/rtl/wb_ddr/ddr_clkgen.v | 224 ++ lm32/logic/sakc/rtl/wb_ddr/ddr_ctrl.v | 370 +++ lm32/logic/sakc/rtl/wb_ddr/ddr_include.v | 122 + lm32/logic/sakc/rtl/wb_ddr/ddr_init.v | 164 ++ lm32/logic/sakc/rtl/wb_ddr/ddr_pulse78.v | 43 + lm32/logic/sakc/rtl/wb_ddr/ddr_rpath.v | 112 + lm32/logic/sakc/rtl/wb_ddr/ddr_wpath.v | 286 ++ lm32/logic/sakc/rtl/wb_ddr/dpram.v | 64 + lm32/logic/sakc/rtl/wb_ddr/gray_counter.v | 35 + lm32/logic/sakc/rtl/wb_ddr/wb_ddr.v | 621 +++++ lm32/logic/sakc/rtl/wb_gpio/wb_gpio.v | 77 + lm32/logic/sakc/rtl/wb_spi/wb_spi.v | 101 + lm32/logic/sakc/rtl/wb_sram/wb_sram16.v | 163 ++ lm32/logic/sakc/rtl/wb_sram/wb_sram32.v | 122 + lm32/logic/sakc/rtl/wb_timer/wb_timer.v | 144 ++ lm32/logic/sakc/rtl/wb_uart/uart.v | 160 ++ lm32/logic/sakc/rtl/wb_uart/wb_uart.v | 114 + lm32/logic/sakc/sim/ddr/ddr.v | 1379 ++++++++++ lm32/logic/sakc/sim/ddr/ddr_parameters.vh | 63 + lm32/logic/sakc/sim/ddr/parameters.v | 64 + lm32/logic/sakc/sim/ddr/readme.txt | 44 + lm32/logic/sakc/sim/sram/sram16.v | 52 + lm32/logic/sakc/sim/unisims/BUFG.v | 33 + lm32/logic/sakc/sim/unisims/DCM.v | 1731 +++++++++++++ lm32/logic/sakc/sim/unisims/DCM_SP.v | 1244 +++++++++ lm32/logic/sakc/sim/unisims/FDDRRSE.v | 102 + lm32/logic/sakc/system.ucf | 40 + lm32/logic/sakc/system.v | 411 +++ lm32/logic/sakc/system.xst | 11 + lm32/logic/sakc/system_conf.v | 45 + lm32/logic/sakc/system_tb.v | 62 + lm32/logic/sakc/tools/lac-tool/lac-tool | 128 + lm32/logic/sakc/tools/srec2vram/Makefile | 10 + lm32/logic/sakc/tools/srec2vram/srec2vram | Bin 0 -> 7835 bytes lm32/logic/sakc/tools/srec2vram/srec2vram.c | 158 ++ lm32/logic/sakc/tools/uploader/memtest | 150 ++ lm32/logic/sakc/tools/uploader/upload | 217 ++ plasma/gpio/Makefile | 2 +- plasma/gpio/gpio.c | 24 +- plasma/include/plasma.h | 3 +- plasma/logic/Makefile | 9 +- plasma/logic/_impact.cmd | 15 - plasma/logic/default.ipf | Bin 3743 -> 0 bytes plasma/logic/default.ipf_ISE_Backup | Bin 3679 -> 0 bytes plasma/logic/mlite_cpu.vhd | 2 +- plasma/logic/mlite_pack.vhd | 80 +- plasma/logic/plasma.vhd | 139 +- plasma/logic/plasma_3e.ucf | 279 -- plasma/logic/plasma_3e.vhd | 277 -- plasma/logic/plasma_TB.v | 58 - plasma/logic/plasma_TB.vhd | 50 +- plasma/logic/plasma_if.ucf | 111 - plasma/logic/plasma_if.vhd | 152 -- plasma/logic/ram.vhd | 176 -- plasma/logic/ram_image.vhd | 65 +- plasma/logic/ram_xilinx.vhd | 11 +- plasma/logic/reg_bank.vhd | 85 - plasma/logic/simulation/wave.do | 33 +- plasma/logic/simulation/wave1.do | 12 +- plasma/logic/uart.vhd | 199 +- 145 files changed, 27924 insertions(+), 1501 deletions(-) create mode 100644 Examples/sram/src/enable_rx.c create mode 100644 lm32/logic/sakc/Makefile create mode 100644 lm32/logic/sakc/firmware/boot0-serial/Makefile create mode 100644 lm32/logic/sakc/firmware/boot0-serial/crt0ram.S create mode 100644 lm32/logic/sakc/firmware/boot0-serial/crt0ram.d create mode 100644 lm32/logic/sakc/firmware/boot0-serial/crt0ram.o create mode 100755 lm32/logic/sakc/firmware/boot0-serial/image create mode 100755 lm32/logic/sakc/firmware/boot0-serial/image.bin create mode 100644 lm32/logic/sakc/firmware/boot0-serial/image.lst create mode 100644 lm32/logic/sakc/firmware/boot0-serial/image.map create mode 100644 lm32/logic/sakc/firmware/boot0-serial/image.ram create mode 100755 lm32/logic/sakc/firmware/boot0-serial/image.srec create mode 100644 lm32/logic/sakc/firmware/boot0-serial/linker.ld create mode 100644 lm32/logic/sakc/firmware/boot0-serial/main.c create mode 100644 lm32/logic/sakc/firmware/boot0-serial/main.d create mode 100644 lm32/logic/sakc/firmware/boot0-serial/main.o create mode 100644 lm32/logic/sakc/firmware/boot0-serial/soc-hw.c create mode 100644 lm32/logic/sakc/firmware/boot0-serial/soc-hw.d create mode 100644 lm32/logic/sakc/firmware/boot0-serial/soc-hw.h create mode 100644 lm32/logic/sakc/firmware/boot0-serial/soc-hw.o create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/Makefile create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/crt0ram.S create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/image.ram create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/linker.ld create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/main.c create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/spike_hw.c create mode 100644 lm32/logic/sakc/firmware/ddr-phaser/spike_hw.h create mode 100644 lm32/logic/sakc/firmware/gdb-test/Makefile create mode 100644 lm32/logic/sakc/firmware/gdb-test/crt0gdb.S create mode 100644 lm32/logic/sakc/firmware/gdb-test/gdb.c create mode 100644 lm32/logic/sakc/firmware/gdb-test/gdb.h create mode 100644 lm32/logic/sakc/firmware/gdb-test/gdb_uart.c create mode 100644 lm32/logic/sakc/firmware/gdb-test/gdb_uart.h create mode 100644 lm32/logic/sakc/firmware/gdb-test/linker.ld create mode 100644 lm32/logic/sakc/firmware/gdb-test/main.c create mode 100644 lm32/logic/sakc/firmware/gdb-test/soc-hw.c create mode 100644 lm32/logic/sakc/firmware/gdb-test/soc-hw.h create mode 100644 lm32/logic/sakc/firmware/gdb-test/start-gdb create mode 100644 lm32/logic/sakc/firmware/hw-test/Makefile create mode 100644 lm32/logic/sakc/firmware/hw-test/crt0ram.S create mode 100644 lm32/logic/sakc/firmware/hw-test/linker.ld create mode 100644 lm32/logic/sakc/firmware/hw-test/main.c create mode 100644 lm32/logic/sakc/firmware/hw-test/soc-hw.c create mode 100644 lm32/logic/sakc/firmware/hw-test/soc-hw.h create mode 100644 lm32/logic/sakc/rtl/lac/dp_ram.v create mode 100644 lm32/logic/sakc/rtl/lac/lac.v create mode 100644 lm32/logic/sakc/rtl/lac/uart.v create mode 100644 lm32/logic/sakc/rtl/lm32/JTAGB.v create mode 100644 lm32/logic/sakc/rtl/lm32/er1.v create mode 100644 lm32/logic/sakc/rtl/lm32/jtag_cores.v create mode 100644 lm32/logic/sakc/rtl/lm32/jtag_lm32.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_adder.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_addsub.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_cpu.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_dcache.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_debug.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_decoder.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_functions.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_icache.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_include.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_include_all.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_instruction_unit.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_interrupt.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_jtag.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_load_store_unit.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_logic_op.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_mc_arithmetic.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_monitor.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_monitor_ram.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_multiplier.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_ram.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_shifter.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_simtrace.v create mode 100644 lm32/logic/sakc/rtl/lm32/lm32_top.v create mode 100644 lm32/logic/sakc/rtl/lm32/spiprog.v create mode 100755 lm32/logic/sakc/rtl/lm32/system.sdc create mode 100644 lm32/logic/sakc/rtl/lm32/typea.v create mode 100644 lm32/logic/sakc/rtl/lm32/typeb.v create mode 100644 lm32/logic/sakc/rtl/wb_bram/wb_bram.v create mode 100644 lm32/logic/sakc/rtl/wb_conbus/wb_conbus_arb.v create mode 100644 lm32/logic/sakc/rtl/wb_conbus/wb_conbus_defines.v create mode 100644 lm32/logic/sakc/rtl/wb_conbus/wb_conbus_top.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/async_fifo.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_clkgen.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_ctrl.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_include.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_init.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_pulse78.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_rpath.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/ddr_wpath.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/dpram.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/gray_counter.v create mode 100644 lm32/logic/sakc/rtl/wb_ddr/wb_ddr.v create mode 100644 lm32/logic/sakc/rtl/wb_gpio/wb_gpio.v create mode 100644 lm32/logic/sakc/rtl/wb_spi/wb_spi.v create mode 100644 lm32/logic/sakc/rtl/wb_sram/wb_sram16.v create mode 100644 lm32/logic/sakc/rtl/wb_sram/wb_sram32.v create mode 100644 lm32/logic/sakc/rtl/wb_timer/wb_timer.v create mode 100644 lm32/logic/sakc/rtl/wb_uart/uart.v create mode 100644 lm32/logic/sakc/rtl/wb_uart/wb_uart.v create mode 100644 lm32/logic/sakc/sim/ddr/ddr.v create mode 100644 lm32/logic/sakc/sim/ddr/ddr_parameters.vh create mode 100644 lm32/logic/sakc/sim/ddr/parameters.v create mode 100644 lm32/logic/sakc/sim/ddr/readme.txt create mode 100644 lm32/logic/sakc/sim/sram/sram16.v create mode 100644 lm32/logic/sakc/sim/unisims/BUFG.v create mode 100644 lm32/logic/sakc/sim/unisims/DCM.v create mode 100644 lm32/logic/sakc/sim/unisims/DCM_SP.v create mode 100644 lm32/logic/sakc/sim/unisims/FDDRRSE.v create mode 100644 lm32/logic/sakc/system.ucf create mode 100644 lm32/logic/sakc/system.v create mode 100644 lm32/logic/sakc/system.xst create mode 100644 lm32/logic/sakc/system_conf.v create mode 100644 lm32/logic/sakc/system_tb.v create mode 100755 lm32/logic/sakc/tools/lac-tool/lac-tool create mode 100644 lm32/logic/sakc/tools/srec2vram/Makefile create mode 100755 lm32/logic/sakc/tools/srec2vram/srec2vram create mode 100644 lm32/logic/sakc/tools/srec2vram/srec2vram.c create mode 100755 lm32/logic/sakc/tools/uploader/memtest create mode 100755 lm32/logic/sakc/tools/uploader/upload delete mode 100644 plasma/logic/_impact.cmd delete mode 100644 plasma/logic/default.ipf delete mode 100644 plasma/logic/default.ipf_ISE_Backup delete mode 100644 plasma/logic/plasma_3e.ucf delete mode 100644 plasma/logic/plasma_3e.vhd delete mode 100644 plasma/logic/plasma_TB.v delete mode 100644 plasma/logic/plasma_if.ucf delete mode 100644 plasma/logic/plasma_if.vhd delete mode 100644 plasma/logic/ram.vhd diff --git a/Examples/sram/src/Makefile b/Examples/sram/src/Makefile index 9511db3..8ae5901 100644 --- a/Examples/sram/src/Makefile +++ b/Examples/sram/src/Makefile @@ -1,6 +1,6 @@ CC = mipsel-openwrt-linux-gcc -all: jz_init_sram jz_test_gpio +all: jz_init_sram jz_test_gpio enable_rx DEBUG = -O3 -g0 @@ -26,6 +26,9 @@ jz_init_sram: $(COMMON_OBJECTS) jz_test_gpio: $(COMMON_OBJECTS) $(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_test_gpio.c -o jz_test_gpio +enable_rx: $(COMMON_OBJECTS) + $(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_rx.c -o enable_rx + .c.o: $(CC) -c $(CCFLAGS) $< -o $@ @@ -33,7 +36,7 @@ upload: jz_init_sram jz_test_gpio scp jz_test_gpio jz_init_sram root@$(NANO_IP): clean: - rm -f *.o jz_init_sram jz_test_gpio ${EXEC} *~ + rm -f *.o jz_init_sram jz_test_gpio enable_rx ${EXEC} *~ indent: indent -bad -bap -nbc -bl -nce -i2 --no-tabs --line-length120 $(COMMON_SOURCES) $(H_SOURCES) diff --git a/Examples/sram/src/enable_rx.c b/Examples/sram/src/enable_rx.c new file mode 100644 index 0000000..be2775e --- /dev/null +++ b/Examples/sram/src/enable_rx.c @@ -0,0 +1,40 @@ +/* + JZ47xx test gpio + + Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com + Carlos Camargo cicamargoba@unal.edu.co + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include + +#include "jz47xx_gpio.h" + +#define RXD_PORT JZ_GPIO_PORT_D +#define RXD_PIN 26 + +int +main () +{ + JZ_PIO *pio = jz_gpio_map (RXD_PORT); + + if (!pio) + return -1; + + jz_gpio_as_func (pio, RXD_PIN, 1); + + return 0; +} diff --git a/Examples/sram/src/jz47xx_gpio.c b/Examples/sram/src/jz47xx_gpio.c index affa85e..81a1c04 100644 --- a/Examples/sram/src/jz47xx_gpio.c +++ b/Examples/sram/src/jz47xx_gpio.c @@ -79,18 +79,21 @@ jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func) pio->PXFUNS = (1 << o); pio->PXTRGC = (1 << o); pio->PXSELC = (1 << o); + pio->PXPES = (1 << o); return 1; case 1: pio->PXFUNS = (1 << o); pio->PXTRGC = (1 << o); pio->PXSELS = (1 << o); + pio->PXPES = (1 << o); return 1; case 2: pio->PXFUNS = (1 << o); pio->PXTRGS = (1 << o); pio->PXSELC = (1 << o); + pio->PXPES = (1 << o); return 1; } return 0; diff --git a/lm32/logic/sakc/Makefile b/lm32/logic/sakc/Makefile new file mode 100644 index 0000000..cc63e8a --- /dev/null +++ b/lm32/logic/sakc/Makefile @@ -0,0 +1,131 @@ +VINCDIR= \ + -I../rtl/wb_conbus \ + -I../rtl/lm32 \ + -I../rtl/wb_ddr + +SYN_SRC= + +SIM_SRC= \ + system_tb.v \ + ../sim/sram/sram16.v \ + ../sim/unisims/BUFG.v \ + ../sim/unisims/DCM.v + +SRC= \ + ../system.v \ + ../rtl/lac/lac.v \ + ../rtl/lac/uart.v \ + ../rtl/lac/dp_ram.v \ + ../rtl/lm32/lm32_cpu.v \ + ../rtl/lm32/lm32_instruction_unit.v \ + ../rtl/lm32/lm32_decoder.v \ + ../rtl/lm32/lm32_simtrace.v \ + ../rtl/lm32/lm32_load_store_unit.v \ + ../rtl/lm32/lm32_adder.v \ + ../rtl/lm32/lm32_addsub.v \ + ../rtl/lm32/lm32_logic_op.v \ + ../rtl/lm32/lm32_shifter.v \ + ../rtl/lm32/lm32_multiplier.v \ + ../rtl/lm32/lm32_mc_arithmetic.v \ + ../rtl/lm32/lm32_interrupt.v \ + ../rtl/lm32/lm32_icache.v \ + ../rtl/lm32/lm32_dcache.v \ + ../rtl/lm32/lm32_ram.v \ + ../rtl/wb_bram/wb_bram.v \ + ../rtl/wb_uart/wb_uart.v \ + ../rtl/wb_timer/wb_timer.v \ + ../rtl/wb_gpio/wb_gpio.v \ + ../rtl/wb_conbus/wb_conbus_top.v \ + ../rtl/wb_conbus/wb_conbus_arb.v \ + ../rtl/wb_sram/wb_sram32.v + +############################################################################# +# Synthesis constants +SYNCLEAN=system.bgn system.drc system.mrp system.ngd system.pcf +SYNCLEAN+=system.bld system.lso system.ncd system.ngm system.srp +SYNCLEAN+=system.bit system_signalbrowser.* system-routed_pad.tx +SYNCLEAN+=system.map system_summary.xml timing.twr +SYNCLEAN+=system-routed* system_usage* system.ngc param.opt netlist.lst +SYNCLEAN+=xst system.prj *ngr *xrpt _xmsgs xlnx_auto_0_xdb *html *log *xwbt + +USAGE_DEPTH=0 +SMARTGUIDE= + +############################################################################# +# Simulation constants +SIMCLEAN=system_tb.vvp system_tb.vcd verilog.log system_tb.vvp.list simulation + +CVER=cver +GTKWAVE=gtkwave +IVERILOG=iverilog +VVP=vvp + +############################################################################# +# +sim: system_tb.vcd +syn: system.bit +view: system_tb.view + +############################################################################# +# Ikarus verilog simulation + +system_tb.vvp: + rm -rf simulation && mkdir simulation + cp system_tb.v system_conf.v simulation && cd simulation && rm -f $@.list + for i in $(SRC); do echo $$i >> simulation/$@.list; done + for i in $(SIM_SRC); do echo $$i >> simulation/$@.list; done + cd simulation && $(IVERILOG) -o $@ $(VINCDIR) -c $@.list -s $(@:.vvp=) + +%.vcd: %.vvp + cd simulation && $(VVP) $< + +############################################################################# +# ISE Synthesis + + +system.prj: + rm -rf build && mkdir build + @rm -f $@ + for i in $(SRC); do echo verilog work $$i >> build/$@; done + for i in $(SRC_HDL); do echo VHDL work $$i >> build/$@; done + +system.ngc: system.prj + cd build && xst -ifn ../system.xst + +system.ngd: system.ngc system.ucf + cd build && ngdbuild -uc ../system.ucf system.ngc + +system.ncd: system.ngd + cd build && map $(SMARTGUIDE) system.ngd + +system-routed.ncd: system.ncd + cd build && par $(SMARTGUIDE) -ol high -w system.ncd system-routed.ncd + +system.bit: system-routed.ncd + cd build && bitgen -w system-routed.ncd system.bit + @mv -f build/system.bit $@ + +system.mcs: system.bit + cd build && promgen -u 0 system + +system-routed.xdl: system-routed.ncd + cd build && xdl -ncd2xdl system-routed.ncd system-routed.xdl + +system-routed.twr: system-routed.ncd + cd build && trce -v 10 system-routed.ncd system.pcf + +timing: system-routed.twr + +usage: system-routed.xdl + xdlanalyze.pl system-routed.xdl $(USAGE_DEPTH) + +#################################################################### +# final targets + +%.view: %.vcd + cd simulation && $(GTKWAVE) $< $<.save + +clean: + rm -Rf build $(SYNCLEAN) $(SIMCLEAN) + +.PHONY: clean view diff --git a/lm32/logic/sakc/firmware/boot0-serial/Makefile b/lm32/logic/sakc/firmware/boot0-serial/Makefile new file mode 100644 index 0000000..372e03a --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/Makefile @@ -0,0 +1,50 @@ +LM32_CC=lm32-elf-gcc +LM32_LD=lm32-elf-ld +LM32_OBJCOPY=lm32-elf-objcopy +LM32_OBJDUMP=lm32-elf-objdump + +SREC2VRAM ?= ../../tools/srec2vram/srec2vram + +VRAMFILE=image.ram + +CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled +LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld +SEGMENTS = -j .text -j .rodata -j .data + +all: $(VRAMFILE) + +crt0ram.o: crt0ram.S + $(LM32_CC) $(CFLAGS) -c crt0ram.S + +main.o: main.c + $(LM32_CC) $(CFLAGS) -c main.c + +soc-hw.o: soc-hw.c + $(LM32_CC) $(CFLAGS) -c soc-hw.c + +image: crt0ram.o main.o soc-hw.o + $(LM32_LD) $(LDFLAGS) -Map image.map -N -o image crt0ram.o main.o soc-hw.o + +image.lst: image + $(LM32_OBJDUMP) -h -S $< > $@ + +image.bin: image + $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.bin + +image.srec: image image.lst + $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec + +$(VHDLFILE): image.srec + $(SREC2VHDL) image.srec > $(VHDLFILE) + +$(VRAMFILE): image.srec + $(SREC2VRAM) image.srec 0x00000000 0x1000 > $(VRAMFILE) + +clean: + rm -f image image.lst image.bin image.srec image.map *.o *.d + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif + diff --git a/lm32/logic/sakc/firmware/boot0-serial/crt0ram.S b/lm32/logic/sakc/firmware/boot0-serial/crt0ram.S new file mode 100644 index 0000000..975a14a --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/crt0ram.S @@ -0,0 +1,85 @@ +/* + * LatticeMico32 C startup code. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Exception handlers - Must be 32 bytes long. */ + .section .text, "ax", @progbits + .global _start + .global irq_enable, irq_disable, irq_mask, jump, halt +_start: +_reset_handler: + xor r0, r0, r0 + wcsr IE, r0 + mvhi r1, hi(_reset_handler) + ori r1, r1, lo(_reset_handler) + wcsr EBA, r1 + calli _crt0 + nop + nop + +_crt0: + /* Setup stack and global pointer */ + mvhi sp, hi(_fstack) + ori sp, sp, lo(_fstack) + mvhi gp, hi(_gp) + ori gp, gp, lo(_gp) + + /* Clear BSS */ + mvhi r1, hi(_fbss) + ori r1, r1, lo(_fbss) + mvhi r3, hi(_ebss) + ori r3, r3, lo(_ebss) +.clearBSS: + be r1, r3, .callMain + sw (r1+0), r0 + addi r1, r1, 4 + bi .clearBSS + +.callMain: + mvi r1, 0 + mvi r2, 0 + mvi r3, 0 + calli main + +irq_enable: + mvi r1, 1 + wcsr IE, r1 + ret + +irq_mask: + mvi r1, 0x0000000f + wcsr IM, r1 + ret + +irq_disable: + mvi r1, 0 + wcsr IE, r1 + ret + +jump: + b r1 + +halt: + bi halt + diff --git a/lm32/logic/sakc/firmware/boot0-serial/crt0ram.d b/lm32/logic/sakc/firmware/boot0-serial/crt0ram.d new file mode 100644 index 0000000..0489cf7 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/crt0ram.d @@ -0,0 +1 @@ +crt0ram.o: crt0ram.S diff --git a/lm32/logic/sakc/firmware/boot0-serial/crt0ram.o b/lm32/logic/sakc/firmware/boot0-serial/crt0ram.o new file mode 100644 index 0000000000000000000000000000000000000000..0aec3da7e925378c0a543e873d1a399cb51f7857 GIT binary patch literal 1132 zcmb7CO=}ZT6upzAT0u?Yq6_OHMUf&hM989`3n^NTqynp7jC4U^D;M%bs-)&bI-Z&-uE?c|KX$cpccpsfxL&VB;>pI zU0<;x^D=h?IROh)tu8}<75O1jX9-zc6S;egcop%*@4BLn`dH+_b!j|rqjp&u-%d|| zb}>)424WoZ2z)R>?$e3a%?Z{hwP=2f{x7JNFyBj^=^?so8V9N}o0!nq!b#XS&PdqH zbGG~k+Ni}&e)ITG91lh+Lj$H(AmL4bd7?)9l&UYJ$dGKF# ztx65&7=w2xO6YuyxM4*N=LkA*=RvN+{VjkOKwXovk52(AbUyWeMKu3W17DfX8?IHY zq2}6ckf2`#?}G$=8+-y1^tZgi2aWVR^J`H3JxIUra(n|msf<5`KB)L-(1#WOlA7Sg zfOr~ae(Q`+&-mFp^Zij~bL*mk8TAvJNfc+UBVn9aldWxTLYX9aY=$F=a%VCp!|ZKj zN2ZrpFZ;uMrc;ye$o9K*R|Y0=61_o3yd%-pE;QeFWcf`w8-RZs@V*JWzhG`Ed7qax se*;?cDkGHd+`BjmY=5gmO&A$@4!nZ}>UN3q53tyFJd;kCd literal 0 HcmV?d00001 diff --git a/lm32/logic/sakc/firmware/boot0-serial/image b/lm32/logic/sakc/firmware/boot0-serial/image new file mode 100755 index 0000000000000000000000000000000000000000..218aff228085a06fca380e6efde5fea64da7d127 GIT binary patch literal 6169 zcmbVQeQaDu5ue>V#~0uE?8HvuHi>#}lg3Trv)x=9lctUBIHaLT>Nv4*(jLFr zkGpdzLa@@lncvLp?Ci|GeS7!yeFr})q@Ze(^iA+q5F=_`P&h^rNV{k?wHW;|P}AfY zA~_Gxi0%iVMf4eX>F)&pXQKCrd~inGXEqSsHQ#c5=0?!tazWe4Gc!KeC*=I_E#x1M zz_ye8f2mYHios7zqC*cq8-c|lWUnniCa7f*a~Phi{5-~ACZe75mG>r|puog;$&az0 z-@T0jpkuE%0W$n(9e+Rb+hDs5V|LC{fc?V975LaNF-sj2Pg48Dx2SdEDGE)@Rs9ac znkj`?w#LF#jJ^EX~eOTvp z@Nb@rj1%Y^uQ(^^h*x=c(1GzO5^OW}MCBvUTVeYSY+g6E7me-P(B0H$?2YYu*#2z> zx$7U2bN#;8M!JTGPTvxs@j+_kyn?oaHi3q^&?B8Bh9i}adEKTib6uSnFJBuOznT18 z2had$7*yrG&UUs7GWa3u2fQDAMcH61;+XB)tMrwwNzfr`Juy)Ec-$dB+YD?%-X5i( ziCNh$vr8fd#K?9h9;<4Bi7h_OM|CL=91~CuEIy+(46n@roGv z0(zu`qsAH}3e<*d2_0yw4O-byosI`J)dopK8w`puNJEgCnAoVf28qHgu;N(%-^H|v zV34C$OK7f6)Q{;K?;!RZfYdCEr7P>#5>extunJ>=pzHOum4=qDlowH#t#FiVPW2F? zmYT?B3};VN^wp(rRRi_4ai&(+BH$FY)p>`ueWMvQ9(*83w1!6!t+lCJS4-%g5PRcn zZX|3F)E!%eBK&AZchP5|oC8(*{gPAP>+|zDM}B`pI$KhT?bt{}2Ydn>Mx9mEE!Tma z@Cn36cQ&xgcCixA&FFB7lgh*MnH3K@9tni06x5iuAizV0#2O|$(Q%@RIUXY#+0BSp zV-$NB9%m>xtkI@C3Ct~S6cZ~FBsw6w2i@g4D1;stH{r=~e1}&#W?|TmQO)YvrdM(| z0~$e>KUC}dO*KKH04Wm0$&q=`r#OM1njn)En~Dy3CoG@myj+vKvghS31SG~}zeax6 zU6P;CD8T4_xl5xETYgdAr4hfw^jEoCqjvTE+022QlXv5JuwjF|7xp)^*)Qb*ZKfvM zB|oPTPbLQCeH!s(A}SAR6bhuXBoArO8pxGV?ZXg5!L;0jk|8OgOr``u-T?m)&8$VP#YMFT zUP2*7N^t!+g+FO7VKTv=X0Ge&6y{MM3w&wCMf4@%Dao(I7DnjTgxA6@?-hM`mRW*A zb_lN(>=&3t-_3K$##IoV5=V$b5$na>Ae?fUSL(y7izUpBe5>62u?;KO!$2HqH@=V; zc~T7W7Omh-_;INo@jvlSuKBB$!}(P zO1*cRwfqbm2$T)vRw3T~XA=oD7E;DZXQK(QRLmv1ryq(=GmkT#jb}G%dgcaA=i4-0 zSflB42ESnN%Lbn__|*<=x42HzCFAGXjT*lf*7Ul@!hfs6BH+sk&9xgzM0*gMe5Z^C zpH+@gY}a#%UgM+RS2Py8*J_Ia9hDe1mInCJlN9P*3w-JmkwCd7x~=32&)bTrYWlwF@Fhbh8;D2SNrG!y8=iswuKXAM1P zdaF#3}lG)}J86zBGTOC%>VR6!FY9*KnTdg~*d=`8wi9bN=~p7E#H z_o60q(D8wblY|)KoS?2cyab-#NUO*BK$~iq4~S(LCxW`(1S~_#%Xpg9&?A zQl4bHmTm{TTT8*I#!HyiS|d@bf@suY&^-FAwwedKpxGC|p4IH{z+PJJ=4FV^Y0+h{ zSC(rbq4wn>j;?pPh-dh%7F_~+dAW9r+UAgpPCOlY|7216Fo)eRH7%F?JgH5yQlIgr^n0exV^{A zrL1l$UC2D-6kPT5p|`u}7SfJKDsLQ%N?M{+@D!^{VUn82m9r(zu3`E}7ZG3LUc#df zUQ8)%S=5R+{l;}1wc}DLeTkCgOy=PoRG2BvXueOA+qHqMd?J_0BVwLdF@2=!sLNVC zQ}^%PyDQR#1m9-zOVQ%PnUXUJS}JHdZMl*=Q=(`gmvl-FMfG#CSOn`%mQ!(O5_|bU zi_+PtoaMcA*0uap!O2vCmrGcAzC4+Qrsl2SpgL8!9C13LSXjozj`^S3dRPl|bvFk+ zhFy=%SZ#Jw@~g>qcqdseFM#KR$~LxR{cVQwRb&?ZGH?jpHtVkkf&e<(;qD=?g10)h zwR{Xb`!$X2qTHR0`54HhU9^c}p*zrZwjsY8Z6aM(rv(4)G25Nb*!LxWQpxb8S zOF>X)7a9Tn&>Ge0)X`IuH}lQ;)f%q)c&u&=*f7^+0Npk_*S8_CJlODlJowvUo7H^} z0_Jk?*8jlp#;)ZLz_`Iy8{2Sa8ER%*%iG|7Y!N8iaAT^DMun&?k6|al z^LX57Ref7Q`Da+2zqN}P%D*^lv;HjpH;Tc=M(tTM*HCT1`q#0M0IT1S)&RKvec<`|_eiw?lTSln z<9YTI{uZF;I}Ojz^L-zGj$GGR&G#bwUjyD`{Qn$y3D|G&FW8nF#&i6?R-lI80L%Mn z*x3IG{Nw1>{t8&H4*wneOdWood2V_={F96p(a&pt0((a9Pt1>e3Z$)mJ%a0f8r{q% zaBl0nry0Kq_Iabn{ukYK{*Vu`1DMYTvwkrE%Q+Y}kz8rV6&ZOt+uWfv2bnsC8 z=z-(=^vBtJ$@LW=9v^<-@Zg~Xdr5zkweh~g!xVSDO-(?u1OiRakh=rOf4%%oO=pp!K1c%|BHBtB(6^zkVUX4&N= I?i$^{086r9p8x;= literal 0 HcmV?d00001 diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.bin b/lm32/logic/sakc/firmware/boot0-serial/image.bin new file mode 100755 index 0000000..219ec83 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/image.bin @@ -0,0 +1,44 @@ +S00C0000696D6167652E62696E89 +S113000098000000D00000007801000038210000B2 +S1130010D0E10000F80000033400000034000000C8 +S1130020781C00003B9C0FFC781A00003B5A02A08D +S11300307801000038210298780300003863029C9C +S1130040442300045820000034210004E3FFFFFD92 +S1130050340100003402000034030000F800001DE5 +S113006034010001D0010000C3A000003401000FDE +S1130070D0210000C3A0000034010000D001000022 +S1130080C3A00000C0200000E0000000379CFFF87F +S11300905B8B00085B9D0004F80000573C2B0008B4 +S11300A0F8000055B56108003C2B0008F800005228 +S11300B0B56108003C2B0008F800004FB56108004A +S11300C02B9D00042B8B0008379C0008C3A0000064 +S11300D0379CFFE45B8B001C5B8C00185B8D001469 +S11300E05B8E00105B8F000C5B9000085B9D00042E +S11300F0F8000040340D00673401002A340E007506 +S1130100340F006478100000442D0008442E0016BB +S1130110442F000ABA00080038210270F800004891 +S1130120F80000355C2DFFFAFBFFFFD9FBFFFFD67B +S1130130F8000031E3FFFFFCFBFFFFD5B8205800B7 +S1130140FBFFFFD3B5616000516CFFF64161000015 +S1130150356B0001F8000031558BFFFDF8000026D7 +S1130160E3FFFFF1FBFFFFCAB8205800FBFFFFC805 +S1130170B5616000516CFFEBF800001F31610000B5 +S1130180356B0001558BFFFDF800001BE3FFFFE614 +S113019078020000384202903803C350284200001D +S11301A0882308005841001034010000584100140D +S11301B03401000A5841000C2841000C20210001A0 +S11301C04420FFFEC3A00000780100003821029003 +S11301D0282100003802C3505822000434020000D1 +S11301E0582200083402000E58220000C3A0000068 +S11301F0C3A00000780100003821028C28220000EE +S113020028410000202100014420FFFE2841000471 +S1130210202100FFC3A00000780200003842028CB5 +S113022028430000202100FF286200002042001023 +S11302305C40FFFE58610004C3A00000402400009D +S11302404480000B780200003842028C28430000EE +S113025028620000204200105C40FFFE5864000445 +S113026034210001402400005C82FFFAC3A0000096 +S11302702A2A53414B432F626F6F746C6F6164651C +S10F0280722A2A203E200D0A0000000013 +S10F028CF0000000F0010000F00200008F +S9030000FC diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.lst b/lm32/logic/sakc/firmware/boot0-serial/image.lst new file mode 100644 index 0000000..3b303e3 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/image.lst @@ -0,0 +1,454 @@ + +image: file format elf32-lm32 + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 00000270 00000000 00000000 00000054 2**2 + CONTENTS, ALLOC, LOAD, CODE + 1 .rodata 0000001c 00000270 00000270 000002c4 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 2 .data 0000000c 0000028c 0000028c 000002e0 2**2 + CONTENTS, ALLOC, LOAD, DATA + 3 .bss 00000004 00000298 00000298 000002ec 2**2 + ALLOC + 4 .debug_abbrev 00000219 00000000 00000000 000002ec 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_info 000003d0 00000000 00000000 00000505 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_line 000002d8 00000000 00000000 000008d5 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_frame 000000a0 00000000 00000000 00000bb0 2**2 + CONTENTS, READONLY, DEBUGGING + 8 .debug_loc 000000fb 00000000 00000000 00000c50 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_pubnames 000000bc 00000000 00000000 00000d4b 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_aranges 00000040 00000000 00000000 00000e07 2**0 + CONTENTS, READONLY, DEBUGGING + 11 .debug_ranges 00000018 00000000 00000000 00000e47 2**0 + CONTENTS, READONLY, DEBUGGING + 12 .debug_str 0000017b 00000000 00000000 00000e5f 2**0 + CONTENTS, READONLY, DEBUGGING + 13 .comment 00000011 00000000 00000000 00000fda 2**0 + CONTENTS, READONLY + +Disassembly of section .text: + +00000000 <_ftext>: + 0: 98 00 00 00 xor r0,r0,r0 + 4: d0 00 00 00 wcsr IE,r0 + 8: 78 01 00 00 mvhi r1,0x0 + c: 38 21 00 00 ori r1,r1,0x0 + 10: d0 e1 00 00 wcsr EBA,r1 + 14: f8 00 00 03 calli 20 <_crt0> + 18: 34 00 00 00 nop + 1c: 34 00 00 00 nop + +00000020 <_crt0>: + 20: 78 1c 00 00 mvhi sp,0x0 + 24: 3b 9c 0f fc ori sp,sp,0xffc + 28: 78 1a 00 00 mvhi gp,0x0 + 2c: 3b 5a 02 a0 ori gp,gp,0x2a0 + 30: 78 01 00 00 mvhi r1,0x0 + 34: 38 21 02 98 ori r1,r1,0x298 + 38: 78 03 00 00 mvhi r3,0x0 + 3c: 38 63 02 9c ori r3,r3,0x29c + +00000040 <.clearBSS>: + 40: 44 23 00 04 be r1,r3,50 <.callMain> + 44: 58 20 00 00 sw (r1+0),r0 + 48: 34 21 00 04 addi r1,r1,4 + 4c: e3 ff ff fd bi 40 <.clearBSS> + +00000050 <.callMain>: + 50: 34 01 00 00 mvi r1,0 + 54: 34 02 00 00 mvi r2,0 + 58: 34 03 00 00 mvi r3,0 + 5c: f8 00 00 1d calli d0
+ +00000060 : + 60: 34 01 00 01 mvi r1,1 + 64: d0 01 00 00 wcsr IE,r1 + 68: c3 a0 00 00 ret + +0000006c : + 6c: 34 01 00 0f mvi r1,15 + 70: d0 21 00 00 wcsr IM,r1 + 74: c3 a0 00 00 ret + +00000078 : + 78: 34 01 00 00 mvi r1,0 + 7c: d0 01 00 00 wcsr IE,r1 + 80: c3 a0 00 00 ret + +00000084 : + 84: c0 20 00 00 b r1 + +00000088 : + 88: e0 00 00 00 bi 88 + +0000008c : + */ +#include "soc-hw.h" + +/* prototypes */ +uint32_t read_uint32() +{ + 8c: 37 9c ff f8 addi sp,sp,-8 + 90: 5b 8b 00 08 sw (sp+8),r11 + 94: 5b 9d 00 04 sw (sp+4),ra + uint32_t val = 0, i; + + for (i = 0; i < 4; i++) { + val <<= 8; + val += (uint8_t)uart_getchar(); + 98: f8 00 00 57 calli 1f4 +uint32_t read_uint32() +{ + uint32_t val = 0, i; + + for (i = 0; i < 4; i++) { + val <<= 8; + 9c: 3c 2b 00 08 sli r11,r1,8 + val += (uint8_t)uart_getchar(); + a0: f8 00 00 55 calli 1f4 + a4: b5 61 08 00 add r1,r11,r1 +uint32_t read_uint32() +{ + uint32_t val = 0, i; + + for (i = 0; i < 4; i++) { + val <<= 8; + a8: 3c 2b 00 08 sli r11,r1,8 + val += (uint8_t)uart_getchar(); + ac: f8 00 00 52 calli 1f4 + b0: b5 61 08 00 add r1,r11,r1 +uint32_t read_uint32() +{ + uint32_t val = 0, i; + + for (i = 0; i < 4; i++) { + val <<= 8; + b4: 3c 2b 00 08 sli r11,r1,8 + val += (uint8_t)uart_getchar(); + b8: f8 00 00 4f calli 1f4 + } + + return val; +} + bc: b5 61 08 00 add r1,r11,r1 + c0: 2b 9d 00 04 lw ra,(sp+4) + c4: 2b 8b 00 08 lw r11,(sp+8) + c8: 37 9c 00 08 addi sp,sp,8 + cc: c3 a0 00 00 ret + +000000d0
: + +int main(int argc, char **argv) +{ + d0: 37 9c ff e4 addi sp,sp,-28 + d4: 5b 8b 00 1c sw (sp+28),r11 + d8: 5b 8c 00 18 sw (sp+24),r12 + dc: 5b 8d 00 14 sw (sp+20),r13 + e0: 5b 8e 00 10 sw (sp+16),r14 + e4: 5b 8f 00 0c sw (sp+12),r15 + e8: 5b 90 00 08 sw (sp+8),r16 + ec: 5b 9d 00 04 sw (sp+4),ra + int8_t *p; + uint8_t c; + + // Initialize UART + uart_init(); + f0: f8 00 00 40 calli 1f0 + + c = '*'; // print msg on first iteration + for(;;) { + uint32_t start, size; + + switch (c) { + f4: 34 0d 00 67 mvi r13,103 +{ + int8_t *p; + uint8_t c; + + // Initialize UART + uart_init(); + f8: 34 01 00 2a mvi r1,42 + + c = '*'; // print msg on first iteration + for(;;) { + uint32_t start, size; + + switch (c) { + fc: 34 0e 00 75 mvi r14,117 + 100: 34 0f 00 64 mvi r15,100 + case 'g': // goto + start = read_uint32(); + jump(start); + break; + default: + uart_putstr("**SAKC/bootloader** > \r\n"); + 104: 78 10 00 00 mvhi r16,0x0 + + c = '*'; // print msg on first iteration + for(;;) { + uint32_t start, size; + + switch (c) { + 108: 44 2d 00 08 be r1,r13,128 + 10c: 44 2e 00 16 be r1,r14,164 + 110: 44 2f 00 0a be r1,r15,138 + case 'g': // goto + start = read_uint32(); + jump(start); + break; + default: + uart_putstr("**SAKC/bootloader** > \r\n"); + 114: ba 00 08 00 mv r1,r16 + 118: 38 21 02 70 ori r1,r1,0x270 + 11c: f8 00 00 48 calli 23c + break; + }; + c = uart_getchar(); + 120: f8 00 00 35 calli 1f4 + + c = '*'; // print msg on first iteration + for(;;) { + uint32_t start, size; + + switch (c) { + 124: 5c 2d ff fa bne r1,r13,10c + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + uart_putchar( *p ); + break; + case 'g': // goto + start = read_uint32(); + 128: fb ff ff d9 calli 8c + jump(start); + 12c: fb ff ff d6 calli 84 + break; + default: + uart_putstr("**SAKC/bootloader** > \r\n"); + break; + }; + c = uart_getchar(); + 130: f8 00 00 31 calli 1f4 + 134: e3 ff ff fc bi 124 + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + *p = uart_getchar(); + break; + case 'd': // download + start = read_uint32(); + 138: fb ff ff d5 calli 8c + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 13c: b8 20 58 00 mv r11,r1 + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + *p = uart_getchar(); + break; + case 'd': // download + start = read_uint32(); + size = read_uint32(); + 140: fb ff ff d3 calli 8c + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 144: b5 61 60 00 add r12,r11,r1 + 148: 51 6c ff f6 bgeu r11,r12,120 + uart_putchar( *p ); + 14c: 41 61 00 00 lbu r1,(r11+0) + *p = uart_getchar(); + break; + case 'd': // download + start = read_uint32(); + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 150: 35 6b 00 01 addi r11,r11,1 + uart_putchar( *p ); + 154: f8 00 00 31 calli 218 + *p = uart_getchar(); + break; + case 'd': // download + start = read_uint32(); + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 158: 55 8b ff fd bgu r12,r11,14c + break; + default: + uart_putstr("**SAKC/bootloader** > \r\n"); + break; + }; + c = uart_getchar(); + 15c: f8 00 00 26 calli 1f4 + 160: e3 ff ff f1 bi 124 + for(;;) { + uint32_t start, size; + + switch (c) { + case 'u': // upload + start = read_uint32(); + 164: fb ff ff ca calli 8c + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 168: b8 20 58 00 mv r11,r1 + uint32_t start, size; + + switch (c) { + case 'u': // upload + start = read_uint32(); + size = read_uint32(); + 16c: fb ff ff c8 calli 8c + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 170: b5 61 60 00 add r12,r11,r1 + 174: 51 6c ff eb bgeu r11,r12,120 + *p = uart_getchar(); + 178: f8 00 00 1f calli 1f4 + 17c: 31 61 00 00 sb (r11+0),r1 + + switch (c) { + case 'u': // upload + start = read_uint32(); + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + 180: 35 6b 00 01 addi r11,r11,1 + 184: 55 8b ff fd bgu r12,r11,178 + break; + default: + uart_putstr("**SAKC/bootloader** > \r\n"); + break; + }; + c = uart_getchar(); + 188: f8 00 00 1b calli 1f4 + 18c: e3 ff ff e6 bi 124 + +00000190 : +void sleep(int msec) +{ + uint32_t tcr; + + // Use timer0.1 + timer0->compare1 = (FCPU/1000)*msec; + 190: 78 02 00 00 mvhi r2,0x0 + 194: 38 42 02 90 ori r2,r2,0x290 + 198: 38 03 c3 50 mvu r3,0xc350 + 19c: 28 42 00 00 lw r2,(r2+0) + 1a0: 88 23 08 00 mul r1,r1,r3 + 1a4: 58 41 00 10 sw (r2+16),r1 + timer0->counter1 = 0; + 1a8: 34 01 00 00 mvi r1,0 + 1ac: 58 41 00 14 sw (r2+20),r1 + timer0->tcr1 = TIMER_EN | TIMER_IRQEN; + 1b0: 34 01 00 0a mvi r1,10 + 1b4: 58 41 00 0c sw (r2+12),r1 + + do { + //halt(); + tcr = timer0->tcr1; + 1b8: 28 41 00 0c lw r1,(r2+12) + } while ( ! (tcr & TIMER_TRIG) ); + 1bc: 20 21 00 01 andi r1,r1,0x1 + 1c0: 44 20 ff fe be r1,r0,1b8 +} + 1c4: c3 a0 00 00 ret + +000001c8 : + +void tic_init() +{ + // Setup timer0.0 + timer0->compare0 = (FCPU/1000); + 1c8: 78 01 00 00 mvhi r1,0x0 + 1cc: 38 21 02 90 ori r1,r1,0x290 + 1d0: 28 21 00 00 lw r1,(r1+0) + 1d4: 38 02 c3 50 mvu r2,0xc350 + 1d8: 58 22 00 04 sw (r1+4),r2 + timer0->counter0 = 0; + 1dc: 34 02 00 00 mvi r2,0 + 1e0: 58 22 00 08 sw (r1+8),r2 + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; + 1e4: 34 02 00 0e mvi r2,14 + 1e8: 58 22 00 00 sw (r1+0),r2 +} + 1ec: c3 a0 00 00 ret + +000001f0 : + //uart0->lcr = 0x03; // Line Control Register: 8N1 + //uart0->mcr = 0x00; // Modem Control Register + + // Setup Divisor register (Fclk / Baud) + //uart0->div = (FCPU/(57600*16)); +} + 1f0: c3 a0 00 00 ret + +000001f4 : + +char uart_getchar() +{ + 1f4: 78 01 00 00 mvhi r1,0x0 + 1f8: 38 21 02 8c ori r1,r1,0x28c + 1fc: 28 22 00 00 lw r2,(r1+0) + while (! (uart0->ucr & UART_DR)) ; + 200: 28 41 00 00 lw r1,(r2+0) + 204: 20 21 00 01 andi r1,r1,0x1 + 208: 44 20 ff fe be r1,r0,200 + return uart0->rxtx; + 20c: 28 41 00 04 lw r1,(r2+4) +} + 210: 20 21 00 ff andi r1,r1,0xff + 214: c3 a0 00 00 ret + +00000218 : + +void uart_putchar(char c) +{ + 218: 78 02 00 00 mvhi r2,0x0 + 21c: 38 42 02 8c ori r2,r2,0x28c + 220: 28 43 00 00 lw r3,(r2+0) + 224: 20 21 00 ff andi r1,r1,0xff + while (uart0->ucr & UART_BUSY) ; + 228: 28 62 00 00 lw r2,(r3+0) + 22c: 20 42 00 10 andi r2,r2,0x10 + 230: 5c 40 ff fe bne r2,r0,228 + uart0->rxtx = c; + 234: 58 61 00 04 sw (r3+4),r1 +} + 238: c3 a0 00 00 ret + +0000023c : + +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + 23c: 40 24 00 00 lbu r4,(r1+0) + 240: 44 80 00 0b be r4,r0,26c + 244: 78 02 00 00 mvhi r2,0x0 + 248: 38 42 02 8c ori r2,r2,0x28c + 24c: 28 43 00 00 lw r3,(r2+0) + return uart0->rxtx; +} + +void uart_putchar(char c) +{ + while (uart0->ucr & UART_BUSY) ; + 250: 28 62 00 00 lw r2,(r3+0) + 254: 20 42 00 10 andi r2,r2,0x10 + 258: 5c 40 ff fe bne r2,r0,250 + uart0->rxtx = c; + 25c: 58 64 00 04 sw (r3+4),r4 +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + uart_putchar(*c); + c++; + 260: 34 21 00 01 addi r1,r1,1 +} + +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + 264: 40 24 00 00 lbu r4,(r1+0) + 268: 5c 82 ff fa bne r4,r2,250 + 26c: c3 a0 00 00 ret diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.map b/lm32/logic/sakc/firmware/boot0-serial/image.map new file mode 100644 index 0000000..b8198a3 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/image.map @@ -0,0 +1,127 @@ + +Memory Configuration + +Name Origin Length Attributes +bram 0x00000000 0x00001000 +*default* 0x00000000 0xffffffff + +Linker script and memory map + + 0x00000000 __DYNAMIC = 0x0 + 0x00000000 _BRAM_START = 0x0 + 0x00001000 _BRAM_SIZE = 0x1000 + 0x00001000 _BRAM_END = (_BRAM_START + _BRAM_SIZE) + +.text 0x00000000 0x270 + 0x00000000 _ftext = . + *(.text .stub .text.* .gnu.linkonce.t.*) + .text 0x00000000 0x8c crt0ram.o + 0x00000000 _start + 0x00000060 irq_enable + 0x0000006c irq_mask + 0x00000078 irq_disable + 0x00000084 jump + 0x00000088 halt + .text 0x0000008c 0x104 main.o + 0x0000008c read_uint32 + 0x000000d0 main + .text 0x00000190 0xe0 soc-hw.o + 0x00000190 sleep + 0x000001c8 tic_init + 0x000001f0 uart_init + 0x000001f4 uart_getchar + 0x00000218 uart_putchar + 0x0000023c uart_putstr + 0x00000270 _etext = . + +.rodata 0x00000270 0x1c + 0x00000270 . = ALIGN (0x4) + 0x00000270 _frodata = . + *(.rodata .rodata.* .gnu.linkonce.r.*) + .rodata.str1.4 + 0x00000270 0x1c main.o + *(.rodata1) + 0x0000028c _erodata = . + +.data 0x0000028c 0xc + 0x0000028c . = ALIGN (0x4) + 0x0000028c _fdata = . + *(.data .data.* .gnu.linkonce.d.*) + .data 0x0000028c 0x0 crt0ram.o + .data 0x0000028c 0x0 main.o + .data 0x0000028c 0xc soc-hw.o + 0x0000028c uart0 + 0x00000290 timer0 + 0x00000294 gpio0 + *(.data1) + 0x000002a0 _gp = ALIGN (0x10) + *(.sdata .sdata.* .gnu.linkonce.s.*) + 0x00000298 _edata = . + +.bss 0x00000298 0x4 + 0x00000298 . = ALIGN (0x4) + 0x00000298 _fbss = . + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + .bss 0x00000298 0x0 crt0ram.o + .bss 0x00000298 0x0 main.o + .bss 0x00000298 0x4 soc-hw.o + 0x00000298 msec + *(COMMON) + 0x0000029c _ebss = . + 0x0000029c _end = . + 0x00000ffc PROVIDE (_fstack, 0xffc) +LOAD crt0ram.o +LOAD main.o +LOAD soc-hw.o +OUTPUT(image elf32-lm32) + +.debug_abbrev 0x00000000 0x219 + .debug_abbrev 0x00000000 0xcd main.o + .debug_abbrev 0x000000cd 0x14c soc-hw.o + +.debug_info 0x00000000 0x3d0 + .debug_info 0x00000000 0x121 main.o + .debug_info 0x00000121 0x2af soc-hw.o + +.debug_line 0x00000000 0x2d8 + .debug_line 0x00000000 0x18f main.o + .debug_line 0x0000018f 0x149 soc-hw.o + +.debug_frame 0x00000000 0xa0 + .debug_frame 0x00000000 0x30 main.o + .debug_frame 0x00000030 0x70 soc-hw.o + +.debug_loc 0x00000000 0xfb + .debug_loc 0x00000000 0xb7 main.o + .debug_loc 0x000000b7 0x44 soc-hw.o + +.debug_pubnames + 0x00000000 0xbc + .debug_pubnames + 0x00000000 0x2b main.o + .debug_pubnames + 0x0000002b 0x91 soc-hw.o + +.debug_aranges 0x00000000 0x40 + .debug_aranges + 0x00000000 0x20 main.o + .debug_aranges + 0x00000020 0x20 soc-hw.o + +.debug_ranges 0x00000000 0x18 + .debug_ranges 0x00000000 0x18 main.o + +.debug_str 0x00000000 0x17b + .debug_str 0x00000000 0xb8 main.o + 0xd0 (size before relaxing) + .debug_str 0x000000b8 0xc3 soc-hw.o + 0x157 (size before relaxing) + +.comment 0x00000000 0x11 + .comment 0x00000000 0x11 main.o + 0x12 (size before relaxing) + .comment 0x00000000 0x12 soc-hw.o diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.ram b/lm32/logic/sakc/firmware/boot0-serial/image.ram new file mode 100644 index 0000000..7c4fbf3 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/image.ram @@ -0,0 +1,1024 @@ +98000000 +d0000000 +78010000 +38210000 +d0e10000 +f8000003 +34000000 +34000000 +781c0000 +3b9c0ffc +781a0000 +3b5a02a0 +78010000 +38210298 +78030000 +3863029c +44230004 +58200000 +34210004 +e3fffffd +34010000 +34020000 +34030000 +f800001d +34010001 +d0010000 +c3a00000 +3401000f +d0210000 +c3a00000 +34010000 +d0010000 +c3a00000 +c0200000 +e0000000 +379cfff8 +5b8b0008 +5b9d0004 +f8000057 +3c2b0008 +f8000055 +b5610800 +3c2b0008 +f8000052 +b5610800 +3c2b0008 +f800004f +b5610800 +2b9d0004 +2b8b0008 +379c0008 +c3a00000 +379cffe4 +5b8b001c +5b8c0018 +5b8d0014 +5b8e0010 +5b8f000c +5b900008 +5b9d0004 +f8000040 +340d0067 +3401002a +340e0075 +340f0064 +78100000 +442d0008 +442e0016 +442f000a +ba000800 +38210270 +f8000048 +f8000035 +5c2dfffa +fbffffd9 +fbffffd6 +f8000031 +e3fffffc +fbffffd5 +b8205800 +fbffffd3 +b5616000 +516cfff6 +41610000 +356b0001 +f8000031 +558bfffd +f8000026 +e3fffff1 +fbffffca +b8205800 +fbffffc8 +b5616000 +516cffeb +f800001f +31610000 +356b0001 +558bfffd +f800001b +e3ffffe6 +78020000 +38420290 +3803c350 +28420000 +88230800 +58410010 +34010000 +58410014 +3401000a +5841000c +2841000c +20210001 +4420fffe +c3a00000 +78010000 +38210290 +28210000 +3802c350 +58220004 +34020000 +58220008 +3402000e +58220000 +c3a00000 +c3a00000 +78010000 +3821028c +28220000 +28410000 +20210001 +4420fffe +28410004 +202100ff +c3a00000 +78020000 +3842028c +28430000 +202100ff +28620000 +20420010 +5c40fffe +58610004 +c3a00000 +40240000 +4480000b +78020000 +3842028c +28430000 +28620000 +20420010 +5c40fffe +58640004 +34210001 +40240000 +5c82fffa +c3a00000 +2a2a5341 +4b432f62 +6f6f746c +6f616465 +722a2a20 +3e200d0a +00000000 +f0000000 +f0010000 +f0020000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.srec b/lm32/logic/sakc/firmware/boot0-serial/image.srec new file mode 100755 index 0000000..178aecc --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/image.srec @@ -0,0 +1,44 @@ +S00D0000696D6167652E7372656314 +S113000098000000D00000007801000038210000B2 +S1130010D0E10000F80000033400000034000000C8 +S1130020781C00003B9C0FFC781A00003B5A02A08D +S11300307801000038210298780300003863029C9C +S1130040442300045820000034210004E3FFFFFD92 +S1130050340100003402000034030000F800001DE5 +S113006034010001D0010000C3A000003401000FDE +S1130070D0210000C3A0000034010000D001000022 +S1130080C3A00000C0200000E0000000379CFFF87F +S11300905B8B00085B9D0004F80000573C2B0008B4 +S11300A0F8000055B56108003C2B0008F800005228 +S11300B0B56108003C2B0008F800004FB56108004A +S11300C02B9D00042B8B0008379C0008C3A0000064 +S11300D0379CFFE45B8B001C5B8C00185B8D001469 +S11300E05B8E00105B8F000C5B9000085B9D00042E +S11300F0F8000040340D00673401002A340E007506 +S1130100340F006478100000442D0008442E0016BB +S1130110442F000ABA00080038210270F800004891 +S1130120F80000355C2DFFFAFBFFFFD9FBFFFFD67B +S1130130F8000031E3FFFFFCFBFFFFD5B8205800B7 +S1130140FBFFFFD3B5616000516CFFF64161000015 +S1130150356B0001F8000031558BFFFDF8000026D7 +S1130160E3FFFFF1FBFFFFCAB8205800FBFFFFC805 +S1130170B5616000516CFFEBF800001F31610000B5 +S1130180356B0001558BFFFDF800001BE3FFFFE614 +S113019078020000384202903803C350284200001D +S11301A0882308005841001034010000584100140D +S11301B03401000A5841000C2841000C20210001A0 +S11301C04420FFFEC3A00000780100003821029003 +S11301D0282100003802C3505822000434020000D1 +S11301E0582200083402000E58220000C3A0000068 +S11301F0C3A00000780100003821028C28220000EE +S113020028410000202100014420FFFE2841000471 +S1130210202100FFC3A00000780200003842028CB5 +S113022028430000202100FF286200002042001023 +S11302305C40FFFE58610004C3A00000402400009D +S11302404480000B780200003842028C28430000EE +S113025028620000204200105C40FFFE5864000445 +S113026034210001402400005C82FFFAC3A0000096 +S11302702A2A53414B432F626F6F746C6F6164651C +S10F0280722A2A203E200D0A0000000013 +S10F028CF0000000F0010000F00200008F +S9030000FC diff --git a/lm32/logic/sakc/firmware/boot0-serial/linker.ld b/lm32/logic/sakc/firmware/boot0-serial/linker.ld new file mode 100644 index 0000000..6d7e779 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/linker.ld @@ -0,0 +1,59 @@ +OUTPUT_FORMAT("elf32-lm32") +ENTRY(_start) + +__DYNAMIC = 0; + + +_BRAM_START = 0x00000000; +_BRAM_SIZE = 0x1000; +_BRAM_END = _BRAM_START + _BRAM_SIZE; + +MEMORY { + bram : ORIGIN = 0x00000000, LENGTH = 0x1000 /* 4k */ +} + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > bram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > bram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > bram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _ebss = .; + _end = .; + } > bram +} + +PROVIDE(_fstack = ORIGIN(bram) + LENGTH(bram) - 4); diff --git a/lm32/logic/sakc/firmware/boot0-serial/main.c b/lm32/logic/sakc/firmware/boot0-serial/main.c new file mode 100644 index 0000000..c3c158d --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/main.c @@ -0,0 +1,57 @@ +/** + * Primitive first stage bootloader + * + * + */ +#include "soc-hw.h" + +/* prototypes */ +uint32_t read_uint32() +{ + uint32_t val = 0, i; + + for (i = 0; i < 4; i++) { + val <<= 8; + val += (uint8_t)uart_getchar(); + } + + return val; +} + +int main(int argc, char **argv) +{ + int8_t *p; + uint8_t c; + + // Initialize UART + uart_init(); + + c = '*'; // print msg on first iteration + for(;;) { + uint32_t start, size; + + switch (c) { + case 'u': // upload + start = read_uint32(); + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + *p = uart_getchar(); + break; + case 'd': // download + start = read_uint32(); + size = read_uint32(); + for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) + uart_putchar( *p ); + break; + case 'g': // goto + start = read_uint32(); + jump(start); + break; + default: + uart_putstr("**SAKC/bootloader** > \r\n"); + break; + }; + c = uart_getchar(); + } +} + diff --git a/lm32/logic/sakc/firmware/boot0-serial/main.d b/lm32/logic/sakc/firmware/boot0-serial/main.d new file mode 100644 index 0000000..6e29089 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/main.d @@ -0,0 +1 @@ +main.o: main.c soc-hw.h diff --git a/lm32/logic/sakc/firmware/boot0-serial/main.o b/lm32/logic/sakc/firmware/boot0-serial/main.o new file mode 100644 index 0000000000000000000000000000000000000000..73dac12da5bda18e39c53e172b656c5aa37d32c9 GIT binary patch literal 4568 zcmb7`YlvJ$7ROIb_sn$W(V1~FaWoU{h>7DQ(>;^4B$yD5({45>VwA8#%f{Q?H#5EI z7yXFw0fGvOi4T0B;s{|^c0ZU8SxDC4vM{hN$f}qRg82~Gpdo%xM8OSN6Pf*=y64=k z85H$E-TIwJovJ#w?&GoB@BEGFFcgZRXTXl3`?S^5He!rMXn6D7!o}<%ie=xV=tY>f zt*03GC%o8C@_NLs$C%A?6#M59BIG!S9HZI8G?IOmR%D-}f$a0tmwlm~H{DM&X+z`b zIJMHtsc>+BC^JE^Op;b+Qq=P<#c0bKBA%Pu{Syn{D|7$(!op?lPbTiO{uAB_DRKwn`Lh54oXl*HC-Vvd(Zi z9@Ntw)X_tj-0Xq14^~+d2lcmAqWE$|@me8fHFa9L zG=qWIJkhR*!6s1&d$|(VY{Xz%Y&^)j47iqc7E{9Im97I`iA*ohI=YLh#DXEi+-*j) z!edM~ry(n`du|1g{$9Qhh!(L z(A_+wVt2L9m<#{yAp>C}mAzsmndc;pYJOt&!Q?D6_G?S9TKcP`ACi9f7wRJtcct{2 z=W5a8(yP8s^hm`BsYNqH_N(VQiO{uZjz~izR!YRuRqKeQcGa)dRg`~irnNE>^+gS@ zvK1dP=2E=BU2%CejgQ~E@xC zW{ExzeFfSmnXK)I5@dD*6KG?Bbqu&6uxS77zmVYPT+X^X$B&HMTWI8!TJnxphO$x{4XT7=|WL=v! z!Y3hKeI`$m*+w;r5Bmh`0cte8dXrMK)v}+;WBIAu%Q?SL@C&J8WyY@*^QnfnKcA{p zCR&Z$#J<{$mnxMvZA_J_GwRz{td}43>b^Z3lM@ZUUc@WL&Ol=T@R}YabBzYj&$VXudO1}403~fqU@BJjRTmjb#flF@ zl?QYBsbqSQe_!1zBOn-Es^%9tYpq-bZcOM*;nh7aA zW?$6k@uhE{0O)#3RyhppzYmvh(D=>I<2jC>vvs0J&@*lc`tZuJEc_ht=i=w$rVyiJ z7&+fZXe#QF0fL4RjxSz)rph_GO-jO+|hDd2sSA zKZdwZVB>teKh5WXd5nEFVLl1AFDLXY9LN5a^ypZkoNLlzaM8JH>}=Zyp9FIp&&%IB z_VN9A98K2>>}2~pXe#P^5e8*o=ihNzuR)IQS+G0rap*h`&x_xkaNfUw-F)YvC(u;X z_eU7qeDlyp&^X@!n(pIoU>yVO;(Nt$D(ZU=24<;Q*EQf%8YDjUe=MwVUqinFO@(8) z4Wh{zWtaWOIL#!&F)ZBM&%V{D_cfSmVEl`O`xpT8?~0SJpU=o$Xeyddb?rlYloq~K zBlk!a`b2l~Tfb9ZtK->d3xc_pp+M&~g#ul_tJVhH{!3{9bo(FW=zI=BfuHvs3Us&5 zy#C-XR3f0S0O}et2p-$X7D}8ts zFelLP{8;8Qf`4|)*dPAys6*pd2W-DPxUb!6$33<2I}yK07)W@BTl)s^ox*AGZsEJZ zzZbqAjN00G+y|;S^VWqkus?-kuJgVs@wdT__mf>G$Nbq@=U*k}cd+AKX~*)nWnS!M z@V~`=5BM`-AN&O#8J!FDv}?m!=z_$&4!$JzSsZ`73vJ8?u%ixP-L?v&-ZU*d0KP+* z_j|AKC^##e0Oy6r!25-{o(compare1 = (FCPU/1000)*msec; + timer0->counter1 = 0; + timer0->tcr1 = TIMER_EN | TIMER_IRQEN; + + do { + //halt(); + tcr = timer0->tcr1; + } while ( ! (tcr & TIMER_TRIG) ); +} + +void tic_init() +{ + // Setup timer0.0 + timer0->compare0 = (FCPU/1000); + timer0->counter0 = 0; + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; +} + +/*************************************************************************** + * UART Functions + */ +void uart_init() +{ + //uart0->ier = 0x00; // Interrupt Enable Register + //uart0->lcr = 0x03; // Line Control Register: 8N1 + //uart0->mcr = 0x00; // Modem Control Register + + // Setup Divisor register (Fclk / Baud) + //uart0->div = (FCPU/(57600*16)); +} + +char uart_getchar() +{ + while (! (uart0->ucr & UART_DR)) ; + return uart0->rxtx; +} + +void uart_putchar(char c) +{ + while (uart0->ucr & UART_BUSY) ; + uart0->rxtx = c; +} + +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + uart_putchar(*c); + c++; + } +} + diff --git a/lm32/logic/sakc/firmware/boot0-serial/soc-hw.d b/lm32/logic/sakc/firmware/boot0-serial/soc-hw.d new file mode 100644 index 0000000..79cbe0c --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/soc-hw.d @@ -0,0 +1 @@ +soc-hw.o: soc-hw.c soc-hw.h diff --git a/lm32/logic/sakc/firmware/boot0-serial/soc-hw.h b/lm32/logic/sakc/firmware/boot0-serial/soc-hw.h new file mode 100644 index 0000000..3c89665 --- /dev/null +++ b/lm32/logic/sakc/firmware/boot0-serial/soc-hw.h @@ -0,0 +1,108 @@ +#ifndef SPIKEHW_H +#define SPIKEHW_H + +#define PROMSTART 0x00000000 +#define RAMSTART 0x00000800 +#define RAMSIZE 0x400 +#define RAMEND (RAMSTART + RAMSIZE) + +#define RAM_START 0x40000000 +#define RAM_SIZE 0x04000000 + +#define FCPU 50000000 + +#define UART_RXBUFSIZE 32 + +/**************************************************************************** + * Types + */ +typedef unsigned int uint32_t; // 32 Bit +typedef signed int int32_t; // 32 Bit + +typedef unsigned char uint8_t; // 8 Bit +typedef signed char int8_t; // 8 Bit + +/**************************************************************************** + * Interrupt handling + */ +typedef void(*isr_ptr_t)(void); + +void irq_enable(); +void irq_disable(); +void irq_set_mask(uint32_t mask); +uint32_t irq_get_mak(); + +void isr_init(); +void isr_register(int irq, isr_ptr_t isr); +void isr_unregister(int irq); + +/**************************************************************************** + * General Stuff + */ +void halt(); +void jump(uint32_t addr); + + +/**************************************************************************** + * Timer + */ +#define TIMER_EN 0x08 // Enable Timer +#define TIMER_AR 0x04 // Auto-Reload +#define TIMER_IRQEN 0x02 // IRQ Enable +#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR) + +typedef struct { + volatile uint32_t tcr0; + volatile uint32_t compare0; + volatile uint32_t counter0; + volatile uint32_t tcr1; + volatile uint32_t compare1; + volatile uint32_t counter1; +} timer_t; + +void msleep(uint32_t msec); +void nsleep(uint32_t nsec); + +void tic_init(); + + +/*************************************************************************** + * GPIO0 + */ +typedef struct { + volatile uint32_t ctrl; + volatile uint32_t dummy1; + volatile uint32_t dummy2; + volatile uint32_t dummy3; + volatile uint32_t in; + volatile uint32_t out; + volatile uint32_t oe; +} gpio_t; + +/*************************************************************************** + * UART0 + */ +#define UART_DR 0x01 // RX Data Ready +#define UART_ERR 0x02 // RX Error +#define UART_BUSY 0x10 // TX Busy + +typedef struct { + volatile uint32_t ucr; + volatile uint32_t rxtx; +} uart_t; + +void uart_init(); +void uart_putchar(char c); +void uart_putstr(char *str); +char uart_getchar(); + + +/*************************************************************************** + * Pointer to actual components + */ +extern timer_t *timer0; +extern uart_t *uart0; +extern gpio_t *gpio0; +extern uint32_t *sram0; + +#endif // SPIKEHW_H diff --git a/lm32/logic/sakc/firmware/boot0-serial/soc-hw.o b/lm32/logic/sakc/firmware/boot0-serial/soc-hw.o new file mode 100644 index 0000000000000000000000000000000000000000..887afb0382a77c2ba9766063b4c572d7fa411ea8 GIT binary patch literal 5276 zcmb7HYiwLc6+Uyl8?U|Vwc~XXmn70AvD+=G*LLC(leQ$O9hww3q@@KHQaSs$wpZPU z*}dDkD6|nRQb9yKTUFvAet_E26r>15d8#5538_dR1;h_P77~abMM{5!A0TSJGjq<} zyOvPZ(axRkeCN!WGiT<`+*t8Tdk*K$}KO zY}aKA4t_}e0LOqgtquBe9Jx8G-^>-!-bq7ek8QrSSfCi&92+B=zd%WinQgo5%7_6m zvfbHFZT_44@Pw}+)@$%@wwv*ECfSqTo!)MS&CoU?ZzuJnk0ftPp2`sQj8QWAKIn;J z0uw~>j7cWh#K2_RKxjYPPt84x?=Sn`qNZTte3f1EMBPx)MJoX zB-|hpWO&qj51JRP;2mb@9Uv#oIw|I)_c|%zq$5sBIq5bh@v0)Y+nqE*JnXm&h!rkx8PB}9f>~1H?U>|Uj47T8;RH9NR?;a-%B^vF3ywgq^Ni=-&KInu|mmKd5 z#2>{I-h&wPzC^p!B=4inLdN`STho?w>H*uJJDDo# z<&=d3cybD9Ai!W|5NMo5O1oZrtbm893UgD38FV(&b~K?)bqL}^9V2A7cRQ$u&AlX{ z+|d<^cY3%LU~J^u=7utu!BG~>y(3+|j_-iDiH#OR+up@v7(j2?#Cup^p1$jN5Z>bv z-rVQ-IQVCy{C>yt4jUI9(By1}bH@DZdOsNyCaKjZO{_keFF{be${4%SZkm14j!L^@ zOZ)%$U1GO$i~ZLA?-KoPX|ZUG%y6UJu0d90_ zFS^$YTjhIL_4BQ&@2|niTn;LwrAoaLu<*-vp&5kIAFQ!RnzVnLTH8*!8n?ovYmP}B-^;j(^6wwAv*RCpR`qe@{@Ye&%mkU9G z^2JsQ&@Z-EmI}pU(|?5W*2Ynl`f{U-s8;HJ7qQ$d)WA6NYNOPpTx%EWP-BFM&qA|+ zyo952+VhxU&BwNQXC(`BetYe$hnC-~4OA_<4|ju53^+KC$2#f=D)(m{zrQz%Y)@&Z zSRZ|_)d#<*d=RT$7FczFA;yg(rwg-WvZxCHTHMKl&p!}~0llhwqtz_b;kF5V0}lQa zcCP?%oSXxl#{<9-e{sy;@Hc@L)tvzmiF-JJ9jf)m^HYDzz}g3JTN#fvR4wYG075Zf z<{x-`0hQz9&nxxU0*?B-3V9w?i|U>Pp%}1t6pt^eQAGDRaAe#OURz!_9+$ryblm5F zqyAomoJG~5x-Wx>`g;m8kInx0(?k6|56pe|AVlf?HN=lNY@e*-dRbbr>&rqOM%AKr z`2Ns6#j3u8c>IKs6t?5St-Z&sL<8qQT>!>+2jMf{#y5nv4^{Rk5T!TpC@_+u{#4dB zjLPqjY_%!TEcexQ}~c5~Nl=Q<0oZ+kiEed8|9uG>uoK2hBz5xtv{DqS12 zgSsx5cgWu!;W6Kg+OGnuJ?0tmpNsI{kMOTVc&xYk>cxDqmMPBnhfpzf#)ki9VBcE) zFTgioYqJfPy@EG@_u>6g{zkF?JorO`0qMA4#7idyzXpu+(E2|GTyoe<1Akn2#!m?5 zcrJ;4K%fQHmwf`3I zlHf;x*9AWbjPuRf%mIJ8lOOXL!B|7{6=!4E<{NnRdoVtVd0B7<7;9wxU>x(~NMFQi zbAAr|uf!$`{Cb4P9IXxZh54h{{0{i95&rLjd5&*J@O8nL(Be$8F+2y1_t5%e9%rk? z8)$Eqn6b_t|J~xbyowg7Yl?T%D`MZue7&0Z$DZ;&fqkev^2XyD>AI#gH8xP3Ve^?EHL7+_Br5(1m6Pe3!VW+Y}N+rMePXwq~Hbc zy1w@VUlg9ti)RF%14hi&594nO#=6kU5&Q$eYv6w-_&o4yf-eC7MljZkejmYq7K}Bb zzX`_vq<;#20r4kMJjj=lme2q5Y!pJa_0qepPs$*Eak#o+#FROaBAT-5E0g literal 0 HcmV?d00001 diff --git a/lm32/logic/sakc/firmware/ddr-phaser/Makefile b/lm32/logic/sakc/firmware/ddr-phaser/Makefile new file mode 100644 index 0000000..465333a --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/Makefile @@ -0,0 +1,50 @@ +LM32_CC=lm32-elf-gcc +LM32_LD=lm32-elf-ld +LM32_OBJCOPY=lm32-elf-objcopy +LM32_OBJDUMP=lm32-elf-objdump + +SREC2VRAM ?= ../../tools/srec2vram/srec2vram + +VRAMFILE=image.ram + +CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled +LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld +SEGMENTS = -j .text -j .rodata -j .data + +all: $(VRAMFILE) + +crt0ram.o: crt0ram.S + $(LM32_CC) $(CFLAGS) -c crt0ram.S + +main.o: main.c + $(LM32_CC) $(CFLAGS) -c main.c + +spike_hw.o: spike_hw.c + $(LM32_CC) $(CFLAGS) -c spike_hw.c + +image: crt0ram.o main.o spike_hw.o + $(LM32_LD) $(LDFLAGS) -Map image.map -N -o image crt0ram.o main.o spike_hw.o + +image.lst: image + $(LM32_OBJDUMP) -h -S $< > $@ + +image.bin: image + $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.bin + +image.srec: image image.lst + $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec + +$(VHDLFILE): image.srec + $(SREC2VHDL) image.srec > $(VHDLFILE) + +$(VRAMFILE): image.srec + $(SREC2VRAM) image.srec 0x00000000 0x1000 > $(VRAMFILE) + +clean: + rm -f image image.lst image.bin image.srec image.map *.o *.d + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif + diff --git a/lm32/logic/sakc/firmware/ddr-phaser/crt0ram.S b/lm32/logic/sakc/firmware/ddr-phaser/crt0ram.S new file mode 100644 index 0000000..0859224 --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/crt0ram.S @@ -0,0 +1,166 @@ +/* + * LatticeMico32 C startup code. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Exception handlers - Must be 32 bytes long. */ + .section .text, "ax", @progbits + .global _start + .global irq_enable, irq_disable, irq_mask, jump, halt +_start: +_reset_handler: + xor r0, r0, r0 + wcsr IE, r0 + mvhi r1, hi(_reset_handler) + ori r1, r1, lo(_reset_handler) + wcsr EBA, r1 + calli _crt0 + nop + nop + +_crt0: + /* Setup stack and global pointer */ + mvhi sp, hi(_fstack) + ori sp, sp, lo(_fstack) + mvhi gp, hi(_gp) + ori gp, gp, lo(_gp) + + /* Clear BSS */ + mvhi r1, hi(_fbss) + ori r1, r1, lo(_fbss) + mvhi r3, hi(_ebss) + ori r3, r3, lo(_ebss) +.clearBSS: + be r1, r3, .callMain + sw (r1+0), r0 + addi r1, r1, 4 + bi .clearBSS + +.callMain: + mvi r1, 0 + mvi r2, 0 + mvi r3, 0 + calli main + +irq_enable: + mvi r1, 1 + wcsr IE, r1 + ret + +irq_mask: + mvi r1, 0x0000000f + wcsr IM, r1 + ret + +irq_disable: + mvi r1, 0 + wcsr IE, r1 + ret + +jump: + b r1 + +halt: + bi halt + + /* Save all registers onto the stack */ +_save_all: + addi sp, sp, -128 + sw (sp+4), r1 + sw (sp+8), r2 + sw (sp+12), r3 + sw (sp+16), r4 + sw (sp+20), r5 + sw (sp+24), r6 + sw (sp+28), r7 + sw (sp+32), r8 + sw (sp+36), r9 + sw (sp+40), r10 +#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE + sw (sp+44), r11 + sw (sp+48), r12 + sw (sp+52), r13 + sw (sp+56), r14 + sw (sp+60), r15 + sw (sp+64), r16 + sw (sp+68), r17 + sw (sp+72), r18 + sw (sp+76), r19 + sw (sp+80), r20 + sw (sp+84), r21 + sw (sp+88), r22 + sw (sp+92), r23 + sw (sp+96), r24 + sw (sp+100), r25 + sw (sp+104), r26 + sw (sp+108), r27 +#endif + sw (sp+120), ea + sw (sp+124), ba + /* ra and sp need special handling, as they have been modified */ + lw r1, (sp+128) + sw (sp+116), r1 + mv r1, sp + addi r1, r1, 128 + sw (sp+112), r1 + ret + + /* Restore all registers and return from exception */ +_restore_all_and_return: + lw r1, (sp+4) + lw r2, (sp+8) + lw r3, (sp+12) + lw r4, (sp+16) + lw r5, (sp+20) + lw r6, (sp+24) + lw r7, (sp+28) + lw r8, (sp+32) + lw r9, (sp+36) + lw r10, (sp+40) +#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE + lw r11, (sp+44) + lw r12, (sp+48) + lw r13, (sp+52) + lw r14, (sp+56) + lw r15, (sp+60) + lw r16, (sp+64) + lw r17, (sp+68) + lw r18, (sp+72) + lw r19, (sp+76) + lw r20, (sp+80) + lw r21, (sp+84) + lw r22, (sp+88) + lw r23, (sp+92) + lw r24, (sp+96) + lw r25, (sp+100) + lw r26, (sp+104) + lw r27, (sp+108) +#endif + lw ra, (sp+116) + lw ea, (sp+120) + lw ba, (sp+124) + /* Stack pointer must be restored last, in case it has been updated */ + lw sp, (sp+112) + eret + + diff --git a/lm32/logic/sakc/firmware/ddr-phaser/image.ram b/lm32/logic/sakc/firmware/ddr-phaser/image.ram new file mode 100644 index 0000000..dcf2d06 --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/image.ram @@ -0,0 +1,1024 @@ +98000000 +d0000000 +78010000 +38210000 +d0e10000 +f8000003 +34000000 +34000000 +781c0000 +3b9c0ffc +781a0000 +3b5a05a0 +78010000 +3821059c +78030000 +3863059c +44230004 +58200000 +34210004 +e3fffffd +34010000 +34020000 +34030000 +f80000dd +34010001 +d0010000 +c3a00000 +3401000f +d0210000 +c3a00000 +34010000 +d0010000 +c3a00000 +c0200000 +e0000000 +379cff80 +5b810004 +5b820008 +5b83000c +5b840010 +5b850014 +5b860018 +5b87001c +5b880020 +5b890024 +5b8a0028 +5b9e0078 +5b9f007c +2b810080 +5b810074 +bb800800 +34210080 +5b810070 +c3a00000 +2b810004 +2b820008 +2b83000c +2b840010 +2b850014 +2b860018 +2b87001c +2b880020 +2b890024 +2b8a0028 +2b9d0074 +2b9e0078 +2b9f007c +2b9c0070 +c3c00000 +78010000 +38210590 +28230000 +28620010 +78010001 +38210000 +a0410800 +c3a00000 +78050000 +78020001 +b8a00800 +38210590 +28230000 +b8402000 +38840000 +28610010 +a0240800 +4420fff9 +28620014 +b8602800 +b8803000 +b8440800 +58610014 +58620014 +28a10010 +a0260800 +4420fffe +c3a00000 +78050000 +78020001 +b8a00800 +38210590 +28230000 +b8402000 +38840000 +28610010 +a0240800 +4420fff9 +28620014 +78010002 +38210000 +b8410800 +58610014 +58620014 +b8601000 +b8801800 +28410010 +a0230800 +4420fffe +c3a00000 +78024000 +b8402800 +38420000 +34040000 +b4221800 +50430004 +58420000 +34420004 +e3fffffd +b8a01000 +38420000 +b4220800 +50410008 +b8201800 +28410000 +44220002 +3404ffff +34420004 +50430002 +e3fffffb +b8800800 +c3a00000 +379cffe0 +5b8b0020 +5b8c001c +5b8d0018 +5b8e0014 +5b8f0010 +5b90000c +5b910008 +5b9d0004 +b8406800 +780f4000 +b9e01000 +38420000 +b5a26000 +78110002 +7c300001 +3a310000 +340e0000 +b9805800 +b9e01000 +38420000 +34030000 +b5a20800 +50410005 +58420000 +34420004 +504b0002 +e3fffffd +b9e01000 +38420000 +b5a20800 +50410009 +28410000 +44220002 +3403ffff +34420004 +504c0002 +e3fffffb +7c610000 +5c200025 +3401004f +f8000078 +5e000025 +78010000 +38210590 +28240000 +78030001 +38630000 +28810010 +a0230800 +4420fffe +28810014 +78020000 +38420590 +b8231800 +58830014 +28420000 +78030001 +58810014 +38630000 +28410010 +a0230800 +4420fffe +35ce0001 +69c100ff +4420ffd2 +2b8b0020 +2b8c001c +2b8d0018 +2b8e0014 +2b8f0010 +2b90000c +2b910008 +2b9d0004 +379c0020 +c3a00000 +3401002d +f8000054 +4600ffdd +78010000 +38210590 +28240000 +78020001 +38420000 +28810010 +a0220800 +4420fffe +28810014 +78020000 +38420590 +b8311800 +58830014 +28420000 +78030001 +58810014 +38630000 +28410010 +a0230800 +4420fffe +35ce0001 +69c100ff +4420ffae +e3ffffdc +379cfffc +5b9d0004 +f800002d +78010000 +38210510 +f800003e +78010000 +38210530 +f800003b +78010000 +3821055c +f8000038 +f8000024 +b8201800 +64640075 +3401ffff +64630064 +34024000 +5c600003 +34010001 +4480fff8 +fbffff84 +e3fffff6 +78020000 +38420594 +3803c350 +28440000 +88230800 +3402000a +58810010 +34010000 +58810014 +5882000c +2881000c +20210001 +4420fffe +c3a00000 +78010000 +38210594 +28230000 +3802c350 +58620004 +34010000 +58610008 +3402000e +58620000 +c3a00000 +c3a00000 +78030000 +b8601000 +38420598 +28420000 +28410000 +20210001 +4420fffb +28410004 +202100ff +c3a00000 +78020000 +38420598 +28420000 +202300ff +28410000 +20210010 +5c20fffe +58430004 +c3a00000 +379cfff8 +5b8b0008 +5b9d0004 +b8205800 +e0000003 +fbfffff2 +356b0001 +41610000 +5c20fffd +2b8b0008 +2b9d0004 +379c0008 +c3a00000 +0d0a0d0a +2a2a2053 +4f432d4c +4d333220 +44445220 +50414853 +4552202a +2a0a0a00 +274f2720 +3d3e204d +656d7465 +7374204f +4b203b20 +272d2720 +3d3e204d +656d7465 +73742066 +61696c65 +640a0a00 +50726573 +73205b75 +5d20666f +72207570 +77617264 +20736361 +6e2c205b +645d2066 +6f722064 +6f776e77 +6172640a +00000000 +00000000 +f0020000 +f0010000 +f0000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/lm32/logic/sakc/firmware/ddr-phaser/linker.ld b/lm32/logic/sakc/firmware/ddr-phaser/linker.ld new file mode 100644 index 0000000..6d7e779 --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/linker.ld @@ -0,0 +1,59 @@ +OUTPUT_FORMAT("elf32-lm32") +ENTRY(_start) + +__DYNAMIC = 0; + + +_BRAM_START = 0x00000000; +_BRAM_SIZE = 0x1000; +_BRAM_END = _BRAM_START + _BRAM_SIZE; + +MEMORY { + bram : ORIGIN = 0x00000000, LENGTH = 0x1000 /* 4k */ +} + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > bram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > bram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > bram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _ebss = .; + _end = .; + } > bram +} + +PROVIDE(_fstack = ORIGIN(bram) + LENGTH(bram) - 4); diff --git a/lm32/logic/sakc/firmware/ddr-phaser/main.c b/lm32/logic/sakc/firmware/ddr-phaser/main.c new file mode 100644 index 0000000..9978c10 --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/main.c @@ -0,0 +1,105 @@ +/** + * DDR Phase Shifter + */ + +#include "spike_hw.h" + +/****************************************************************************** + * Control DDR phase shift + */ +inline int ps_ready() +{ + return (gpio0->in & (1 << 16)); // return 1 when ready, 0 otherwise +} + +inline void ps_inc() +{ + uint32_t tmp; + + while ( ! ps_ready() ); + + tmp = gpio0->out; + gpio0->out = tmp | (1 << 16); + gpio0->out = tmp; + + while ( ! ps_ready() ); +} + +inline void ps_dec() +{ + uint32_t tmp; + + while ( ! ps_ready() ); + + tmp = gpio0->out; + gpio0->out = tmp | (1 << 17); + gpio0->out = tmp; + + while ( ! ps_ready() ); +} + +/****************************************************************************** + * Simple memory tester + * + * Returns -1 on error, 0 when OK. + */ +inline int memtest(uint32_t size) +{ + volatile uint32_t *p; + int res = 0; + + for (p=(uint32_t *)RAM_START; p<(uint32_t *)(RAM_START+size); p++) { + *p = (uint32_t) p; + } + + for (p=(uint32_t *)RAM_START; p<(uint32_t *)(RAM_START+size); p++) { + if (*p != (uint32_t)p) { + res = -1; + } + } + + return res; +} + + +void scan_phase(int dir, uint32_t size) +{ + int i; + + for (i=0; i<=255; i++) { + if (memtest(size) == 0) + uart_putchar('O'); + else + uart_putchar('-'); + + if (dir == 1) ps_inc(); else ps_dec(); + } +} + + + +int main(int argc, char **argv) +{ + uint32_t scan_size = 16*1024; // scan 16 kByte + + // Initialize stuff + uart_init(); + + uart_putstr("\r\n\r\n** SOC-LM32 DDR PAHSER **\n\n"); + uart_putstr("'O' => Memtest OK ; '-' => Memtest failed\n\n"); + uart_putstr("Press [u] for upward scan, [d] for downward\n"); + + for(;;) { + uint8_t c = uart_getchar(); + + switch (c) { + case 'u': // scan upward + scan_phase(1, scan_size); + break; + case 'd': // scan downward + scan_phase(-1, scan_size); + break; + } + } +} + diff --git a/lm32/logic/sakc/firmware/ddr-phaser/spike_hw.c b/lm32/logic/sakc/firmware/ddr-phaser/spike_hw.c new file mode 100644 index 0000000..c6986c4 --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/spike_hw.c @@ -0,0 +1,68 @@ +#include "spike_hw.h" + +uart_t *uart0 = (uart_t *) 0xF0000000; +timer_t *timer0 = (timer_t *) 0xF0010000; +gpio_t *gpio0 = (gpio_t *) 0xF0020000; + +uint32_t msec = 0; + +/*************************************************************************** + * General utility functions + */ +void sleep(int msec) +{ + uint32_t tcr; + + // Use timer0.1 + timer0->compare1 = (FCPU/1000)*msec; + timer0->counter1 = 0; + timer0->tcr1 = TIMER_EN | TIMER_IRQEN; + + do { + //halt(); + tcr = timer0->tcr1; + } while ( ! (tcr & TIMER_TRIG) ); +} + +void tic_init() +{ + // Setup timer0.0 + timer0->compare0 = (FCPU/1000); + timer0->counter0 = 0; + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; +} + +/*************************************************************************** + * UART Functions + */ +void uart_init() +{ + //uart0->ier = 0x00; // Interrupt Enable Register + //uart0->lcr = 0x03; // Line Control Register: 8N1 + //uart0->mcr = 0x00; // Modem Control Register + + // Setup Divisor register (Fclk / Baud) + //uart0->div = (FCPU/(57600*16)); +} + +char uart_getchar() +{ + while (! (uart0->ucr & UART_DR)) ; + return uart0->rxtx; +} + +void uart_putchar(char c) +{ + while (uart0->ucr & UART_BUSY) ; + uart0->rxtx = c; +} + +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + uart_putchar(*c); + c++; + } +} + diff --git a/lm32/logic/sakc/firmware/ddr-phaser/spike_hw.h b/lm32/logic/sakc/firmware/ddr-phaser/spike_hw.h new file mode 100644 index 0000000..3c89665 --- /dev/null +++ b/lm32/logic/sakc/firmware/ddr-phaser/spike_hw.h @@ -0,0 +1,108 @@ +#ifndef SPIKEHW_H +#define SPIKEHW_H + +#define PROMSTART 0x00000000 +#define RAMSTART 0x00000800 +#define RAMSIZE 0x400 +#define RAMEND (RAMSTART + RAMSIZE) + +#define RAM_START 0x40000000 +#define RAM_SIZE 0x04000000 + +#define FCPU 50000000 + +#define UART_RXBUFSIZE 32 + +/**************************************************************************** + * Types + */ +typedef unsigned int uint32_t; // 32 Bit +typedef signed int int32_t; // 32 Bit + +typedef unsigned char uint8_t; // 8 Bit +typedef signed char int8_t; // 8 Bit + +/**************************************************************************** + * Interrupt handling + */ +typedef void(*isr_ptr_t)(void); + +void irq_enable(); +void irq_disable(); +void irq_set_mask(uint32_t mask); +uint32_t irq_get_mak(); + +void isr_init(); +void isr_register(int irq, isr_ptr_t isr); +void isr_unregister(int irq); + +/**************************************************************************** + * General Stuff + */ +void halt(); +void jump(uint32_t addr); + + +/**************************************************************************** + * Timer + */ +#define TIMER_EN 0x08 // Enable Timer +#define TIMER_AR 0x04 // Auto-Reload +#define TIMER_IRQEN 0x02 // IRQ Enable +#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR) + +typedef struct { + volatile uint32_t tcr0; + volatile uint32_t compare0; + volatile uint32_t counter0; + volatile uint32_t tcr1; + volatile uint32_t compare1; + volatile uint32_t counter1; +} timer_t; + +void msleep(uint32_t msec); +void nsleep(uint32_t nsec); + +void tic_init(); + + +/*************************************************************************** + * GPIO0 + */ +typedef struct { + volatile uint32_t ctrl; + volatile uint32_t dummy1; + volatile uint32_t dummy2; + volatile uint32_t dummy3; + volatile uint32_t in; + volatile uint32_t out; + volatile uint32_t oe; +} gpio_t; + +/*************************************************************************** + * UART0 + */ +#define UART_DR 0x01 // RX Data Ready +#define UART_ERR 0x02 // RX Error +#define UART_BUSY 0x10 // TX Busy + +typedef struct { + volatile uint32_t ucr; + volatile uint32_t rxtx; +} uart_t; + +void uart_init(); +void uart_putchar(char c); +void uart_putstr(char *str); +char uart_getchar(); + + +/*************************************************************************** + * Pointer to actual components + */ +extern timer_t *timer0; +extern uart_t *uart0; +extern gpio_t *gpio0; +extern uint32_t *sram0; + +#endif // SPIKEHW_H diff --git a/lm32/logic/sakc/firmware/gdb-test/Makefile b/lm32/logic/sakc/firmware/gdb-test/Makefile new file mode 100644 index 0000000..a5dce59 --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/Makefile @@ -0,0 +1,43 @@ +LM32_CC=lm32-elf-gcc +LM32_LD=lm32-elf-ld +LM32_OBJCOPY=lm32-elf-objcopy +LM32_OBJDUMP=lm32-elf-objdump + +SREC2VRAM ?= ../../tools/srec2vram/srec2vram +VRAMFILE=image.ram + +CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled +LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld +SEGMENTS = -j .boot -j .text -j .rodata -j .data + +all: image.srec $(VRAMFILE) + +%.o: %.S + $(LM32_CC) $(CFLAGS) -c $< + +%.o: %.c + $(LM32_CC) $(CFLAGS) -c $< + +image: crt0gdb.o main.o soc-hw.o gdb.o gdb_uart.o + $(LM32_LD) $(LDFLAGS) -Map image.map -N -o image $^ + +image.lst: image + $(LM32_OBJDUMP) -h -S $< > $@ + +image.bin: image + $(LM32_OBJCOPY) $(SEGMENTS) -O binary image image.bin + +image.srec: image image.lst + $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec + +$(VRAMFILE): image.srec + $(SREC2VRAM) image.srec 0x40000000 0x100000 > $(VRAMFILE) + +clean: + rm -f image image.lst image.bin image.srec image.map *.o *.d + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif + diff --git a/lm32/logic/sakc/firmware/gdb-test/crt0gdb.S b/lm32/logic/sakc/firmware/gdb-test/crt0gdb.S new file mode 100644 index 0000000..ecf952a --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/crt0gdb.S @@ -0,0 +1,290 @@ +/* + * LatticeMico32 GDB C startup code. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Exception handlers - Must be 32 bytes long. */ + + .section .boot, "ax", @progbits + + .global _start +_start: +_reset_handler: + bi _crt0 + nop + nop + nop + nop + nop + nop + nop + +_breakpoint_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ba + mvi r1, 1 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _b_restore_all_and_return + +_instruction_bus_error_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ea + mvi r1, 2 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _e_restore_all_and_return + +_watchpoint_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ba + mvi r1, 3 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _b_restore_all_and_return + +_data_bus_error_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ea + mvi r1, 4 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _e_restore_all_and_return + +_divide_by_zero_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ea + mvi r1, 5 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _e_restore_all_and_return + +_interrupt_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ea + mvi r1, 6 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _e_restore_all_and_return + +_system_call_handler: + sw (sp+0), ra + calli _save_all + sw (sp+128), ea + mvi r1, 7 + sw (sp+132), r1 + mv r1, sp + calli _handle_exception + bi _e_restore_all_and_return + + /* Program starts here */ + +_crt0: + /* Clear r0 */ + xor r0, r0, r0 + + /* Clear all other regs (needed so that simulations match) */ + mvi r1, 0 + mvi r2, 0 + mvi r3, 0 + mvi r4, 0 + mvi r5, 0 + mvi r6, 0 + mvi r7, 0 + mvi r8, 0 + mvi r9, 0 + mvi r10, 0 + mvi r11, 0 + mvi r12, 0 + mvi r13, 0 + mvi r14, 0 + mvi r15, 0 + mvi r16, 0 + mvi r17, 0 + mvi r18, 0 + mvi r19, 0 + mvi r20, 0 + mvi r21, 0 + mvi r22, 0 + mvi r23, 0 + mvi r24, 0 + mvi r25, 0 + mvi r26, 0 + mvi r27, 0 + mvi r28, 0 + mvi r29, 0 + mvi r30, 0 + mvi r31, 0 + + /* Setup stack and global pointer */ + mvhi sp, hi(_fstack) + ori sp, sp, lo(_fstack) + mvhi gp, hi(_gp) + ori gp, gp, lo(_gp) + + /* Clear BSS */ + mvhi r1, hi(_fbss) + ori r1, r1, lo(_fbss) + mvhi r3, hi(_ebss) + ori r3, r3, lo(_ebss) +.clearBSS: + be r1, r3, .callMain + sw (r1+0), r0 + addi r1, r1, 4 + bi .clearBSS + +.callMain: + mvi r1, 0 + mvi r2, 0 + mvi r3, 0 + /* Enter debug exception handler */ + mvhi ba, hi(main) + ori ba, ba, lo(main) + bi _breakpoint_handler + + /* Save all registers onto the stack */ +_save_all: + addi sp, sp, -136 + sw (sp+0), r0 + sw (sp+4), r1 + sw (sp+8), r2 + sw (sp+12), r3 + sw (sp+16), r4 + sw (sp+20), r5 + sw (sp+24), r6 + sw (sp+28), r7 + sw (sp+32), r8 + sw (sp+36), r9 + sw (sp+40), r10 + sw (sp+44), r11 + sw (sp+48), r12 + sw (sp+52), r13 + sw (sp+56), r14 + sw (sp+60), r15 + sw (sp+64), r16 + sw (sp+68), r17 + sw (sp+72), r18 + sw (sp+76), r19 + sw (sp+80), r20 + sw (sp+84), r21 + sw (sp+88), r22 + sw (sp+92), r23 + sw (sp+96), r24 + sw (sp+100), r25 + sw (sp+104), r26 + sw (sp+108), r27 + sw (sp+120), ea + sw (sp+124), ba + /* ra and sp need special handling, as they have been modified */ + lw r1, (sp+136) + sw (sp+116), r1 + mv r1, sp + addi r1, r1, 136 + sw (sp+112), r1 + ret + + /* Restore all registers and return from exception */ +_e_restore_all_and_return: + lw r1, (sp+4) + lw r2, (sp+8) + lw r3, (sp+12) + lw r4, (sp+16) + lw r5, (sp+20) + lw r6, (sp+24) + lw r7, (sp+28) + lw r8, (sp+32) + lw r9, (sp+36) + lw r10, (sp+40) + lw r11, (sp+44) + lw r12, (sp+48) + lw r13, (sp+52) + lw r14, (sp+56) + lw r15, (sp+60) + lw r16, (sp+64) + lw r17, (sp+68) + lw r18, (sp+72) + lw r19, (sp+76) + lw r20, (sp+80) + lw r21, (sp+84) + lw r22, (sp+88) + lw r23, (sp+92) + lw r24, (sp+96) + lw r25, (sp+100) + lw r26, (sp+104) + lw r27, (sp+108) + lw ra, (sp+116) + lw ba, (sp+124) + /* Restore EA from PC */ + lw ea, (sp+128) + /* Stack pointer must be restored last, in case it has been updated */ + lw sp, (sp+112) + eret + + /* Restore all registers and return from breakpoint */ +_b_restore_all_and_return: + lw r1, (sp+4) + lw r2, (sp+8) + lw r3, (sp+12) + lw r4, (sp+16) + lw r5, (sp+20) + lw r6, (sp+24) + lw r7, (sp+28) + lw r8, (sp+32) + lw r9, (sp+36) + lw r10, (sp+40) + lw r11, (sp+44) + lw r12, (sp+48) + lw r13, (sp+52) + lw r14, (sp+56) + lw r15, (sp+60) + lw r16, (sp+64) + lw r17, (sp+68) + lw r18, (sp+72) + lw r19, (sp+76) + lw r20, (sp+80) + lw r21, (sp+84) + lw r22, (sp+88) + lw r23, (sp+92) + lw r24, (sp+96) + lw r25, (sp+100) + lw r26, (sp+104) + lw r27, (sp+108) + lw ra, (sp+116) + lw ea, (sp+120) + /* Restore BA from PC */ + lw ba, (sp+128) + /* Stack pointer must be restored last, in case it has been updated */ + lw sp, (sp+112) + bret diff --git a/lm32/logic/sakc/firmware/gdb-test/gdb.c b/lm32/logic/sakc/firmware/gdb-test/gdb.c new file mode 100644 index 0000000..3780c3e --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/gdb.c @@ -0,0 +1,1214 @@ +/* + * Low-level support for LM32 remote debuging with GDB. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include + +// #include + +#include "gdb.h" +#include "gdb_uart.h" + +/* Enable system call support */ +#undef GDB_SYSCALLS_ENABLED 1 +/* Enable open/close system calls */ +#undef GDB_OPEN_CLOSE_SYSCALLS_ENABLED +/* Enable support for z packets */ +#undef GDB_HARDWARE_BREAKPOINTS_ENABLED +/* Enable support for q packets */ +#undef GDB_ECLIPSE_SUPPORT +/* Enable support for X packets */ +#define GDB_BINARY_DOWNLOAD_ENABLED +/* Enable support for P packets */ +#define GDB_P_ENABLED +/* Enable support for remote stub debugging */ +#undef GDB_REMOTE_DEBUG_ENABLED +/* Enable support for run-length encoding */ +#undef GDB_RLE_ENABLED +/* Enable support for restart packets */ +#undef GDB_RESTART_ENABLED + +/* Exception IDs */ +#define LM32_EXCEPTION_RESET 0x0 +#define LM32_EXCEPTION_INST_BREAKPOINT 0x1 +#define LM32_EXCEPTION_INST_BUS_ERROR 0x2 +#define LM32_EXCEPTION_DATA_BREAKPOINT 0x3 +#define LM32_EXCEPTION_DATA_BUS_ERROR 0x4 +#define LM32_EXCEPTION_DIVIDE_BY_ZERO 0x5 +#define LM32_EXCEPTION_INTERRUPT 0x6 +#define LM32_EXCEPTION_SYSTEM_CALL 0x7 + +/* Breakpoint instruction */ +#define LM32_BREAK 0xac000002UL + +/* BUFMAX defines the maximum number of characters in inbound/outbound buffers */ +#define BUFMAX 400 + +/* Function prototypes */ +#ifdef GDB_REMOTE_DEBUG_ENABLED +static int gdb_write (char *data, int len); +static int gdb_puts (char *str); +static void gdb_putint (int num); +#endif +static unsigned char *getpacket (void); +static unsigned char *getpacket (void); + +/* For integer to ASCII conversion */ +static const char hexchars[]="0123456789abcdef"; + +/* This numbering must be consistant with GDBs numbering in gdb/lm32-tdep.c */ +enum regnames { + R0, R1, R2, R3, R4, R5, R6, R7, + R8, R9, R10, R11, R12, R13, R14, R15, + R16, R17, R18, R19, R20, R21, R22, R23, + R24, R25, GP, FP, SP, RA, EA, BE, + PC, EID, NUM_REGS +}; + +/* I/O packet buffers */ +static unsigned char remcomInBuffer[BUFMAX]; +static unsigned char remcomOutBuffer[BUFMAX]; + +/* Set by debugger to indicate that when handling memory faults (bus errors), the + handler should set the mem_err flag and skip over the faulting instruction */ +static volatile int may_fault; + +/* Set by bus error exception handler, this indicates to caller of mem2hex, + * hex2mem or bin2mem that there has been an error. */ +static volatile int mem_err; + +/* Indicates if we're single stepping */ +static unsigned char stepping; +static unsigned *seq_ptr; +static unsigned seq_insn; +static unsigned *branch_ptr; +static unsigned branch_insn; +static char branch_step; + +#ifdef GDB_REMOTE_DEBUG_ENABLED +/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ +static int remote_debug; +#endif + +/* interrupt handler */ +static void (*intr_handler)(void); + +/* Convert ch from a hex digit to an int */ + +static int +hex (unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +/* Scan for the sequence $# */ + +static unsigned char * +getpacket (void) +{ + unsigned char *buffer = &remcomInBuffer[0]; + unsigned char checksum; + unsigned char xmitcsum; + int count; + char ch; + + while (1) + { + /* wait around for the start character, ignore all other characters */ + while ((ch = _gdb_read_char ()) != '$') + ; + +retry: + checksum = 0; + xmitcsum = -1; + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) + { + ch = _gdb_read_char (); + if (ch == '$') + goto retry; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') + { + ch = _gdb_read_char (); + xmitcsum = hex (ch) << 4; + ch = _gdb_read_char (); + xmitcsum += hex (ch); + + if (checksum != xmitcsum) + { +#ifdef GDB_REMOTE_DEBUG_ENABLED + if (remote_debug) + { + gdb_puts ("Bad checksum: "); + gdb_putint (checksum); + gdb_puts (" != "); + gdb_putint (xmitcsum); + gdb_puts ("\n"); + } +#endif + _gdb_write_char ('-'); /* failed checksum */ + } + else + { + _gdb_write_char ('+'); /* successful transfer */ + + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') + { + _gdb_write_char (buffer[0]); + _gdb_write_char (buffer[1]); + + return &buffer[3]; + } + + return &buffer[0]; + } + } + } +} + +/* Send the packet in buffer. */ +#ifdef GDB_RLE_ENABLED +static void +putpacket (unsigned char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch; + int run_length; + int run_idx; + char run_length_char; + + /* $#. */ + do + { + _gdb_write_char ('$'); + checksum = 0; + count = 0; + + while (ch = buffer[count]) + { + /* Transmit character */ + _gdb_write_char (ch); + checksum += ch; + count += 1; + /* Determine how many consecutive characters there are that are the + * same as the character we just transmitted */ + run_length = 0; + run_idx = count; + while ((buffer[run_idx++] == ch) && (run_length < 97)) + run_length++; + /* Encode run length as an ASCII character */ + run_length_char = (char)(run_length + 29); + if ( (run_length >= 3) + && (run_length_char != '$') + && (run_length_char != '#') + && (run_length_char != '+') + && (run_length_char != '-') + ) + { + /* Transmit run-length */ + _gdb_write_char ('*'); + checksum += '*'; + _gdb_write_char (run_length_char); + checksum += run_length_char; + count += run_length; + } + } + + _gdb_write_char ('#'); + _gdb_write_char (hexchars[(checksum >> 4) & 0xf]); + _gdb_write_char (hexchars[checksum & 0xf]); + } + while (_gdb_read_char () != '+'); +} +#else +static void +putpacket (unsigned char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch; + + /* $#. */ + do + { + _gdb_write_char ('$'); + checksum = 0; + count = 0; + + while (ch = buffer[count]) + { + _gdb_write_char (ch); + checksum += ch; + count += 1; + } + + _gdb_write_char ('#'); + _gdb_write_char (hexchars[checksum >> 4]); + _gdb_write_char (hexchars[checksum % 16]); + } + while (_gdb_read_char () != '+'); +} +#endif + +#ifdef GDB_REMOTE_DEBUG_ENABLED + +/* Make gdb write n bytes to stdout (not assumed to be null-terminated). + Returns: number of bytes written */ + +static int +gdb_write (char *data, int len) +{ + char *buf, *cpy; + int i; + char temp[100]; + + buf = temp; + buf[0] = 'O'; + i = 0; + while (i < len) + { + for (cpy = buf + 1; + i < len && cpy < buf + sizeof (temp) - 3; i++) + { + *cpy++ = hexchars[data[i] >> 4]; + *cpy++ = hexchars[data[i] & 0x0F]; + } + *cpy = 0; + putpacket (buf); + } + return len; +} + +/* Make gdb write a null-terminated string to stdout. + Returns: the length of the string */ + +static int +gdb_puts (char *str) +{ + return gdb_write (str, strlen (str)); +} + +/* Make gdb write an integer to stdout. */ + +static void +gdb_putint (int num) +{ + char buf[9]; + int cnt; + char *ptr; + int digit; + + ptr = buf; + for (cnt = 7 ; cnt >= 0 ; cnt--) { + digit = (num >> (cnt * 4)) & 0xf; + + if (digit <= 9) + *ptr++ = (char) ('0' + digit); + else + *ptr++ = (char) ('a' - 10 + digit); + } + + *ptr = (char) 0; + gdb_puts (buf); +} + +#endif + +static void +allow_nested_exception () +{ + mem_err = 0; + may_fault = 1; +} + +static void +disallow_nested_exception () +{ + mem_err = 0; + may_fault = 0; +} + +/* Convert the memory pointed to by mem into hex, placing result in buf. + * Return a pointer to the last char put in buf ('\0'), in case of mem fault, + * return NULL. + */ + +static unsigned char * +mem2hex (unsigned char *mem, unsigned char *buf, int count) +{ + unsigned char ch; + +#if 0 + /* Some h/w registers require word/half-word access, so treat them as a special case */ + if ((count == 4) && (((unsigned)mem & 3) == 0)) + { + unsigned long val; + int i; + + /* Read 32-bit value from memory */ + val = *(unsigned long *)mem; + /* Return NULL if the memory access caused an exception */ + if (mem_err) + return NULL; + /* Convert 32-bit value to a hex string */ + for (i = 28; i >= 0; i -= 4) + *buf++ = hexchars[(val >> i) & 0xf]; + } + else if ((count == 2) && (((unsigned)mem & 1) == 0)) + { + unsigned short val; + int i; + + /* Read 16-bit value from memory */ + val = *(unsigned short *)mem; + /* Return NULL if the memory access caused an exception */ + if (mem_err) + return NULL; + /* Convert 16-bit value to a hex string */ + for (i = 12; i >= 0; i -= 4) + *buf++ = hexchars[(val >> i) & 0xf]; + } + else +#endif + { + while (count-- > 0) + { + ch = *mem++; + if (mem_err) + return NULL; + *buf++ = hexchars[(ch >> 4) & 0xf]; + *buf++ = hexchars[ch & 0xf]; + } + } + + *buf = '\0'; + return buf; +} + +/* convert the hex array pointed to by buf into binary to be placed in mem + * return a pointer to the character AFTER the last byte written */ + +static char * +hex2mem (unsigned char *buf, unsigned char *mem, int count) +{ + int i; + unsigned char ch; + +#if 0 + /* Some h/w registers require word/half-word access, so treat them as a special case */ + if ((count == 4) && (((unsigned)mem & 3) == 0)) + { + unsigned long val; + int i; + + /* Convert hex data to 32-bit value */ + val = 0; + for (i = 24; i >= 0; i -= 4) + val |= hex (*buf++) << i; + /* Attempt to write data to memory */ + *(unsigned long *)mem = val; + /* Return NULL if write caused an exception */ + if (mem_err) + return NULL; + mem += 4; + } + else if ((count == 2) && (((unsigned)mem & 1) == 0)) + { + unsigned short val; + + /* Convert hex data to 16-bit value */ + val = 0; + for (i = 12; i >= 0; i -= 4) + val |= hex (*buf++) << i; + /* Attempt to write data to memory */ + *(unsigned short *)mem = val; + /* Return NULL if write caused an exception */ + if (mem_err) + return NULL; + mem += 2; + } + else +#endif + { + for (i = 0; i < count; i++) + { + /* Convert hex data to 8-bit value */ + ch = hex (*buf++) << 4; + ch |= hex (*buf++); + /* Attempt to write data to memory */ + *mem++ = ch; + /* Return NULL if write caused an exception */ + if (mem_err) + return NULL; + } + } + return mem; +} + +#ifdef GDB_BINARY_DOWNLOAD_ENABLED + +/* Copy the binary data pointed to by buf to mem and + * return a pointer to the character AFTER the last byte written + * $, # and 0x7d are escaped with 0x7d */ + +static char * +bin2mem (unsigned char *buf, unsigned char *mem, int count) +{ + int i; + unsigned char c; + +#if 0 + /* Some h/w registers require word/half-word access, so treat them as a special case */ + if ((count == 4) && (((unsigned)mem & 3) == 0)) + { + unsigned long val; + int i; + + /* Convert binary data to 32-bit value */ + val = 0; + for (i = 24; i >= 0; i -= 8) + { + c = *buf++; + if (c == 0x7d) + c = *buf++ ^ 0x20; + val |= c << i; + } + /* Attempt to write value to memory */ + *(unsigned long *)mem = val; + /* Return NULL if write caused an exception */ + if (mem_err) + return NULL; + mem += 4; + } + else if ((count == 2) && (((unsigned)mem & 1) == 0)) + { + unsigned short val; + int i; + + /* Convert binary data to 16-bit */ + val = 0; + for (i = 8; i >= 0; i -= 8) + { + c = *buf++; + if (c == 0x7d) + c = *buf++ ^ 0x20; + val |= c << i; + } + /* Attempt to write value to memory */ + *(unsigned short *)mem = val; + /* Return NULL if write caused an exception */ + if (mem_err) + return NULL; + mem += 2; + } + else +#endif + { + for (i = 0; i < count; i++) + { + /* Convert binary data to unsigned byte */ + c = *buf++; + if (c == 0x7d) + c = *buf++ ^ 0x20; + /* Attempt to write value to memory */ + *mem++ = c; + /* Return NULL if write caused an exception */ + if (mem_err) + return NULL; + } + } + return mem; +} +#endif + +/* Convert the exception identifier to a signal number. */ + +static int +computeSignal (int eid) +{ + switch (eid) + { + case LM32_EXCEPTION_RESET: + return 0; + case LM32_EXCEPTION_INTERRUPT: + return SIGINT; + case LM32_EXCEPTION_DATA_BREAKPOINT: + case LM32_EXCEPTION_INST_BREAKPOINT: + return SIGTRAP; + case LM32_EXCEPTION_INST_BUS_ERROR: + case LM32_EXCEPTION_DATA_BUS_ERROR: + return SIGSEGV; + case LM32_EXCEPTION_DIVIDE_BY_ZERO: + return SIGFPE; + } + return SIGHUP; /* default for things we don't know about */ +} + +/* Flush the instruction cache */ + +static void +flush_i_cache (void) +{ + /* Executing this does no harm on CPUs without a cache */ + /* We flush DCache as well incase debugger has accessed memory directly */ + __asm__ __volatile__ ("wcsr ICC, %0\n" + "nop\n" + "nop\n" + "nop\n" + "wcsr DCC, %0\n" + "nop\n" + "nop\n" + "nop" + : + : "r" (1) + ); +} + +/* + * While we find nice hex chars, build an int. + * Return number of chars processed. + */ + +static int +hexToInt (char **ptr, int *intValue) +{ + int numChars = 0; + int hexValue; + + *intValue = 0; + + while (**ptr) + { + hexValue = hex(**ptr); + if (hexValue < 0) + break; + + *intValue = (*intValue << 4) | hexValue; + numChars ++; + + (*ptr)++; + } + + return (numChars); +} + +/* Convert a register to a hex string */ + +static unsigned char * +reg2hex (unsigned val, unsigned char *buf) +{ + *buf++ = hexchars[(val >> 28) & 0xf]; + *buf++ = hexchars[(val >> 24) & 0xf]; + *buf++ = hexchars[(val >> 20) & 0xf]; + *buf++ = hexchars[(val >> 16) & 0xf]; + *buf++ = hexchars[(val >> 12) & 0xf]; + *buf++ = hexchars[(val >> 8) & 0xf]; + *buf++ = hexchars[(val >> 4) & 0xf]; + *buf++ = hexchars[val & 0xf]; + + return buf; +} + +#ifdef GDB_HARDWARE_BREAKPOINTS_ENABLED + +/* Set a h/w breakpoint at the given address */ + +static int +set_hw_breakpoint(int address, int length) +{ + int bp; + + /* Find a free break point register and then set it */ + __asm__ ("rcsr %0, BP0" : "=d" (bp)); + if ((bp & 0x01) == 0) + { + __asm__ ("wcsr BP0, %0" : : "d" (address | 1)); + return 1; + } + __asm__ ("rcsr %0, BP1" : "=d" (bp)); + if ((bp & 0x01) == 0) + { + __asm__ ("wcsr BP1, %0" : : "d" (address | 1)); + return 1; + } + __asm__ ("rcsr %0, BP2" : "=d" (bp)); + if ((bp & 0x01) == 0) + { + __asm__ ("wcsr BP2, %0" : : "d" (address | 1)); + return 1; + } + __asm__ ("rcsr %0, BP3" : "=d" (bp)); + if ((bp & 0x01) == 0) + { + __asm__ ("wcsr BP3, %0" : : "d" (address | 1)); + return 1; + } + /* No free breakpoint registers */ + return -1; +} + +/* Remove a h/w breakpoint which should be set at the given address */ + +static int +disable_hw_breakpoint(int address, int length) +{ + int bp; + + /* Try to find matching breakpoint register */ + __asm__ ("rcsr %0, BP0" : "=d" (bp)); + if ((bp & 0xfffffffc) == (address & 0xfffffffc)) + { + __asm__ ("wcsr BP0, %0" : : "d" (0)); + return 1; + } + __asm__ ("rcsr %0, BP1" : "=d" (bp)); + if ((bp & 0xfffffffc) == (address & 0xfffffffc)) + { + __asm__ ("wcsr BP1, %0" : : "d" (0)); + return 1; + } + __asm__ ("rcsr %0, BP2" : "=d" (bp)); + if ((bp & 0xfffffffc) == (address & 0xfffffffc)) + { + __asm__ ("wcsr BP2, %0" : : "d" (0)); + return 1; + } + __asm__ ("rcsr %0, BP3" : "=d" (bp)); + if ((bp & 0xfffffffc) == (address & 0xfffffffc)) + { + __asm__ ("wcsr BP3, %0" : : "d" (0)); + return 1; + } + /* Breakpoint not found */ + return -1; +} + +#endif + +/* This function does all command procesing for interfacing to gdb. + * The error codes we return are errno numbers */ + +void +_handle_exception (unsigned int *registers) +{ + int tt; /* Trap type */ + int sigval; + int addr; + int length; + char *ptr; + unsigned int *sp; + int err; + unsigned int dc; + int pathlen; + int retcode; + int reterrno; + int reg; + unsigned char status; + unsigned insn; + unsigned opcode; + unsigned branch_target; + + /* Check for bus error caused by this code (rather than the program being debugged) */ + if (may_fault && (registers[EID] == LM32_EXCEPTION_DATA_BUS_ERROR)) + { +#ifdef GDB_REMOTE_DEBUG_ENABLED + if (remote_debug) + gdb_puts ("Bus error in monitor\n"); +#endif + /* Indicate that a fault occured */ + mem_err = 1; + /* Skip over faulting instruction */ + registers[PC] += 4; + /* Resume execution */ + return; + } + + if (stepping) + { + /* Remove breakpoints */ + *seq_ptr = seq_insn; + if (branch_step) + *branch_ptr = branch_insn; + stepping = 0; + } + + /* Convert exception ID to a signal number */ + sigval = computeSignal(registers[EID]); + if (sigval == SIGINT) { + if (intr_handler != NULL) { + (*intr_handler)(); + return; + } else { + _gdb_ack_interrupt (); + } + } + + /* Set pointer to start of output buffer */ + ptr = remcomOutBuffer; + +#ifdef GDB_SYSCALLS_ENABLED + if (registers[EID] == LM32_EXCEPTION_SYSTEM_CALL) + { + /*_gpio.OutData = 0x82;*/ + + /* Calls to strlen in the following code may cause bus errors */ + allow_nested_exception (); + /* Pass system calls to the debugger */ + switch (registers[R8]) + { + case SYS_exit: + *ptr++ = 'W'; + *ptr++ = hexchars[(registers[R1] >> 4) & 0xf]; + *ptr++ = hexchars[registers[R1] & 0xf]; + *ptr++ = 0; + intr_handler = NULL; + break; + +#ifdef GDB_OPEN_CLOSE_SYSCALLS_ENABLED + case SYS_open: + memcpy (ptr, "Fopen,", 6); + ptr += 6; + ptr = reg2hex(registers[R1], ptr); + *ptr++ = '/'; + pathlen = strlen((unsigned char *)registers[R1]) + 1; + ptr = reg2hex(pathlen, ptr); + *ptr++ = ','; + ptr = reg2hex(registers[R2], ptr); + *ptr++ = ','; + ptr = reg2hex(registers[R3], ptr); + *ptr++ = 0; + break; + + case SYS_close: + memcpy (ptr, "Fclose,", 7); + ptr += 7; + ptr = reg2hex(registers[R1], ptr); + *ptr++ = 0; + break; +#endif + + case SYS_read: + memcpy (ptr, "Fread,", 6); + ptr += 6; + ptr = reg2hex(registers[R1], ptr); + *ptr++ = ','; + ptr = reg2hex(registers[R2], ptr); + *ptr++ = ','; + ptr = reg2hex(registers[R3], ptr); + *ptr++ = 0; + break; + + case SYS_write: + memcpy (ptr, "Fwrite,", 7); + ptr += 7; + ptr = reg2hex(registers[R1], ptr); + *ptr++ = ','; + ptr = reg2hex(registers[R2], ptr); + *ptr++ = ','; + ptr = reg2hex(registers[R3], ptr); + *ptr++ = 0; + break; + + case 231: + /*_gpio.OutData = 0x90;*/ + intr_handler = registers[R1]; + /* Skip over instruction */ + registers[PC] += 4; + return; + + case 232: + intr_handler = NULL; + /* Skip over instruction */ + registers[PC] += 4; + return; + + default: /* Unknown or unsupported system call */ + /* Indicate to calling program that its not supported */ + registers[R1] = -1; + registers[R2] = 0; + registers[R3] = ENOSYS; + /* Skip over instruction */ + registers[PC] += 4; + return; + } + /* Check to see if a bus error occured */ + if (mem_err) + { + disallow_nested_exception (); + /* Indicate error to calling program */ + registers[R1] = -1; + registers[R2] = 0; + registers[R3] = ENOSYS; + /* Skip over scall instruction */ + registers[PC] += 4; + return; + } + disallow_nested_exception (); + } + else +#endif /* GDB_SYSCALLS_ENABLED */ + { + /* reply to host that an exception has occurred */ + + *ptr++ = 'T'; + + *ptr++ = hexchars[(sigval >> 4) & 0xf]; + *ptr++ = hexchars[sigval & 0xf]; + + *ptr++ = hexchars[(PC >> 4) & 0xf]; + *ptr++ = hexchars[PC & 0xf]; + *ptr++ = ':'; + ptr = mem2hex ((unsigned char *)®isters[PC], ptr, 4); + *ptr++ = ';'; + + *ptr++ = hexchars[(SP >> 4) & 0xf]; + *ptr++ = hexchars[SP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex ((unsigned char *)®isters[SP], ptr, 4); + *ptr++ = ';'; + + *ptr++ = 0; + } + + if (registers[EID]) + putpacket (remcomOutBuffer); + + while (1) + { + remcomOutBuffer[0] = 0; + + ptr = getpacket(); + + switch (*ptr++) + { + case '?': /* return last signal */ + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval & 0xf]; + remcomOutBuffer[3] = 0; + break; + +#ifdef GDB_REMOTE_DEBUG_ENABLED + case 'd': /* toggle debug flag */ + remote_debug = !(remote_debug); + break; +#endif + + case 'g': /* return the value of the CPU registers */ + ptr = remcomOutBuffer; + ptr = mem2hex ((unsigned char *)registers, ptr, NUM_REGS * 4); + break; + + case 'G': /* set the value of the CPU registers */ + hex2mem (ptr, (unsigned char *)registers, NUM_REGS * 4); + strcpy (remcomOutBuffer, "OK"); + break; + +#ifdef GDB_P_ENABLED + case 'p': /* Return the value of the specified register */ + if (hexToInt (&ptr, ®)) + { + ptr = remcomOutBuffer; + ptr = mem2hex ((unsigned char *)®isters[reg], ptr, 4); + } + else + strcpy (remcomOutBuffer, "E22"); + break; + + case 'P': /* Set the specified register to the given value */ + if (hexToInt (&ptr, ®) + && *ptr++ == '=') + { + hex2mem (ptr, (unsigned char *)®isters[reg], 4); + strcpy (remcomOutBuffer, "OK"); + } + else + strcpy (remcomOutBuffer, "E22"); + break; +#endif + + case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + /* Try to read %x,%x. */ + if (hexToInt (&ptr, &addr) + && *ptr++ == ',' + && hexToInt (&ptr, &length) + && length < (sizeof(remcomOutBuffer)/2)) + { + allow_nested_exception (); + if (NULL == mem2hex((unsigned char *)addr, remcomOutBuffer, length)) + strcpy (remcomOutBuffer, "E14"); + disallow_nested_exception (); + } + else + strcpy (remcomOutBuffer,"E22"); + break; + + case 'M': /* MAA.AA,LLLL: Write LLLL bytes at address AA.AA */ + /* Try to read '%x,%x:'. */ + if (hexToInt (&ptr, &addr) + && *ptr++ == ',' + && hexToInt (&ptr, &length) + && *ptr++ == ':') + { + allow_nested_exception (); + if (hex2mem(ptr, (char *)addr, length)) + strcpy (remcomOutBuffer, "OK"); + else + strcpy (remcomOutBuffer, "E14"); + disallow_nested_exception (); + } + else + strcpy (remcomOutBuffer, "E22"); + break; + +#ifdef GDB_BINARY_DOWNLOAD_ENABLED + case 'X': /* XAA.AA,LLLL: Write LLLL bytes at address AA.AA */ + /* Try to read '%x,%x:'. */ + if (hexToInt (&ptr, &addr) + && *ptr++ == ',' + && hexToInt (&ptr, &length) + && *ptr++ == ':') + { + allow_nested_exception (); + if (bin2mem (ptr, (unsigned char *)addr, length)) + strcpy (remcomOutBuffer, "OK"); + else + strcpy (remcomOutBuffer, "E14"); + disallow_nested_exception (); + } + else + strcpy (remcomOutBuffer, "E22"); + break; +#endif + +#if 0 + case 'C': /* CSS;AA..AA Continue with signal SS at address AA..AA(optional) */ + /* Set signal number */ + if (hexToInt (&ptr, &sigval)) + registers[EID] = sigval; + /* try to read optional parameter, pc unchanged if no parm */ + if (*ptr == ';') + { + ptr++; + if (hexToInt (&ptr, &addr)) + registers[PC] = addr; + } + flush_i_cache (); + return; +#endif + + case 'c': /* cAA..AA Continue at address AA..AA(optional) */ + /* try to read optional parameter, pc unchanged if no parm */ + if (hexToInt (&ptr, &addr)) + registers[PC] = addr; + flush_i_cache (); + return; + + case 's': /* step at address AA (optional) */ + /* try to read optional parameter, pc unchanged if no parm */ + if (hexToInt (&ptr, &addr)) + registers[PC] = addr; + stepping = 1; + /* Is instruction a branch? */ + insn = *(unsigned *)registers[PC]; + opcode = insn & 0xfc000000; + if ( (opcode == 0xe0000000) + || (opcode == 0xf8000000) + ) + { + branch_step = 1; + branch_target = registers[PC] + (((signed)insn << 6) >> 4); + } + else if ( (opcode == 0x44000000) + || (opcode == 0x48000000) + || (opcode == 0x4c000000) + || (opcode == 0x50000000) + || (opcode == 0x54000000) + || (opcode == 0x5c000000) + ) + { + branch_step = 1; + branch_target = registers[PC] + (((signed)insn << 16) >> 14); + } + else if ( (opcode == 0xd8000000) + || (opcode == 0xc0000000) + ) + { + branch_step = 1; + branch_target = registers[(insn >> 21) & 0x1f]; + } + else + branch_step = 0; + /* Set breakpoint after instruction we're stepping */ + seq_ptr = (unsigned *)registers[PC]; + seq_ptr++; + seq_insn = *seq_ptr; + *seq_ptr = LM32_BREAK; + if (branch_step) + { + /* Set breakpoint on branch target */ + branch_ptr = (unsigned *)branch_target; + branch_insn = *branch_ptr; + *branch_ptr = LM32_BREAK; + } + flush_i_cache (); + return; + +#ifdef GDB_HARDWARE_BREAKPOINTS_ENABLED + case 'Z': + switch (*ptr++) + { + case '1': /* Insert h/w breakpoint */ + if (*ptr++ == ',' + && hexToInt (&ptr, &addr) + && *ptr++ == ',' + && hexToInt (&ptr, &length)) + { + err = set_hw_breakpoint(addr, length); + if (err > 0) + strcpy (remcomOutBuffer, "OK"); + else if (err < 0) + strcpy (remcomOutBuffer, "E28"); + } + else + strcpy (remcomOutBuffer, "E22"); + break; + } + break; + + case 'z': + switch (*ptr++) + { + case '1': /* Remove h/w breakpoint */ + if (*ptr++ == ',' + && hexToInt (&ptr, &addr) + && *ptr++ == ',' + && hexToInt (&ptr, &length)) + { + err = disable_hw_breakpoint(addr, length); + if (err > 0) + strcpy (remcomOutBuffer, "OK"); + else if (err < 0) + strcpy (remcomOutBuffer, "E28"); + } + else + strcpy (remcomOutBuffer, "E22"); + break; + } + break; +#endif + +#ifdef GDB_SYSCALLS_ENABLED + case 'F': /* system call result */ + if ( (ptr[0] == '-') + && (ptr[1] == '1') + && (ptr[2] == ',') + ) + { + /* System call failed */ + ptr += 3; + hexToInt (&ptr, &reterrno); + retcode = -1; + } + else + { + /* System call was successful */ + hexToInt (&ptr, &retcode); + allow_nested_exception (); + /* Check if a bus error occured when mapping data structures */ + if (mem_err) + { + reterrno = EFAULT; + retcode = -1; + } + disallow_nested_exception (); + } + /* Skip over scall instruction */ + registers[PC] += 4; + /* Set return value */ + registers[R1] = retcode; + registers[R2] = 0; + registers[R3] = reterrno; + return; +#endif /* GDB_SYSCALLS_ENABLED */ + +#ifdef GDB_ECLIPSE_SUPPORT + case 'q': /* Query */ + if (ptr[0] == 'C') + { + /* Return current thread ID. We only support 1. */ + strcpy (remcomOutBuffer, "qC1"); + } + else if (!strncmp (&ptr[0], "fThreadInfo", 11)) + { + /* Return all thread IDs. We only support 1. */ + strcpy (remcomOutBuffer, "m1"); + } + else if (!strncmp (&ptr[0], "sThreadInfo", 11)) + { + /* Indicate there are no more threads. */ + strcpy (remcomOutBuffer, "l"); + } + break; +#endif + +#ifdef GDB_RESTART_ENABLED + case 'r': /* Reset */ + case 'R': + /* We reset by branching to the reset exception handler. */ + registers[PC] = 0; + return; +#endif + + } + + /* reply to the request */ + putpacket (remcomOutBuffer); + } +} + + diff --git a/lm32/logic/sakc/firmware/gdb-test/gdb.h b/lm32/logic/sakc/firmware/gdb-test/gdb.h new file mode 100644 index 0000000..b992af1 --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/gdb.h @@ -0,0 +1,37 @@ +/* + * LatticeMico32 GDB I/O. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LM32_GDB_H +#define _LM32_GDB_H + +/* Write a single character to debug host */ +void _gdb_write_char (char); +/* Read and return a single character from debug host */ +char _gdb_read_char (void); +/* Acknowledge interrupt that caused CPU to enter debug mode */ +void _gdb_ack_interrupt (void); + +#endif /* _LM32_GDB_H */ + diff --git a/lm32/logic/sakc/firmware/gdb-test/gdb_uart.c b/lm32/logic/sakc/firmware/gdb-test/gdb_uart.c new file mode 100644 index 0000000..fe12d1d --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/gdb_uart.c @@ -0,0 +1,23 @@ +#include "soc-hw.h" + +/* Write a single character to debug host */ +void +_gdb_write_char (char c) +{ + uart_putchar(c); +} + +/* Read and return a single character from debug host */ +char +_gdb_read_char (void) +{ + return uart_getchar(); +} + +/* Acknowledge specified interrupt that caused CPU to enter debug mode */ +void +_gdb_ack_interrupt (void) +{ + /* ACK interrupt */ + /*__asm__ ("wcsr\tIA, %0" : : "d" (1 << interrupt));*/ +} diff --git a/lm32/logic/sakc/firmware/gdb-test/gdb_uart.h b/lm32/logic/sakc/firmware/gdb-test/gdb_uart.h new file mode 100644 index 0000000..dc7f64a --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/gdb_uart.h @@ -0,0 +1,5 @@ + +void _gdb_write_char (char c); +char _gdb_read_char (void); +void _gdb_ack_interrupt (void) ; + diff --git a/lm32/logic/sakc/firmware/gdb-test/linker.ld b/lm32/logic/sakc/firmware/gdb-test/linker.ld new file mode 100644 index 0000000..dad4fb0 --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/linker.ld @@ -0,0 +1,67 @@ +OUTPUT_FORMAT("elf32-lm32") +ENTRY(_start) + +__DYNAMIC = 0; + + +_RAM_START = 0x40000000; +_RAM_SIZE = 0x100000; +_RAM_END = _RAM_START + _RAM_SIZE; + +MEMORY { + ram : ORIGIN = 0x40000000, LENGTH = 0x100000 /* 1M */ +} + +SECTIONS +{ + .boot : + { + _fboot = .; + *(.boot) + _eboot = .; + } > ram + + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > ram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > ram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > ram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _ebss = .; + _end = .; + } > ram +} + +PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4); + diff --git a/lm32/logic/sakc/firmware/gdb-test/main.c b/lm32/logic/sakc/firmware/gdb-test/main.c new file mode 100644 index 0000000..0580633 --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/main.c @@ -0,0 +1,20 @@ +#include "soc-hw.h" + +void main() +{ + gpio0->oe = 0x000000ff; + for(;;) { + int i; + + for(i=0; i<8; i++) { + uint32_t out1, out2; + + out1 = 0x01 << i; + out2 = 0x80 >> i; + gpio0->out = out1 | out2; + + msleep(100); + } + } +} + diff --git a/lm32/logic/sakc/firmware/gdb-test/soc-hw.c b/lm32/logic/sakc/firmware/gdb-test/soc-hw.c new file mode 100644 index 0000000..8d4515e --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/soc-hw.c @@ -0,0 +1,133 @@ +#include "soc-hw.h" + +uart_t *uart0 = (uart_t *) 0xf0000000; +timer_t *timer0 = (timer_t *) 0xf0010000; +gpio_t *gpio0 = (gpio_t *) 0xF0020000; + +isr_ptr_t isr_table[32]; + + +void tic_isr(); +/*************************************************************************** + * IRQ handling + */ +void isr_null() +{ +} + +void irq_handler(uint32_t pending) +{ + int i; + + for(i=0; i<32; i++) { + if (pending & 0x01) (*isr_table[i])(); + pending >>= 1; + } +} + +void isr_init() +{ + int i; + for(i=0; i<32; i++) + isr_table[i] = &isr_null; +} + +void isr_register(int irq, isr_ptr_t isr) +{ + isr_table[irq] = isr; +} + +void isr_unregister(int irq) +{ + isr_table[irq] = &isr_null; +} + +/*************************************************************************** + * TIMER Functions + */ +void msleep(uint32_t msec) +{ + uint32_t tcr; + + // Use timer0.1 + timer0->compare1 = (FCPU/1000)*msec; + timer0->counter1 = 0; + timer0->tcr1 = TIMER_EN; + + do { + //halt(); + tcr = timer0->tcr1; + } while ( ! (tcr & TIMER_TRIG) ); +} + +void nsleep(uint32_t nsec) +{ + uint32_t tcr; + + // Use timer0.1 + timer0->compare1 = (FCPU/1000000)*nsec; + timer0->counter1 = 0; + timer0->tcr1 = TIMER_EN; + + do { + //halt(); + tcr = timer0->tcr1; + } while ( ! (tcr & TIMER_TRIG) ); +} + + +uint32_t tic_msec; + +void tic_isr() +{ + tic_msec++; + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; +} + +void tic_init() +{ + tic_msec = 0; + + // Setup timer0.0 + timer0->compare0 = (FCPU/10000); + timer0->counter0 = 0; + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; + + isr_register(1, &tic_isr); +} + + +/*************************************************************************** + * UART Functions + */ +void uart_init() +{ + //uart0->ier = 0x00; // Interrupt Enable Register + //uart0->lcr = 0x03; // Line Control Register: 8N1 + //uart0->mcr = 0x00; // Modem Control Register + + // Setup Divisor register (Fclk / Baud) + //uart0->div = (FCPU/(57600*16)); +} + +char uart_getchar() +{ + while (! (uart0->ucr & UART_DR)) ; + return uart0->rxtx; +} + +void uart_putchar(char c) +{ + while (uart0->ucr & UART_BUSY) ; + uart0->rxtx = c; +} + +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + uart_putchar(*c); + c++; + } +} + diff --git a/lm32/logic/sakc/firmware/gdb-test/soc-hw.h b/lm32/logic/sakc/firmware/gdb-test/soc-hw.h new file mode 100644 index 0000000..3c89665 --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/soc-hw.h @@ -0,0 +1,108 @@ +#ifndef SPIKEHW_H +#define SPIKEHW_H + +#define PROMSTART 0x00000000 +#define RAMSTART 0x00000800 +#define RAMSIZE 0x400 +#define RAMEND (RAMSTART + RAMSIZE) + +#define RAM_START 0x40000000 +#define RAM_SIZE 0x04000000 + +#define FCPU 50000000 + +#define UART_RXBUFSIZE 32 + +/**************************************************************************** + * Types + */ +typedef unsigned int uint32_t; // 32 Bit +typedef signed int int32_t; // 32 Bit + +typedef unsigned char uint8_t; // 8 Bit +typedef signed char int8_t; // 8 Bit + +/**************************************************************************** + * Interrupt handling + */ +typedef void(*isr_ptr_t)(void); + +void irq_enable(); +void irq_disable(); +void irq_set_mask(uint32_t mask); +uint32_t irq_get_mak(); + +void isr_init(); +void isr_register(int irq, isr_ptr_t isr); +void isr_unregister(int irq); + +/**************************************************************************** + * General Stuff + */ +void halt(); +void jump(uint32_t addr); + + +/**************************************************************************** + * Timer + */ +#define TIMER_EN 0x08 // Enable Timer +#define TIMER_AR 0x04 // Auto-Reload +#define TIMER_IRQEN 0x02 // IRQ Enable +#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR) + +typedef struct { + volatile uint32_t tcr0; + volatile uint32_t compare0; + volatile uint32_t counter0; + volatile uint32_t tcr1; + volatile uint32_t compare1; + volatile uint32_t counter1; +} timer_t; + +void msleep(uint32_t msec); +void nsleep(uint32_t nsec); + +void tic_init(); + + +/*************************************************************************** + * GPIO0 + */ +typedef struct { + volatile uint32_t ctrl; + volatile uint32_t dummy1; + volatile uint32_t dummy2; + volatile uint32_t dummy3; + volatile uint32_t in; + volatile uint32_t out; + volatile uint32_t oe; +} gpio_t; + +/*************************************************************************** + * UART0 + */ +#define UART_DR 0x01 // RX Data Ready +#define UART_ERR 0x02 // RX Error +#define UART_BUSY 0x10 // TX Busy + +typedef struct { + volatile uint32_t ucr; + volatile uint32_t rxtx; +} uart_t; + +void uart_init(); +void uart_putchar(char c); +void uart_putstr(char *str); +char uart_getchar(); + + +/*************************************************************************** + * Pointer to actual components + */ +extern timer_t *timer0; +extern uart_t *uart0; +extern gpio_t *gpio0; +extern uint32_t *sram0; + +#endif // SPIKEHW_H diff --git a/lm32/logic/sakc/firmware/gdb-test/start-gdb b/lm32/logic/sakc/firmware/gdb-test/start-gdb new file mode 100644 index 0000000..138bfe8 --- /dev/null +++ b/lm32/logic/sakc/firmware/gdb-test/start-gdb @@ -0,0 +1,6 @@ +#!/bin/sh + +lm32-elf-gdb image << ENDL +target remote /dev/ttyUSB0 +ENDL + diff --git a/lm32/logic/sakc/firmware/hw-test/Makefile b/lm32/logic/sakc/firmware/hw-test/Makefile new file mode 100644 index 0000000..674cdb8 --- /dev/null +++ b/lm32/logic/sakc/firmware/hw-test/Makefile @@ -0,0 +1,46 @@ +LM32_CC=lm32-elf-gcc +LM32_LD=lm32-elf-ld +LM32_OBJCOPY=lm32-elf-objcopy +LM32_OBJDUMP=lm32-elf-objdump + +SREC2VRAM ?= ../../tools/srec2vram/srec2vram +VRAMFILE=image.ram + +CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled +LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld +SEGMENTS = -j .text -j .rodata -j .data + +all: image.srec $(VRAMFILE) + +crt0ram.o: crt0ram.S + $(LM32_CC) $(CFLAGS) -c crt0ram.S + +main.o: main.c + $(LM32_CC) $(CFLAGS) -c main.c + +soc-hw.o: soc-hw.c + $(LM32_CC) $(CFLAGS) -c soc-hw.c + +image: crt0ram.o main.o soc-hw.o linker.ld Makefile + $(LM32_LD) $(LDFLAGS) -Map image.map -N -o image crt0ram.o main.o soc-hw.o + +image.lst: image + $(LM32_OBJDUMP) -h -S $< > $@ + +image.bin: image + $(LM32_OBJCOPY) $(SEGMENTS) -O binary image image.bin + +image.srec: image image.lst + $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec + +$(VRAMFILE): image.srec + $(SREC2VRAM) image.srec 0x40000000 0x1000 > $(VRAMFILE) + +clean: + rm -f image image.lst image.bin image.srec image.map *.o *.d + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif + diff --git a/lm32/logic/sakc/firmware/hw-test/crt0ram.S b/lm32/logic/sakc/firmware/hw-test/crt0ram.S new file mode 100644 index 0000000..72caf27 --- /dev/null +++ b/lm32/logic/sakc/firmware/hw-test/crt0ram.S @@ -0,0 +1,249 @@ +/* + * LatticeMico32 C startup code. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Exception handlers - Must be 32 bytes long. */ + .section .text, "ax", @progbits + .global _start + .global irq_enable, irq_disable, irq_set_mask, irq_get_mask + .global jump, halt + .global get_sp, get_gp + +_start: +_reset_handler: + xor r0, r0, r0 + wcsr IE, r0 + mvhi r1, hi(_reset_handler) + ori r1, r1, lo(_reset_handler) + wcsr EBA, r1 + calli _crt0 + nop + nop + +_breakpoint_handler: + nop + nop + nop + nop + nop + nop + nop + nop + +_ibuserror_handler: + nop + nop + nop + nop + nop + nop + nop + nop + +_watchpoint_handler: + nop + nop + nop + nop + nop + nop + nop + nop + +_dbuserror_handler: + nop + nop + nop + nop + nop + nop + nop + nop + +_divzero_handler: + nop + nop + nop + nop + nop + nop + nop + nop + +_interrupt_handler: + sw (sp+0), ra + calli _save_all + rcsr r1, IP + calli irq_handler + mvhi r1, 0xffff + ori r1, r1, 0xffff + wcsr IP, r1 + bi _restore_all_and_eret + +_scall_handler: + nop + nop + nop + nop + nop + nop + nop + nop + +_crt0: + /* Setup stack and global pointer */ + mvhi sp, hi(_fstack) + ori sp, sp, lo(_fstack) + mvhi gp, hi(_gp) + ori gp, gp, lo(_gp) + + /* Clear BSS */ + mvhi r1, hi(_fbss) + ori r1, r1, lo(_fbss) + mvhi r3, hi(_ebss) + ori r3, r3, lo(_ebss) +.clearBSS: + be r1, r3, .callMain + sw (r1+0), r0 + addi r1, r1, 4 + bi .clearBSS + +.callMain: + mvi r1, 0 + mvi r2, 0 + mvi r3, 0 + calli main + +irq_enable: + mvi r1, 1 + wcsr IE, r1 + ret + +irq_disable: + mvi r1, 0 + wcsr IE, r1 + ret + +irq_set_mask: + wcsr IM, r1 + ret + +irq_get_mask: + rcsr r1, IM + ret + +jump: + b r1 + +halt: + bi halt + + /* Save all registers onto the stack */ +_save_all: + addi sp, sp, -128 + sw (sp+4), r1 + sw (sp+8), r2 + sw (sp+12), r3 + sw (sp+16), r4 + sw (sp+20), r5 + sw (sp+24), r6 + sw (sp+28), r7 + sw (sp+32), r8 + sw (sp+36), r9 + sw (sp+40), r10 +#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE + sw (sp+44), r11 + sw (sp+48), r12 + sw (sp+52), r13 + sw (sp+56), r14 + sw (sp+60), r15 + sw (sp+64), r16 + sw (sp+68), r17 + sw (sp+72), r18 + sw (sp+76), r19 + sw (sp+80), r20 + sw (sp+84), r21 + sw (sp+88), r22 + sw (sp+92), r23 + sw (sp+96), r24 + sw (sp+100), r25 + sw (sp+104), r26 + sw (sp+108), r27 +#endif + sw (sp+120), ea + sw (sp+124), ba + /* ra and sp need special handling, as they have been modified */ + lw r1, (sp+128) + sw (sp+116), r1 + mv r1, sp + addi r1, r1, 128 + sw (sp+112), r1 + ret + + /* Restore all registers and return from exception */ +_restore_all_and_eret: + lw r1, (sp+4) + lw r2, (sp+8) + lw r3, (sp+12) + lw r4, (sp+16) + lw r5, (sp+20) + lw r6, (sp+24) + lw r7, (sp+28) + lw r8, (sp+32) + lw r9, (sp+36) + lw r10, (sp+40) +#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE + lw r11, (sp+44) + lw r12, (sp+48) + lw r13, (sp+52) + lw r14, (sp+56) + lw r15, (sp+60) + lw r16, (sp+64) + lw r17, (sp+68) + lw r18, (sp+72) + lw r19, (sp+76) + lw r20, (sp+80) + lw r21, (sp+84) + lw r22, (sp+88) + lw r23, (sp+92) + lw r24, (sp+96) + lw r25, (sp+100) + lw r26, (sp+104) + lw r27, (sp+108) +#endif + lw ra, (sp+116) + lw ea, (sp+120) + lw ba, (sp+124) + /* Stack pointer must be restored last, in case it has been updated */ + lw sp, (sp+112) + eret + +get_sp: + mv r1, sp + ret + +get_gp: + mv r1, gp + ret + diff --git a/lm32/logic/sakc/firmware/hw-test/linker.ld b/lm32/logic/sakc/firmware/hw-test/linker.ld new file mode 100644 index 0000000..972fc56 --- /dev/null +++ b/lm32/logic/sakc/firmware/hw-test/linker.ld @@ -0,0 +1,59 @@ +OUTPUT_FORMAT("elf32-lm32") +ENTRY(_start) + +__DYNAMIC = 0; + + +_RAM_START = 0x40000000; +_RAM_SIZE = 0x1000; +_RAM_END = _RAM_START + _RAM_SIZE; + +MEMORY { + ram : ORIGIN = 0x40000000, LENGTH = 0x1000 /* 4k */ +} + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > ram + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + _erodata = .; + } > ram + + .data : + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; + } > ram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _ebss = .; + _end = .; + } > ram +} + +PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4); diff --git a/lm32/logic/sakc/firmware/hw-test/main.c b/lm32/logic/sakc/firmware/hw-test/main.c new file mode 100644 index 0000000..a7cb0ba --- /dev/null +++ b/lm32/logic/sakc/firmware/hw-test/main.c @@ -0,0 +1,151 @@ +/** + * + */ + +#include "soc-hw.h" + +inline void writeint(uint32_t val) +{ + uint32_t i, digit; + + for (i=0; i<8; i++) { + digit = (val & 0xf0000000) >> 28; + if (digit >= 0xA) + uart_putchar('A'+digit-10); + else + uart_putchar('0'+digit); + val <<= 4; + } +} + +void test2() { + uart_putchar('b'); +} + +void test() { + uart_putchar('a'); + test2(); + uart_putchar('c'); +} + +char glob[] = "Global"; + +volatile uint32_t *p; +volatile uint8_t *p2; + +extern uint32_t tic_msec; + +int main() +{ + char test2[] = "Lokalerstr"; + char *str = test2; + uint32_t i; + +// for (i = 0; i < 4; i++) + // test2[i] = 'l'; + // glob[0] = 'g'; + + // Initialize stuff + uart_init(); + + // Say Hello! + uart_putstr( "** Spike Test Firmware **\n" ); + + // Initialize TIC + isr_init(); + tic_init(); + irq_set_mask( 0x00000002 ); + irq_enable(); + + // Say Hello! + uart_putstr( "Timer Interrupt instelled.\n" ); + + // Do some trivial tests + uart_putstr( "Subroutine-Return Test: " ); + test(); + uart_putchar('\n'); + + uart_putstr( "Local-Pointer Test:" ); + for (;*str; str++) { + uart_putchar(*str); + } + uart_putchar('\n'); + + uart_putstr( "Global-Pointer Test:" ); + str = glob; + for (;*str; str++) { + uart_putchar(*str); + } + uart_putchar('\n'); + + uart_putstr( "Stack Pointer : " ); + writeint(get_sp()); + uart_putchar('\n'); + + uart_putstr( "Global Pointer: " ); + writeint(get_gp()); + uart_putchar('\n'); + + uart_putstr( "Timer Test (1s): " ); + for(i=0; i<4; i++) { + uart_putstr("tic..."); + msleep(1000); + } + uart_putchar('\n'); + + uart_putstr( "Timer Interrupt counter: " ); + writeint( tic_msec ); + uart_putchar('\n'); + + int val = tic_msec; + uart_putstr( "Shift: " ); + writeint( val ); + uart_putstr(" <-> "); + for(i=0; i<32; i++) { + if (val & 0x80000000) + uart_putchar( '1' ); + else + uart_putchar( '0' ); + + val <<= 1; + } + uart_putstr("\r\n"); + + uart_putstr( "GPIO Test..." ); + gpio0->oe = 0x000000ff; + for(;;) { + for(i=0; i<8; i++) { + uint32_t out1, out2; + + out1 = 0x01 << i; + out2 = 0x80 >> i; + gpio0->out = out1 | out2; + + msleep(100); + } + } + + +/* + uart_putstr( "Memory Dump: " ); + uint32_t *start = (uint32_t *)0x40000000; + uint32_t *end = (uint32_t *)0x40000100; + uint32_t *p; + for (p=start; p>= 1; + } +} + +void isr_init() +{ + int i; + for(i=0; i<32; i++) + isr_table[i] = &isr_null; +} + +void isr_register(int irq, isr_ptr_t isr) +{ + isr_table[irq] = isr; +} + +void isr_unregister(int irq) +{ + isr_table[irq] = &isr_null; +} + +/*************************************************************************** + * TIMER Functions + */ +void msleep(uint32_t msec) +{ + uint32_t tcr; + + // Use timer0.1 + timer0->compare1 = (FCPU/1000)*msec; + timer0->counter1 = 0; + timer0->tcr1 = TIMER_EN; + + do { + //halt(); + tcr = timer0->tcr1; + } while ( ! (tcr & TIMER_TRIG) ); +} + +void nsleep(uint32_t nsec) +{ + uint32_t tcr; + + // Use timer0.1 + timer0->compare1 = (FCPU/1000000)*nsec; + timer0->counter1 = 0; + timer0->tcr1 = TIMER_EN; + + do { + //halt(); + tcr = timer0->tcr1; + } while ( ! (tcr & TIMER_TRIG) ); +} + + +uint32_t tic_msec; + +void tic_isr() +{ + tic_msec++; + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; +} + +void tic_init() +{ + tic_msec = 0; + + // Setup timer0.0 + timer0->compare0 = (FCPU/10000); + timer0->counter0 = 0; + timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; + + isr_register(1, &tic_isr); +} + + +/*************************************************************************** + * UART Functions + */ +void uart_init() +{ + //uart0->ier = 0x00; // Interrupt Enable Register + //uart0->lcr = 0x03; // Line Control Register: 8N1 + //uart0->mcr = 0x00; // Modem Control Register + + // Setup Divisor register (Fclk / Baud) + //uart0->div = (FCPU/(57600*16)); +} + +char uart_getchar() +{ + while (! (uart0->ucr & UART_DR)) ; + return uart0->rxtx; +} + +void uart_putchar(char c) +{ + while (uart0->ucr & UART_BUSY) ; + uart0->rxtx = c; +} + +void uart_putstr(char *str) +{ + char *c = str; + while(*c) { + uart_putchar(*c); + c++; + } +} + diff --git a/lm32/logic/sakc/firmware/hw-test/soc-hw.h b/lm32/logic/sakc/firmware/hw-test/soc-hw.h new file mode 100644 index 0000000..3c89665 --- /dev/null +++ b/lm32/logic/sakc/firmware/hw-test/soc-hw.h @@ -0,0 +1,108 @@ +#ifndef SPIKEHW_H +#define SPIKEHW_H + +#define PROMSTART 0x00000000 +#define RAMSTART 0x00000800 +#define RAMSIZE 0x400 +#define RAMEND (RAMSTART + RAMSIZE) + +#define RAM_START 0x40000000 +#define RAM_SIZE 0x04000000 + +#define FCPU 50000000 + +#define UART_RXBUFSIZE 32 + +/**************************************************************************** + * Types + */ +typedef unsigned int uint32_t; // 32 Bit +typedef signed int int32_t; // 32 Bit + +typedef unsigned char uint8_t; // 8 Bit +typedef signed char int8_t; // 8 Bit + +/**************************************************************************** + * Interrupt handling + */ +typedef void(*isr_ptr_t)(void); + +void irq_enable(); +void irq_disable(); +void irq_set_mask(uint32_t mask); +uint32_t irq_get_mak(); + +void isr_init(); +void isr_register(int irq, isr_ptr_t isr); +void isr_unregister(int irq); + +/**************************************************************************** + * General Stuff + */ +void halt(); +void jump(uint32_t addr); + + +/**************************************************************************** + * Timer + */ +#define TIMER_EN 0x08 // Enable Timer +#define TIMER_AR 0x04 // Auto-Reload +#define TIMER_IRQEN 0x02 // IRQ Enable +#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR) + +typedef struct { + volatile uint32_t tcr0; + volatile uint32_t compare0; + volatile uint32_t counter0; + volatile uint32_t tcr1; + volatile uint32_t compare1; + volatile uint32_t counter1; +} timer_t; + +void msleep(uint32_t msec); +void nsleep(uint32_t nsec); + +void tic_init(); + + +/*************************************************************************** + * GPIO0 + */ +typedef struct { + volatile uint32_t ctrl; + volatile uint32_t dummy1; + volatile uint32_t dummy2; + volatile uint32_t dummy3; + volatile uint32_t in; + volatile uint32_t out; + volatile uint32_t oe; +} gpio_t; + +/*************************************************************************** + * UART0 + */ +#define UART_DR 0x01 // RX Data Ready +#define UART_ERR 0x02 // RX Error +#define UART_BUSY 0x10 // TX Busy + +typedef struct { + volatile uint32_t ucr; + volatile uint32_t rxtx; +} uart_t; + +void uart_init(); +void uart_putchar(char c); +void uart_putstr(char *str); +char uart_getchar(); + + +/*************************************************************************** + * Pointer to actual components + */ +extern timer_t *timer0; +extern uart_t *uart0; +extern gpio_t *gpio0; +extern uint32_t *sram0; + +#endif // SPIKEHW_H diff --git a/lm32/logic/sakc/rtl/lac/dp_ram.v b/lm32/logic/sakc/rtl/lac/dp_ram.v new file mode 100644 index 0000000..b21eae2 --- /dev/null +++ b/lm32/logic/sakc/rtl/lac/dp_ram.v @@ -0,0 +1,43 @@ +//------------------------------------------------------------------ +// Dual port memory (one read and one write port, same width) +//------------------------------------------------------------------ + +module dp_ram #( + parameter adr_width = 11, + parameter dat_width = 8 +) ( + // read port a + input clk_a, + input [adr_width-1:0] adr_a, + output reg [dat_width-1:0] dat_a, + // write port b + input clk_b, + input [adr_width-1:0] adr_b, + input [dat_width-1:0] dat_b, + input we_b +); + +parameter depth = (1 << adr_width); + +// actual ram cells +reg [dat_width-1:0] ram [0:depth-1]; + +//------------------------------------------------------------------ +// read port +//------------------------------------------------------------------ +always @(posedge clk_a) +begin + dat_a <= ram[adr_a]; +end + +//------------------------------------------------------------------ +// write port +//------------------------------------------------------------------ +always @(posedge clk_b) +begin + if (we_b) begin + ram[adr_b] <= dat_b; + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/lac/lac.v b/lm32/logic/sakc/rtl/lac/lac.v new file mode 100644 index 0000000..852f764 --- /dev/null +++ b/lm32/logic/sakc/rtl/lac/lac.v @@ -0,0 +1,262 @@ +//------------------------------------------------------------------ +// Logic Analyzer Component +//------------------------------------------------------------------ + +module lac #( + parameter uart_freq_hz = 100000000, + parameter uart_baud = 115200, + parameter adr_width = 11, + parameter width = 8 +) ( + input reset, + input uart_clk, + input uart_rxd, + output uart_cts, + output uart_txd, + input uart_rts, + // actual probe input + input probe_clk, + input [width-1:0] probe, + output reg [7:0] select +); + +parameter cmd_nop = 8'h20; +parameter cmd_arm = 8'h01; +parameter cmd_disarm = 8'h02; + +//------------------------------------------------------------------ +// uart instantiation +//------------------------------------------------------------------ +assign uart_cts = 1; + +reg tx_wr; +wire tx_busy; +reg [7:0] tx_data; + +wire [7:0] rx_data; +wire rx_avail; +reg rx_ack; + +uart #( + .freq_hz( uart_freq_hz ), + .baud( uart_baud ) +) uart0 ( + .reset( reset ), + .clk( uart_clk ), + // UART + .uart_txd( uart_txd ), + .uart_rxd( uart_rxd ), + // + .rx_data( rx_data ), + .rx_avail( rx_avail ), + .rx_error( rx_error ), + .rx_ack( rx_ack ), + .tx_data( tx_data ), + .tx_wr( tx_wr ), + .tx_busy( tx_busy ) +); + +//------------------------------------------------------------------ +// handshake signal between clock domains +//------------------------------------------------------------------ +reg [7:0] trig_mask; +reg [7:0] trig_cond; +reg [7:0] trig_pre; + +reg [adr_width-1:0] start_adr; // set in probe_clk domain + +reg armed; // set in uart_clk domain +reg triggered; // set in probe_clk domain + +//------------------------------------------------------------------ +// uart state machine +//------------------------------------------------------------------ +wire rx_req; +assign rx_req = rx_avail & ~rx_ack; + +reg triggered_synced; +wire [width-1:0] read_dat; +reg [adr_width-1:0] read_adr; +wire [adr_width-1:0] read_adr_next; + +assign read_adr_next = read_adr + 1; + +reg [2:0] state; + +parameter s_idle = 0; +parameter s_read_select= 1; +parameter s_read_mask = 2; +parameter s_read_comp = 3; +parameter s_read_pre = 4; +parameter s_triggered = 5; +parameter s_send_byte = 6; + +always @(posedge uart_clk) +begin + if (reset) begin + state <= s_idle; + select <= 0; + armed <= 0; + tx_wr <= 0; + end else begin + triggered_synced <= triggered; + + rx_ack <= 0; // default until set otherwise + tx_wr <= 0; + + case (state) + s_idle: begin + + if (rx_req) begin + case (rx_data) + cmd_arm: begin + rx_ack <= 1; + state <= s_read_select; + end + cmd_disarm: begin + rx_ack <= 1; + armed <= 0; + end + default: begin + rx_ack <= 1; + end + endcase + end + + if (~rx_req && triggered_synced) begin + state <= s_triggered; + end + end + s_read_select: begin + if (rx_req) begin + rx_ack <= 1; + select <= rx_data; + state <= s_read_mask; + end + end + s_read_mask: begin + if (rx_req) begin + rx_ack <= 1; + trig_mask <= rx_data; + state <= s_read_comp; + end + end + s_read_comp: begin + if (rx_req) begin + rx_ack <= 1; + trig_cond <= rx_data; + armed <= 1; + state <= s_read_pre; + end + end + s_read_pre: begin + if (rx_req) begin + rx_ack <= 1; + trig_pre <= rx_data; + armed <= 1; + state <= s_idle; + end + end + s_triggered: begin + armed <= 0; + read_adr <= start_adr; + tx_data <= adr_width; + tx_wr <= 1; + state <= s_send_byte; + end + s_send_byte: begin + tx_wr <= 0; + + if (~tx_busy & ~tx_wr) begin + if (read_adr_next == start_adr) + state <= s_idle; + + read_adr <= read_adr_next; + tx_data <= read_dat; + tx_wr <= 1; + end + end + default: + state <= s_idle; + endcase + end +end + +//------------------------------------------------------------------ +// Sampling clock domain +//------------------------------------------------------------------ + +// register probe input for better F_max +reg [width-1:0] probe_r; + +always @(posedge probe_clk) + probe_r <= probe; + +// Sampling machinery +reg armed_synced; +reg armed_synced2; +reg sampling; + +reg [adr_width-1:0] write_adr; +wire [adr_width-1:0] next_adr; +assign next_adr = write_adr + 1; + +wire cond_match; +assign cond_match = (probe_r & trig_mask) == (trig_cond & trig_mask) && armed_synced2; + +always @(posedge probe_clk) +begin + if (reset) begin + armed_synced <= 0; + armed_synced2 <= 0; + sampling <= 0; + triggered <= 0; + write_adr <= 0; + end else begin + armed_synced <= armed; + armed_synced2 <= armed_synced; + + if (armed_synced2 || sampling) begin + write_adr <= next_adr; + end + + if (~triggered && armed_synced2) begin + if (cond_match) begin + sampling <= 1; + triggered <= 1; + start_adr <= write_adr; + end + end + + if (sampling && next_adr == start_adr) begin + sampling <= 0; + end + + if (~sampling && ~armed_synced2 && triggered) + triggered <= 0; + end +end + + +//------------------------------------------------------------------ +// dual port memory +//------------------------------------------------------------------ +wire write_en; +assign write_en = sampling || cond_match; + +dp_ram #( + .adr_width( adr_width ), + .dat_width( width ) +) ram0 ( + // read port a + .clk_a( uart_clk ), + .adr_a( read_adr ), + .dat_a( read_dat ), + // write port b + .clk_b( probe_clk ), + .adr_b( write_adr ), + .dat_b( probe_r ), + .we_b( write_en ) +); + +endmodule diff --git a/lm32/logic/sakc/rtl/lac/uart.v b/lm32/logic/sakc/rtl/lac/uart.v new file mode 100644 index 0000000..b7a033e --- /dev/null +++ b/lm32/logic/sakc/rtl/lac/uart.v @@ -0,0 +1,155 @@ +//----------------------------------------------------- +// Design Name : uart +// File Name : uart.v +//----------------------------------------------------- +module uart #( + parameter freq_hz = 100000000, + parameter baud = 115200 +) ( + input reset, + input clk, + // UART lines + input uart_rxd, + output reg uart_txd, + // + output reg [7:0] rx_data, + output reg rx_avail, + output reg rx_error, + input rx_ack, + input [7:0] tx_data, + input tx_wr, + output reg tx_busy +); + +parameter divisor = freq_hz/baud/16; + +//----------------------------------------------------------------- +// enable16 generator +//----------------------------------------------------------------- +reg [15:0] enable16_counter; + +wire enable16; +assign enable16 = (enable16_counter == 0); + +always @(posedge clk) +begin + if (reset) begin + enable16_counter <= divisor-1; + end else begin + enable16_counter <= enable16_counter - 1; + if (enable16_counter == 0) begin + enable16_counter <= divisor-1; + end + end +end + +//----------------------------------------------------------------- +// syncronize uart_rxd +//----------------------------------------------------------------- +reg uart_rxd1; +reg uart_rxd2; + +always @(posedge clk) +begin + uart_rxd1 <= uart_rxd; + uart_rxd2 <= uart_rxd1; +end + +//----------------------------------------------------------------- +// UART RX Logic +//----------------------------------------------------------------- +reg rx_busy; +reg [3:0] rx_count16; +reg [3:0] rx_bitcount; +reg [7:0] rxd_reg; + +always @ (posedge clk) +begin + if (reset) begin + rx_busy <= 0; + rx_count16 <= 0; + rx_bitcount <= 0; + rx_avail <= 0; + rx_error <= 0; + end else begin + if (rx_ack) begin + rx_avail <= 0; + rx_error <= 0; + end + + if (enable16) begin + if (!rx_busy) begin // look for start bit + if (!uart_rxd2) begin // start bit found + rx_busy <= 1; + rx_count16 <= 7; + rx_bitcount <= 0; + end + end else begin + rx_count16 <= rx_count16 + 1; + + if (rx_count16 == 0) begin // sample + rx_bitcount <= rx_bitcount + 1; + + if (rx_bitcount == 0) begin // verify startbit + if (uart_rxd2) begin + rx_busy <= 0; + end + end else if (rx_bitcount == 9) begin // look for stop bit + rx_busy <= 0; + if (uart_rxd2) begin // stop bit ok + rx_data <= rxd_reg; + rx_avail <= 1; + rx_error <= 0; + end else begin // bas stop bit + rx_error <= 1; + end + end else begin + rxd_reg <= { uart_rxd2, rxd_reg[7:1] }; + end + end + end + end + end +end + +//----------------------------------------------------------------- +// UART TX Logic +//----------------------------------------------------------------- +reg [3:0] tx_bitcount; +reg [3:0] tx_count16; +reg [7:0] txd_reg; + +always @ (posedge clk) +begin + if (reset) begin + tx_busy <= 0; + uart_txd <= 1; + end else begin + if (tx_wr && !tx_busy) begin + txd_reg <= tx_data; + tx_bitcount <= 0; + tx_count16 <= 1; + tx_busy <= 1; + uart_txd <= 0; + end else if (enable16 && tx_busy) begin + tx_count16 <= tx_count16 + 1; + + if (tx_count16 == 0) begin + tx_bitcount <= tx_bitcount + 1; + + if (tx_bitcount == 8) begin + uart_txd <= 'b1; + end else if (tx_bitcount == 9) begin + uart_txd <= 'b1; + tx_busy <= 0; + end else begin + uart_txd <= txd_reg[0]; + txd_reg <= { 1'b0, txd_reg[7:1] }; + end + end + end + end +end + + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/JTAGB.v b/lm32/logic/sakc/rtl/lm32/JTAGB.v new file mode 100644 index 0000000..1abfb6b --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/JTAGB.v @@ -0,0 +1,15 @@ +module JTAGB ( + output JTCK, + output JRTI1, + output JRTI2, + output JTDI, + output JSHIFT, + output JUPDATE, + output JRSTN, + output JCE1, + output JCE2, + input JTDO1, + input JTDO2 + ) /*synthesis syn_black_box */; + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/er1.v b/lm32/logic/sakc/rtl/lm32/er1.v new file mode 100644 index 0000000..f346198 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/er1.v @@ -0,0 +1,218 @@ +/*-- --------------------------------------------------------------------------- +-- +-- Name : ER1.v +-- +-- Description: +-- +-- This module is where the ER1 register implemented. ER1 and ER2 registers +-- can be registers implemented in Lattice FPGAs using normal FPGA's +-- programmable logic resources. Once they are implemented, they can be +-- accessed as if they are JTAG data registers through the FPGA JTAG port. +-- In order to accessing these registers, JTAG instructions ER1(0x32) or +-- ER2(0x38) needs to be written to the JTAG IR register for enabling the +-- ER1/ER2 accessing logic. The ER1 or ER2 accessing logic can only be +-- enabled one at a time. Once they are enabled, they will be disabled if +-- another JTAG instruction is written into the JTAG instruction register. +-- The registers allow dynamically accessing the FPGA internal information +-- even when the device is running. Therefore, they are very useful for some +-- of the IP cores. In order to let ER1/ER2 registers shared by multiple IP +-- cores or other designs, there is a ER1/ER2 structure patterned by Lattice. +-- The ER1/ER2 structure allows only one ER1 register but more than one ER2 +-- registers in an FPGA device. Please refer to the related document for +-- this patterned ER1/ER2 structure. +-- +-- $Log: $ +-- +-- $Header: $ +-- +-- Copyright (C) 2004 Lattice Semiconductor Corp. All rights reserved. +-- +-- ---------------------------------------------------------------------------*/ + +module ER1 (input JTCK, + input JTDI, + output JTDO1, + output reg JTDO2, + input JSHIFT, + input JUPDATE, + input JRSTN, + input JCE1, + input [14:0] ER2_TDO, + output reg [14:0] IP_ENABLE, + input ISPTRACY_ER2_TDO, + output ISPTRACY_ENABLE, + output CONTROL_DATAN)/* synthesis syn_hier = hard */; + + + wire controlDataNBit; + wire ispTracyEnableBit; + wire [3:0] encodedIpEnableBits; + wire [9:0] er1TdiBit; + wire captureDrER1; + + + assign JTDO1 = er1TdiBit[0]; + + TYPEB BIT0 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[1]), + .TDO(er1TdiBit[0]), + .DATA_IN(1'b0), + .CAPTURE_DR(captureDrER1)); + + TYPEB BIT1 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[2]), + .TDO(er1TdiBit[1]), + .DATA_IN(1'b0), + .CAPTURE_DR(captureDrER1)); + + TYPEB BIT2 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[3]), + .TDO(er1TdiBit[2]), + .DATA_IN(1'b1), + .CAPTURE_DR(captureDrER1)); + + TYPEA BIT3 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[4]), + .TDO(er1TdiBit[3]), + .DATA_OUT(controlDataNBit), + .DATA_IN(controlDataNBit), + .CAPTURE_DR(captureDrER1), + .UPDATE_DR(JUPDATE)); + + assign CONTROL_DATAN = controlDataNBit; + + TYPEA BIT4 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[5]), + .TDO(er1TdiBit[4]), + .DATA_OUT(ispTracyEnableBit), + .DATA_IN(ispTracyEnableBit), + .CAPTURE_DR(captureDrER1), + .UPDATE_DR(JUPDATE) + ); + + assign ISPTRACY_ENABLE = ispTracyEnableBit; + + TYPEA BIT5 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[6]), + .TDO(er1TdiBit[5]), + .DATA_OUT(encodedIpEnableBits[0]), + .DATA_IN(encodedIpEnableBits[0]), + .CAPTURE_DR(captureDrER1), + .UPDATE_DR(JUPDATE)); + + TYPEA BIT6 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[7]), + .TDO(er1TdiBit[6]), + .DATA_OUT(encodedIpEnableBits[1]), + .DATA_IN(encodedIpEnableBits[1]), + .CAPTURE_DR(captureDrER1), + .UPDATE_DR(JUPDATE)); + + TYPEA BIT7 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[8]), + .TDO(er1TdiBit[7]), + .DATA_OUT(encodedIpEnableBits[2]), + .DATA_IN(encodedIpEnableBits[2]), + .CAPTURE_DR(captureDrER1), + .UPDATE_DR(JUPDATE)); + + TYPEA BIT8 (.CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(JCE1), + .TDI(er1TdiBit[9]), + .TDO(er1TdiBit[8]), + .DATA_OUT(encodedIpEnableBits[3]), + .DATA_IN(encodedIpEnableBits[3]), + .CAPTURE_DR(captureDrER1), + .UPDATE_DR(JUPDATE) + ); + + assign er1TdiBit[9] = JTDI; + assign captureDrER1 = !JSHIFT & JCE1; + + always @ (encodedIpEnableBits,ISPTRACY_ER2_TDO, ER2_TDO) + begin + case (encodedIpEnableBits) + 4'h0: begin + IP_ENABLE <= 15'b000000000000000; + JTDO2 <= ISPTRACY_ER2_TDO; + end + 4'h1: begin + IP_ENABLE <= 15'b000000000000001; + JTDO2 <= ER2_TDO[0]; + end + 4'h2: begin + IP_ENABLE <= 15'b000000000000010; + JTDO2 <= ER2_TDO[1]; + end + 4'h3: begin + IP_ENABLE <= 15'b000000000000100; + JTDO2 <= ER2_TDO[2]; + end + 4'h4: begin + IP_ENABLE <= 15'b000000000001000; + JTDO2 <= ER2_TDO[3]; + end + 4'h5: begin + IP_ENABLE <= 15'b000000000010000; + JTDO2 <= ER2_TDO[4]; + end + 4'h6: begin + IP_ENABLE <= 15'b000000000100000; + JTDO2 <= ER2_TDO[5]; + end + 4'h7: begin + IP_ENABLE <= 15'b000000001000000; + JTDO2 <= ER2_TDO[6]; + end + 4'h8: begin + IP_ENABLE <= 15'b000000010000000; + JTDO2 <= ER2_TDO[7]; + end + 4'h9: begin + IP_ENABLE <= 15'b000000100000000; + JTDO2 <= ER2_TDO[8]; + end + 4'hA: begin + IP_ENABLE <= 15'b000001000000000; + JTDO2 <= ER2_TDO[9]; + end + 4'hB: begin + IP_ENABLE <= 15'b000010000000000; + JTDO2 <= ER2_TDO[10]; + end + 4'hC: begin + IP_ENABLE <= 15'b000100000000000; + JTDO2 <= ER2_TDO[11]; + end + 4'hD: begin + IP_ENABLE <= 15'b001000000000000; + JTDO2 <= ER2_TDO[12]; + end + 4'hE: begin + IP_ENABLE <= 15'b010000000000000; + JTDO2 <= ER2_TDO[13]; + end + 4'hF: begin + IP_ENABLE <= 15'b100000000000000; + JTDO2 <= ER2_TDO[14]; + end + endcase + end +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/jtag_cores.v b/lm32/logic/sakc/rtl/lm32/jtag_cores.v new file mode 100644 index 0000000..99d6c6e --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/jtag_cores.v @@ -0,0 +1,213 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : jtag_cores.v +// Title : Instantiates all IP cores on JTAG chain. +// Dependencies : system_conf.v +// Version : 6.0.13 +// ============================================================================= + +`include "system_conf.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module jtag_cores ( + // ----- Inputs ------- +`ifdef INCLUDE_LM32 + reg_d, + reg_addr_d, +`endif +`ifdef INCLUDE_SPI + spi_q, +`endif + // ----- Outputs ------- +`ifdef INCLUDE_LM32 + reg_update, + reg_q, + reg_addr_q, +`endif +`ifdef INCLUDE_SPI + spi_c, + spi_d, + spi_sn, +`endif + jtck, + jrstn + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +`ifdef INCLUDE_LM32 +input [7:0] reg_d; +input [2:0] reg_addr_d; +`endif + +`ifdef INCLUDE_SPI +input spi_q; +`endif + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +`ifdef INCLUDE_LM32 +output reg_update; +wire reg_update; +output [7:0] reg_q; +wire [7:0] reg_q; +output [2:0] reg_addr_q; +wire [2:0] reg_addr_q; +`endif + +`ifdef INCLUDE_SPI +output spi_c; +wire spi_c; +output spi_d; +wire spi_d; +output spi_sn; +wire spi_sn; +`endif + +output jtck; +wire jtck; /* synthesis ER1_MARK="jtck" */ /* synthesis syn_keep=1 */ +output jrstn; +wire jrstn; /* synthesis ER1_MARK="jrstn" */ /* synthesis syn_keep=1 */ + + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire rtiER1; +wire rtiER2; +wire tdi;/* synthesis ER1_MARK="jtdi" */ /* synthesis syn_keep=1 */ +wire tdoEr1;/* synthesis ER1_MARK="jtdo1" */ /* synthesis syn_keep=1 */ +wire tdoEr2; +wire jtdo2_mux;/* synthesis ER1_MARK="jtdo2" */ /* synthesis syn_keep=1 */ +wire spi_tdo2; +wire shiftDr;/* synthesis ER1_MARK="jshift" */ /* synthesis syn_keep=1 */ +wire updateDr;/* synthesis ER1_MARK="jupdate" */ /* synthesis syn_keep=1 */ +wire enableEr1;/* synthesis ER1_MARK="jce1" */ /* synthesis syn_keep=1 */ +wire enableEr2;/* synthesis ER1_MARK="jce2" */ /* synthesis syn_keep=1 */ +wire [14:0] ipEnable;/* synthesis ER1_MARK="ip_enable" */ /* synthesis syn_keep=1 */ +wire controlDataN;/* synthesis ER1_MARK="control_datan" */ /* synthesis syn_keep=1 */ +wire lm32_isptracy_enable;/* synthesis ER1_MARK="isptracy_enable" */ /* synthesis syn_keep=1 */ + + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + parameter lat_family = `LATTICE_FAMILY; + +generate + if (lat_family == "EC" || lat_family == "ECP" || lat_family == "XP") begin + JTAGB jtagb (.JTCK (jtck), + .JRTI1 (rtiER1), + .JRTI2 (rtiER2), + .JTDI (tdi), + .JSHIFT (shiftDr), + .JUPDATE (updateDr), + .JRSTN (jrstn), + .JCE1 (enableEr1), + .JCE2 (enableEr2), + .JTDO1 (tdoEr1), + .JTDO2 (jtdo2_mux)) /* synthesis ER1="ENABLED" */ /* synthesis ER2="ENABLED" */ /* synthesis JTAG_FLASH_PRGRM="DISABLED" */; + end else if (lat_family == "ECP2" || lat_family == "ECP2M") begin + JTAGC jtagc (.JTCK (jtck), + .JRTI1 (rtiER1), + .JRTI2 (rtiER2), + .JTDI (tdi), + .JSHIFT (shiftDr), + .JUPDATE (updateDr), + .JRSTN (jrstn), + .IJTAGEN (1'b1), + .JCE1 (enableEr1), + .JCE2 (enableEr2), + .JTDO1 (tdoEr1), + .JTDO2 (jtdo2_mux)) /* synthesis ER1="ENABLED" */ /* synthesis ER2="ENABLED" */ /* synthesis JTAG_FLASH_PRGRM="DISABLED" */; + end else if (lat_family == "SC" || lat_family == "SCM") begin // if (lat_family == "ECP2" || lat_family == "ECP2M") + JTAGA jtaga(.JTCK (jtck), + .JRTI1 (rtiER1), + .JRTI2 (rtiER2), + .JTDI (tdi), + .JSHIFT (shiftDr), + .JUPDATE (updateDr), + .JRSTN (jrstn), + .JCE1 (enableEr1), + .JCE2 (enableEr2), + .JTDO1 (tdoEr1), + .JTDO2 (jtdo2_mux)) /* synthesis ER1="ENABLED" */ /* synthesis ER2="ENABLED" */ /* synthesis JTAG_FLASH_PRGRM="DISABLED" */; + end +endgenerate + +ER1 er1 ( + .JTCK (jtck), + .JTDI (tdi), + .JTDO1 (tdoEr1), + .JTDO2 (jtdo2_mux), + .JSHIFT (shiftDr), + .JUPDATE (updateDr), + .JRSTN (jrstn), + .JCE1 (enableEr1), + .ER2_TDO ({13'b0,tdoEr2,spi_tdo2}), + .IP_ENABLE (ipEnable), + .ISPTRACY_ENABLE(lm32_isptracy_enable), + .ISPTRACY_ER2_TDO(lm32_isptracy_enable), + .CONTROL_DATAN (controlDataN)); + +`ifdef INCLUDE_LM32 +jtag_lm32 jtag_lm32 ( + .JTCK (jtck), + .JTDI (tdi), + .JTDO2 (tdoEr2), + .JSHIFT (shiftDr), + .JUPDATE (updateDr), + .JRSTN (jrstn), + .JCE2 (enableEr2), + .JTAGREG_ENABLE (ipEnable[1]), + .CONTROL_DATAN (controlDataN), + .REG_UPDATE (reg_update), + .REG_D (reg_d), + .REG_ADDR_D (reg_addr_d), + .REG_Q (reg_q), + .REG_ADDR_Q (reg_addr_q) + ); +`endif + +`ifdef INCLUDE_SPI +SPIPROG spiprog_inst ( + .JTCK (tck), + .JTDI (tdi), + .JTDO2 (spi_tdo2), + .JSHIFT (shiftDr), + .JUPDATE (updateDr), + .JRSTN (resetN), + .JCE2 (enableEr2), + .SPIPROG_ENABLE (ipEnable[0]), + .CONTROL_DATAN (controlDataN), + .SPI_C (spi_c), + .SPI_D (spi_d), + .SPI_SN (spi_sn), + .SPI_Q (spi_q) + ); +`endif + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/jtag_lm32.v b/lm32/logic/sakc/rtl/lm32/jtag_lm32.v new file mode 100644 index 0000000..259a0c1 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/jtag_lm32.v @@ -0,0 +1,195 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : jtag_lm32.v +// Title : JTAG data register for LM32 CPU debug interface +// Version : 6.0.13 +// ============================================================================= + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module jtag_lm32 ( + input JTCK, + input JTDI, + output JTDO2, + input JSHIFT, + input JUPDATE, + input JRSTN, + input JCE2, + input JTAGREG_ENABLE, + input CONTROL_DATAN, + output REG_UPDATE, + input [7:0] REG_D, + input [2:0] REG_ADDR_D, + output [7:0] REG_Q, + output [2:0] REG_ADDR_Q + ); + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire [9:0] tdibus; + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +TYPEA DATA_BIT0 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(JTDI), + .TDO(tdibus[0]), + .DATA_OUT(REG_Q[0]), + .DATA_IN(REG_D[0]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT1 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[0]), + .TDO(tdibus[1]), + .DATA_OUT(REG_Q[1]), + .DATA_IN(REG_D[1]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT2 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[1]), + .TDO(tdibus[2]), + .DATA_OUT(REG_Q[2]), + .DATA_IN(REG_D[2]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT3 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[2]), + .TDO(tdibus[3]), + .DATA_OUT(REG_Q[3]), + .DATA_IN(REG_D[3]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT4 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[3]), + .TDO(tdibus[4]), + .DATA_OUT(REG_Q[4]), + .DATA_IN(REG_D[4]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT5 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[4]), + .TDO(tdibus[5]), + .DATA_OUT(REG_Q[5]), + .DATA_IN(REG_D[5]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT6 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[5]), + .TDO(tdibus[6]), + .DATA_OUT(REG_Q[6]), + .DATA_IN(REG_D[6]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA DATA_BIT7 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[6]), + .TDO(tdibus[7]), + .DATA_OUT(REG_Q[7]), + .DATA_IN(REG_D[7]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA ADDR_BIT0 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[7]), + .TDO(tdibus[8]), + .DATA_OUT(REG_ADDR_Q[0]), + .DATA_IN(REG_ADDR_D[0]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA ADDR_BIT1 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[8]), + .TDO(tdibus[9]), + .DATA_OUT(REG_ADDR_Q[1]), + .DATA_IN(REG_ADDR_D[1]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +TYPEA ADDR_BIT2 ( + .CLK(JTCK), + .RESET_N(JRSTN), + .CLKEN(clk_enable), + .TDI(tdibus[9]), + .TDO(JTDO2), + .DATA_OUT(REG_ADDR_Q[2]), + .DATA_IN(REG_ADDR_D[2]), + .CAPTURE_DR(captureDr), + .UPDATE_DR(JUPDATE) + ); + +///////////////////////////////////////////////////// +// Combinational logic +///////////////////////////////////////////////////// + +assign clk_enable = JTAGREG_ENABLE & JCE2; +assign captureDr = !JSHIFT & JCE2; +// JCE2 is only active during shift +assign REG_UPDATE = JTAGREG_ENABLE & JUPDATE; + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_adder.v b/lm32/logic/sakc/rtl/lm32/lm32_adder.v new file mode 100644 index 0000000..63b230b --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_adder.v @@ -0,0 +1,110 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// ============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_adder.v +// Title : Integer adder / subtractor with comparison flag generation +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_adder ( + // ----- Inputs ------- + adder_op_x, + adder_op_x_n, + operand_0_x, + operand_1_x, + // ----- Outputs ------- + adder_result_x, + adder_carry_n_x, + adder_overflow_x + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input adder_op_x; // Operating to perform, 0 for addition, 1 for subtraction +input adder_op_x_n; // Inverted version of adder_op_x +input [`LM32_WORD_RNG] operand_0_x; // Operand to add, or subtract from +input [`LM32_WORD_RNG] operand_1_x; // Opearnd to add, or subtract by + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [`LM32_WORD_RNG] adder_result_x; // Result of addition or subtraction +wire [`LM32_WORD_RNG] adder_result_x; +output adder_carry_n_x; // Inverted carry +wire adder_carry_n_x; +output adder_overflow_x; // Indicates if overflow occured, only valid for subtractions +reg adder_overflow_x; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire a_sign; // Sign (i.e. positive or negative) of operand 0 +wire b_sign; // Sign of operand 1 +wire result_sign; // Sign of result + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +lm32_addsub addsub ( + // ----- Inputs ----- + .DataA (operand_0_x), + .DataB (operand_1_x), + .Cin (adder_op_x), + .Add_Sub (adder_op_x_n), + // ----- Ouputs ----- + .Result (adder_result_x), + .Cout (adder_carry_n_x) + ); + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +// Extract signs of operands and result + +assign a_sign = operand_0_x[`LM32_WORD_WIDTH-1]; +assign b_sign = operand_1_x[`LM32_WORD_WIDTH-1]; +assign result_sign = adder_result_x[`LM32_WORD_WIDTH-1]; + +// Determine whether an overflow occured when performing a subtraction + +always @* +begin + // +ve - -ve = -ve -> overflow + // -ve - +ve = +ve -> overflow + if ( (!a_sign & b_sign & result_sign) + || (a_sign & !b_sign & !result_sign) + ) + adder_overflow_x = `TRUE; + else + adder_overflow_x = `FALSE; +end + +endmodule + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_addsub.v b/lm32/logic/sakc/rtl/lm32/lm32_addsub.v new file mode 100644 index 0000000..bcfe7e1 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_addsub.v @@ -0,0 +1,69 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_addsub.v +// Title : PMI adder/subtractor. +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_addsub ( + // ----- Inputs ------- + DataA, + DataB, + Cin, + Add_Sub, + // ----- Outputs ------- + Result, + Cout + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input [31:0] DataA; +input [31:0] DataB; +input Cin; +input Add_Sub; + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [31:0] Result; +wire [31:0] Result; +output Cout; +wire Cout; + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + + wire [32:0] tmp_addResult = DataA + DataB + Cin; + wire [32:0] tmp_subResult = DataA - DataB - !Cin; + + assign Result = (Add_Sub == 1) ? tmp_addResult[31:0] : tmp_subResult[31:0]; + assign Cout = (Add_Sub == 1) ? tmp_addResult[32] : !tmp_subResult[32]; + + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_cpu.v b/lm32/logic/sakc/rtl/lm32/lm32_cpu.v new file mode 100644 index 0000000..d7de0b9 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_cpu.v @@ -0,0 +1,2304 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_cpu.v +// Title : Top-level of CPU. +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_cpu ( + // ----- Inputs ------- + clk_i, +`ifdef CFG_EBR_NEGEDGE_REGISTER_FILE + clk_n_i, +`endif + rst_i, + // From external devices +`ifdef CFG_INTERRUPTS_ENABLED + interrupt_n, +`endif + // From user logic +`ifdef CFG_USER_ENABLED + user_result, + user_complete, +`endif +`ifdef CFG_JTAG_ENABLED + // From JTAG + jtag_clk, + jtag_update, + jtag_reg_q, + jtag_reg_addr_q, +`endif +`ifdef CFG_IWB_ENABLED + // Instruction Wishbone master + I_DAT_I, + I_ACK_I, + I_ERR_I, + I_RTY_I, +`endif + // Data Wishbone master + D_DAT_I, + D_ACK_I, + D_ERR_I, + D_RTY_I, + // ----- Outputs ------- +`ifdef CFG_TRACE_ENABLED + trace_pc, + trace_pc_valid, + trace_exception, + trace_eid, + trace_eret, +`ifdef CFG_DEBUG_ENABLED + trace_bret, +`endif +`endif +`ifdef CFG_JTAG_ENABLED + jtag_reg_d, + jtag_reg_addr_d, +`endif +`ifdef CFG_USER_ENABLED + user_valid, + user_opcode, + user_operand_0, + user_operand_1, +`endif +`ifdef CFG_IWB_ENABLED + // Instruction Wishbone master + I_DAT_O, + I_ADR_O, + I_CYC_O, + I_SEL_O, + I_STB_O, + I_WE_O, + I_CTI_O, + I_LOCK_O, + I_BTE_O, +`endif + // Data Wishbone master + D_DAT_O, + D_ADR_O, + D_CYC_O, + D_SEL_O, + D_STB_O, + D_WE_O, + D_CTI_O, + D_LOCK_O, + D_BTE_O + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter eba_reset = `CFG_EBA_RESET; // Reset value for EBA CSR +`ifdef CFG_DEBUG_ENABLED +parameter deba_reset = `CFG_DEBA_RESET; // Reset value for DEBA CSR +`endif + +`ifdef CFG_ICACHE_ENABLED +parameter icache_associativity = `CFG_ICACHE_ASSOCIATIVITY; // Associativity of the cache (Number of ways) +parameter icache_sets = `CFG_ICACHE_SETS; // Number of sets +parameter icache_bytes_per_line = `CFG_ICACHE_BYTES_PER_LINE; // Number of bytes per cache line +parameter icache_base_address = `CFG_ICACHE_BASE_ADDRESS; // Base address of cachable memory +parameter icache_limit = `CFG_ICACHE_LIMIT; // Limit (highest address) of cachable memory +`else +parameter icache_associativity = 1; +parameter icache_sets = 512; +parameter icache_bytes_per_line = 16; +parameter icache_base_address = 0; +parameter icache_limit = 0; +`endif + +`ifdef CFG_DCACHE_ENABLED +parameter dcache_associativity = `CFG_DCACHE_ASSOCIATIVITY; // Associativity of the cache (Number of ways) +parameter dcache_sets = `CFG_DCACHE_SETS; // Number of sets +parameter dcache_bytes_per_line = `CFG_DCACHE_BYTES_PER_LINE; // Number of bytes per cache line +parameter dcache_base_address = `CFG_DCACHE_BASE_ADDRESS; // Base address of cachable memory +parameter dcache_limit = `CFG_DCACHE_LIMIT; // Limit (highest address) of cachable memory +`else +parameter dcache_associativity = 1; +parameter dcache_sets = 512; +parameter dcache_bytes_per_line = 16; +parameter dcache_base_address = 0; +parameter dcache_limit = 0; +`endif + +`ifdef CFG_DEBUG_ENABLED +parameter watchpoints = `CFG_WATCHPOINTS; // Number of h/w watchpoint CSRs +`else +parameter watchpoints = 4'h0; +`endif +`ifdef CFG_ROM_DEBUG_ENABLED +parameter breakpoints = `CFG_BREAKPOINTS; // Number of h/w breakpoint CSRs +`else +parameter breakpoints = 4'h0; +`endif + +`ifdef CFG_INTERRUPTS_ENABLED +parameter interrupts = `CFG_INTERRUPTS; // Number of interrupts +`else +parameter interrupts = 0; +`endif + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +`ifdef CFG_EBR_NEGEDGE_REGISTER_FILE +input clk_n_i; // Inverted clock +`endif +input rst_i; // Reset + +`ifdef CFG_INTERRUPTS_ENABLED +input [`LM32_INTERRUPT_RNG] interrupt_n; // Interrupt pins, active-low +`endif + +`ifdef CFG_USER_ENABLED +input [`LM32_WORD_RNG] user_result; // User-defined instruction result +input user_complete; // User-defined instruction execution is complete +`endif + +`ifdef CFG_JTAG_ENABLED +input jtag_clk; // JTAG clock +input jtag_update; // JTAG state machine is in data register update state +input [`LM32_BYTE_RNG] jtag_reg_q; +input [2:0] jtag_reg_addr_q; +`endif + +`ifdef CFG_IWB_ENABLED +input [`LM32_WORD_RNG] I_DAT_I; // Instruction Wishbone interface read data +input I_ACK_I; // Instruction Wishbone interface acknowledgement +input I_ERR_I; // Instruction Wishbone interface error +input I_RTY_I; // Instruction Wishbone interface retry +`endif + +input [`LM32_WORD_RNG] D_DAT_I; // Data Wishbone interface read data +input D_ACK_I; // Data Wishbone interface acknowledgement +input D_ERR_I; // Data Wishbone interface error +input D_RTY_I; // Data Wishbone interface retry + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +`ifdef CFG_TRACE_ENABLED +output [`LM32_PC_RNG] trace_pc; // PC to trace +reg [`LM32_PC_RNG] trace_pc; +output trace_pc_valid; // Indicates that a new trace PC is valid +reg trace_pc_valid; +output trace_exception; // Indicates an exception has occured +reg trace_exception; +output [`LM32_EID_RNG] trace_eid; // Indicates what type of exception has occured +reg [`LM32_EID_RNG] trace_eid; +output trace_eret; // Indicates an eret instruction has been executed +reg trace_eret; +`ifdef CFG_DEBUG_ENABLED +output trace_bret; // Indicates a bret instruction has been executed +reg trace_bret; +`endif +`endif + +`ifdef CFG_JTAG_ENABLED +output [`LM32_BYTE_RNG] jtag_reg_d; +wire [`LM32_BYTE_RNG] jtag_reg_d; +output [2:0] jtag_reg_addr_d; +wire [2:0] jtag_reg_addr_d; +`endif + +`ifdef CFG_USER_ENABLED +output user_valid; // Indicates if user_opcode is valid +wire user_valid; +output [`LM32_USER_OPCODE_RNG] user_opcode; // User-defined instruction opcode +reg [`LM32_USER_OPCODE_RNG] user_opcode; +output [`LM32_WORD_RNG] user_operand_0; // First operand for user-defined instruction +wire [`LM32_WORD_RNG] user_operand_0; +output [`LM32_WORD_RNG] user_operand_1; // Second operand for user-defined instruction +wire [`LM32_WORD_RNG] user_operand_1; +`endif + +`ifdef CFG_IWB_ENABLED +output [`LM32_WORD_RNG] I_DAT_O; // Instruction Wishbone interface write data +wire [`LM32_WORD_RNG] I_DAT_O; +output [`LM32_WORD_RNG] I_ADR_O; // Instruction Wishbone interface address +wire [`LM32_WORD_RNG] I_ADR_O; +output I_CYC_O; // Instruction Wishbone interface cycle +wire I_CYC_O; +output [`LM32_BYTE_SELECT_RNG] I_SEL_O; // Instruction Wishbone interface byte select +wire [`LM32_BYTE_SELECT_RNG] I_SEL_O; +output I_STB_O; // Instruction Wishbone interface strobe +wire I_STB_O; +output I_WE_O; // Instruction Wishbone interface write enable +wire I_WE_O; +output [`LM32_CTYPE_RNG] I_CTI_O; // Instruction Wishbone interface cycle type +wire [`LM32_CTYPE_RNG] I_CTI_O; +output I_LOCK_O; // Instruction Wishbone interface lock bus +wire I_LOCK_O; +output [`LM32_BTYPE_RNG] I_BTE_O; // Instruction Wishbone interface burst type +wire [`LM32_BTYPE_RNG] I_BTE_O; +`endif + +output [`LM32_WORD_RNG] D_DAT_O; // Data Wishbone interface write data +wire [`LM32_WORD_RNG] D_DAT_O; +output [`LM32_WORD_RNG] D_ADR_O; // Data Wishbone interface address +wire [`LM32_WORD_RNG] D_ADR_O; +output D_CYC_O; // Data Wishbone interface cycle +wire D_CYC_O; +output [`LM32_BYTE_SELECT_RNG] D_SEL_O; // Data Wishbone interface byte select +wire [`LM32_BYTE_SELECT_RNG] D_SEL_O; +output D_STB_O; // Data Wishbone interface strobe +wire D_STB_O; +output D_WE_O; // Data Wishbone interface write enable +wire D_WE_O; +output [`LM32_CTYPE_RNG] D_CTI_O; // Data Wishbone interface cycle type +wire [`LM32_CTYPE_RNG] D_CTI_O; +output D_LOCK_O; // Date Wishbone interface lock bus +wire D_LOCK_O; +output [`LM32_BTYPE_RNG] D_BTE_O; // Data Wishbone interface burst type +wire [`LM32_BTYPE_RNG] D_BTE_O; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +// Pipeline registers + +`ifdef LM32_CACHE_ENABLED +reg valid_a; // Instruction in A stage is valid +`endif +reg valid_f; // Instruction in F stage is valid +reg valid_d; // Instruction in D stage is valid +reg valid_x; // Instruction in X stage is valid +reg valid_m; // Instruction in M stage is valid +reg valid_w; // Instruction in W stage is valid + +wire [`LM32_WORD_RNG] immediate_d; // Immediate operand +wire load_d; // Indicates a load instruction +reg load_x; +reg load_m; +wire store_d; // Indicates a store instruction +reg store_x; +reg store_m; +wire [`LM32_SIZE_RNG] size_d; // Size of load/store (byte, hword, word) +reg [`LM32_SIZE_RNG] size_x; +wire branch_d; // Indicates a branch instruction +reg branch_x; +reg branch_m; +wire branch_reg_d; // Branch to register or immediate +wire [`LM32_PC_RNG] branch_offset_d; // Branch offset for immediate branches +reg [`LM32_PC_RNG] branch_target_x; // Address to branch to +reg [`LM32_PC_RNG] branch_target_m; +wire [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0_d; // Which result should be selected in D stage for operand 0 +wire [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1_d; // Which result should be selected in D stage for operand 1 + +wire x_result_sel_csr_d; // Select X stage result from CSRs +reg x_result_sel_csr_x; +`ifdef LM32_MC_ARITHMETIC_ENABLED +wire x_result_sel_mc_arith_d; // Select X stage result from multi-cycle arithmetic unit +reg x_result_sel_mc_arith_x; +`endif +`ifdef LM32_NO_BARREL_SHIFT +wire x_result_sel_shift_d; // Select X stage result from shifter +reg x_result_sel_shift_x; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED +wire x_result_sel_sext_d; // Select X stage result from sign-extend logic +reg x_result_sel_sext_x; +`endif +wire x_result_sel_logic_d; // Select X stage result from logic op unit +reg x_result_sel_logic_x; +`ifdef CFG_USER_ENABLED +wire x_result_sel_user_d; // Select X stage result from user-defined logic +reg x_result_sel_user_x; +`endif +wire x_result_sel_add_d; // Select X stage result from adder +reg x_result_sel_add_x; +wire m_result_sel_compare_d; // Select M stage result from comparison logic +reg m_result_sel_compare_x; +reg m_result_sel_compare_m; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +wire m_result_sel_shift_d; // Select M stage result from shifter +reg m_result_sel_shift_x; +reg m_result_sel_shift_m; +`endif +wire w_result_sel_load_d; // Select W stage result from load/store unit +reg w_result_sel_load_x; +reg w_result_sel_load_m; +reg w_result_sel_load_w; +`ifdef CFG_PL_MULTIPLY_ENABLED +wire w_result_sel_mul_d; // Select W stage result from multiplier +reg w_result_sel_mul_x; +reg w_result_sel_mul_m; +reg w_result_sel_mul_w; +`endif +wire x_bypass_enable_d; // Whether result is bypassable in X stage +reg x_bypass_enable_x; +wire m_bypass_enable_d; // Whether result is bypassable in M stage +reg m_bypass_enable_x; +reg m_bypass_enable_m; +wire sign_extend_d; // Whether to sign-extend or zero-extend +reg sign_extend_x; +wire write_enable_d; // Register file write enable +reg write_enable_x; +wire write_enable_q_x; +reg write_enable_m; +wire write_enable_q_m; +reg write_enable_w; +wire write_enable_q_w; +wire read_enable_0_d; // Register file read enable 0 +wire [`LM32_REG_IDX_RNG] read_idx_0_d; // Register file read index 0 +wire read_enable_1_d; // Register file read enable 1 +wire [`LM32_REG_IDX_RNG] read_idx_1_d; // Register file read index 1 +wire [`LM32_REG_IDX_RNG] write_idx_d; // Register file write index +reg [`LM32_REG_IDX_RNG] write_idx_x; +reg [`LM32_REG_IDX_RNG] write_idx_m; +reg [`LM32_REG_IDX_RNG] write_idx_w; +wire [`LM32_CSR_RNG] csr_d; // CSR read/write index +reg [`LM32_CSR_RNG] csr_x; +wire [`LM32_CONDITION_RNG] condition_d; // Branch condition +reg [`LM32_CONDITION_RNG] condition_x; +`ifdef CFG_DEBUG_ENABLED +wire break_d; // Indicates a break instruction +reg break_x; +`endif +wire scall_d; // Indicates a scall instruction +reg scall_x; +wire eret_d; // Indicates an eret instruction +reg eret_x; +wire eret_q_x; +reg eret_m; +`ifdef CFG_TRACE_ENABLED +reg eret_w; +`endif +`ifdef CFG_DEBUG_ENABLED +wire bret_d; // Indicates a bret instruction +reg bret_x; +wire bret_q_x; +reg bret_m; +`ifdef CFG_TRACE_ENABLED +reg bret_w; +`endif +`endif +wire csr_write_enable_d; // CSR write enable +reg csr_write_enable_x; +wire csr_write_enable_q_x; +`ifdef CFG_USER_ENABLED +wire [`LM32_USER_OPCODE_RNG] user_opcode_d; // User-defined instruction opcode +`endif + +`ifdef CFG_BUS_ERRORS_ENABLED +wire bus_error_d; // Indicates an bus error occured while fetching the instruction in this pipeline stage +reg bus_error_x; +`endif + +reg [`LM32_WORD_RNG] d_result_0; // Result of instruction in D stage (operand 0) +reg [`LM32_WORD_RNG] d_result_1; // Result of instruction in D stage (operand 1) +reg [`LM32_WORD_RNG] x_result; // Result of instruction in X stage +reg [`LM32_WORD_RNG] m_result; // Result of instruction in M stage +reg [`LM32_WORD_RNG] w_result; // Result of instruction in W stage + +reg [`LM32_WORD_RNG] operand_0_x; // Operand 0 for X stage instruction +reg [`LM32_WORD_RNG] operand_1_x; // Operand 1 for X stage instruction +reg [`LM32_WORD_RNG] store_operand_x; // Data read from register to store +reg [`LM32_WORD_RNG] operand_m; // Operand for M stage instruction +reg [`LM32_WORD_RNG] operand_w; // Operand for W stage instruction + +// To/from register file +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +wire [`LM32_WORD_RNG] reg_data_live_0; +wire [`LM32_WORD_RNG] reg_data_live_1; +reg use_buf; // Whether to use reg_data_live or reg_data_buf +reg [`LM32_WORD_RNG] reg_data_buf_0; +reg [`LM32_WORD_RNG] reg_data_buf_1; +`endif +`ifdef LM32_EBR_REGISTER_FILE +`else +reg [`LM32_WORD_RNG] registers[0:(1<<`LM32_REG_IDX_WIDTH)-1]; // Register file +`endif +wire [`LM32_WORD_RNG] reg_data_0; // Register file read port 0 data +wire [`LM32_WORD_RNG] reg_data_1; // Register file read port 1 data +reg [`LM32_WORD_RNG] bypass_data_0; // Register value 0 after bypassing +reg [`LM32_WORD_RNG] bypass_data_1; // Register value 1 after bypassing +wire reg_write_enable_q_w; + +reg interlock; // Indicates pipeline should be stalled because of a read-after-write hazzard + +wire stall_a; // Stall instruction in A pipeline stage +wire stall_f; // Stall instruction in F pipeline stage +wire stall_d; // Stall instruction in D pipeline stage +wire stall_x; // Stall instruction in X pipeline stage +wire stall_m; // Stall instruction in M pipeline stage + +// To/from adder +wire adder_op_d; // Whether to add or subtract +reg adder_op_x; +reg adder_op_x_n; // Inverted version of adder_op_x +wire [`LM32_WORD_RNG] adder_result_x; // Result from adder +wire adder_overflow_x; // Whether a signed overflow occured +wire adder_carry_n_x; // Whether a carry was generated + +// To/from logical operations unit +wire [`LM32_LOGIC_OP_RNG] logic_op_d; // Which operation to perform +reg [`LM32_LOGIC_OP_RNG] logic_op_x; +wire [`LM32_WORD_RNG] logic_result_x; // Result of logical operation + +`ifdef CFG_SIGN_EXTEND_ENABLED +// From sign-extension unit +wire [`LM32_WORD_RNG] sextb_result_x; // Result of byte sign-extension +wire [`LM32_WORD_RNG] sexth_result_x; // Result of half-word sign-extenstion +wire [`LM32_WORD_RNG] sext_result_x; // Result of sign-extension specified by instruction +`endif + +// To/from shifter +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +`ifdef CFG_ROTATE_ENABLED +wire rotate_d; // Whether we should rotate or shift +reg rotate_x; +`endif +wire direction_d; // Which direction to shift in +reg direction_x; +reg direction_m; +wire [`LM32_WORD_RNG] shifter_result_m; // Result of shifter +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +wire shift_left_d; // Indicates whether to perform a left shift or not +wire shift_left_q_d; +wire shift_right_d; // Indicates whether to perform a right shift or not +wire shift_right_q_d; +`endif +`ifdef LM32_NO_BARREL_SHIFT +wire [`LM32_WORD_RNG] shifter_result_x; // Result of single-bit right shifter +`endif + +// To/from multiplier +`ifdef LM32_MULTIPLY_ENABLED +wire [`LM32_WORD_RNG] multiplier_result_w; // Result from multiplier +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED +wire multiply_d; // Indicates whether to perform a multiply or not +wire multiply_q_d; +`endif + +// To/from divider +`ifdef CFG_MC_DIVIDE_ENABLED +wire divide_d; // Indicates whether to perform a divider or not +wire divide_q_d; +wire modulus_d; +wire modulus_q_d; +wire divide_by_zero_x; // Indicates an attempt was made to divide by zero +`endif + +// To from multi-cycle arithmetic unit +`ifdef LM32_MC_ARITHMETIC_ENABLED +wire mc_stall_request_x; // Multi-cycle arithmetic unit stall request +wire [`LM32_WORD_RNG] mc_result_x; +`endif + +// From CSRs +`ifdef CFG_INTERRUPTS_ENABLED +wire [`LM32_WORD_RNG] interrupt_csr_read_data_x;// Data read from interrupt CSRs +`endif +wire [`LM32_WORD_RNG] cfg; // Configuration CSR +`ifdef CFG_CYCLE_COUNTER_ENABLED +reg [`LM32_WORD_RNG] cc; // Cycle counter CSR +`endif +reg [`LM32_WORD_RNG] csr_read_data_x; // Data read from CSRs + +// To/from instruction unit +wire [`LM32_PC_RNG] pc_f; // PC of instruction in F stage +wire [`LM32_PC_RNG] pc_d; // PC of instruction in D stage +wire [`LM32_PC_RNG] pc_x; // PC of instruction in X stage +wire [`LM32_PC_RNG] pc_m; // PC of instruction in M stage +wire [`LM32_PC_RNG] pc_w; // PC of instruction in W stage +`ifdef CFG_TRACE_ENABLED +reg [`LM32_PC_RNG] pc_c; // PC of last commited instruction +`endif +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +wire [`LM32_INSTRUCTION_RNG] instruction_f; // Instruction in F stage +`endif +wire [`LM32_INSTRUCTION_RNG] instruction_d; // Instruction in D stage +`ifdef CFG_ICACHE_ENABLED +wire iflush; // Flush instruction cache +wire icache_stall_request; // Stall pipeline because instruction cache is busy +wire icache_restart_request; // Restart instruction that caused an instruction cache miss +wire icache_refill_request; // Request to refill instruction cache +wire icache_refilling; // Indicates the instruction cache is being refilled +`endif + +// To/from load/store unit +`ifdef CFG_DCACHE_ENABLED +wire dflush_x; // Flush data cache +reg dflush_m; +wire dcache_stall_request; // Stall pipeline because data cache is busy +wire dcache_restart_request; // Restart instruction that caused a data cache miss +wire dcache_refill_request; // Request to refill data cache +wire dcache_refilling; // Indicates the data cache is being refilled +`endif +wire [`LM32_WORD_RNG] load_data_w; // Result of a load instruction +wire stall_wb_load; // Stall pipeline because of a load via the data Wishbone interface + +// To/from JTAG interface +`ifdef CFG_JTAG_ENABLED +`ifdef CFG_JTAG_UART_ENABLED +wire [`LM32_WORD_RNG] jtx_csr_read_data; // Read data for JTX CSR +wire [`LM32_WORD_RNG] jrx_csr_read_data; // Read data for JRX CSR +`endif +`ifdef CFG_HW_DEBUG_ENABLED +wire jtag_csr_write_enable; // Debugger CSR write enable +wire [`LM32_WORD_RNG] jtag_csr_write_data; // Data to write to specified CSR +wire [`LM32_CSR_RNG] jtag_csr; // Which CSR to write +wire jtag_read_enable; +wire [`LM32_BYTE_RNG] jtag_read_data; +wire jtag_write_enable; +wire [`LM32_BYTE_RNG] jtag_write_data; +wire [`LM32_WORD_RNG] jtag_address; +wire jtag_access_complete; +`endif +`ifdef CFG_DEBUG_ENABLED +wire jtag_break; // Request from debugger to raise a breakpoint +`endif +`endif + +// Hazzard detection +wire raw_x_0; // RAW hazzard between instruction in X stage and read port 0 +wire raw_x_1; // RAW hazzard between instruction in X stage and read port 1 +wire raw_m_0; // RAW hazzard between instruction in M stage and read port 0 +wire raw_m_1; // RAW hazzard between instruction in M stage and read port 1 +wire raw_w_0; // RAW hazzard between instruction in W stage and read port 0 +wire raw_w_1; // RAW hazzard between instruction in W stage and read port 1 + +// Control flow +wire cmp_zero; // Result of comparison is zero +wire cmp_negative; // Result of comparison is negative +wire cmp_overflow; // Comparison produced an overflow +wire cmp_carry_n; // Comparison produced a carry, inverted +reg condition_met_x; // Condition of branch instruction is met +reg condition_met_m; +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH +wire branch_taken_x; // Branch is taken in X stage +`endif +wire branch_taken_m; // Branch is taken in M stage + +wire kill_f; // Kill instruction in F stage +wire kill_d; // Kill instruction in D stage +wire kill_x; // Kill instruction in X stage +wire kill_m; // Kill instruction in M stage +wire kill_w; // Kill instruction in W stage + +reg [`LM32_PC_WIDTH+2-1:8] eba; // Exception Base Address (EBA) CSR +`ifdef CFG_DEBUG_ENABLED +reg [`LM32_PC_WIDTH+2-1:8] deba; // Debug Exception Base Address (DEBA) CSR +`endif +reg [`LM32_EID_RNG] eid_x; // Exception ID in X stage +`ifdef CFG_TRACE_ENABLED +reg [`LM32_EID_RNG] eid_m; // Exception ID in M stage +reg [`LM32_EID_RNG] eid_w; // Exception ID in W stage +`endif + +`ifdef CFG_DEBUG_ENABLED +`ifdef LM32_SINGLE_STEP_ENABLED +wire dc_ss; // Is single-step enabled +`endif +wire dc_re; // Remap all exceptions +wire exception_x; // An exception occured in the X stage +reg exception_m; // An instruction that caused an exception is in the M stage +wire debug_exception_x; // Indicates if a debug exception has occured +reg debug_exception_m; +reg debug_exception_w; +wire debug_exception_q_w; +wire non_debug_exception_x; // Indicates if a non debug exception has occured +reg non_debug_exception_m; +reg non_debug_exception_w; +wire non_debug_exception_q_w; +`else +wire exception_x; // Indicates if a debug exception has occured +reg exception_m; +reg exception_w; +wire exception_q_w; +`endif + +`ifdef CFG_DEBUG_ENABLED +`ifdef CFG_JTAG_ENABLED +wire reset_exception; // Indicates if a reset exception has occured +`endif +`endif +`ifdef CFG_INTERRUPTS_ENABLED +wire interrupt_exception; // Indicates if an interrupt exception has occured +`endif +`ifdef CFG_DEBUG_ENABLED +wire breakpoint_exception; // Indicates if a breakpoint exception has occured +wire watchpoint_exception; // Indicates if a watchpoint exception has occured +`endif +`ifdef CFG_BUS_ERRORS_ENABLED +wire instruction_bus_error_exception; // Indicates if an instruction bus error exception has occured +wire data_bus_error_exception; // Indicates if a data bus error exception has occured +`endif +`ifdef CFG_MC_DIVIDE_ENABLED +wire divide_by_zero_exception; // Indicates if a divide by zero exception has occured +`endif +wire system_call_exception; // Indicates if a system call exception has occured + +`ifdef CFG_BUS_ERRORS_ENABLED +reg data_bus_error_seen; // Indicates if a data bus error was seen +`endif + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +// Instruction unit +lm32_instruction_unit #( + .associativity (icache_associativity), + .sets (icache_sets), + .bytes_per_line (icache_bytes_per_line), + .base_address (icache_base_address), + .limit (icache_limit) + ) instruction_unit ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + // From pipeline + .stall_a (stall_a), + .stall_f (stall_f), + .stall_d (stall_d), + .stall_x (stall_x), + .stall_m (stall_m), + .valid_f (valid_f), + .kill_f (kill_f), +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + .branch_taken_x (branch_taken_x), + .branch_target_x (branch_target_x), +`endif + .branch_taken_m (branch_taken_m), + .branch_target_m (branch_target_m), +`ifdef CFG_ICACHE_ENABLED + .iflush (iflush), +`endif +`ifdef CFG_DCACHE_ENABLED + .dcache_restart_request (dcache_restart_request), + .dcache_refill_request (dcache_refill_request), + .dcache_refilling (dcache_refilling), +`endif +`ifdef CFG_IWB_ENABLED + // From Wishbone + .i_dat_i (I_DAT_I), + .i_ack_i (I_ACK_I), + .i_err_i (I_ERR_I), + .i_rty_i (I_RTY_I), +`endif +`ifdef CFG_HW_DEBUG_ENABLED + .jtag_read_enable (jtag_read_enable), + .jtag_write_enable (jtag_write_enable), + .jtag_write_data (jtag_write_data), + .jtag_address (jtag_address), +`endif + // ----- Outputs ------- + // To pipeline + .pc_f (pc_f), + .pc_d (pc_d), + .pc_x (pc_x), + .pc_m (pc_m), + .pc_w (pc_w), +`ifdef CFG_ICACHE_ENABLED + .icache_stall_request (icache_stall_request), + .icache_restart_request (icache_restart_request), + .icache_refill_request (icache_refill_request), + .icache_refilling (icache_refilling), +`endif +`ifdef CFG_IWB_ENABLED + // To Wishbone + .i_dat_o (I_DAT_O), + .i_adr_o (I_ADR_O), + .i_cyc_o (I_CYC_O), + .i_sel_o (I_SEL_O), + .i_stb_o (I_STB_O), + .i_we_o (I_WE_O), + .i_cti_o (I_CTI_O), + .i_lock_o (I_LOCK_O), + .i_bte_o (I_BTE_O), +`endif +`ifdef CFG_HW_DEBUG_ENABLED + .jtag_read_data (jtag_read_data), + .jtag_access_complete (jtag_access_complete), +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + .bus_error_d (bus_error_d), +`endif +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE + .instruction_f (instruction_f), +`endif + .instruction_d (instruction_d) + ); + +// Trace instructions in simulation +lm32_simtrace simtrace ( + .clk_i (clk_i), + .rst_i (rst_i), + .stall_x (stall_x), + .stall_m (stall_m), + .valid_w (valid_w), + .kill_w (kill_w), + .instruction_d (instruction_d), + .pc_w (pc_w) + ); + +// Instruction decoder +lm32_decoder decoder ( + // ----- Inputs ------- + .instruction (instruction_d), + // ----- Outputs ------- + .d_result_sel_0 (d_result_sel_0_d), + .d_result_sel_1 (d_result_sel_1_d), + .x_result_sel_csr (x_result_sel_csr_d), +`ifdef LM32_MC_ARITHMETIC_ENABLED + .x_result_sel_mc_arith (x_result_sel_mc_arith_d), +`endif +`ifdef LM32_NO_BARREL_SHIFT + .x_result_sel_shift (x_result_sel_shift_d), +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + .x_result_sel_sext (x_result_sel_sext_d), +`endif + .x_result_sel_logic (x_result_sel_logic_d), +`ifdef CFG_USER_ENABLED + .x_result_sel_user (x_result_sel_user_d), +`endif + .x_result_sel_add (x_result_sel_add_d), + .m_result_sel_compare (m_result_sel_compare_d), +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + .m_result_sel_shift (m_result_sel_shift_d), +`endif + .w_result_sel_load (w_result_sel_load_d), +`ifdef CFG_PL_MULTIPLY_ENABLED + .w_result_sel_mul (w_result_sel_mul_d), +`endif + .x_bypass_enable (x_bypass_enable_d), + .m_bypass_enable (m_bypass_enable_d), + .read_enable_0 (read_enable_0_d), + .read_idx_0 (read_idx_0_d), + .read_enable_1 (read_enable_1_d), + .read_idx_1 (read_idx_1_d), + .write_enable (write_enable_d), + .write_idx (write_idx_d), + .immediate (immediate_d), + .branch_offset (branch_offset_d), + .load (load_d), + .store (store_d), + .size (size_d), + .sign_extend (sign_extend_d), + .adder_op (adder_op_d), + .logic_op (logic_op_d), +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + .direction (direction_d), +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + .shift_left (shift_left_d), + .shift_right (shift_right_d), +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + .multiply (multiply_d), +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + .divide (divide_d), + .modulus (modulus_d), +`endif + .branch (branch_d), + .branch_reg (branch_reg_d), + .condition (condition_d), +`ifdef CFG_DEBUG_ENABLED + .break (break_d), +`endif + .scall (scall_d), + .eret (eret_d), +`ifdef CFG_DEBUG_ENABLED + .bret (bret_d), +`endif +`ifdef CFG_USER_ENABLED + .user_opcode (user_opcode_d), +`endif + .csr_write_enable (csr_write_enable_d) + ); + +// Load/store unit +lm32_load_store_unit #( + .associativity (dcache_associativity), + .sets (dcache_sets), + .bytes_per_line (dcache_bytes_per_line), + .base_address (dcache_base_address), + .limit (dcache_limit) + ) load_store_unit ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + // From pipeline + .stall_a (stall_a), + .stall_x (stall_x), + .stall_m (stall_m), + .kill_x (kill_x), + .kill_m (kill_m), + .exception_m (exception_m), + .store_operand_x (store_operand_x), + .load_store_address_x (adder_result_x), + .load_store_address_m (operand_m), + .load_store_address_w (operand_w[1:0]), + .load_q_x (load_q_x), + .load_q_m (load_q_m), + .store_q_m (store_q_m), + .sign_extend_x (sign_extend_x), + .size_x (size_x), +`ifdef CFG_DCACHE_ENABLED + .dflush (dflush_m), +`endif + // From Wishbone + .d_dat_i (D_DAT_I), + .d_ack_i (D_ACK_I), + .d_err_i (D_ERR_I), + .d_rty_i (D_RTY_I), + // ----- Outputs ------- + // To pipeline +`ifdef CFG_DCACHE_ENABLED + .dcache_refill_request (dcache_refill_request), + .dcache_restart_request (dcache_restart_request), + .dcache_stall_request (dcache_stall_request), + .dcache_refilling (dcache_refilling), +`endif + .load_data_w (load_data_w), + .stall_wb_load (stall_wb_load), + // To Wishbone + .d_dat_o (D_DAT_O), + .d_adr_o (D_ADR_O), + .d_cyc_o (D_CYC_O), + .d_sel_o (D_SEL_O), + .d_stb_o (D_STB_O), + .d_we_o (D_WE_O), + .d_cti_o (D_CTI_O), + .d_lock_o (D_LOCK_O), + .d_bte_o (D_BTE_O) + ); + +// Adder +lm32_adder adder ( + // ----- Inputs ------- + .adder_op_x (adder_op_x), + .adder_op_x_n (adder_op_x_n), + .operand_0_x (operand_0_x), + .operand_1_x (operand_1_x), + // ----- Outputs ------- + .adder_result_x (adder_result_x), + .adder_carry_n_x (adder_carry_n_x), + .adder_overflow_x (adder_overflow_x) + ); + +// Logic operations +lm32_logic_op logic_op ( + // ----- Inputs ------- + .logic_op_x (logic_op_x), + .operand_0_x (operand_0_x), + + .operand_1_x (operand_1_x), + // ----- Outputs ------- + .logic_result_x (logic_result_x) + ); + +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +// Pipelined barrel-shifter +lm32_shifter shifter ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + .stall_x (stall_x), + .direction_x (direction_x), + .sign_extend_x (sign_extend_x), + .operand_0_x (operand_0_x), + .operand_1_x (operand_1_x), + // ----- Outputs ------- + .shifter_result_m (shifter_result_m) + ); +`endif + +`ifdef CFG_PL_MULTIPLY_ENABLED +// Pipeline fixed-point multiplier +lm32_multiplier multiplier ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + .stall_x (stall_x), + .stall_m (stall_m), + .operand_0 (d_result_0), + .operand_1 (d_result_1), + // ----- Outputs ------- + .result (multiplier_result_w) + ); +`endif + +`ifdef LM32_MC_ARITHMETIC_ENABLED +// Multi-cycle arithmetic +lm32_mc_arithmetic mc_arithmetic ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + .stall_d (stall_d), + .kill_x (kill_x), +`ifdef CFG_MC_DIVIDE_ENABLED + .divide_d (divide_q_d), + .modulus_d (modulus_q_d), +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + .multiply_d (multiply_q_d), +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + .shift_left_d (shift_left_q_d), + .shift_right_d (shift_right_q_d), + .sign_extend_d (sign_extend_d), +`endif + .operand_0_d (d_result_0), + .operand_1_d (d_result_1), + // ----- Outputs ------- + .result_x (mc_result_x), +`ifdef CFG_MC_DIVIDE_ENABLED + .divide_by_zero_x (divide_by_zero_x), +`endif + .stall_request_x (mc_stall_request_x) + ); +`endif + +`ifdef CFG_INTERRUPTS_ENABLED +// Interrupt unit +lm32_interrupt interrupt ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + // From external devices + .interrupt_n (interrupt_n), + // From pipeline + .stall_x (stall_x), +`ifdef CFG_DEBUG_ENABLED + .non_debug_exception (non_debug_exception_q_w), + .debug_exception (debug_exception_q_w), +`else + .exception (exception_q_w), +`endif + .eret_q_x (eret_q_x), +`ifdef CFG_DEBUG_ENABLED + .bret_q_x (bret_q_x), +`endif + .csr (csr_x), + .csr_write_data (operand_1_x), + .csr_write_enable (csr_write_enable_q_x), + // ----- Outputs ------- + .interrupt_exception (interrupt_exception), + // To pipeline + .csr_read_data (interrupt_csr_read_data_x) + ); +`endif + +`ifdef CFG_JTAG_ENABLED +// JTAG interface +lm32_jtag jtag ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + // From JTAG + .jtag_clk (jtag_clk), + .jtag_update (jtag_update), + .jtag_reg_q (jtag_reg_q), + .jtag_reg_addr_q (jtag_reg_addr_q), + // From pipeline +`ifdef CFG_JTAG_UART_ENABLED + .csr (csr_x), + .csr_write_data (operand_1_x), + .csr_write_enable (csr_write_enable_q_x), + .stall_x (stall_x), +`endif +`ifdef CFG_HW_DEBUG_ENABLED + .jtag_read_data (jtag_read_data), + .jtag_access_complete (jtag_access_complete), +`endif +`ifdef CFG_DEBUG_ENABLED + .exception_q_w (debug_exception_q_w || non_debug_exception_q_w), +`endif + // ----- Outputs ------- + // To pipeline +`ifdef CFG_JTAG_UART_ENABLED + .jtx_csr_read_data (jtx_csr_read_data), + .jrx_csr_read_data (jrx_csr_read_data), +`endif +`ifdef CFG_HW_DEBUG_ENABLED + .jtag_csr_write_enable (jtag_csr_write_enable), + .jtag_csr_write_data (jtag_csr_write_data), + .jtag_csr (jtag_csr), + .jtag_read_enable (jtag_read_enable), + .jtag_write_enable (jtag_write_enable), + .jtag_write_data (jtag_write_data), + .jtag_address (jtag_address), +`endif +`ifdef CFG_DEBUG_ENABLED + .jtag_break (jtag_break), + .jtag_reset (reset_exception), +`endif + // To JTAG + .jtag_reg_d (jtag_reg_d), + .jtag_reg_addr_d (jtag_reg_addr_d) + ); +`endif + +`ifdef CFG_DEBUG_ENABLED +// Debug unit +lm32_debug #( + .breakpoints (breakpoints), + .watchpoints (watchpoints) + ) hw_debug ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + .pc_x (pc_x), + .load_x (load_x), + .store_x (store_x), + .load_store_address_x (adder_result_x), + .csr_write_enable_x (csr_write_enable_q_x), + .csr_write_data (operand_1_x), + .csr_x (csr_x), +`ifdef CFG_HW_DEBUG_ENABLED + .jtag_csr_write_enable (jtag_csr_write_enable), + .jtag_csr_write_data (jtag_csr_write_data), + .jtag_csr (jtag_csr), +`endif +`ifdef LM32_SINGLE_STEP_ENABLED + .eret_q_x (eret_q_x), + .bret_q_x (bret_q_x), + .stall_x (stall_x), + .exception_x (exception_x), + .q_x (q_x), +`ifdef CFG_DCACHE_ENABLED + .dcache_refill_request (dcache_refill_request), +`endif +`endif + // ----- Outputs ------- +`ifdef LM32_SINGLE_STEP_ENABLED + .dc_ss (dc_ss), +`endif + .dc_re (dc_re), + .bp_match (bp_match), + .wp_match (wp_match) + ); +`endif + +// Register file + +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE + +lm32_ram #( + // ----- Parameters ------- + .data_width (`LM32_WORD_WIDTH), + .address_width (`LM32_REG_IDX_WIDTH) + ) reg_0 ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .enable_read (stall_d == `FALSE), + .read_address (instruction_f[25:21]), + .enable_write (`TRUE), + .write_address (write_idx_w), + .write_data (w_result), + .write_enable (reg_write_enable_q_w), + // ----- Outputs ------- + .read_data (reg_data_live_0) + ); + +lm32_ram #( + // ----- Parameters ------- + .data_width (`LM32_WORD_WIDTH), + .address_width (`LM32_REG_IDX_WIDTH) + ) reg_1 ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .enable_read (stall_d == `FALSE), + .read_address (instruction_f[20:16]), + .enable_write (`TRUE), + .write_address (write_idx_w), + .write_data (w_result), + .write_enable (reg_write_enable_q_w), + // ----- Outputs ------- + .read_data (reg_data_live_1) + ); + +`endif + +`ifdef CFG_EBR_NEGEDGE_REGISTER_FILE + +lm32_ram #( + // ----- Parameters ------- + .data_width (`LM32_WORD_WIDTH), + .address_width (`LM32_REG_IDX_WIDTH) + ) reg_0 ( + // ----- Inputs ------- + .read_clk (clk_n_i), + .write_clk (clk_i), + .reset (rst_i), + .enable_read (stall_f == `FALSE), + .read_address (read_idx_0_d), + .enable_write (`TRUE), + .write_address (write_idx_w), + .write_data (w_result), + .write_enable (reg_write_enable_q_w), + // ----- Outputs ------- + .read_data (reg_data_0) + ); + +lm32_ram #( + // ----- Parameters ------- + .data_width (`LM32_WORD_WIDTH), + .address_width (`LM32_REG_IDX_WIDTH) + ) reg_1 ( + // ----- Inputs ------- + .read_clk (clk_n_i), + .write_clk (clk_i), + .reset (rst_i), + .enable_read (stall_f == `FALSE), + .read_address (read_idx_1_d), + .enable_write (`TRUE), + .write_address (write_idx_w), + .write_data (w_result), + .write_enable (reg_write_enable_q_w), + // ----- Outputs ------- + .read_data (reg_data_1) + ); + +`endif + + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +// Select between buffered and live data from register file +assign reg_data_0 = use_buf ? reg_data_buf_0 : reg_data_live_0; +assign reg_data_1 = use_buf ? reg_data_buf_1 : reg_data_live_1; +`endif +`ifdef LM32_EBR_REGISTER_FILE +`else +// Register file read ports +assign reg_data_0 = registers[read_idx_0_d]; +assign reg_data_1 = registers[read_idx_1_d]; +`endif + +// Detect read-after-write hazzards +assign raw_x_0 = (write_idx_x == read_idx_0_d) && (write_enable_q_x == `TRUE); +assign raw_m_0 = (write_idx_m == read_idx_0_d) && (write_enable_q_m == `TRUE); +assign raw_w_0 = (write_idx_w == read_idx_0_d) && (write_enable_q_w == `TRUE); +assign raw_x_1 = (write_idx_x == read_idx_1_d) && (write_enable_q_x == `TRUE); +assign raw_m_1 = (write_idx_m == read_idx_1_d) && (write_enable_q_m == `TRUE); +assign raw_w_1 = (write_idx_w == read_idx_1_d) && (write_enable_q_w == `TRUE); + +// Interlock detection - Raise an interlock for RAW hazzards +always @* +begin + if ( ( (x_bypass_enable_x == `FALSE) + && ( ((read_enable_0_d == `TRUE) && (raw_x_0 == `TRUE)) + || ((read_enable_1_d == `TRUE) && (raw_x_1 == `TRUE)) + ) + ) + || ( (m_bypass_enable_m == `FALSE) + && ( ((read_enable_0_d == `TRUE) && (raw_m_0 == `TRUE)) + || ((read_enable_1_d == `TRUE) && (raw_m_1 == `TRUE)) + ) + ) + ) + interlock = `TRUE; + else + interlock = `FALSE; +end + +// Bypass for reg port 0 +always @* +begin + if (raw_x_0 == `TRUE) + bypass_data_0 = x_result; + else if (raw_m_0 == `TRUE) + bypass_data_0 = m_result; + else if (raw_w_0 == `TRUE) + bypass_data_0 = w_result; + else + bypass_data_0 = reg_data_0; +end + +// Bypass for reg port 1 +always @* +begin + if (raw_x_1 == `TRUE) + bypass_data_1 = x_result; + else if (raw_m_1 == `TRUE) + bypass_data_1 = m_result; + else if (raw_w_1 == `TRUE) + bypass_data_1 = w_result; + else + bypass_data_1 = reg_data_1; +end + +// D stage result selection +always @* +begin + d_result_0 = d_result_sel_0_d[0] ? {pc_f, 2'b00} : bypass_data_0; + case (d_result_sel_1_d) + `LM32_D_RESULT_SEL_1_ZERO: d_result_1 = {`LM32_WORD_WIDTH{1'b0}}; + `LM32_D_RESULT_SEL_1_REG_1: d_result_1 = bypass_data_1; + `LM32_D_RESULT_SEL_1_IMMEDIATE: d_result_1 = immediate_d; + default: d_result_1 = {`LM32_WORD_WIDTH{1'bx}}; + endcase +end + +`ifdef CFG_USER_ENABLED +// Operands for user-defined instructions +assign user_operand_0 = operand_0_x; +assign user_operand_1 = operand_1_x; +`endif + +`ifdef CFG_SIGN_EXTEND_ENABLED +// Sign-extension +assign sextb_result_x = {{24{operand_0_x[7]}}, operand_0_x[7:0]}; +assign sexth_result_x = {{16{operand_0_x[15]}}, operand_0_x[15:0]}; +assign sext_result_x = size_x == `LM32_SIZE_BYTE ? sextb_result_x : sexth_result_x; +`endif + +`ifdef LM32_NO_BARREL_SHIFT +// Only single bit shift operations are supported when barrel-shifter isn't implemented +assign shifter_result_x = {operand_0_x[`LM32_WORD_WIDTH-1] & sign_extend_x, operand_0_x[`LM32_WORD_WIDTH-1:1]}; +`endif + +// Condition evaluation +assign cmp_zero = operand_0_x == operand_1_x; +assign cmp_negative = adder_result_x[`LM32_WORD_WIDTH-1]; +assign cmp_overflow = adder_overflow_x; +assign cmp_carry_n = adder_carry_n_x; +always @* +begin + case (condition_x) + `LM32_CONDITION_U1: condition_met_x = `TRUE; + `LM32_CONDITION_U2: condition_met_x = `TRUE; + `LM32_CONDITION_E: condition_met_x = cmp_zero; + `LM32_CONDITION_NE: condition_met_x = !cmp_zero; + `LM32_CONDITION_G: condition_met_x = !cmp_zero && (cmp_negative == cmp_overflow); + `LM32_CONDITION_GU: condition_met_x = cmp_carry_n && !cmp_zero; + `LM32_CONDITION_GE: condition_met_x = cmp_negative == cmp_overflow; + `LM32_CONDITION_GEU: condition_met_x = cmp_carry_n; + default: condition_met_x = 1'bx; + endcase +end + +// X stage result selection +always @* +begin + x_result = x_result_sel_add_x ? adder_result_x + : x_result_sel_csr_x ? csr_read_data_x +`ifdef CFG_SIGN_EXTEND_ENABLED + : x_result_sel_sext_x ? sext_result_x +`endif +`ifdef CFG_USER_ENABLED + : x_result_sel_user_x ? user_result +`endif +`ifdef LM32_NO_BARREL_SHIFT + : x_result_sel_shift_x ? shifter_result_x +`endif +`ifdef LM32_MC_ARITHMETIC_ENABLED + : x_result_sel_mc_arith_x ? mc_result_x +`endif + : logic_result_x; +end + +// M stage result selection +always @* +begin + m_result = m_result_sel_compare_m ? {{`LM32_WORD_WIDTH-1{1'b0}}, condition_met_m} +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + : m_result_sel_shift_m ? shifter_result_m +`endif + : operand_m; +end + +// W stage result selection +always @* +begin + w_result = w_result_sel_load_w ? load_data_w +`ifdef CFG_PL_MULTIPLY_ENABLED + : w_result_sel_mul_w ? multiplier_result_w +`endif + : operand_w; +end + +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH +// Indicate when a branch should be taken in X stage +assign branch_taken_x = (stall_x == `FALSE) + && ( (branch_x == `TRUE) + && ((condition_x == `LM32_CONDITION_U1) || (condition_x == `LM32_CONDITION_U2)) + && (valid_x == `TRUE) + ); +`endif + +// Indicate when a branch should be taken in M stage (exceptions are a type of branch) +assign branch_taken_m = (stall_m == `FALSE) + && ( ( (branch_m == `TRUE) + && (condition_met_m == `TRUE) + && (valid_m == `TRUE) + ) + || (exception_m == `TRUE) + ); + +// Generate signal that will kill instructions in each pipeline stage when necessary +assign kill_f = (branch_taken_m == `TRUE) +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + || (branch_taken_x == `TRUE) +`endif +`ifdef CFG_ICACHE_ENABLED + || (icache_refill_request == `TRUE) +`endif +`ifdef CFG_DCACHE_ENABLED + || (dcache_refill_request == `TRUE) +`endif + ; +assign kill_d = (branch_taken_m == `TRUE) +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + || (branch_taken_x == `TRUE) +`endif +`ifdef CFG_ICACHE_ENABLED + || (icache_refill_request == `TRUE) +`endif +`ifdef CFG_DCACHE_ENABLED + || (dcache_refill_request == `TRUE) +`endif + ; +assign kill_x = (branch_taken_m == `TRUE) +`ifdef CFG_DCACHE_ENABLED + || (dcache_refill_request == `TRUE) +`endif + ; +assign kill_m = `FALSE +`ifdef CFG_DCACHE_ENABLED + || (dcache_refill_request == `TRUE) +`endif + ; +assign kill_w = `FALSE +`ifdef CFG_DCACHE_ENABLED + || (dcache_refill_request == `TRUE) +`endif + ; + +// Exceptions + +`ifdef CFG_DEBUG_ENABLED +assign breakpoint_exception = (break_x == `TRUE) + || (bp_match == `TRUE) +`ifdef CFG_JTAG_ENABLED + || (jtag_break == `TRUE) +`endif + ; +assign watchpoint_exception = wp_match == `TRUE; +`endif +`ifdef CFG_BUS_ERRORS_ENABLED +assign instruction_bus_error_exception = bus_error_x == `TRUE; +assign data_bus_error_exception = data_bus_error_seen == `TRUE; +`endif +`ifdef CFG_MC_DIVIDE_ENABLED +assign divide_by_zero_exception = divide_by_zero_x == `TRUE; +`endif +assign system_call_exception = scall_x == `TRUE; + +`ifdef CFG_DEBUG_ENABLED +assign debug_exception_x = (breakpoint_exception == `TRUE) + || (watchpoint_exception == `TRUE) + ; + +assign non_debug_exception_x = (system_call_exception == `TRUE) +`ifdef CFG_JTAG_ENABLED + || (reset_exception == `TRUE) +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + || (instruction_bus_error_exception == `TRUE) + || (data_bus_error_exception == `TRUE) +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + || (divide_by_zero_exception == `TRUE) +`endif +`ifdef CFG_INTERRUPTS_ENABLED + || ( (interrupt_exception == `TRUE) +`ifdef LM32_SINGLE_STEP_ENABLED + && (dc_ss == `FALSE) +`endif + ) +`endif + ; + +assign exception_x = (debug_exception_x == `TRUE) || (non_debug_exception_x == `TRUE); +`else +assign exception_x = (system_call_exception == `TRUE) +`ifdef CFG_BUS_ERRORS_ENABLED + || (instruction_bus_error_exception == `TRUE) + || (data_bus_error_exception == `TRUE) +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + || (divide_by_zero_exception == `TRUE) +`endif +`ifdef CFG_INTERRUPTS_ENABLED + || ( (interrupt_exception == `TRUE) +`ifdef LM32_SINGLE_STEP_ENABLED + && (dc_ss == `FALSE) +`endif + ) +`endif + ; +`endif + +// Exception ID +always @* +begin +`ifdef CFG_DEBUG_ENABLED +`ifdef CFG_JTAG_ENABLED + if (reset_exception == `TRUE) + eid_x = `LM32_EID_RESET; + else +`endif + if (breakpoint_exception == `TRUE) + eid_x = `LM32_EID_BREAKPOINT; + else +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + if (instruction_bus_error_exception == `TRUE) + eid_x = `LM32_EID_INST_BUS_ERROR; + else +`endif +`ifdef CFG_DEBUG_ENABLED + if (watchpoint_exception == `TRUE) + eid_x = `LM32_EID_WATCHPOINT; + else +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + if (data_bus_error_exception == `TRUE) + eid_x = `LM32_EID_DATA_BUS_ERROR; + else +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + if (divide_by_zero_exception == `TRUE) + eid_x = `LM32_EID_DIVIDE_BY_ZERO; + else +`endif +`ifdef CFG_INTERRUPTS_ENABLED + if ( (interrupt_exception == `TRUE) +`ifdef LM32_SINGLE_STEP_ENABLED + && (dc_ss == `FALSE) +`endif + ) + eid_x = `LM32_EID_INTERRUPT; + else +`endif + eid_x = `LM32_EID_SCALL; +end + +// Stall generation + +assign stall_a = (stall_f == `TRUE); + +assign stall_f = (stall_d == `TRUE); + +assign stall_d = (stall_x == `TRUE) + || ( (interlock == `TRUE) + && (kill_d == `FALSE) + ) + || ( (eret_d == `TRUE) + && (load_q_x == `TRUE) + ) +`ifdef CFG_DEBUG_ENABLED + || ( (bret_d == `TRUE) + && (load_q_x == `TRUE) + ) +`endif + || ( (csr_write_enable_d == `TRUE) + && (load_q_x == `TRUE) + ) + ; + +assign stall_x = (stall_m == `TRUE) +`ifdef LM32_MC_ARITHMETIC_ENABLED + || ( (mc_stall_request_x == `TRUE) + && (kill_x == `FALSE) + ) +`endif + ; + +assign stall_m = (stall_wb_load == `TRUE) +`ifdef CFG_SIZE_OVER_SPEED + || (D_CYC_O == `TRUE) +`else + || ( (D_CYC_O == `TRUE) + && ( (store_m == `TRUE) + || (load_m == `TRUE) + || (load_x == `TRUE) + ) + ) +`endif +`ifdef CFG_DCACHE_ENABLED + || (dcache_stall_request == `TRUE) // Need to stall in case a taken branch is in M stage and data cache is only being flush, so wont be restarted +`endif +`ifdef CFG_ICACHE_ENABLED + || (icache_stall_request == `TRUE) // Pipeline needs to be stalled otherwise branches may be lost + || ((I_CYC_O == `TRUE) && ((branch_m == `TRUE) || (exception_m == `TRUE))) +`else +`ifdef CFG_IWB_ENABLED + || (I_CYC_O == `TRUE) +`endif +`endif +`ifdef CFG_USER_ENABLED + || ( (user_valid == `TRUE) // Stall whole pipeline, rather than just X stage, where the instruction is, so we don't have to worry about exceptions (maybe) + && (user_complete == `FALSE) + ) +`endif + ; + +// Qualify state changing control signals +`ifdef LM32_MC_ARITHMETIC_ENABLED +wire q_d = (valid_d == `TRUE) && (kill_d == `FALSE); +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +assign shift_left_q_d = (shift_left_d == `TRUE) && (q_d == `TRUE); +assign shift_right_q_d = (shift_right_d == `TRUE) && (q_d == `TRUE); +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED +assign multiply_q_d = (multiply_d == `TRUE) && (q_d == `TRUE); +`endif +`ifdef CFG_MC_DIVIDE_ENABLED +assign divide_q_d = (divide_d == `TRUE) && (q_d == `TRUE); +assign modulus_q_d = (modulus_d == `TRUE) && (q_d == `TRUE); +`endif +wire q_x = (valid_x == `TRUE) && (kill_x == `FALSE); +assign csr_write_enable_q_x = (csr_write_enable_x == `TRUE) && (q_x == `TRUE); +assign eret_q_x = (eret_x == `TRUE) && (q_x == `TRUE); +`ifdef CFG_DEBUG_ENABLED +assign bret_q_x = (bret_x == `TRUE) && (q_x == `TRUE); +`endif +assign load_q_x = (load_x == `TRUE) + && (q_x == `TRUE) +`ifdef CFG_DEBUG_ENABLED + && (bp_match == `FALSE) +`endif + ; +`ifdef CFG_USER_ENABLED +assign user_valid = (x_result_sel_user_x == `TRUE) && (q_x == `TRUE); +`endif +wire q_m = (valid_m == `TRUE) && (kill_m == `FALSE) && (exception_m == `FALSE); +assign load_q_m = (load_m == `TRUE) && (q_m == `TRUE); +assign store_q_m = (store_m == `TRUE) && (q_m == `TRUE); +`ifdef CFG_DEBUG_ENABLED +assign debug_exception_q_w = ((debug_exception_w == `TRUE) && (valid_w == `TRUE)); +assign non_debug_exception_q_w = ((non_debug_exception_w == `TRUE) && (valid_w == `TRUE)); +`else +assign exception_q_w = ((exception_w == `TRUE) && (valid_w == `TRUE)); +`endif +// Don't qualify register write enables with kill, as the signal is needed early, and it doesn't matter if the instruction is killed (except for the actual write - but that is handled separately) +assign write_enable_q_x = (write_enable_x == `TRUE) && (valid_x == `TRUE); +assign write_enable_q_m = (write_enable_m == `TRUE) && (valid_m == `TRUE); +assign write_enable_q_w = (write_enable_w == `TRUE) && (valid_w == `TRUE); +// The enable that actually does write the registers needs to be qualified with kill +assign reg_write_enable_q_w = (write_enable_w == `TRUE) && (kill_w == `FALSE) && (valid_w == `TRUE); + +// Configuration (CFG) CSR +assign cfg = { + `LM32_REVISION, + watchpoints[3:0], + breakpoints[3:0], + interrupts[5:0], +`ifdef CFG_JTAG_UART_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_ROM_DEBUG_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_HW_DEBUG_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_DEBUG_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_ICACHE_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_DCACHE_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_CYCLE_COUNTER_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_USER_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef LM32_BARREL_SHIFT_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + `TRUE, +`else + `FALSE, +`endif +`ifdef LM32_MULTIPLY_ENABLED + `TRUE +`else + `FALSE +`endif + }; + +// Cache flush +`ifdef CFG_ICACHE_ENABLED +assign iflush = (csr_write_enable_d == `TRUE) + && (csr_d == `LM32_CSR_ICC) + && (stall_d == `FALSE) + && (kill_d == `FALSE) + && (valid_d == `TRUE); +`endif +`ifdef CFG_DCACHE_ENABLED +assign dflush_x = (csr_write_enable_q_x == `TRUE) + && (csr_x == `LM32_CSR_DCC); +`endif + +// Extract CSR index +assign csr_d = read_idx_0_d[`LM32_CSR_RNG]; + +// CSR reads +always @* +begin + case (csr_x) +`ifdef CFG_INTERRUPTS_ENABLED + `LM32_CSR_IE, + `LM32_CSR_IM, + `LM32_CSR_IP: csr_read_data_x = interrupt_csr_read_data_x; +`endif +`ifdef CFG_CYCLE_COUNTER_ENABLED + `LM32_CSR_CC: csr_read_data_x = cc; +`endif + `LM32_CSR_CFG: csr_read_data_x = cfg; + `LM32_CSR_EBA: csr_read_data_x = {eba, 8'h00}; +`ifdef CFG_DEBUG_ENABLED + `LM32_CSR_DEBA: csr_read_data_x = {deba, 8'h00}; +`endif +`ifdef CFG_JTAG_UART_ENABLED + `LM32_CSR_JTX: csr_read_data_x = jtx_csr_read_data; + `LM32_CSR_JRX: csr_read_data_x = jrx_csr_read_data; +`endif + default: csr_read_data_x = {`LM32_WORD_WIDTH{1'bx}}; + endcase +end + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +// Exception Base Address (EBA) CSR +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + eba <= eba_reset[`LM32_PC_WIDTH+2-1:8]; + else + begin + if ((csr_write_enable_q_x == `TRUE) && (csr_x == `LM32_CSR_EBA) && (stall_x == `FALSE)) + eba <= operand_1_x[`LM32_PC_WIDTH+2-1:8]; +`ifdef CFG_HW_DEBUG_ENABLED + if ((jtag_csr_write_enable == `TRUE) && (jtag_csr == `LM32_CSR_EBA)) + eba <= jtag_csr_write_data[`LM32_PC_WIDTH+2-1:8]; +`endif + end +end + +`ifdef CFG_DEBUG_ENABLED +// Debug Exception Base Address (DEBA) CSR +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + deba <= deba_reset[`LM32_PC_WIDTH+2-1:8]; + else + begin + if ((csr_write_enable_q_x == `TRUE) && (csr_x == `LM32_CSR_DEBA) && (stall_x == `FALSE)) + deba <= operand_1_x[`LM32_PC_WIDTH+2-1:8]; +`ifdef CFG_HW_DEBUG_ENABLED + if ((jtag_csr_write_enable == `TRUE) && (jtag_csr == `LM32_CSR_DEBA)) + deba <= jtag_csr_write_data[`LM32_PC_WIDTH+2-1:8]; +`endif + end +end +`endif + +// Cycle Counter (CC) CSR +`ifdef CFG_CYCLE_COUNTER_ENABLED +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + cc <= {`LM32_WORD_WIDTH{1'b0}}; + else + cc <= cc + 1'b1; +end +`endif + +`ifdef CFG_BUS_ERRORS_ENABLED +// Watch for data bus errors +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + data_bus_error_seen <= `FALSE; + else + begin + // Set flag when bus error is detected + if ((D_ERR_I == `TRUE) && (D_CYC_O == `TRUE)) + data_bus_error_seen <= `TRUE; + // Clear flag when exception is taken + if ((exception_m == `TRUE) && (kill_m == `FALSE)) + data_bus_error_seen <= `FALSE; + end +end +`endif + +// Valid bits to indicate whether an instruction in a partcular pipeline stage is valid or not + +`ifdef CFG_ICACHE_ENABLED +`ifdef CFG_DCACHE_ENABLED +always @* +begin + if ( (icache_refill_request == `TRUE) + || (dcache_refill_request == `TRUE) + ) + valid_a = `FALSE; + else if ( (icache_restart_request == `TRUE) + || (dcache_restart_request == `TRUE) + ) + valid_a = `TRUE; + else + valid_a = !icache_refilling && !dcache_refilling; +end +`else +always @* +begin + if (icache_refill_request == `TRUE) + valid_a = `FALSE; + else if (icache_restart_request == `TRUE) + valid_a = `TRUE; + else + valid_a = !icache_refilling; +end +`endif +`else +`ifdef CFG_DCACHE_ENABLED +always @* +begin + if (dcache_refill_request == `TRUE) + valid_a = `FALSE; + else if (dcache_restart_request == `TRUE) + valid_a = `TRUE; + else + valid_a = !dcache_refilling; +end +`endif +`endif + +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + valid_f <= `FALSE; + valid_d <= `FALSE; + valid_x <= `FALSE; + valid_m <= `FALSE; + valid_w <= `FALSE; + end + else + begin + if ((kill_f == `TRUE) || (stall_a == `FALSE)) +`ifdef LM32_CACHE_ENABLED + valid_f <= valid_a; +`else + valid_f <= `TRUE; +`endif + else if (stall_f == `FALSE) + valid_f <= `FALSE; + if (kill_d == `TRUE) + valid_d <= `FALSE; + else if (stall_f == `FALSE) + valid_d <= valid_f & !kill_f; + else if (stall_d == `FALSE) + valid_d <= `FALSE; + if (kill_x == `TRUE) + valid_x <= `FALSE; + else if (stall_d == `FALSE) + valid_x <= valid_d & !kill_d; + else if (stall_x == `FALSE) + valid_x <= `FALSE; + if (kill_m == `TRUE) + valid_m <= `FALSE; + else if (stall_x == `FALSE) + valid_m <= valid_x & !kill_x; + else if (stall_m == `FALSE) + valid_m <= `FALSE; + if (stall_m == `FALSE) + valid_w <= valid_m & !kill_m; + else + valid_w <= `FALSE; + end +end + +// Microcode pipeline registers +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin +`ifdef CFG_USER_ENABLED + user_opcode <= {`LM32_USER_OPCODE_WIDTH{1'b0}}; +`endif + operand_0_x <= {`LM32_WORD_WIDTH{1'b0}}; + operand_1_x <= {`LM32_WORD_WIDTH{1'b0}}; + store_operand_x <= {`LM32_WORD_WIDTH{1'b0}}; + branch_target_x <= {`LM32_WORD_WIDTH{1'b0}}; + x_result_sel_csr_x <= `FALSE; +`ifdef LM32_MC_ARITHMETIC_ENABLED + x_result_sel_mc_arith_x <= `FALSE; +`endif +`ifdef LM32_NO_BARREL_SHIFT + x_result_sel_shift_x <= `FALSE; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + x_result_sel_sext_x <= `FALSE; +`endif + x_result_sel_logic_x <= `FALSE; +`ifdef CFG_USER_ENABLED + x_result_sel_user_x <= `FALSE; +`endif + x_result_sel_add_x <= `FALSE; + m_result_sel_compare_x <= `FALSE; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + m_result_sel_shift_x <= `FALSE; +`endif + w_result_sel_load_x <= `FALSE; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_x <= `FALSE; +`endif + x_bypass_enable_x <= `FALSE; + m_bypass_enable_x <= `FALSE; + write_enable_x <= `FALSE; + write_idx_x <= {`LM32_REG_IDX_WIDTH{1'b0}}; + csr_x <= {`LM32_CSR_WIDTH{1'b0}}; + load_x <= `FALSE; + store_x <= `FALSE; + size_x <= {`LM32_SIZE_WIDTH{1'b0}}; + sign_extend_x <= `FALSE; + adder_op_x <= `FALSE; + adder_op_x_n <= `FALSE; + logic_op_x <= 4'h0; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + direction_x <= `FALSE; +`endif +`ifdef CFG_ROTATE_ENABLED + rotate_x <= `FALSE; + +`endif + branch_x <= `FALSE; + condition_x <= `LM32_CONDITION_U1; +`ifdef CFG_DEBUG_ENABLED + break_x <= `FALSE; +`endif + scall_x <= `FALSE; + eret_x <= `FALSE; +`ifdef CFG_DEBUG_ENABLED + bret_x <= `FALSE; +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_x <= `FALSE; +`endif + csr_write_enable_x <= `FALSE; + operand_m <= {`LM32_WORD_WIDTH{1'b0}}; + branch_target_m <= {`LM32_WORD_WIDTH{1'b0}}; + m_result_sel_compare_m <= `FALSE; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + m_result_sel_shift_m <= `FALSE; +`endif + w_result_sel_load_m <= `FALSE; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_m <= `FALSE; +`endif + m_bypass_enable_m <= `FALSE; + branch_m <= `FALSE; + exception_m <= `FALSE; + load_m <= `FALSE; + store_m <= `FALSE; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + direction_m <= `FALSE; +`endif + write_enable_m <= `FALSE; + write_idx_m <= {`LM32_REG_IDX_WIDTH{1'b0}}; + condition_met_m <= `FALSE; +`ifdef CFG_DCACHE_ENABLED + dflush_m <= `FALSE; +`endif +`ifdef CFG_DEBUG_ENABLED + debug_exception_m <= `FALSE; + non_debug_exception_m <= `FALSE; +`endif + operand_w <= {`LM32_WORD_WIDTH{1'b0}}; + w_result_sel_load_w <= `FALSE; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_w <= `FALSE; +`endif + write_idx_w <= {`LM32_REG_IDX_WIDTH{1'b0}}; + write_enable_w <= `FALSE; +`ifdef CFG_DEBUG_ENABLED + debug_exception_w <= `FALSE; + non_debug_exception_w <= `FALSE; +`else + exception_w <= `FALSE; +`endif + end + else + begin + // D/X stage registers + + if (stall_x == `FALSE) + begin +`ifdef CFG_USER_ENABLED + user_opcode <= user_opcode_d; +`endif + operand_0_x <= d_result_0; + operand_1_x <= d_result_1; + store_operand_x <= bypass_data_1; + branch_target_x <= branch_reg_d == `TRUE ? bypass_data_0[`LM32_PC_RNG] : pc_d + branch_offset_d; + x_result_sel_csr_x <= x_result_sel_csr_d; +`ifdef LM32_MC_ARITHMETIC_ENABLED + x_result_sel_mc_arith_x <= x_result_sel_mc_arith_d; +`endif +`ifdef LM32_NO_BARREL_SHIFT + x_result_sel_shift_x <= x_result_sel_shift_d; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + x_result_sel_sext_x <= x_result_sel_sext_d; +`endif + x_result_sel_logic_x <= x_result_sel_logic_d; +`ifdef CFG_USER_ENABLED + x_result_sel_user_x <= x_result_sel_user_d; +`endif + x_result_sel_add_x <= x_result_sel_add_d; + m_result_sel_compare_x <= m_result_sel_compare_d; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + m_result_sel_shift_x <= m_result_sel_shift_d; +`endif + w_result_sel_load_x <= w_result_sel_load_d; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_x <= w_result_sel_mul_d; +`endif + x_bypass_enable_x <= x_bypass_enable_d; + m_bypass_enable_x <= m_bypass_enable_d; + load_x <= load_d; + store_x <= store_d; + branch_x <= branch_d; + write_idx_x <= write_idx_d; + csr_x <= csr_d; + size_x <= size_d; + sign_extend_x <= sign_extend_d; + adder_op_x <= adder_op_d; + adder_op_x_n <= ~adder_op_d; + logic_op_x <= logic_op_d; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + direction_x <= direction_d; +`endif +`ifdef CFG_ROTATE_ENABLED + rotate_x <= rotate_d; +`endif + condition_x <= condition_d; + csr_write_enable_x <= csr_write_enable_d; +`ifdef CFG_DEBUG_ENABLED + break_x <= break_d; +`endif + scall_x <= scall_d; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_x <= bus_error_d; +`endif + eret_x <= eret_d; +`ifdef CFG_DEBUG_ENABLED + bret_x <= bret_d; +`endif + write_enable_x <= write_enable_d; + end + + // X/M stage registers + + if (stall_m == `FALSE) + begin + operand_m <= x_result; + m_result_sel_compare_m <= m_result_sel_compare_x; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + m_result_sel_shift_m <= m_result_sel_shift_x; +`endif + if (exception_x == `TRUE) + begin + w_result_sel_load_m <= `FALSE; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_m <= `FALSE; +`endif + end + else + begin + w_result_sel_load_m <= w_result_sel_load_x; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_m <= w_result_sel_mul_x; +`endif + end + m_bypass_enable_m <= m_bypass_enable_x; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + direction_m <= direction_x; +`endif + load_m <= load_x; + store_m <= store_x; +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + branch_m <= branch_x && !branch_taken_x; +`else + branch_m <= branch_x; +`endif +`ifdef CFG_DEBUG_ENABLED + if (debug_exception_x == `TRUE) + write_idx_m <= `LM32_BA_REG; + else if (non_debug_exception_x == `TRUE) + write_idx_m <= `LM32_EA_REG; + else + write_idx_m <= write_idx_x; +`else + if (exception_x == `TRUE) + write_idx_m <= `LM32_EA_REG; + else + write_idx_m <= write_idx_x; +`endif + condition_met_m <= condition_met_x; +`ifdef CFG_DEBUG_ENABLED + branch_target_m <= exception_x == `TRUE ? {(debug_exception_x == `TRUE) || (dc_re == `TRUE) ? deba : eba, eid_x, {3{1'b0}}} : branch_target_x; +`else + branch_target_m <= exception_x == `TRUE ? {eba, eid_x, {3{1'b0}}} : branch_target_x; +`endif +`ifdef CFG_TRACE_ENABLED + eid_m <= eid_x; +`endif +`ifdef CFG_DCACHE_ENABLED + dflush_m <= dflush_x; +`endif + eret_m <= eret_q_x; +`ifdef CFG_DEBUG_ENABLED + bret_m <= bret_q_x; +`endif + write_enable_m <= exception_x == `TRUE ? `TRUE : write_enable_x; +`ifdef CFG_DEBUG_ENABLED + debug_exception_m <= debug_exception_x; + non_debug_exception_m <= non_debug_exception_x; +`endif + end + + // State changing regs + if (stall_m == `FALSE) + begin + if ((exception_x == `TRUE) && (q_x == `TRUE) && (stall_x == `FALSE)) + exception_m <= `TRUE; + else + exception_m <= `FALSE; + end + + // M/W stage registers + + operand_w <= exception_m == `TRUE ? {pc_m, 2'b00} : m_result; + w_result_sel_load_w <= w_result_sel_load_m; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul_w <= w_result_sel_mul_m; +`endif + write_idx_w <= write_idx_m; +`ifdef CFG_TRACE_ENABLED + eid_w <= eid_m; + eret_w <= eret_m; +`ifdef CFG_DEBUG_ENABLED + bret_w <= bret_m; +`endif +`endif + write_enable_w <= write_enable_m; +`ifdef CFG_DEBUG_ENABLED + debug_exception_w <= debug_exception_m; + non_debug_exception_w <= non_debug_exception_m; +`else + exception_w <= exception_m; +`endif + end +end + +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +// Buffer data read from register file, in case a stall occurs, and watch for +// any writes to the modified registers +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + use_buf <= `FALSE; + reg_data_buf_0 <= {`LM32_WORD_WIDTH{1'b0}}; + reg_data_buf_1 <= {`LM32_WORD_WIDTH{1'b0}}; + end + else + begin + if (stall_d == `FALSE) + use_buf <= `FALSE; + else if (use_buf == `FALSE) + begin + reg_data_buf_0 <= reg_data_live_0; + reg_data_buf_1 <= reg_data_live_1; + use_buf <= `TRUE; + end + if (reg_write_enable_q_w == `TRUE) + begin + if (write_idx_w == read_idx_0_d) + reg_data_buf_0 <= w_result; + if (write_idx_w == read_idx_1_d) + reg_data_buf_1 <= w_result; + end + end +end +`endif + +`ifdef LM32_EBR_REGISTER_FILE +`else +// Register file write port +// Adding a reset causes a huge slowdown and requires lots of extra LUTs +always @(posedge clk_i) +begin + if (reg_write_enable_q_w == `TRUE) + registers[write_idx_w] <= w_result; +end +`endif + +`ifdef CFG_TRACE_ENABLED +// PC tracing logic +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + trace_pc_valid <= `FALSE; + trace_pc <= {`LM32_PC_WIDTH{1'b0}}; + trace_exception <= `FALSE; + trace_eid <= `LM32_EID_RESET; + trace_eret <= `FALSE; +`ifdef CFG_DEBUG_ENABLED + trace_bret <= `FALSE; +`endif + pc_c <= `CFG_EBA_RESET/4; + end + else + begin + trace_pc_valid <= `FALSE; + + // Has an exception occured +`ifdef CFG_DEBUG_ENABLED + if ((debug_exception_q_w == `TRUE) || (non_debug_exception_q_w == `TRUE)) +`else + if (exception_q_w == `TRUE) +`endif + begin + trace_exception <= `TRUE; + trace_pc_valid <= `TRUE; + trace_pc <= pc_w; + trace_eid <= eid_w; + end + else + trace_exception <= `FALSE; + + if ((valid_w == `TRUE) && (!kill_w)) + begin + // An instruction is commiting. Determine if it is non-sequential + if (pc_c + 1'b1 != pc_w) + begin + // Non-sequential instruction + trace_pc_valid <= `TRUE; + trace_pc <= pc_w; + end + // Record PC so we can determine if next instruction is sequential or not + pc_c <= pc_w; + // Indicate if it was an eret/bret instruction + trace_eret <= eret_w; +`ifdef CFG_DEBUG_ENABLED + trace_bret <= bret_w; +`endif + end + else + begin + trace_eret <= `FALSE; +`ifdef CFG_DEBUG_ENABLED + trace_bret <= `FALSE; +`endif + end + end +end +`endif + +///////////////////////////////////////////////////// +// Behavioural Logic +///////////////////////////////////////////////////// + +// synthesis translate_off + +// Reset register 0. Only needed for simulation. +initial +begin +`ifdef LM32_EBR_REGISTER_FILE + reg_0.mem[0] = {`LM32_WORD_WIDTH{1'b0}}; + reg_1.mem[0] = {`LM32_WORD_WIDTH{1'b0}}; +`else + registers[0] = {`LM32_WORD_WIDTH{1'b0}}; +`endif +end + +// synthesis translate_on + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_dcache.v b/lm32/logic/sakc/rtl/lm32/lm32_dcache.v new file mode 100644 index 0000000..6fa0d9f --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_dcache.v @@ -0,0 +1,494 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_dcache.v +// Title : Data cache +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +`ifdef CFG_DCACHE_ENABLED + +`define LM32_DC_ADDR_OFFSET_RNG addr_offset_msb:addr_offset_lsb +`define LM32_DC_ADDR_SET_RNG addr_set_msb:addr_set_lsb +`define LM32_DC_ADDR_TAG_RNG addr_tag_msb:addr_tag_lsb +`define LM32_DC_ADDR_IDX_RNG addr_set_msb:addr_offset_lsb + +`define LM32_DC_TMEM_ADDR_WIDTH addr_set_width +`define LM32_DC_TMEM_ADDR_RNG (`LM32_DC_TMEM_ADDR_WIDTH-1):0 +`define LM32_DC_DMEM_ADDR_WIDTH (addr_offset_width+addr_set_width) +`define LM32_DC_DMEM_ADDR_RNG (`LM32_DC_DMEM_ADDR_WIDTH-1):0 + +`define LM32_DC_TAGS_WIDTH (addr_tag_width+1) +`define LM32_DC_TAGS_RNG (`LM32_DC_TAGS_WIDTH-1):0 +`define LM32_DC_TAGS_TAG_RNG (`LM32_DC_TAGS_WIDTH-1):1 +`define LM32_DC_TAGS_VALID_RNG 0 + +`define LM32_DC_STATE_RNG 2:0 +`define LM32_DC_STATE_FLUSH 3'b001 +`define LM32_DC_STATE_CHECK 3'b010 +`define LM32_DC_STATE_REFILL 3'b100 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_dcache ( + // ----- Inputs ----- + clk_i, + rst_i, + stall_a, + stall_x, + stall_m, + address_x, + address_m, + load_q_m, + store_q_m, + store_data, + store_byte_select, + refill_ready, + refill_data, + dflush, + // ----- Outputs ----- + stall_request, + restart_request, + refill_request, + refill_address, + refilling, + load_data + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter associativity = 1; // Associativity of the cache (Number of ways) +parameter sets = 512; // Number of sets +parameter bytes_per_line = 16; // Number of bytes per cache line +parameter base_address = 0; // Base address of cachable memory +parameter limit = 0; // Limit (highest address) of cachable memory + +//localparam addr_offset_width = clogb2(bytes_per_line)-1-2; +localparam addr_offset_width = 2; +//localparam addr_set_width = clogb2(sets)-1; +localparam addr_set_width = 9; +localparam addr_offset_lsb = 2; +localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1); +localparam addr_set_lsb = (addr_offset_msb+1); +localparam addr_set_msb = (addr_set_lsb+addr_set_width-1); +localparam addr_tag_lsb = (addr_set_msb+1); +localparam addr_tag_msb = 31; +localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input stall_a; // Stall A stage +input stall_x; // Stall X stage +input stall_m; // Stall M stage + +input [`LM32_WORD_RNG] address_x; // X stage load/store address +input [`LM32_WORD_RNG] address_m; // M stage load/store address +input load_q_m; // Load instruction in M stage +input store_q_m; // Store instruction in M stage +input [`LM32_WORD_RNG] store_data; // Data to store +input [`LM32_BYTE_SELECT_RNG] store_byte_select; // Which bytes in store data should be modified + +input refill_ready; // Indicates next word of refill data is ready +input [`LM32_WORD_RNG] refill_data; // Refill data + +input dflush; // Indicates cache should be flushed + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output stall_request; // Request pipeline be stalled because cache is busy +wire stall_request; +output restart_request; // Request to restart instruction that caused the cache miss +reg restart_request; +output refill_request; // Request a refill +reg refill_request; +output [`LM32_WORD_RNG] refill_address; // Address to refill from +reg [`LM32_WORD_RNG] refill_address; +output refilling; // Indicates if the cache is currently refilling +reg refilling; +output [`LM32_WORD_RNG] load_data; // Data read from cache +wire [`LM32_WORD_RNG] load_data; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire read_port_enable; // Cache memory read port clock enable +wire write_port_enable; // Cache memory write port clock enable +wire [0:associativity-1] way_tmem_we; // Tag memory write enable +wire [0:associativity-1] way_dmem_we; // Data memory write enable +wire [`LM32_WORD_RNG] way_data[0:associativity-1]; // Data read from data memory +wire [`LM32_DC_TAGS_TAG_RNG] way_tag[0:associativity-1];// Tag read from tag memory +wire [0:associativity-1] way_valid; // Indicates which ways are valid +wire [0:associativity-1] way_match; // Indicates which ways matched +wire miss; // Indicates no ways matched + +wire [`LM32_DC_TMEM_ADDR_RNG] tmem_read_address; // Tag memory read address +wire [`LM32_DC_TMEM_ADDR_RNG] tmem_write_address; // Tag memory write address +wire [`LM32_DC_DMEM_ADDR_RNG] dmem_read_address; // Data memory read address +wire [`LM32_DC_DMEM_ADDR_RNG] dmem_write_address; // Data memory write address +wire [`LM32_DC_TAGS_RNG] tmem_write_data; // Tag memory write data +reg [`LM32_WORD_RNG] dmem_write_data; // Data memory write data + +reg [`LM32_DC_STATE_RNG] state; // Current state of FSM +wire flushing; // Indicates if cache is currently flushing +wire check; // Indicates if cache is currently checking for hits/misses +wire refill; // Indicates if cache is currently refilling + +wire valid_store; // Indicates if there is a valid store instruction +reg [associativity-1:0] refill_way_select; // Which way should be refilled +reg [`LM32_DC_ADDR_OFFSET_RNG] refill_offset; // Which word in cache line should be refilled +wire last_refill; // Indicates when on last cycle of cache refill +reg [`LM32_DC_TMEM_ADDR_RNG] flush_set; // Which set is currently being flushed + +genvar i, j; + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +generate + for (i = 0; i < associativity; i = i + 1) + begin : memories +// Way data + + if (`LM32_DC_DMEM_ADDR_WIDTH < 7) + begin : data_memories +lm32_ram #( + // ----- Parameters ------- + .data_width (32), + .address_width (`LM32_DC_DMEM_ADDR_WIDTH) + ) way_0_data_ram ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .read_address (dmem_read_address), + .enable_read (read_port_enable), + .write_address (dmem_write_address), + .enable_write (write_port_enable), + .write_enable (way_dmem_we[i]), + .write_data (dmem_write_data), + // ----- Outputs ------- + .read_data (way_data[i]) + ); + end + else + begin + for (j = 0; j < 4; j = j + 1) + begin : byte_memories +lm32_ram #( + // ----- Parameters ------- + .data_width (8), + .address_width (`LM32_DC_DMEM_ADDR_WIDTH) + ) way_0_data_ram ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .read_address (dmem_read_address), + .enable_read (read_port_enable), + .write_address (dmem_write_address), + .enable_write (write_port_enable), + .write_enable (way_dmem_we[i] & (store_byte_select[j] | refill)), + .write_data (dmem_write_data[(j+1)*8-1:j*8]), + // ----- Outputs ------- + .read_data (way_data[i][(j+1)*8-1:j*8]) + ); + end + end + +// Way tags +lm32_ram #( + // ----- Parameters ------- + .data_width (`LM32_DC_TAGS_WIDTH), + .address_width (`LM32_DC_TMEM_ADDR_WIDTH) + ) way_0_tag_ram ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .read_address (tmem_read_address), + .enable_read (read_port_enable), + .write_address (tmem_write_address), + .enable_write (`TRUE), + .write_enable (way_tmem_we[i]), + .write_data (tmem_write_data), + // ----- Outputs ------- + .read_data ({way_tag[i], way_valid[i]}) + ); + + end + +endgenerate + +///////////////////////////////////////////////////// +// Combinational logic +///////////////////////////////////////////////////// + +// Compute which ways in the cache match the address being read +generate + for (i = 0; i < associativity; i = i + 1) + begin : match +assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE}); + end +endgenerate + +// Select data from way that matched the address being read +generate + if (associativity == 1) + begin : data_1 +assign load_data = way_data[0]; + end + else if (associativity == 2) + begin : data_2 +assign load_data = way_match[0] ? way_data[0] : way_data[1]; + end +endgenerate + +generate + if (`LM32_DC_DMEM_ADDR_WIDTH < 7) + begin +// Select data to write to data memories +always @(*) +begin + if (refill == `TRUE) + dmem_write_data = refill_data; + else + begin + dmem_write_data[`LM32_BYTE_0_RNG] = store_byte_select[0] ? store_data[`LM32_BYTE_0_RNG] : load_data[`LM32_BYTE_0_RNG]; + dmem_write_data[`LM32_BYTE_1_RNG] = store_byte_select[1] ? store_data[`LM32_BYTE_1_RNG] : load_data[`LM32_BYTE_1_RNG]; + dmem_write_data[`LM32_BYTE_2_RNG] = store_byte_select[2] ? store_data[`LM32_BYTE_2_RNG] : load_data[`LM32_BYTE_2_RNG]; + dmem_write_data[`LM32_BYTE_3_RNG] = store_byte_select[3] ? store_data[`LM32_BYTE_3_RNG] : load_data[`LM32_BYTE_3_RNG]; + end +end + end + else + begin +// Select data to write to data memories - FIXME: Should use different write ports on dual port RAMs, but they don't work +always @(*) +begin + if (refill == `TRUE) + dmem_write_data = refill_data; + else + dmem_write_data = store_data; +end + end +endgenerate + +// Compute address to use to index into the data memories +generate + if (bytes_per_line > 4) +assign dmem_write_address = (refill == `TRUE) + ? {refill_address[`LM32_DC_ADDR_SET_RNG], refill_offset} + : address_m[`LM32_DC_ADDR_IDX_RNG]; + else +assign dmem_write_address = (refill == `TRUE) + ? refill_address[`LM32_DC_ADDR_SET_RNG] + : address_m[`LM32_DC_ADDR_IDX_RNG]; +endgenerate +assign dmem_read_address = address_x[`LM32_DC_ADDR_IDX_RNG]; +// Compute address to use to index into the tag memories +assign tmem_write_address = (flushing == `TRUE) + ? flush_set + : refill_address[`LM32_DC_ADDR_SET_RNG]; +assign tmem_read_address = address_x[`LM32_DC_ADDR_SET_RNG]; + +// Compute signal to indicate when we are on the last refill accesses +generate + if (bytes_per_line > 4) +assign last_refill = refill_offset == {addr_offset_width{1'b1}}; + else +assign last_refill = `TRUE; +endgenerate + +// Compute data and tag memory access enable +assign read_port_enable = (stall_x == `FALSE); +assign write_port_enable = (refill_ready == `TRUE) || !stall_m; + +// Determine when we have a valid store +assign valid_store = (store_q_m == `TRUE) && (check == `TRUE); + +// Compute data and tag memory write enables +generate + if (associativity == 1) + begin : we_1 +assign way_dmem_we[0] = (refill_ready == `TRUE) || ((valid_store == `TRUE) && (way_match[0] == `TRUE)); +assign way_tmem_we[0] = (refill_ready == `TRUE) || (flushing == `TRUE); + end + else + begin : we_2 +assign way_dmem_we[0] = ((refill_ready == `TRUE) && (refill_way_select[0] == `TRUE)) || ((valid_store == `TRUE) && (way_match[0] == `TRUE)); +assign way_dmem_we[1] = ((refill_ready == `TRUE) && (refill_way_select[1] == `TRUE)) || ((valid_store == `TRUE) && (way_match[1] == `TRUE)); +assign way_tmem_we[0] = ((refill_ready == `TRUE) && (refill_way_select[0] == `TRUE)) || (flushing == `TRUE); +assign way_tmem_we[1] = ((refill_ready == `TRUE) && (refill_way_select[1] == `TRUE)) || (flushing == `TRUE); + end +endgenerate + +// On the last refill cycle set the valid bit, for all other writes it should be cleared +assign tmem_write_data[`LM32_DC_TAGS_VALID_RNG] = ((last_refill == `TRUE) || (valid_store == `TRUE)) && (flushing == `FALSE); +assign tmem_write_data[`LM32_DC_TAGS_TAG_RNG] = refill_address[`LM32_DC_ADDR_TAG_RNG]; + +// Signals that indicate which state we are in +assign flushing = state[0]; +assign check = state[1]; +assign refill = state[2]; + +assign miss = (~(|way_match)) && (load_q_m == `TRUE) && (stall_m == `FALSE); +assign stall_request = (check == `FALSE); + +///////////////////////////////////////////////////// +// Sequential logic +///////////////////////////////////////////////////// + +// Record way selected for replacement on a cache miss +generate + if (associativity >= 2) + begin : way_select +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + refill_way_select <= {{associativity-1{1'b0}}, 1'b1}; + else + begin + if (refill_request == `TRUE) + refill_way_select <= {refill_way_select[0], refill_way_select[1]}; + end +end + end +endgenerate + +// Record whether we are currently refilling +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + refilling <= `FALSE; + else + refilling <= refill; +end + +// Instruction cache control FSM +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + state <= `LM32_DC_STATE_FLUSH; + flush_set <= {`LM32_DC_TMEM_ADDR_WIDTH{1'b1}}; + refill_request <= `FALSE; + refill_address <= {`LM32_WORD_WIDTH{1'bx}}; + restart_request <= `FALSE; + end + else + begin + case (state) + + // Flush the cache + `LM32_DC_STATE_FLUSH: + begin + if (flush_set == {`LM32_DC_TMEM_ADDR_WIDTH{1'b0}}) + state <= `LM32_DC_STATE_CHECK; + flush_set <= flush_set - 1'b1; + end + + // Check for cache misses + `LM32_DC_STATE_CHECK: + begin + if (stall_a == `FALSE) + restart_request <= `FALSE; + if (miss == `TRUE) + begin + refill_request <= `TRUE; + refill_address <= address_m; + state <= `LM32_DC_STATE_REFILL; + end + else if (dflush == `TRUE) + state <= `LM32_DC_STATE_FLUSH; + end + + // Refill a cache line + `LM32_DC_STATE_REFILL: + begin + refill_request <= `FALSE; + if (refill_ready == `TRUE) + begin + if (last_refill == `TRUE) + begin + restart_request <= `TRUE; + state <= `LM32_DC_STATE_CHECK; + end + end + end + + endcase + end +end + +generate + if (bytes_per_line > 4) + begin +// Refill offset +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + refill_offset <= {addr_offset_width{1'b0}}; + else + begin + case (state) + + // Check for cache misses + `LM32_DC_STATE_CHECK: + begin + if (miss == `TRUE) + refill_offset <= {addr_offset_width{1'b0}}; + end + + // Refill a cache line + `LM32_DC_STATE_REFILL: + begin + if (refill_ready == `TRUE) + refill_offset <= refill_offset + 1'b1; + end + + endcase + end +end + end +endgenerate + +endmodule + +`endif + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_debug.v b/lm32/logic/sakc/rtl/lm32/lm32_debug.v new file mode 100644 index 0000000..0092e2c --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_debug.v @@ -0,0 +1,340 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_debug.v +// Title : Hardware debug registers and associated logic. +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +`ifdef CFG_DEBUG_ENABLED + +// States for single-step FSM +`define LM32_DEBUG_SS_STATE_RNG 2:0 +`define LM32_DEBUG_SS_STATE_IDLE 3'b000 +`define LM32_DEBUG_SS_STATE_WAIT_FOR_RET 3'b001 +`define LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN 3'b010 +`define LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT 3'b011 +`define LM32_DEBUG_SS_STATE_RESTART 3'b100 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_debug ( + // ----- Inputs ------- + clk_i, + rst_i, + pc_x, + load_x, + store_x, + load_store_address_x, + csr_write_enable_x, + csr_write_data, + csr_x, +`ifdef CFG_HW_DEBUG_ENABLED + jtag_csr_write_enable, + jtag_csr_write_data, + jtag_csr, +`endif +`ifdef LM32_SINGLE_STEP_ENABLED + eret_q_x, + bret_q_x, + stall_x, + exception_x, + q_x, +`ifdef CFG_DCACHE_ENABLED + dcache_refill_request, +`endif +`endif + // ----- Outputs ------- +`ifdef LM32_SINGLE_STEP_ENABLED + dc_ss, +`endif + dc_re, + bp_match, + wp_match + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter breakpoints = 0; // Number of breakpoint CSRs +parameter watchpoints = 0; // Number of watchpoint CSRs + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input [`LM32_PC_RNG] pc_x; // X stage PC +input load_x; // Load instruction in X stage +input store_x; // Store instruction in X stage +input [`LM32_WORD_RNG] load_store_address_x; // Load or store effective address +input csr_write_enable_x; // wcsr instruction in X stage +input [`LM32_WORD_RNG] csr_write_data; // Data to write to CSR +input [`LM32_CSR_RNG] csr_x; // Which CSR to write +`ifdef CFG_HW_DEBUG_ENABLED +input jtag_csr_write_enable; // JTAG interface CSR write enable +input [`LM32_WORD_RNG] jtag_csr_write_data; // Data to write to CSR +input [`LM32_CSR_RNG] jtag_csr; // Which CSR to write +`endif +`ifdef LM32_SINGLE_STEP_ENABLED +input eret_q_x; // eret instruction in X stage +input bret_q_x; // bret instruction in X stage +input stall_x; // Instruction in X stage is stalled +input exception_x; // An exception has occured in X stage +input q_x; // Indicates the instruction in the X stage is qualified +`ifdef CFG_DCACHE_ENABLED +input dcache_refill_request; // Indicates data cache wants to be refilled +`endif +`endif + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +`ifdef LM32_SINGLE_STEP_ENABLED +output dc_ss; // Single-step enable +reg dc_ss; +`endif +output dc_re; // Remap exceptions +reg dc_re; +output bp_match; // Indicates a breakpoint has matched +wire bp_match; +output wp_match; // Indicates a watchpoint has matched +wire wp_match; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +genvar i; // Loop index for generate statements + +// Debug CSRs + +reg [`LM32_PC_RNG] bp_a[0:breakpoints-1]; // Instruction breakpoint address +reg bp_e[0:breakpoints-1]; // Instruction breakpoint enable +wire [0:breakpoints-1]bp_match_n; // Indicates if a h/w instruction breakpoint matched + +reg [`LM32_WPC_C_RNG] wpc_c[0:watchpoints-1]; // Watchpoint enable +reg [`LM32_WORD_RNG] wp[0:watchpoints-1]; // Watchpoint address +wire [0:watchpoints-1]wp_match_n; // Indicates if a h/w data watchpoint matched + +wire debug_csr_write_enable; // Debug CSR write enable (from either a wcsr instruction of external debugger) +wire [`LM32_WORD_RNG] debug_csr_write_data; // Data to write to debug CSR +wire [`LM32_CSR_RNG] debug_csr; // Debug CSR to write to + +`ifdef LM32_SINGLE_STEP_ENABLED +// FIXME: Declaring this as a reg causes ModelSim 6.1.15b to crash, so use integer for now +//reg [`LM32_DEBUG_SS_STATE_RNG] state; // State of single-step FSM +integer state; // State of single-step FSM +`endif + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +// Check for breakpoints +generate + for (i = 0; i < breakpoints; i = i + 1) + begin : bp_comb +assign bp_match_n[i] = ((bp_a[i] == pc_x) && (bp_e[i] == `TRUE)); + end +endgenerate +generate +`ifdef LM32_SINGLE_STEP_ENABLED + if (breakpoints > 0) +assign bp_match = (|bp_match_n) || (state == `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT); + else +assign bp_match = state == `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT; +`else + if (breakpoints > 0) +assign bp_match = |bp_match_n; + else +assign bp_match = `FALSE; +`endif +endgenerate + +// Check for watchpoints +generate + for (i = 0; i < watchpoints; i = i + 1) + begin : wp_comb +assign wp_match_n[i] = (wp[i] == load_store_address_x) && ((load_x & wpc_c[i][0]) | (store_x & wpc_c[i][1])); + end +endgenerate +generate + if (watchpoints > 0) +assign wp_match = |wp_match_n; + else +assign wp_match = `FALSE; +endgenerate + +`ifdef CFG_HW_DEBUG_ENABLED +// Multiplex between wcsr instruction writes and debugger writes to the debug CSRs +assign debug_csr_write_enable = (csr_write_enable_x == `TRUE) || (jtag_csr_write_enable == `TRUE); +assign debug_csr_write_data = jtag_csr_write_enable == `TRUE ? jtag_csr_write_data : csr_write_data; +assign debug_csr = jtag_csr_write_enable == `TRUE ? jtag_csr : csr_x; +`else +assign debug_csr_write_enable = csr_write_enable_x; +assign debug_csr_write_data = csr_write_data; +assign debug_csr = csr_x; +`endif + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +// Breakpoint address and enable CSRs +generate + for (i = 0; i < breakpoints; i = i + 1) + begin : bp_seq +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + bp_a[i] <= {`LM32_PC_WIDTH{1'bx}}; + bp_e[i] <= `FALSE; + end + else + begin + if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_BP0 + i)) + begin + bp_a[i] <= debug_csr_write_data[`LM32_PC_RNG]; + bp_e[i] <= debug_csr_write_data[0]; + end + end +end + end +endgenerate + +// Watchpoint address and control flags CSRs +generate + for (i = 0; i < watchpoints; i = i + 1) + begin : wp_seq +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + wp[i] <= {`LM32_WORD_WIDTH{1'bx}}; + wpc_c[i] <= `LM32_WPC_C_DISABLED; + end + else + begin + if (debug_csr_write_enable == `TRUE) + begin + if (debug_csr == `LM32_CSR_DC) + wpc_c[i] <= debug_csr_write_data[3+i*2:2+i*2]; + if (debug_csr == `LM32_CSR_WP0 + i) + wp[i] <= debug_csr_write_data; + end + end +end + end +endgenerate + +// Remap exceptions control bit +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + dc_re <= `FALSE; + else + begin + if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_DC)) + dc_re <= debug_csr_write_data[1]; + end +end + +`ifdef LM32_SINGLE_STEP_ENABLED +// Single-step control flag +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + state <= `LM32_DEBUG_SS_STATE_IDLE; + dc_ss <= `FALSE; + end + else + begin + if ((debug_csr_write_enable == `TRUE) && (debug_csr == `LM32_CSR_DC)) + begin + dc_ss <= debug_csr_write_data[0]; + if (debug_csr_write_data[0] == `FALSE) + state <= `LM32_DEBUG_SS_STATE_IDLE; + else + state <= `LM32_DEBUG_SS_STATE_WAIT_FOR_RET; + end + case (state) + `LM32_DEBUG_SS_STATE_WAIT_FOR_RET: + begin + // Wait for eret or bret instruction to be executed + if ( ( (eret_q_x == `TRUE) + || (bret_q_x == `TRUE) + ) + && (stall_x == `FALSE) + ) + state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN; + end + `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN: + begin + // Wait for an instruction to be executed + if ((q_x == `TRUE) && (stall_x == `FALSE)) + state <= `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT; + end + `LM32_DEBUG_SS_STATE_RAISE_BREAKPOINT: + begin + // Wait for exception to be raised +`ifdef CFG_DCACHE_ENABLED + if (dcache_refill_request == `TRUE) + state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN; + else +`endif + if ((exception_x == `TRUE) && (q_x == `TRUE) && (stall_x == `FALSE)) + begin + dc_ss <= `FALSE; + state <= `LM32_DEBUG_SS_STATE_RESTART; + end + end + `LM32_DEBUG_SS_STATE_RESTART: + begin + // Watch to see if stepped instruction is restarted due to a cache miss +`ifdef CFG_DCACHE_ENABLED + if (dcache_refill_request == `TRUE) + state <= `LM32_DEBUG_SS_STATE_EXECUTE_ONE_INSN; + else +`endif + state <= `LM32_DEBUG_SS_STATE_IDLE; + end + endcase + end +end +`endif + +endmodule + +`endif diff --git a/lm32/logic/sakc/rtl/lm32/lm32_decoder.v b/lm32/logic/sakc/rtl/lm32/lm32_decoder.v new file mode 100644 index 0000000..8376d66 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_decoder.v @@ -0,0 +1,564 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_decoder.v +// Title : Instruction decoder +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +// Index of opcode field in an instruction +`define LM32_OPCODE_RNG 31:26 +`define LM32_OP_RNG 30:26 + +// Opcodes - Some are only listed as 5 bits as their MSB is a don't care +`define LM32_OPCODE_ADD 5'b01101 +`define LM32_OPCODE_AND 5'b01000 +`define LM32_OPCODE_ANDHI 6'b011000 +`define LM32_OPCODE_B 6'b110000 +`define LM32_OPCODE_BI 6'b111000 +`define LM32_OPCODE_BE 6'b010001 +`define LM32_OPCODE_BG 6'b010010 +`define LM32_OPCODE_BGE 6'b010011 +`define LM32_OPCODE_BGEU 6'b010100 +`define LM32_OPCODE_BGU 6'b010101 +`define LM32_OPCODE_BNE 6'b010111 +`define LM32_OPCODE_CALL 6'b110110 +`define LM32_OPCODE_CALLI 6'b111110 +`define LM32_OPCODE_CMPE 5'b11001 +`define LM32_OPCODE_CMPG 5'b11010 +`define LM32_OPCODE_CMPGE 5'b11011 +`define LM32_OPCODE_CMPGEU 5'b11100 +`define LM32_OPCODE_CMPGU 5'b11101 +`define LM32_OPCODE_CMPNE 5'b11111 +`define LM32_OPCODE_DIVU 6'b100011 +`define LM32_OPCODE_LB 6'b000100 +`define LM32_OPCODE_LBU 6'b010000 +`define LM32_OPCODE_LH 6'b000111 +`define LM32_OPCODE_LHU 6'b001011 +`define LM32_OPCODE_LW 6'b001010 +`define LM32_OPCODE_MODU 6'b110001 +`define LM32_OPCODE_MUL 5'b00010 +`define LM32_OPCODE_NOR 5'b00001 +`define LM32_OPCODE_OR 5'b01110 +`define LM32_OPCODE_ORHI 6'b011110 +`define LM32_OPCODE_RAISE 6'b101011 +`define LM32_OPCODE_RCSR 6'b100100 +`define LM32_OPCODE_SB 6'b001100 +`define LM32_OPCODE_SEXTB 6'b101100 +`define LM32_OPCODE_SEXTH 6'b110111 +`define LM32_OPCODE_SH 6'b000011 +`define LM32_OPCODE_SL 5'b01111 +`define LM32_OPCODE_SR 5'b00101 +`define LM32_OPCODE_SRU 5'b00000 +`define LM32_OPCODE_SUB 6'b110010 +`define LM32_OPCODE_SW 6'b010110 +`define LM32_OPCODE_USER 6'b110011 +`define LM32_OPCODE_WCSR 6'b110100 +`define LM32_OPCODE_XNOR 5'b01001 +`define LM32_OPCODE_XOR 5'b00110 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_decoder ( + // ----- Inputs ------- + instruction, + // ----- Outputs ------- + d_result_sel_0, + d_result_sel_1, + x_result_sel_csr, +`ifdef LM32_MC_ARITHMETIC_ENABLED + x_result_sel_mc_arith, +`endif +`ifdef LM32_NO_BARREL_SHIFT + x_result_sel_shift, +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + x_result_sel_sext, +`endif + x_result_sel_logic, +`ifdef CFG_USER_ENABLED + x_result_sel_user, +`endif + x_result_sel_add, + m_result_sel_compare, +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + m_result_sel_shift, +`endif + w_result_sel_load, +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul, +`endif + x_bypass_enable, + m_bypass_enable, + read_enable_0, + read_idx_0, + read_enable_1, + read_idx_1, + write_enable, + write_idx, + immediate, + branch_offset, + load, + store, + size, + sign_extend, + adder_op, + logic_op, +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + direction, +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + shift_left, + shift_right, +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + multiply, +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + divide, + modulus, +`endif + branch, + branch_reg, + condition, +`ifdef CFG_DEBUG_ENABLED + break, +`endif + scall, + eret, +`ifdef CFG_DEBUG_ENABLED + bret, +`endif +`ifdef CFG_USER_ENABLED + user_opcode, +`endif + csr_write_enable + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input [`LM32_INSTRUCTION_RNG] instruction; // Instruction to decode + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0; +reg [`LM32_D_RESULT_SEL_0_RNG] d_result_sel_0; +output [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1; +reg [`LM32_D_RESULT_SEL_1_RNG] d_result_sel_1; +output x_result_sel_csr; +reg x_result_sel_csr; +`ifdef LM32_MC_ARITHMETIC_ENABLED +output x_result_sel_mc_arith; +reg x_result_sel_mc_arith; +`endif +`ifdef LM32_NO_BARREL_SHIFT +output x_result_sel_shift; +reg x_result_sel_shift; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED +output x_result_sel_sext; +reg x_result_sel_sext; +`endif +output x_result_sel_logic; +reg x_result_sel_logic; +`ifdef CFG_USER_ENABLED +output x_result_sel_user; +reg x_result_sel_user; +`endif +output x_result_sel_add; +reg x_result_sel_add; +output m_result_sel_compare; +reg m_result_sel_compare; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +output m_result_sel_shift; +reg m_result_sel_shift; +`endif +output w_result_sel_load; +reg w_result_sel_load; +`ifdef CFG_PL_MULTIPLY_ENABLED +output w_result_sel_mul; +reg w_result_sel_mul; +`endif +output x_bypass_enable; +wire x_bypass_enable; +output m_bypass_enable; +wire m_bypass_enable; +output read_enable_0; +wire read_enable_0; +output [`LM32_REG_IDX_RNG] read_idx_0; +wire [`LM32_REG_IDX_RNG] read_idx_0; +output read_enable_1; +wire read_enable_1; +output [`LM32_REG_IDX_RNG] read_idx_1; +wire [`LM32_REG_IDX_RNG] read_idx_1; +output write_enable; +wire write_enable; +output [`LM32_REG_IDX_RNG] write_idx; +wire [`LM32_REG_IDX_RNG] write_idx; +output [`LM32_WORD_RNG] immediate; +wire [`LM32_WORD_RNG] immediate; +output [`LM32_PC_RNG] branch_offset; +wire [`LM32_PC_RNG] branch_offset; +output load; +wire load; +output store; +wire store; +output [`LM32_SIZE_RNG] size; +wire [`LM32_SIZE_RNG] size; +output sign_extend; +wire sign_extend; +output adder_op; +wire adder_op; +output [`LM32_LOGIC_OP_RNG] logic_op; +wire [`LM32_LOGIC_OP_RNG] logic_op; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +output direction; +wire direction; +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +output shift_left; +wire shift_left; +output shift_right; +wire shift_right; +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED +output multiply; +wire multiply; +`endif +`ifdef CFG_MC_DIVIDE_ENABLED +output divide; +wire divide; +output modulus; +wire modulus; +`endif +output branch; +wire branch; +output branch_reg; +wire branch_reg; +output [`LM32_CONDITION_RNG] condition; +wire [`LM32_CONDITION_RNG] condition; +`ifdef CFG_DEBUG_ENABLED +output break; +wire break; +`endif +output scall; +wire scall; +output eret; +wire eret; +`ifdef CFG_DEBUG_ENABLED +output bret; +wire bret; +`endif +`ifdef CFG_USER_ENABLED +output [`LM32_USER_OPCODE_RNG] user_opcode; +wire [`LM32_USER_OPCODE_RNG] user_opcode; +`endif +output csr_write_enable; +wire csr_write_enable; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire [`LM32_WORD_RNG] extended_immediate; // Zero or sign extended immediate +wire [`LM32_WORD_RNG] high_immediate; // Immediate as high 16 bits +wire [`LM32_WORD_RNG] call_immediate; // Call immediate +wire [`LM32_WORD_RNG] branch_immediate; // Conditional branch immediate +wire sign_extend_immediate; // Whether the immediate should be sign extended (`TRUE) or zero extended (`FALSE) +wire select_high_immediate; // Whether to select the high immediate +wire select_call_immediate; // Whether to select the call immediate + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Combinational logic +///////////////////////////////////////////////////// + +// Determine opcode +wire op_add = instruction[`LM32_OP_RNG] == `LM32_OPCODE_ADD; +wire op_and = instruction[`LM32_OP_RNG] == `LM32_OPCODE_AND; +wire op_andhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ANDHI; +wire op_b = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_B; +wire op_bi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BI; +wire op_be = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BE; +wire op_bg = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BG; +wire op_bge = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGE; +wire op_bgeu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGEU; +wire op_bgu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BGU; +wire op_bne = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_BNE; +wire op_call = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALL; +wire op_calli = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_CALLI; +wire op_cmpe = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPE; +wire op_cmpg = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPG; +wire op_cmpge = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGE; +wire op_cmpgeu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGEU; +wire op_cmpgu = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPGU; +wire op_cmpne = instruction[`LM32_OP_RNG] == `LM32_OPCODE_CMPNE; +`ifdef CFG_MC_DIVIDE_ENABLED +wire op_divu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_DIVU; +`endif +wire op_lb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LB; +wire op_lbu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LBU; +wire op_lh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LH; +wire op_lhu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LHU; +wire op_lw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_LW; +`ifdef CFG_MC_DIVIDE_ENABLED +wire op_modu = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_MODU; +`endif +`ifdef LM32_MULTIPLY_ENABLED +wire op_mul = instruction[`LM32_OP_RNG] == `LM32_OPCODE_MUL; +`endif +wire op_nor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_NOR; +wire op_or = instruction[`LM32_OP_RNG] == `LM32_OPCODE_OR; +wire op_orhi = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_ORHI; +wire op_raise = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RAISE; +wire op_rcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_RCSR; +wire op_sb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SB; +`ifdef CFG_SIGN_EXTEND_ENABLED +wire op_sextb = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTB; +wire op_sexth = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SEXTH; +`endif +wire op_sh = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SH; +`ifdef LM32_BARREL_SHIFT_ENABLED +wire op_sl = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SL; +`endif +wire op_sr = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SR; +wire op_sru = instruction[`LM32_OP_RNG] == `LM32_OPCODE_SRU; +wire op_sub = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SUB; +wire op_sw = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_SW; +wire op_user = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_USER; +wire op_wcsr = instruction[`LM32_OPCODE_RNG] == `LM32_OPCODE_WCSR; +wire op_xnor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XNOR; +wire op_xor = instruction[`LM32_OP_RNG] == `LM32_OPCODE_XOR; + +// Group opcodes by function +wire arith = op_add | op_sub; +wire logicc = op_and | op_andhi | op_nor | op_or | op_orhi | op_xor | op_xnor; +wire cmp = op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne; +wire bra = op_b | op_bi | op_be | op_bg | op_bge | op_bgeu | op_bgu | op_bne; +wire call = op_call | op_calli; +`ifdef LM32_BARREL_SHIFT_ENABLED +wire shift = op_sl | op_sr | op_sru; +`endif +`ifdef LM32_NO_BARREL_SHIFT +wire shift = op_sr | op_sru; +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +assign shift_left = op_sl; +assign shift_right = op_sr | op_sru; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED +wire sext = op_sextb | op_sexth; +`endif +`ifdef LM32_MULTIPLY_ENABLED +wire multiply = op_mul; +`endif +`ifdef CFG_MC_DIVIDE_ENABLED +assign divide = op_divu; +assign modulus = op_modu; +`endif +assign load = op_lb | op_lbu | op_lh | op_lhu | op_lw; +assign store = op_sb | op_sh | op_sw; + +// Select pipeline multiplexor controls +always @* +begin + // D stage + if (call) + d_result_sel_0 = `LM32_D_RESULT_SEL_0_NEXT_PC; + else + d_result_sel_0 = `LM32_D_RESULT_SEL_0_REG_0; + if (call) + d_result_sel_1 = `LM32_D_RESULT_SEL_1_ZERO; + else if ((instruction[31] == 1'b0) && !bra) + d_result_sel_1 = `LM32_D_RESULT_SEL_1_IMMEDIATE; + else + d_result_sel_1 = `LM32_D_RESULT_SEL_1_REG_1; + // X stage + x_result_sel_csr = `FALSE; +`ifdef LM32_MC_ARITHMETIC_ENABLED + x_result_sel_mc_arith = `FALSE; +`endif +`ifdef LM32_NO_BARREL_SHIFT + x_result_sel_shift = `FALSE; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + x_result_sel_sext = `FALSE; +`endif + x_result_sel_logic = `FALSE; +`ifdef CFG_USER_ENABLED + x_result_sel_user = `FALSE; +`endif + x_result_sel_add = `FALSE; + if (op_rcsr) + x_result_sel_csr = `TRUE; +`ifdef LM32_MC_ARITHMETIC_ENABLED +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + else if (shift_left | shift_right) + x_result_sel_mc_arith = `TRUE; +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + else if (divide | modulus) + x_result_sel_mc_arith = `TRUE; +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + else if (multiply) + x_result_sel_mc_arith = `TRUE; +`endif +`endif +`ifdef LM32_NO_BARREL_SHIFT + else if (shift) + x_result_sel_shift = `TRUE; +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + else if (sext) + x_result_sel_sext = `TRUE; +`endif + else if (logicc) + x_result_sel_logic = `TRUE; +`ifdef CFG_USER_ENABLED + else if (op_user) + x_result_sel_user = `TRUE; +`endif + else + x_result_sel_add = `TRUE; + + // M stage + + m_result_sel_compare = cmp; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + m_result_sel_shift = shift; +`endif + + // W stage + w_result_sel_load = load; +`ifdef CFG_PL_MULTIPLY_ENABLED + w_result_sel_mul = op_mul; +`endif +end + +// Set if result is valid at end of X stage +assign x_bypass_enable = arith + | logicc +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + | shift_left + | shift_right +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + | multiply +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + | divide + | modulus +`endif +`ifdef LM32_NO_BARREL_SHIFT + | shift +`endif +`ifdef CFG_SIGN_EXTEND_ENABLED + | sext +`endif +`ifdef CFG_USER_ENABLED + | op_user +`endif + | op_rcsr + ; +// Set if result is valid at end of M stage +assign m_bypass_enable = x_bypass_enable +`ifdef CFG_PL_BARREL_SHIFT_ENABLED + | shift +`endif + | cmp + ; +// Register file read port 0 +assign read_enable_0 = ~(op_bi | op_calli); +assign read_idx_0 = instruction[25:21]; +// Register file read port 1 +assign read_enable_1 = ~(op_bi | op_calli | load); +assign read_idx_1 = instruction[20:16]; +// Register file write port +assign write_enable = ~(bra | op_raise | store | op_wcsr); +assign write_idx = call + ? 5'd29 + : instruction[31] == 1'b0 + ? instruction[20:16] + : instruction[15:11]; + +// Size of load/stores +assign size = instruction[27:26]; +// Whether to sign or zero extend +assign sign_extend = instruction[28]; +// Set adder_op to 1 to perform a subtraction +assign adder_op = op_sub | op_cmpe | op_cmpg | op_cmpge | op_cmpgeu | op_cmpgu | op_cmpne | bra; +// Logic operation (and, or, etc) +assign logic_op = instruction[29:26]; +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +// Shift direction +assign direction = instruction[29]; +`endif +// Control flow microcodes +assign branch = bra | call; +assign branch_reg = op_call | op_b; +assign condition = instruction[28:26]; +`ifdef CFG_DEBUG_ENABLED +assign break = op_raise & ~instruction[2]; +`endif +assign scall = op_raise & instruction[2]; +assign eret = op_b & (instruction[25:21] == 5'd30); +`ifdef CFG_DEBUG_ENABLED +assign bret = op_b & (instruction[25:21] == 5'd31); +`endif +`ifdef CFG_USER_ENABLED +// Extract user opcode +assign user_opcode = instruction[10:0]; +`endif +// CSR read/write +assign csr_write_enable = op_wcsr; + +// Extract immediate from instruction + +assign sign_extend_immediate = ~(op_and | op_cmpgeu | op_cmpgu | op_nor | op_or | op_xnor | op_xor); +assign select_high_immediate = op_andhi | op_orhi; +assign select_call_immediate = instruction[31]; + +assign high_immediate = {instruction[15:0], 16'h0000}; +assign extended_immediate = {{16{sign_extend_immediate & instruction[15]}}, instruction[15:0]}; +assign call_immediate = {{6{instruction[25]}}, instruction[25:0]}; +assign branch_immediate = {{16{instruction[15]}}, instruction[15:0]}; + +assign immediate = select_high_immediate == `TRUE + ? high_immediate + : extended_immediate; + +assign branch_offset = select_call_immediate == `TRUE + ? call_immediate + : branch_immediate; + +endmodule + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_functions.v b/lm32/logic/sakc/rtl/lm32/lm32_functions.v new file mode 100644 index 0000000..85aff19 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_functions.v @@ -0,0 +1,29 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_functions.v +// Title : Common functions +// Version : 6.1.17 +// ============================================================================= + +function integer clogb2; +input [31:0] value; +begin + for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) + value = value >> 1; +end +endfunction diff --git a/lm32/logic/sakc/rtl/lm32/lm32_icache.v b/lm32/logic/sakc/rtl/lm32/lm32_icache.v new file mode 100644 index 0000000..ce5d96a --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_icache.v @@ -0,0 +1,428 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_icache.v +// Title : Instruction cache +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +`define LM32_IC_ADDR_OFFSET_RNG addr_offset_msb:addr_offset_lsb +`define LM32_IC_ADDR_SET_RNG addr_set_msb:addr_set_lsb +`define LM32_IC_ADDR_TAG_RNG addr_tag_msb:addr_tag_lsb +`define LM32_IC_ADDR_IDX_RNG addr_set_msb:addr_offset_lsb + +`define LM32_IC_TMEM_ADDR_WIDTH addr_set_width +`define LM32_IC_TMEM_ADDR_RNG (`LM32_IC_TMEM_ADDR_WIDTH-1):0 +`define LM32_IC_DMEM_ADDR_WIDTH (addr_offset_width+addr_set_width) +`define LM32_IC_DMEM_ADDR_RNG (`LM32_IC_DMEM_ADDR_WIDTH-1):0 + +`define LM32_IC_TAGS_WIDTH (addr_tag_width+1) +`define LM32_IC_TAGS_RNG (`LM32_IC_TAGS_WIDTH-1):0 +`define LM32_IC_TAGS_TAG_RNG (`LM32_IC_TAGS_WIDTH-1):1 +`define LM32_IC_TAGS_VALID_RNG 0 + +`define LM32_IC_STATE_RNG 3:0 +`define LM32_IC_STATE_FLUSH_INIT 4'b0001 +`define LM32_IC_STATE_FLUSH 4'b0010 +`define LM32_IC_STATE_CHECK 4'b0100 +`define LM32_IC_STATE_REFILL 4'b1000 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_icache ( + // ----- Inputs ----- + clk_i, + rst_i, + stall_a, + stall_f, + address_a, + address_f, + read_enable_f, + refill_ready, + refill_data, + iflush, + // ----- Outputs ----- + stall_request, + restart_request, + refill_request, + refill_address, + refilling, + inst + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter associativity = 1; // Associativity of the cache (Number of ways) +parameter sets = 512; // Number of sets +parameter bytes_per_line = 16; // Number of bytes per cache line +parameter base_address = 0; // Base address of cachable memory +parameter limit = 0; // Limit (highest address) of cachable memory + +localparam addr_offset_width = 2; +localparam addr_set_width = 9; +localparam addr_offset_lsb = 2; +localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1); +localparam addr_set_lsb = (addr_offset_msb+1); +localparam addr_set_msb = (addr_set_lsb+addr_set_width-1); +localparam addr_tag_lsb = (addr_set_msb+1); +localparam addr_tag_msb = 31; +localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input stall_a; // Stall instruction in A stage +input stall_f; // Stall instruction in F stage + +input [`LM32_PC_RNG] address_a; // Address of instruction in A stage +input [`LM32_PC_RNG] address_f; // Address of instruction in F stage +input read_enable_f; // Indicates if cache access is valid + +input refill_ready; // Next word of refill data is ready +input [`LM32_INSTRUCTION_RNG] refill_data; // Data to refill the cache with + +input iflush; // Flush the cache + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output stall_request; // Request to stall the pipeline +wire stall_request; +output restart_request; // Request to restart instruction that caused the cache miss +reg restart_request; +output refill_request; // Request to refill a cache line +wire refill_request; +output [`LM32_PC_RNG] refill_address; // Base address of cache refill +reg [`LM32_PC_RNG] refill_address; +output refilling; // Indicates the instruction cache is currently refilling +reg refilling; +output [`LM32_INSTRUCTION_RNG] inst; // Instruction read from cache +wire [`LM32_INSTRUCTION_RNG] inst; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire enable; +wire [0:associativity-1] way_mem_we; +wire [`LM32_INSTRUCTION_RNG] way_data[0:associativity-1]; +wire [`LM32_IC_TAGS_TAG_RNG] way_tag[0:associativity-1]; +wire [0:associativity-1] way_valid; +wire [0:associativity-1] way_match; +wire miss; + +wire [`LM32_IC_TMEM_ADDR_RNG] tmem_read_address; +wire [`LM32_IC_TMEM_ADDR_RNG] tmem_write_address; +wire [`LM32_IC_DMEM_ADDR_RNG] dmem_read_address; +wire [`LM32_IC_DMEM_ADDR_RNG] dmem_write_address; +wire [`LM32_IC_TAGS_RNG] tmem_write_data; + +reg [`LM32_IC_STATE_RNG] state; +wire flushing; +wire check; +wire refill; + +reg [associativity-1:0] refill_way_select; +reg [`LM32_IC_ADDR_OFFSET_RNG] refill_offset; +wire last_refill; +reg [`LM32_IC_TMEM_ADDR_RNG] flush_set; + +genvar i; + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +generate + for (i = 0; i < associativity; i = i + 1) + begin : memories + +// Way 0 data +lm32_ram #( + // ----- Parameters ------- + .data_width (32), + .address_width (`LM32_IC_DMEM_ADDR_WIDTH) + ) way_0_data_ram ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .read_address (dmem_read_address), + .enable_read (enable), + .write_address (dmem_write_address), + .enable_write (`TRUE), + .write_enable (way_mem_we[i]), + .write_data (refill_data), + // ----- Outputs ------- + .read_data (way_data[i]) + ); + +// Way 0 tags +lm32_ram #( + // ----- Parameters ------- + .data_width (`LM32_IC_TAGS_WIDTH), + .address_width (`LM32_IC_TMEM_ADDR_WIDTH) + ) way_0_tag_ram ( + // ----- Inputs ------- + .read_clk (clk_i), + .write_clk (clk_i), + .reset (rst_i), + .read_address (tmem_read_address), + .enable_read (enable), + .write_address (tmem_write_address), + .enable_write (`TRUE), + .write_enable (way_mem_we[i] | flushing), + .write_data (tmem_write_data), + // ----- Outputs ------- + .read_data ({way_tag[i], way_valid[i]}) + ); + + end +endgenerate + +///////////////////////////////////////////////////// +// Combinational logic +///////////////////////////////////////////////////// + +// Compute which ways in the cache match the address address being read +generate + for (i = 0; i < associativity; i = i + 1) + begin : match +assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE}); + end +endgenerate + +// Select data from way that matched the address being read +generate + if (associativity == 1) + begin : inst_1 +assign inst = way_data[0]; + end + else if (associativity == 2) + begin : inst_2 +assign inst = way_match[0] ? way_data[0] : way_data[1]; + end +endgenerate + +// Compute address to use to index into the data memories +generate + if (bytes_per_line > 4) + begin : wadr1 +assign dmem_write_address = {refill_address[`LM32_IC_ADDR_SET_RNG], refill_offset}; + end + else + begin : wadr2 +assign dmem_write_address = refill_address[`LM32_IC_ADDR_SET_RNG]; + end +endgenerate + +assign dmem_read_address = address_a[`LM32_IC_ADDR_IDX_RNG]; + +// Compute address to use to index into the tag memories +assign tmem_read_address = address_a[`LM32_IC_ADDR_SET_RNG]; +assign tmem_write_address = flushing + ? flush_set + : refill_address[`LM32_IC_ADDR_SET_RNG]; + +// Compute signal to indicate when we are on the last refill accesses +generate + if (bytes_per_line > 4) + begin : lrefil1 +assign last_refill = refill_offset == {addr_offset_width{1'b1}}; + end + else + begin : lrefil2 +assign last_refill = `TRUE; + end +endgenerate + +// Compute data and tag memory access enable +assign enable = (stall_a == `FALSE); + +// Compute data and tag memory write enables +generate + if (associativity == 1) + begin : we_1 +assign way_mem_we[0] = (refill_ready == `TRUE); + end + else + begin : we_2 +assign way_mem_we[0] = (refill_ready == `TRUE) && (refill_way_select[0] == `TRUE); +assign way_mem_we[1] = (refill_ready == `TRUE) && (refill_way_select[1] == `TRUE); + end +endgenerate + +// On the last refill cycle set the valid bit, for all other writes it should be cleared +assign tmem_write_data[`LM32_IC_TAGS_VALID_RNG] = last_refill & !flushing; +assign tmem_write_data[`LM32_IC_TAGS_TAG_RNG] = refill_address[`LM32_IC_ADDR_TAG_RNG]; + +// Signals that indicate which state we are in +assign flushing = |state[1:0]; +assign check = state[2]; +assign refill = state[3]; + +assign miss = (~(|way_match)) && (read_enable_f == `TRUE) && (stall_f == `FALSE); +assign stall_request = (check == `FALSE); +assign refill_request = (refill == `TRUE); + +///////////////////////////////////////////////////// +// Sequential logic +///////////////////////////////////////////////////// + +// Record way selected for replacement on a cache miss +generate + if (associativity >= 2) + begin : way_select +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + refill_way_select <= {{associativity-1{1'b0}}, 1'b1}; + else + begin + if (miss == `TRUE) + refill_way_select <= {refill_way_select[0], refill_way_select[1]}; + end +end + end +endgenerate + +// Record whether we are refilling +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + refilling <= `FALSE; + else + refilling <= refill; +end + +// Instruction cache control FSM +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + state <= `LM32_IC_STATE_FLUSH_INIT; + flush_set <= {`LM32_IC_TMEM_ADDR_WIDTH{1'b1}}; + refill_address <= {`LM32_PC_WIDTH{1'bx}}; + restart_request <= `FALSE; + end + else + begin + case (state) + + // Flush the cache for the first time after reset + `LM32_IC_STATE_FLUSH_INIT: + begin + if (flush_set == {`LM32_IC_TMEM_ADDR_WIDTH{1'b0}}) + state <= `LM32_IC_STATE_CHECK; + flush_set <= flush_set - 1'b1; + end + + // Flush the cache in response to an write to the ICC CSR + `LM32_IC_STATE_FLUSH: + begin + if (flush_set == {`LM32_IC_TMEM_ADDR_WIDTH{1'b0}}) + state <= `LM32_IC_STATE_REFILL; + flush_set <= flush_set - 1'b1; + end + + // Check for cache misses + `LM32_IC_STATE_CHECK: + begin + if (stall_a == `FALSE) + restart_request <= `FALSE; + if (iflush == `TRUE) + begin + refill_address <= address_f; + state <= `LM32_IC_STATE_FLUSH; + end + else if (miss == `TRUE) + begin + refill_address <= address_f; + state <= `LM32_IC_STATE_REFILL; + end + end + + // Refill a cache line + `LM32_IC_STATE_REFILL: + begin + if (refill_ready == `TRUE) + begin + if (last_refill == `TRUE) + begin + restart_request <= `TRUE; + state <= `LM32_IC_STATE_CHECK; + end + end + end + + endcase + end +end + +generate + if (bytes_per_line > 4) + begin : refilof1 +// Refill offset +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + refill_offset <= {addr_offset_width{1'b0}}; + else + begin + case (state) + + // Check for cache misses + `LM32_IC_STATE_CHECK: + begin + if (iflush == `TRUE) + refill_offset <= {addr_offset_width{1'b0}}; + else if (miss == `TRUE) + refill_offset <= {addr_offset_width{1'b0}}; + end + + // Refill a cache line + `LM32_IC_STATE_REFILL: + begin + if (refill_ready == `TRUE) + refill_offset <= refill_offset + 1'b1; + end + + endcase + end +end + end +endgenerate + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_include.v b/lm32/logic/sakc/rtl/lm32/lm32_include.v new file mode 100644 index 0000000..494fbf3 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_include.v @@ -0,0 +1,320 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_include.v +// Title : CPU global macros +// Version : 6.1.17 +// ============================================================================= + +`ifdef LM32_INCLUDE_V +`else +`define LM32_INCLUDE_V + +// Configuration options +`include "system_conf.v" + +`ifdef TRUE +`else +`define TRUE 1'b1 +`define FALSE 1'b0 +`define TRUE_N 1'b0 +`define FALSE_N 1'b1 +`endif + +// Wishbone configuration +`define CFG_IWB_ENABLED +`define CFG_DWB_ENABLED + +// Data-path width +`define LM32_WORD_WIDTH 32 +`define LM32_WORD_RNG (`LM32_WORD_WIDTH-1):0 +`define LM32_SHIFT_WIDTH 5 +`define LM32_SHIFT_RNG (`LM32_SHIFT_WIDTH-1):0 +`define LM32_BYTE_SELECT_WIDTH 4 +`define LM32_BYTE_SELECT_RNG (`LM32_BYTE_SELECT_WIDTH-1):0 + +// Register file size +`define LM32_REGISTERS 32 +`define LM32_REG_IDX_WIDTH 5 +`define LM32_REG_IDX_RNG (`LM32_REG_IDX_WIDTH-1):0 + +// Standard register numbers +`define LM32_RA_REG `LM32_REG_IDX_WIDTH'd29 +`define LM32_EA_REG `LM32_REG_IDX_WIDTH'd30 +`define LM32_BA_REG `LM32_REG_IDX_WIDTH'd31 + +// Range of Program Counter. Two LSBs are always 0. +`ifdef CFG_ICACHE_ENABLED +// XXX `define LM32_PC_WIDTH (clogb2(`CFG_ICACHE_LIMIT-`CFG_ICACHE_BASE_ADDRESS)-2) XXX +`define LM32_PC_WIDTH 30 +`else +`ifdef CFG_IWB_ENABLED +`define LM32_PC_WIDTH (`LM32_WORD_WIDTH-2) +`else +`define LM32_PC_WIDTH `LM32_IROM_ADDRESS_WIDTH +`endif +`endif +`define LM32_PC_RNG (`LM32_PC_WIDTH+2-1):2 + +// Range of an instruction +`define LM32_INSTRUCTION_WIDTH 32 +`define LM32_INSTRUCTION_RNG (`LM32_INSTRUCTION_WIDTH-1):0 + +// Adder operation +`define LM32_ADDER_OP_ADD 1'b0 +`define LM32_ADDER_OP_SUBTRACT 1'b1 + +// Shift direction +`define LM32_SHIFT_OP_RIGHT 1'b0 +`define LM32_SHIFT_OP_LEFT 1'b1 + +// Currently always enabled +`define CFG_BUS_ERRORS_ENABLED + +// Derive macro that indicates whether we have single-stepping or not +`ifdef CFG_ROM_DEBUG_ENABLED +`define LM32_SINGLE_STEP_ENABLED +`else +`ifdef CFG_HW_DEBUG_ENABLED +`define LM32_SINGLE_STEP_ENABLED +`endif +`endif + +// Derive macro that indicates whether JTAG interface is required +`ifdef CFG_JTAG_UART_ENABLED +`define LM32_JTAG_ENABLED +`else +`ifdef CFG_DEBUG_ENABLED +`define LM32_JTAG_ENABLED +`else +`endif +`endif + +// Derive macro that indicates whether we have a barrel-shifter or not +`ifdef CFG_PL_BARREL_SHIFT_ENABLED +`define LM32_BARREL_SHIFT_ENABLED +`else // CFG_PL_BARREL_SHIFT_ENABLED +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +`define LM32_BARREL_SHIFT_ENABLED +`else +`define LM32_NO_BARREL_SHIFT +`endif +`endif // CFG_PL_BARREL_SHIFT_ENABLED + +// Derive macro that indicates whether we have a multiplier or not +`ifdef CFG_PL_MULTIPLY_ENABLED +`define LM32_MULTIPLY_ENABLED +`else +`ifdef CFG_MC_MULTIPLY_ENABLED +`define LM32_MULTIPLY_ENABLED +`endif +`endif + +// Derive a macro that indicates whether or not the multi-cycle arithmetic unit is required +`ifdef CFG_MC_DIVIDE_ENABLED +`define LM32_MC_ARITHMETIC_ENABLED +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED +`define LM32_MC_ARITHMETIC_ENABLED +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +`define LM32_MC_ARITHMETIC_ENABLED +`endif + +// Derive macro that indicates if we are using an EBR register file +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +`define LM32_EBR_REGISTER_FILE +`endif +`ifdef CFG_EBR_NEGEDGE_REGISTER_FILE +`define LM32_EBR_REGISTER_FILE +`endif + +// Revision number +`define LM32_REVISION 6'h11 + +// Logical operations - Function encoded directly in instruction +`define LM32_LOGIC_OP_RNG 3:0 + +// Conditions for conditional branches +`define LM32_CONDITION_WIDTH 3 +`define LM32_CONDITION_RNG (`LM32_CONDITION_WIDTH-1):0 +`define LM32_CONDITION_E 3'b001 +`define LM32_CONDITION_G 3'b010 +`define LM32_CONDITION_GE 3'b011 +`define LM32_CONDITION_GEU 3'b100 +`define LM32_CONDITION_GU 3'b101 +`define LM32_CONDITION_NE 3'b111 +`define LM32_CONDITION_U1 3'b000 +`define LM32_CONDITION_U2 3'b110 + +// Size of load or store instruction - Encoding corresponds to opcode +`define LM32_SIZE_WIDTH 2 +`define LM32_SIZE_RNG 1:0 +`define LM32_SIZE_BYTE 2'b00 +`define LM32_SIZE_HWORD 2'b11 +`define LM32_SIZE_WORD 2'b10 +`define LM32_ADDRESS_LSBS_WIDTH 2 + +// Width and range of a CSR index +`ifdef CFG_DEBUG_ENABLED +`define LM32_CSR_WIDTH 5 +`define LM32_CSR_RNG (`LM32_CSR_WIDTH-1):0 +`else +`ifdef CFG_JTAG_ENABLED +`define LM32_CSR_WIDTH 4 +`define LM32_CSR_RNG (`LM32_CSR_WIDTH-1):0 +`else +`define LM32_CSR_WIDTH 3 +`define LM32_CSR_RNG (`LM32_CSR_WIDTH-1):0 +`endif +`endif + +// CSR indices +`define LM32_CSR_IE `LM32_CSR_WIDTH'h0 +`define LM32_CSR_IM `LM32_CSR_WIDTH'h1 +`define LM32_CSR_IP `LM32_CSR_WIDTH'h2 +`define LM32_CSR_ICC `LM32_CSR_WIDTH'h3 +`define LM32_CSR_DCC `LM32_CSR_WIDTH'h4 +`define LM32_CSR_CC `LM32_CSR_WIDTH'h5 +`define LM32_CSR_CFG `LM32_CSR_WIDTH'h6 +`define LM32_CSR_EBA `LM32_CSR_WIDTH'h7 +`ifdef CFG_DEBUG_ENABLED +`define LM32_CSR_DC `LM32_CSR_WIDTH'h8 +`define LM32_CSR_DEBA `LM32_CSR_WIDTH'h9 +`endif +`ifdef CFG_JTAG_ENABLED +`define LM32_CSR_JTX `LM32_CSR_WIDTH'he +`define LM32_CSR_JRX `LM32_CSR_WIDTH'hf +`endif +`ifdef CFG_DEBUG_ENABLED +`define LM32_CSR_BP0 `LM32_CSR_WIDTH'h10 +`define LM32_CSR_BP1 `LM32_CSR_WIDTH'h11 +`define LM32_CSR_BP2 `LM32_CSR_WIDTH'h12 +`define LM32_CSR_BP3 `LM32_CSR_WIDTH'h13 +`define LM32_CSR_WP0 `LM32_CSR_WIDTH'h18 +`define LM32_CSR_WP1 `LM32_CSR_WIDTH'h19 +`define LM32_CSR_WP2 `LM32_CSR_WIDTH'h1a +`define LM32_CSR_WP3 `LM32_CSR_WIDTH'h1b +`endif + +// Values for WPC CSR +`define LM32_WPC_C_RNG 1:0 +`define LM32_WPC_C_DISABLED 2'b00 +`define LM32_WPC_C_READ 2'b01 +`define LM32_WPC_C_WRITE 2'b10 +`define LM32_WPC_C_READ_WRITE 2'b11 + +// Exception IDs +`define LM32_EID_WIDTH 3 +`define LM32_EID_RNG (`LM32_EID_WIDTH-1):0 +`define LM32_EID_RESET 3'h0 +`define LM32_EID_BREAKPOINT 3'd1 +`define LM32_EID_INST_BUS_ERROR 3'h2 +`define LM32_EID_WATCHPOINT 3'd3 +`define LM32_EID_DATA_BUS_ERROR 3'h4 +`define LM32_EID_DIVIDE_BY_ZERO 3'h5 +`define LM32_EID_INTERRUPT 3'h6 +`define LM32_EID_SCALL 3'h7 + +// Pipeline result selection mux controls + +`define LM32_D_RESULT_SEL_0_RNG 0:0 +`define LM32_D_RESULT_SEL_0_REG_0 1'b0 +`define LM32_D_RESULT_SEL_0_NEXT_PC 1'b1 + +`define LM32_D_RESULT_SEL_1_RNG 1:0 +`define LM32_D_RESULT_SEL_1_ZERO 2'b00 +`define LM32_D_RESULT_SEL_1_REG_1 2'b01 +`define LM32_D_RESULT_SEL_1_IMMEDIATE 2'b10 + +`define LM32_USER_OPCODE_WIDTH 11 +`define LM32_USER_OPCODE_RNG (`LM32_USER_OPCODE_WIDTH-1):0 + +// Derive a macro to indicate if either of the caches are implemented +`ifdef CFG_ICACHE_ENABLED +`define LM32_CACHE_ENABLED +`else +`ifdef CFG_DCACHE_ENABLED +`define LM32_CACHE_ENABLED +`endif +`endif + +///////////////////////////////////////////////////// +// Interrupts +///////////////////////////////////////////////////// + +// Always enable interrupts +`define CFG_INTERRUPTS_ENABLED + +// Currently this is fixed to 32 and should not be changed +`define CFG_INTERRUPTS 32 +`define LM32_INTERRUPT_WIDTH `CFG_INTERRUPTS +`define LM32_INTERRUPT_RNG (`LM32_INTERRUPT_WIDTH-1):0 + +///////////////////////////////////////////////////// +// General +///////////////////////////////////////////////////// + +// Sub-word range types +`define LM32_BYTE_WIDTH 8 +`define LM32_BYTE_RNG 7:0 +`define LM32_HWORD_WIDTH 16 +`define LM32_HWORD_RNG 15:0 + +// Word sub-byte indicies +`define LM32_BYTE_0_RNG 7:0 +`define LM32_BYTE_1_RNG 15:8 +`define LM32_BYTE_2_RNG 23:16 +`define LM32_BYTE_3_RNG 31:24 + +// Word sub-halfword indices +`define LM32_HWORD_0_RNG 15:0 +`define LM32_HWORD_1_RNG 31:16 + +// Use an asynchronous reset +// To use a synchronous reset, define this macro as nothing +`define CFG_RESET_SENSITIVITY or posedge rst_i + +// V.T. Srce +`define SRCE + +// Whether to include context registers for debug exceptions +// in addition to standard exception handling registers +// Bizarre - Removing this increases LUT count! +`define CFG_DEBUG_EXCEPTIONS_ENABLED + +// Wishbone defines +// Refer to Wishbone System-on-Chip Interconnection Architecture +// These should probably be moved to a Wishbone common file + +// Wishbone cycle types +`define LM32_CTYPE_WIDTH 3 +`define LM32_CTYPE_RNG (`LM32_CTYPE_WIDTH-1):0 +`define LM32_CTYPE_CLASSIC 3'b000 +`define LM32_CTYPE_CONSTANT 3'b001 +`define LM32_CTYPE_INCREMENTING 3'b010 +`define LM32_CTYPE_END 3'b111 + +// Wishbone burst types +`define LM32_BTYPE_WIDTH 2 +`define LM32_BTYPE_RNG (`LM32_BTYPE_WIDTH-1):0 +`define LM32_BTYPE_LINEAR 2'b00 +`define LM32_BTYPE_4_BEAT 2'b01 +`define LM32_BTYPE_8_BEAT 2'b10 +`define LM32_BTYPE_16_BEAT 2'b11 + +`endif diff --git a/lm32/logic/sakc/rtl/lm32/lm32_include_all.v b/lm32/logic/sakc/rtl/lm32/lm32_include_all.v new file mode 100644 index 0000000..645bb3b --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_include_all.v @@ -0,0 +1,32 @@ +`ifndef LM32_ALL_FILES +`define LM32_ALL_FILES +//`ifndef SIMULATION +//`include "pmi_def.v" +//`endif +// JTAG Debug related files +`include "../components/lm32_top/rtl/verilog/er1.v" +`include "../components/lm32_top/rtl/verilog/typeb.v" +`include "../components/lm32_top/rtl/verilog/typea.v" +`include "../components/lm32_top/rtl/verilog/jtag_cores.v" +`include "../components/lm32_top/rtl/verilog/jtag_lm32.v" +// CPU Core related files +`include "../components/lm32_top/rtl/verilog/lm32_addsub.v" +`include "../components/lm32_top/rtl/verilog/lm32_adder.v" +`include "../components/lm32_top/rtl/verilog/lm32_cpu.v" +`include "../components/lm32_top/rtl/verilog/lm32_dcache.v" +`include "../components/lm32_top/rtl/verilog/lm32_debug.v" +`include "../components/lm32_top/rtl/verilog/lm32_decoder.v" +`include "../components/lm32_top/rtl/verilog/lm32_icache.v" +`include "../components/lm32_top/rtl/verilog/lm32_instruction_unit.v" +`include "../components/lm32_top/rtl/verilog/lm32_interrupt.v" +`include "../components/lm32_top/rtl/verilog/lm32_load_store_unit.v" +`include "../components/lm32_top/rtl/verilog/lm32_logic_op.v" +`include "../components/lm32_top/rtl/verilog/lm32_mc_arithmetic.v" +`include "../components/lm32_top/rtl/verilog/lm32_multiplier.v" +`include "../components/lm32_top/rtl/verilog/lm32_shifter.v" +`include "../components/lm32_top/rtl/verilog/lm32_top.v" +`include "../components/lm32_top/rtl/verilog/lm32_monitor.v" +`include "../components/lm32_top/rtl/verilog/lm32_monitor_ram.v" +`include "../components/lm32_top/rtl/verilog/lm32_ram.v" +`include "../components/lm32_top/rtl/verilog/lm32_jtag.v" +`endif // LM32_ALL_FILES diff --git a/lm32/logic/sakc/rtl/lm32/lm32_instruction_unit.v b/lm32/logic/sakc/rtl/lm32/lm32_instruction_unit.v new file mode 100644 index 0000000..734951e --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_instruction_unit.v @@ -0,0 +1,751 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_instruction_unit.v +// Title : Instruction unit +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_instruction_unit ( + // ----- Inputs ------- + clk_i, + rst_i, + // From pipeline + stall_a, + stall_f, + stall_d, + stall_x, + stall_m, + valid_f, + kill_f, +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + branch_taken_x, + branch_target_x, +`endif + branch_taken_m, + branch_target_m, +`ifdef CFG_ICACHE_ENABLED + iflush, +`endif +`ifdef CFG_DCACHE_ENABLED + dcache_restart_request, + dcache_refill_request, + dcache_refilling, +`endif +`ifdef CFG_IWB_ENABLED + // From Wishbone + i_dat_i, + i_ack_i, + i_err_i, + i_rty_i, +`endif +`ifdef CFG_HW_DEBUG_ENABLED + jtag_read_enable, + jtag_write_enable, + jtag_write_data, + jtag_address, +`endif + // ----- Outputs ------- + // To pipeline + pc_f, + pc_d, + pc_x, + pc_m, + pc_w, +`ifdef CFG_ICACHE_ENABLED + icache_stall_request, + icache_restart_request, + icache_refill_request, + icache_refilling, +`endif +`ifdef CFG_IWB_ENABLED + // To Wishbone + i_dat_o, + i_adr_o, + i_cyc_o, + i_sel_o, + i_stb_o, + i_we_o, + i_cti_o, + i_lock_o, + i_bte_o, +`endif +`ifdef CFG_HW_DEBUG_ENABLED + jtag_read_data, + jtag_access_complete, +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_d, +`endif +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE + instruction_f, +`endif + instruction_d + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter associativity = 1; // Associativity of the cache (Number of ways) +parameter sets = 512; // Number of sets +parameter bytes_per_line = 16; // Number of bytes per cache line +parameter base_address = 0; // Base address of cachable memory +parameter limit = 0; // Limit (highest address) of cachable memory + +// For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used +//localparam addr_offset_width = (bytes_per_line == 4 ? 1 : clogb2(bytes_per_line)-1-2); +localparam addr_offset_width = 2; +localparam addr_offset_lsb = 2; +localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input stall_a; // Stall A stage instruction +input stall_f; // Stall F stage instruction +input stall_d; // Stall D stage instruction +input stall_x; // Stall X stage instruction +input stall_m; // Stall M stage instruction +input valid_f; // Instruction in F stage is valid +input kill_f; // Kill instruction in F stage + +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH +input branch_taken_x; // Branch instruction in X stage is taken +input [`LM32_PC_RNG] branch_target_x; // Target PC of X stage branch instruction +`endif +input branch_taken_m; // Branch instruction in M stage is taken +input [`LM32_PC_RNG] branch_target_m; // Target PC of M stage branch instruction + +`ifdef CFG_ICACHE_ENABLED +input iflush; // Flush instruction cache +`endif +`ifdef CFG_DCACHE_ENABLED +input dcache_restart_request; // Restart instruction that caused a data cache miss +input dcache_refill_request; // Request to refill data cache +input dcache_refilling; +`endif + +`ifdef CFG_IWB_ENABLED +input [`LM32_WORD_RNG] i_dat_i; // Instruction Wishbone interface read data +input i_ack_i; // Instruction Wishbone interface acknowledgement +input i_err_i; // Instruction Wishbone interface error +input i_rty_i; // Instruction Wishbone interface retry +`endif + +`ifdef CFG_HW_DEBUG_ENABLED +input jtag_read_enable; // JTAG read memory request +input jtag_write_enable; // JTAG write memory request +input [`LM32_BYTE_RNG] jtag_write_data; // JTAG wrirte data +input [`LM32_WORD_RNG] jtag_address; // JTAG read/write address +`endif + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [`LM32_PC_RNG] pc_f; // F stage PC +reg [`LM32_PC_RNG] pc_f; +output [`LM32_PC_RNG] pc_d; // D stage PC +reg [`LM32_PC_RNG] pc_d; +output [`LM32_PC_RNG] pc_x; // X stage PC +reg [`LM32_PC_RNG] pc_x; +output [`LM32_PC_RNG] pc_m; // M stage PC +reg [`LM32_PC_RNG] pc_m; +output [`LM32_PC_RNG] pc_w; // W stage PC +reg [`LM32_PC_RNG] pc_w; + +`ifdef CFG_ICACHE_ENABLED +output icache_stall_request; // Instruction cache stall request +wire icache_stall_request; +output icache_restart_request; // Request to restart instruction that cached instruction cache miss +wire icache_restart_request; +output icache_refill_request; // Instruction cache refill request +wire icache_refill_request; +output icache_refilling; // Indicates the icache is refilling +wire icache_refilling; +`endif + +`ifdef CFG_IWB_ENABLED +output [`LM32_WORD_RNG] i_dat_o; // Instruction Wishbone interface write data +`ifdef CFG_HW_DEBUG_ENABLED +reg [`LM32_WORD_RNG] i_dat_o; +`else +wire [`LM32_WORD_RNG] i_dat_o; +`endif +output [`LM32_WORD_RNG] i_adr_o; // Instruction Wishbone interface address +reg [`LM32_WORD_RNG] i_adr_o; +output i_cyc_o; // Instruction Wishbone interface cycle +reg i_cyc_o; +output [`LM32_BYTE_SELECT_RNG] i_sel_o; // Instruction Wishbone interface byte select +`ifdef CFG_HW_DEBUG_ENABLED +reg [`LM32_BYTE_SELECT_RNG] i_sel_o; +`else +wire [`LM32_BYTE_SELECT_RNG] i_sel_o; +`endif +output i_stb_o; // Instruction Wishbone interface strobe +reg i_stb_o; +output i_we_o; // Instruction Wishbone interface write enable +`ifdef CFG_HW_DEBUG_ENABLED +reg i_we_o; +`else +wire i_we_o; +`endif +output [`LM32_CTYPE_RNG] i_cti_o; // Instruction Wishbone interface cycle type +reg [`LM32_CTYPE_RNG] i_cti_o; +output i_lock_o; // Instruction Wishbone interface lock bus +reg i_lock_o; +output [`LM32_BTYPE_RNG] i_bte_o; // Instruction Wishbone interface burst type +wire [`LM32_BTYPE_RNG] i_bte_o; +`endif + +`ifdef CFG_HW_DEBUG_ENABLED +output [`LM32_BYTE_RNG] jtag_read_data; // Data read for JTAG interface +reg [`LM32_BYTE_RNG] jtag_read_data; +output jtag_access_complete; // Requested memory access by JTAG interface is complete +wire jtag_access_complete; +`endif + +`ifdef CFG_BUS_ERRORS_ENABLED +output bus_error_d; // Indicates a bus error occured while fetching the instruction +reg bus_error_d; +`endif +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +output [`LM32_INSTRUCTION_RNG] instruction_f; // F stage instruction (only to have register indices extracted from) +wire [`LM32_INSTRUCTION_RNG] instruction_f; +`endif +output [`LM32_INSTRUCTION_RNG] instruction_d; // D stage instruction to be decoded +reg [`LM32_INSTRUCTION_RNG] instruction_d; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +reg [`LM32_PC_RNG] pc_a; // A stage PC + +`ifdef LM32_CACHE_ENABLED +reg [`LM32_PC_RNG] restart_address; // Address to restart from after a cache miss +`endif + +`ifdef CFG_ICACHE_ENABLED +wire icache_read_enable_f; // Indicates if instruction cache miss is valid +wire [`LM32_PC_RNG] icache_refill_address; // Address that caused cache miss +reg icache_refill_ready; // Indicates when next word of refill data is ready to be written to cache +reg [`LM32_INSTRUCTION_RNG] icache_refill_data; // Next word of refill data, fetched from Wishbone +wire [`LM32_INSTRUCTION_RNG] icache_data_f; // Instruction fetched from instruction cache +wire [`LM32_CTYPE_RNG] first_cycle_type; // First Wishbone cycle type +wire [`LM32_CTYPE_RNG] next_cycle_type; // Next Wishbone cycle type +wire last_word; // Indicates if this is the last word in the cache line +wire [`LM32_PC_RNG] first_address; // First cache refill address +`else +`ifdef CFG_IWB_ENABLED +reg [`LM32_INSTRUCTION_RNG] wb_data_f; // Instruction fetched from Wishbone +`endif +`endif +`ifdef CFG_IROM_ENABLED +wire irom_select_a; // Indicates if A stage PC maps to a ROM address +reg irom_select_f; // Indicates if F stage PC maps to a ROM address +wire [`LM32_INSTRUCTION_RNG] irom_data_f; // Instruction fetched from ROM +`endif +`ifdef CFG_EBR_POSEDGE_REGISTER_FILE +`else +wire [`LM32_INSTRUCTION_RNG] instruction_f; // F stage instruction +`endif +`ifdef CFG_BUS_ERRORS_ENABLED +reg bus_error_f; // Indicates if a bus error occured while fetching the instruction in the F stage +`endif + +`ifdef CFG_HW_DEBUG_ENABLED +reg jtag_access; // Indicates if a JTAG WB access is in progress +`endif + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +// Instruction ROM +`ifdef CFG_IROM_ENABLED +pmi_ram_dp #( + // ----- Parameters ------- + .pmi_wr_addr_depth (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), + .pmi_wr_addr_width ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), + .pmi_wr_data_width (`LM32_INSTRUCTION_WIDTH), + .pmi_rd_addr_depth (1 << (clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), + .pmi_rd_addr_width ((clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)), + .pmi_rd_data_width (`LM32_INSTRUCTION_WIDTH), + .pmi_regmode ("noreg"), + .pmi_gsr ("enable"), + .pmi_resetmode ("async"), + .pmi_init_file (`CFG_IROM_INIT_FILE), + .pmi_init_file_format ("hex"), + .module_type ("pmi_ram_dp") + ) ram ( + // ----- Inputs ------- + .RdClock (clk_i), + .WrClock (`FALSE), + .Reset (rst_i), + .Data ({32{1'b0}}), + .RdAddress (pc_a[(clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1)+2-1:2]), + .WrAddress ({(clogb2(`CFG_IROM_LIMIT/4-`CFG_IROM_BASE_ADDRESS/4+1)-1){1'b0}}), + .RdClockEn (~stall_a), + .WrClockEn (`FALSE), + .WE (`FALSE), + // ----- Outputs ------- + .Q (irom_data_f) + ); +`endif + +`ifdef CFG_ICACHE_ENABLED +// Instruction cache +lm32_icache #( + .associativity (associativity), + .sets (sets), + .bytes_per_line (bytes_per_line), + .base_address (base_address), + .limit (limit) + ) icache ( + // ----- Inputs ----- + .clk_i (clk_i), + .rst_i (rst_i), + .stall_a (stall_a), + .stall_f (stall_f), + .address_a (pc_a), + .address_f (pc_f), + .read_enable_f (icache_read_enable_f), + .refill_ready (icache_refill_ready), + .refill_data (icache_refill_data), + .iflush (iflush), + // ----- Outputs ----- + .stall_request (icache_stall_request), + .restart_request (icache_restart_request), + .refill_request (icache_refill_request), + .refill_address (icache_refill_address), + .refilling (icache_refilling), + .inst (icache_data_f) + ); +`endif + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +`ifdef CFG_ICACHE_ENABLED +// Generate signal that indicates when instruction cache misses are valid +assign icache_read_enable_f = (valid_f == `TRUE) + && (kill_f == `FALSE) +`ifdef CFG_DCACHE_ENABLED + && (dcache_restart_request == `FALSE) +`endif +`ifdef CFG_IROM_ENABLED + && (irom_select_f == `FALSE) +`endif + ; +`endif + +// Compute address of next instruction to fetch +always @(*) +begin + // The request from the latest pipeline stage must take priority +`ifdef CFG_DCACHE_ENABLED + if (dcache_restart_request == `TRUE) + pc_a = restart_address; + else +`endif + if (branch_taken_m == `TRUE) + pc_a = branch_target_m; +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + else if (branch_taken_x == `TRUE) + pc_a = branch_target_x; +`endif + else +`ifdef CFG_ICACHE_ENABLED + if (icache_restart_request == `TRUE) + pc_a = restart_address; + else +`endif + pc_a = pc_f + 1'b1; +end + +// Select where instruction should be fetched from +`ifdef CFG_IROM_ENABLED +assign irom_select_a = ({pc_a, 2'b00} >= `CFG_IROM_BASE_ADDRESS) && ({pc_a, 2'b00} <= `CFG_IROM_LIMIT); +`endif + +// Select instruction from selected source +`ifdef CFG_ICACHE_ENABLED +`ifdef CFG_IROM_ENABLED +assign instruction_f = irom_select_f == `TRUE ? irom_data_f : icache_data_f; +`else +assign instruction_f = icache_data_f; +`endif +`else +`ifdef CFG_IROM_ENABLED +`ifdef CFG_IWB_ENABLED +assign instruction_f = irom_select_f == `TRUE ? irom_data_f : wb_data_f; +`else +assign instruction_f = irom_data_f; +`endif +`else +assign instruction_f = wb_data_f; +`endif +`endif + +// Unused/constant Wishbone signals +`ifdef CFG_IWB_ENABLED +`ifdef CFG_HW_DEBUG_ENABLED +`else +assign i_dat_o = 32'd0; +assign i_we_o = `FALSE; +assign i_sel_o = 4'b1111; +`endif +assign i_bte_o = `LM32_BTYPE_LINEAR; +`endif + +`ifdef CFG_ICACHE_ENABLED +// Determine parameters for next cache refill Wishbone access +// generate +// case (bytes_per_line) +// 4: +// begin +// assign first_cycle_type = `LM32_CTYPE_END; +// assign next_cycle_type = `LM32_CTYPE_END; +// assign last_word = `TRUE; +// assign first_address = icache_refill_address; +// end +// 8: +// begin +// assign first_cycle_type = `LM32_CTYPE_INCREMENTING; +// assign next_cycle_type = `LM32_CTYPE_END; +// assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 1'b1; +// assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}}; +// end +// 16: +// begin +assign first_cycle_type = `LM32_CTYPE_INCREMENTING; +assign next_cycle_type = i_adr_o[addr_offset_msb] == 1'b1 ? `LM32_CTYPE_END : `LM32_CTYPE_INCREMENTING; +assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 2'b11; +assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}}; +// end +// endcase +// endgenerate +`endif + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +// PC +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + pc_f <= (`CFG_EBA_RESET-4)/4; + pc_d <= {`LM32_PC_WIDTH{1'b0}}; + pc_x <= {`LM32_PC_WIDTH{1'b0}}; + pc_m <= {`LM32_PC_WIDTH{1'b0}}; + pc_w <= {`LM32_PC_WIDTH{1'b0}}; + end + else + begin + if (stall_f == `FALSE) + pc_f <= pc_a; + if (stall_d == `FALSE) + pc_d <= pc_f; + if (stall_x == `FALSE) + pc_x <= pc_d; + if (stall_m == `FALSE) + pc_m <= pc_x; + pc_w <= pc_m; + end +end + +`ifdef LM32_CACHE_ENABLED +// Address to restart from after a cache miss has been handled +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + restart_address <= {`LM32_PC_WIDTH{1'b0}}; + else + begin +`ifdef CFG_DCACHE_ENABLED +`ifdef CFG_ICACHE_ENABLED + // D-cache restart address must take priority, otherwise instructions will be lost + if (dcache_refill_request == `TRUE) + restart_address <= pc_w; + else if ((icache_refill_request == `TRUE) && (!dcache_refilling)) + restart_address <= icache_refill_address; +`else + if (dcache_refill_request == `TRUE) + restart_address <= pc_w; +`endif +`else +`ifdef CFG_ICACHE_ENABLED + if (icache_refill_request == `TRUE) + restart_address <= icache_refill_address; +`endif +`endif + end +end +`endif + +// Record where instruction was fetched from +`ifdef CFG_IROM_ENABLED +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + irom_select_f <= `FALSE; + else + begin + if (stall_f == `FALSE) + irom_select_f <= irom_select_a; + end +end +`endif + +`ifdef CFG_HW_DEBUG_ENABLED +assign jtag_access_complete = (i_cyc_o == `TRUE) && ((i_ack_i == `TRUE) || (i_err_i == `TRUE)) && (jtag_access == `TRUE); +always @* +begin + case (jtag_address[1:0]) + 2'b00: jtag_read_data = i_dat_i[`LM32_BYTE_3_RNG]; + 2'b01: jtag_read_data = i_dat_i[`LM32_BYTE_2_RNG]; + 2'b10: jtag_read_data = i_dat_i[`LM32_BYTE_1_RNG]; + 2'b11: jtag_read_data = i_dat_i[`LM32_BYTE_0_RNG]; + endcase +end +`endif + +`ifdef CFG_IWB_ENABLED +// Instruction Wishbone interface +`ifdef CFG_ICACHE_ENABLED +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + i_cyc_o <= `FALSE; + i_stb_o <= `FALSE; + i_adr_o <= {`LM32_WORD_WIDTH{1'b0}}; + i_cti_o <= `LM32_CTYPE_END; + i_lock_o <= `FALSE; + icache_refill_data <= {`LM32_INSTRUCTION_WIDTH{1'b0}}; + icache_refill_ready <= `FALSE; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_f <= `FALSE; +`endif +`ifdef CFG_HW_DEBUG_ENABLED + i_we_o <= `FALSE; + i_sel_o <= 4'b1111; + jtag_access <= `FALSE; +`endif + end + else + begin + icache_refill_ready <= `FALSE; + // Is a cycle in progress? + if (i_cyc_o == `TRUE) + begin + // Has cycle completed? + if ((i_ack_i == `TRUE) || (i_err_i == `TRUE)) + begin +`ifdef CFG_HW_DEBUG_ENABLED + if (jtag_access == `TRUE) + begin + i_cyc_o <= `FALSE; + i_stb_o <= `FALSE; + i_we_o <= `FALSE; + jtag_access <= `FALSE; + end + else +`endif + begin + if (last_word == `TRUE) + begin + // Cache line fill complete + i_cyc_o <= `FALSE; + i_stb_o <= `FALSE; + i_lock_o <= `FALSE; + end + // Fetch next word in cache line + i_adr_o[addr_offset_msb:addr_offset_lsb] <= i_adr_o[addr_offset_msb:addr_offset_lsb] + 1'b1; + i_cti_o <= next_cycle_type; + // Write fetched data into instruction cache + icache_refill_ready <= `TRUE; + icache_refill_data <= i_dat_i; + end + end +`ifdef CFG_BUS_ERRORS_ENABLED + if (i_err_i == `TRUE) + begin + bus_error_f <= `TRUE; + $display ("Instruction bus error. Address: %x", i_adr_o); + end +`endif + end + else + begin + if ((icache_refill_request == `TRUE) && (icache_refill_ready == `FALSE)) + begin + // Read first word of cache line +`ifdef CFG_HW_DEBUG_ENABLED + i_sel_o <= 4'b1111; +`endif + i_adr_o <= {first_address, 2'b00}; + i_cyc_o <= `TRUE; + i_stb_o <= `TRUE; + i_cti_o <= first_cycle_type; + //i_lock_o <= `TRUE; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_f <= `FALSE; +`endif + end +`ifdef CFG_HW_DEBUG_ENABLED + else + begin + if ((jtag_read_enable == `TRUE) || (jtag_write_enable == `TRUE)) + begin + case (jtag_address[1:0]) + 2'b00: i_sel_o <= 4'b1000; + 2'b01: i_sel_o <= 4'b0100; + 2'b10: i_sel_o <= 4'b0010; + 2'b11: i_sel_o <= 4'b0001; + endcase + i_adr_o <= jtag_address; + i_dat_o <= {4{jtag_write_data}}; + i_cyc_o <= `TRUE; + i_stb_o <= `TRUE; + i_we_o <= jtag_write_enable; + i_cti_o <= `LM32_CTYPE_END; + jtag_access <= `TRUE; + end + end +`endif +`ifdef CFG_BUS_ERRORS_ENABLED + // Clear bus error when exception taken, otherwise they would be + // continually generated if exception handler is cached +`ifdef CFG_FAST_UNCONDITIONAL_BRANCH + if (branch_taken_x == `TRUE) + bus_error_f <= `FALSE; +`endif + if (branch_taken_m == `TRUE) + bus_error_f <= `FALSE; +`endif + end + end +end +`else +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + i_cyc_o <= `FALSE; + i_stb_o <= `FALSE; + i_adr_o <= {`LM32_WORD_WIDTH{1'b0}}; + i_cti_o <= `LM32_CTYPE_CLASSIC; + i_lock_o <= `FALSE; + wb_data_f <= {`LM32_INSTRUCTION_WIDTH{1'b0}}; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_f <= `FALSE; +`endif + end + else + begin + // Is a cycle in progress? + if (i_cyc_o == `TRUE) + begin + // Has cycle completed? + if((i_ack_i == `TRUE) || (i_err_i == `TRUE)) + begin + // Cycle complete + i_cyc_o <= `FALSE; + i_stb_o <= `FALSE; + // Register fetched instruction + wb_data_f <= i_dat_i; + end +`ifdef CFG_BUS_ERRORS_ENABLED + if (i_err_i == `TRUE) + begin + bus_error_f <= `TRUE; + $display ("Instruction bus error. Address: %x", i_adr_o); + end +`endif + end + else + begin + // Wait for an instruction fetch from an external address + if ( (stall_a == `FALSE) +`ifdef CFG_IROM_ENABLED + && (irom_select_a == `FALSE) +`endif + ) + begin + // Fetch instruction +`ifdef CFG_HW_DEBUG_ENABLED + i_sel_o <= 4'b1111; +`endif + i_adr_o <= {pc_a, 2'b00}; + i_cyc_o <= `TRUE; + i_stb_o <= `TRUE; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_f <= `FALSE; +`endif + end + end + end +end +`endif +`endif + +// Instruction register +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + instruction_d <= {`LM32_INSTRUCTION_WIDTH{1'b0}}; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_d <= `FALSE; +`endif + end + else + begin + if (stall_d == `FALSE) + begin + instruction_d <= instruction_f; +`ifdef CFG_BUS_ERRORS_ENABLED + bus_error_d <= bus_error_f; +`endif + end + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_interrupt.v b/lm32/logic/sakc/rtl/lm32/lm32_interrupt.v new file mode 100644 index 0000000..71e54f5 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_interrupt.v @@ -0,0 +1,333 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_interrupt.v +// Title : Interrupt logic +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "system_conf.v" +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_interrupt ( + // ----- Inputs ------- + clk_i, + rst_i, + // From external devices + interrupt_n, + // From pipeline + stall_x, +`ifdef CFG_DEBUG_ENABLED + non_debug_exception, + debug_exception, +`else + exception, +`endif + eret_q_x, +`ifdef CFG_DEBUG_ENABLED + bret_q_x, +`endif + csr, + csr_write_data, + csr_write_enable, + // ----- Outputs ------- + interrupt_exception, + // To pipeline + csr_read_data + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter interrupts = `CFG_INTERRUPTS; // Number of interrupts + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input [interrupts-1:0] interrupt_n; // Interrupt pins, active-low + +input stall_x; // Stall X pipeline stage + +`ifdef CFG_DEBUG_ENABLED +input non_debug_exception; // Non-debug related exception has been raised +input debug_exception; // Debug-related exception has been raised +`else +input exception; // Exception has been raised +`endif +input eret_q_x; // Return from exception +`ifdef CFG_DEBUG_ENABLED +input bret_q_x; // Return from breakpoint +`endif + +input [`LM32_CSR_RNG] csr; // CSR read/write index +input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR +input csr_write_enable; // CSR write enable + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output interrupt_exception; // Request to raide an interrupt exception +wire interrupt_exception; + +output [`LM32_WORD_RNG] csr_read_data; // Data read from CSR +reg [`LM32_WORD_RNG] csr_read_data; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +wire [interrupts-1:0] asserted; // Which interrupts are currently being asserted +wire [interrupts-1:0] interrupt_n_exception; + +// Interrupt CSRs + +reg ie; // Interrupt enable +reg eie; // Exception interrupt enable +`ifdef CFG_DEBUG_ENABLED +reg bie; // Breakpoint interrupt enable +`endif +reg [interrupts-1:0] ip; // Interrupt pending +reg [interrupts-1:0] im; // Interrupt mask + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +// Determine which interrupts have occured and are unmasked +assign interrupt_n_exception = ip & im; + +// Determine if any unmasked interrupts have occured +assign interrupt_exception = (|interrupt_n_exception) & ie; + +// Determine which interrupts are currently being asserted (active-low) or are already pending +assign asserted = ip | ~interrupt_n; + +//assign ie_csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}}, +//`ifdef CFG_DEBUG_ENABLED +// bie, +//`else +// 1'b0, +//`endif +// eie, +// ie +// }; +wire ip_csr_read_data = ip; +wire im_csr_read_data = im; +// XXX JB XXX +// generate +// if (interrupts > 1) +// begin +// CSR read +always @* +begin + case (csr) + `LM32_CSR_IE: csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}}, +`ifdef CFG_DEBUG_ENABLED + bie, +`else + 1'b0, +`endif + eie, + ie + }; + `LM32_CSR_IP: csr_read_data = ip; + `LM32_CSR_IM: csr_read_data = im; + default: csr_read_data = {`LM32_WORD_WIDTH{1'bx}}; + endcase +end +// XXX JB XXX +// end +// else +// begin +//// CSR read +//always @* +//begin +// case (csr) +// `LM32_CSR_IE: csr_read_data = {{`LM32_WORD_WIDTH-3{1'b0}}, +//`ifdef CFG_DEBUG_ENABLED +// bie, +//`else +// 1'b0, +//`endif +// eie, +// ie +// }; +// `LM32_CSR_IP: csr_read_data = ip; +// default: csr_read_data = {`LM32_WORD_WIDTH{1'bx}}; +// endcase +//end +// end +//endgenerate + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +// XXX JB XXX +//generate +// if (interrupts > 1) +// begin +// IE, IM, IP - Interrupt Enable, Interrupt Mask and Interrupt Pending CSRs +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + ie <= `FALSE; + eie <= `FALSE; +`ifdef CFG_DEBUG_ENABLED + bie <= `FALSE; +`endif + im <= {interrupts{1'b0}}; + ip <= {interrupts{1'b0}}; + end + else + begin + // Set IP bit when interrupt line is asserted + ip <= asserted; +`ifdef CFG_DEBUG_ENABLED + if (non_debug_exception == `TRUE) + begin + // Save and then clear interrupt enable + eie <= ie; + ie <= `FALSE; + end + else if (debug_exception == `TRUE) + begin + // Save and then clear interrupt enable + bie <= ie; + ie <= `FALSE; + end +`else + if (exception == `TRUE) + begin + // Save and then clear interrupt enable + eie <= ie; + ie <= `FALSE; + end +`endif + else if (stall_x == `FALSE) + begin + if (eret_q_x == `TRUE) + // Restore interrupt enable + ie <= eie; +`ifdef CFG_DEBUG_ENABLED + else if (bret_q_x == `TRUE) + // Restore interrupt enable + ie <= bie; +`endif + else if (csr_write_enable == `TRUE) + begin + // Handle wcsr write + if (csr == `LM32_CSR_IE) + begin + ie <= csr_write_data[0]; + eie <= csr_write_data[1]; +`ifdef CFG_DEBUG_ENABLED + bie <= csr_write_data[2]; +`endif + end + if (csr == `LM32_CSR_IM) + im <= csr_write_data[interrupts-1:0]; + if (csr == `LM32_CSR_IP) + ip <= asserted & ~csr_write_data[interrupts-1:0]; + end + end + end +end +// end +//else +// begin +//// IE, IM, IP - Interrupt Enable, Interrupt Mask and Interrupt Pending CSRs +//always @(posedge clk_i `CFG_RESET_SENSITIVITY) +//begin +// if (rst_i == `TRUE) +// begin +// ie <= `FALSE; +// eie <= `FALSE; +//`ifdef CFG_DEBUG_ENABLED +// bie <= `FALSE; +//`endif +// ip <= {interrupts{1'b0}}; +// end +// else +// begin +// // Set IP bit when interrupt line is asserted +// ip <= asserted; +//`ifdef CFG_DEBUG_ENABLED +// if (non_debug_exception == `TRUE) +// begin +// // Save and then clear interrupt enable +// eie <= ie; +// ie <= `FALSE; +// end +// else if (debug_exception == `TRUE) +// begin +// // Save and then clear interrupt enable +// bie <= ie; +// ie <= `FALSE; +// end +//`else +// if (exception == `TRUE) +// begin +// // Save and then clear interrupt enable +// eie <= ie; +// ie <= `FALSE; +// end +//`endif +// else if (stall_x == `FALSE) +// begin +// if (eret_q_x == `TRUE) +// // Restore interrupt enable +// ie <= eie; +//`ifdef CFG_DEBUG_ENABLED +// else if (bret_q_x == `TRUE) +// // Restore interrupt enable +// ie <= bie; +//`endif +// else if (csr_write_enable == `TRUE) +// begin +// // Handle wcsr write +// if (csr == `LM32_CSR_IE) +// begin +// ie <= csr_write_data[0]; +// eie <= csr_write_data[1]; +//`ifdef CFG_DEBUG_ENABLED +// bie <= csr_write_data[2]; +//`endif +// end +// if (csr == `LM32_CSR_IP) +// ip <= asserted & ~csr_write_data[interrupts-1:0]; +// end +// end +// end +//end +// end +//endgenerate + +endmodule + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_jtag.v b/lm32/logic/sakc/rtl/lm32/lm32_jtag.v new file mode 100644 index 0000000..6613d31 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_jtag.v @@ -0,0 +1,491 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_jtag.v +// Title : JTAG interface +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +`ifdef CFG_JTAG_ENABLED + +`define LM32_DP 3'b000 +`define LM32_TX 3'b001 +`define LM32_RX 3'b010 + +// LM32 Debug Protocol commands IDs +`define LM32_DP_RNG 3:0 +`define LM32_DP_READ_MEMORY 4'b0001 +`define LM32_DP_WRITE_MEMORY 4'b0010 +`define LM32_DP_READ_SEQUENTIAL 4'b0011 +`define LM32_DP_WRITE_SEQUENTIAL 4'b0100 +`define LM32_DP_WRITE_CSR 4'b0101 +`define LM32_DP_BREAK 4'b0110 +`define LM32_DP_RESET 4'b0111 + +// States for FSM +`define LM32_JTAG_STATE_RNG 3:0 +`define LM32_JTAG_STATE_READ_COMMAND 4'h0 +`define LM32_JTAG_STATE_READ_BYTE_0 4'h1 +`define LM32_JTAG_STATE_READ_BYTE_1 4'h2 +`define LM32_JTAG_STATE_READ_BYTE_2 4'h3 +`define LM32_JTAG_STATE_READ_BYTE_3 4'h4 +`define LM32_JTAG_STATE_READ_BYTE_4 4'h5 +`define LM32_JTAG_STATE_PROCESS_COMMAND 4'h6 +`define LM32_JTAG_STATE_WAIT_FOR_MEMORY 4'h7 +`define LM32_JTAG_STATE_WAIT_FOR_CSR 4'h8 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_jtag ( + // ----- Inputs ------- + clk_i, + rst_i, + jtag_clk, + jtag_update, + jtag_reg_q, + jtag_reg_addr_q, +`ifdef CFG_JTAG_UART_ENABLED + csr, + csr_write_enable, + csr_write_data, + stall_x, +`endif +`ifdef CFG_HW_DEBUG_ENABLED + jtag_read_data, + jtag_access_complete, +`endif +`ifdef CFG_DEBUG_ENABLED + exception_q_w, +`endif + // ----- Outputs ------- +`ifdef CFG_JTAG_UART_ENABLED + jtx_csr_read_data, + jrx_csr_read_data, +`endif +`ifdef CFG_HW_DEBUG_ENABLED + jtag_csr_write_enable, + jtag_csr_write_data, + jtag_csr, + jtag_read_enable, + jtag_write_enable, + jtag_write_data, + jtag_address, +`endif +`ifdef CFG_DEBUG_ENABLED + jtag_break, + jtag_reset, +`endif + jtag_reg_d, + jtag_reg_addr_d + ); + + parameter lat_family = `LATTICE_FAMILY; + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input jtag_clk; // JTAG clock +input jtag_update; // JTAG data register has been updated +input [`LM32_BYTE_RNG] jtag_reg_q; // JTAG data register +input [2:0] jtag_reg_addr_q; // JTAG data register + +`ifdef CFG_JTAG_UART_ENABLED +input [`LM32_CSR_RNG] csr; // CSR to write +input csr_write_enable; // CSR write enable +input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR +input stall_x; // Stall instruction in X stage +`endif +`ifdef CFG_HW_DEBUG_ENABLED +input [`LM32_BYTE_RNG] jtag_read_data; // Data read from requested address +input jtag_access_complete; // Memory access if complete +`endif +`ifdef CFG_DEBUG_ENABLED +input exception_q_w; // Indicates an exception has occured in W stage +`endif + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +`ifdef CFG_JTAG_UART_ENABLED +output [`LM32_WORD_RNG] jtx_csr_read_data; // Value of JTX CSR for rcsr instructions +wire [`LM32_WORD_RNG] jtx_csr_read_data; +output [`LM32_WORD_RNG] jrx_csr_read_data; // Value of JRX CSR for rcsr instructions +wire [`LM32_WORD_RNG] jrx_csr_read_data; +`endif +`ifdef CFG_HW_DEBUG_ENABLED +output jtag_csr_write_enable; // CSR write enable +reg jtag_csr_write_enable; +output [`LM32_WORD_RNG] jtag_csr_write_data; // Data to write to specified CSR +wire [`LM32_WORD_RNG] jtag_csr_write_data; +output [`LM32_CSR_RNG] jtag_csr; // CSR to write +wire [`LM32_CSR_RNG] jtag_csr; +output jtag_read_enable; // Memory read enable +reg jtag_read_enable; +output jtag_write_enable; // Memory write enable +reg jtag_write_enable; +output [`LM32_BYTE_RNG] jtag_write_data; // Data to write to specified address +wire [`LM32_BYTE_RNG] jtag_write_data; +output [`LM32_WORD_RNG] jtag_address; // Memory read/write address +wire [`LM32_WORD_RNG] jtag_address; +`endif +`ifdef CFG_DEBUG_ENABLED +output jtag_break; // Request to raise a breakpoint exception +reg jtag_break; +output jtag_reset; // Request to raise a reset exception +reg jtag_reset; +`endif +output [`LM32_BYTE_RNG] jtag_reg_d; +reg [`LM32_BYTE_RNG] jtag_reg_d; +output [2:0] jtag_reg_addr_d; +wire [2:0] jtag_reg_addr_d; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +reg rx_toggle; // Clock-domain crossing registers +reg rx_toggle_r; // Registered version of rx_toggle +reg rx_toggle_r_r; // Registered version of rx_toggle_r +reg rx_toggle_r_r_r; // Registered version of rx_toggle_r_r + +reg [`LM32_BYTE_RNG] rx_byte; +reg [2:0] rx_addr; + +`ifdef CFG_JTAG_UART_ENABLED +reg [`LM32_BYTE_RNG] uart_tx_byte; // UART TX data +reg uart_tx_valid; // TX data is valid +reg [`LM32_BYTE_RNG] uart_rx_byte; // UART RX data +reg uart_rx_valid; // RX data is valid +`endif + +reg [`LM32_DP_RNG] command; // The last received command +`ifdef CFG_HW_DEBUG_ENABLED +reg [`LM32_BYTE_RNG] jtag_byte_0; // Registers to hold command paramaters +reg [`LM32_BYTE_RNG] jtag_byte_1; +reg [`LM32_BYTE_RNG] jtag_byte_2; +reg [`LM32_BYTE_RNG] jtag_byte_3; +reg [`LM32_BYTE_RNG] jtag_byte_4; +reg processing; // Indicates if we're still processing a memory read/write +`endif + +reg [`LM32_JTAG_STATE_RNG] state; // Current state of FSM + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +`ifdef CFG_HW_DEBUG_ENABLED +assign jtag_csr_write_data = {jtag_byte_0, jtag_byte_1, jtag_byte_2, jtag_byte_3}; +assign jtag_csr = jtag_byte_4[`LM32_CSR_RNG]; +assign jtag_address = {jtag_byte_0, jtag_byte_1, jtag_byte_2, jtag_byte_3}; +assign jtag_write_data = jtag_byte_4; +`endif + +// Generate status flags for reading via the JTAG interface +`ifdef CFG_JTAG_UART_ENABLED +assign jtag_reg_addr_d[1:0] = {uart_rx_valid, uart_tx_valid}; +`else +assign jtag_reg_addr_d[1:0] = 2'b00; +`endif +`ifdef CFG_HW_DEBUG_ENABLED +assign jtag_reg_addr_d[2] = processing; +`else +assign jtag_reg_addr_d[2] = 1'b0; +`endif + +`ifdef CFG_JTAG_UART_ENABLED +assign jtx_csr_read_data = {{`LM32_WORD_WIDTH-9{1'b0}}, uart_tx_valid, 8'h00}; +assign jrx_csr_read_data = {{`LM32_WORD_WIDTH-9{1'b0}}, uart_rx_valid, uart_rx_byte}; +`endif + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +// Toggle a flag when a JTAG write occurs +generate + if (lat_family == "EC" || lat_family == "ECP" || + lat_family == "XP" || lat_family == "ECP2" || lat_family == "ECP2M") begin + + always @(posedge jtag_clk `CFG_RESET_SENSITIVITY) + begin + if (rst_i == `TRUE) + rx_toggle <= 1'b0; + else + if (jtag_update == `TRUE) + rx_toggle <= ~rx_toggle; + end + + end else begin // for SC & SCM + + always @(negedge jtag_update `CFG_RESET_SENSITIVITY) + begin + if (rst_i == `TRUE) + rx_toggle <= 1'b0; + else + rx_toggle <= ~rx_toggle; + end + + end +endgenerate + +always @(*) +begin + rx_byte = jtag_reg_q; + rx_addr = jtag_reg_addr_q; +end + +// Clock domain crossing from JTAG clock domain to CPU clock domain +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + rx_toggle_r <= 1'b0; + rx_toggle_r_r <= 1'b0; + rx_toggle_r_r_r <= 1'b0; + end + else + begin + rx_toggle_r <= rx_toggle; + rx_toggle_r_r <= rx_toggle_r; + rx_toggle_r_r_r <= rx_toggle_r_r; + end +end + +// LM32 debug protocol state machine +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + state <= `LM32_JTAG_STATE_READ_COMMAND; + command <= 4'b0000; + jtag_reg_d <= 8'h00; +`ifdef CFG_HW_DEBUG_ENABLED + processing <= `FALSE; + jtag_csr_write_enable <= `FALSE; + jtag_read_enable <= `FALSE; + jtag_write_enable <= `FALSE; +`endif +`ifdef CFG_DEBUG_ENABLED + jtag_break <= `FALSE; + jtag_reset <= `FALSE; +`endif +`ifdef CFG_JTAG_UART_ENABLED + uart_tx_byte <= 8'h00; + uart_tx_valid <= `FALSE; + uart_rx_byte <= 8'h00; + uart_rx_valid <= `FALSE; +`endif + end + else + begin +`ifdef CFG_JTAG_UART_ENABLED + if ((csr_write_enable == `TRUE) && (stall_x == `FALSE)) + begin + case (csr) + `LM32_CSR_JTX: + begin + // Set flag indicating data is available + uart_tx_byte <= csr_write_data[`LM32_BYTE_0_RNG]; + uart_tx_valid <= `TRUE; + end + `LM32_CSR_JRX: + begin + // Clear flag indidicating data has been received + uart_rx_valid <= `FALSE; + end + endcase + end +`endif +`ifdef CFG_DEBUG_ENABLED + // When an exception has occured, clear the requests + if (exception_q_w == `TRUE) + begin + jtag_break <= `FALSE; + jtag_reset <= `FALSE; + end +`endif + case (state) + `LM32_JTAG_STATE_READ_COMMAND: + begin + // Wait for rx register to toggle which indicates new data is available + if (rx_toggle_r_r != rx_toggle_r_r_r) + begin + command <= rx_byte[7:4]; + case (rx_addr) +`ifdef CFG_DEBUG_ENABLED + `LM32_DP: + begin + case (rx_byte[7:4]) +`ifdef CFG_HW_DEBUG_ENABLED + `LM32_DP_READ_MEMORY: + state <= `LM32_JTAG_STATE_READ_BYTE_0; + `LM32_DP_READ_SEQUENTIAL: + begin + {jtag_byte_2, jtag_byte_3} <= {jtag_byte_2, jtag_byte_3} + 1'b1; + state <= `LM32_JTAG_STATE_PROCESS_COMMAND; + end + `LM32_DP_WRITE_MEMORY: + state <= `LM32_JTAG_STATE_READ_BYTE_0; + `LM32_DP_WRITE_SEQUENTIAL: + begin + {jtag_byte_2, jtag_byte_3} <= {jtag_byte_2, jtag_byte_3} + 1'b1; + state <= 5; + end + `LM32_DP_WRITE_CSR: + state <= `LM32_JTAG_STATE_READ_BYTE_0; +`endif + `LM32_DP_BREAK: + begin +`ifdef CFG_JTAG_UART_ENABLED + uart_rx_valid <= `FALSE; + uart_tx_valid <= `FALSE; +`endif + jtag_break <= `TRUE; + end + `LM32_DP_RESET: + begin +`ifdef CFG_JTAG_UART_ENABLED + uart_rx_valid <= `FALSE; + uart_tx_valid <= `FALSE; +`endif + jtag_reset <= `TRUE; + end + endcase + end +`endif +`ifdef CFG_JTAG_UART_ENABLED + `LM32_TX: + begin + uart_rx_byte <= rx_byte; + uart_rx_valid <= `TRUE; + end + `LM32_RX: + begin + jtag_reg_d <= uart_tx_byte; + uart_tx_valid <= `FALSE; + end +`endif + default: + ; + endcase + end + end +`ifdef CFG_HW_DEBUG_ENABLED + `LM32_JTAG_STATE_READ_BYTE_0: + begin + if (rx_toggle_r_r != rx_toggle_r_r_r) + begin + jtag_byte_0 <= rx_byte; + state <= `LM32_JTAG_STATE_READ_BYTE_1; + end + end + `LM32_JTAG_STATE_READ_BYTE_1: + begin + if (rx_toggle_r_r != rx_toggle_r_r_r) + begin + jtag_byte_1 <= rx_byte; + state <= `LM32_JTAG_STATE_READ_BYTE_2; + end + end + `LM32_JTAG_STATE_READ_BYTE_2: + begin + if (rx_toggle_r_r != rx_toggle_r_r_r) + begin + jtag_byte_2 <= rx_byte; + state <= `LM32_JTAG_STATE_READ_BYTE_3; + end + end + `LM32_JTAG_STATE_READ_BYTE_3: + begin + if (rx_toggle_r_r != rx_toggle_r_r_r) + begin + jtag_byte_3 <= rx_byte; + if (command == `LM32_DP_READ_MEMORY) + state <= `LM32_JTAG_STATE_PROCESS_COMMAND; + else + state <= `LM32_JTAG_STATE_READ_BYTE_4; + end + end + `LM32_JTAG_STATE_READ_BYTE_4: + begin + if (rx_toggle_r_r != rx_toggle_r_r_r) + begin + jtag_byte_4 <= rx_byte; + state <= `LM32_JTAG_STATE_PROCESS_COMMAND; + end + end + `LM32_JTAG_STATE_PROCESS_COMMAND: + begin + case (command) + `LM32_DP_READ_MEMORY, + `LM32_DP_READ_SEQUENTIAL: + begin + jtag_read_enable <= `TRUE; + processing <= `TRUE; + state <= `LM32_JTAG_STATE_WAIT_FOR_MEMORY; + end + `LM32_DP_WRITE_MEMORY, + `LM32_DP_WRITE_SEQUENTIAL: + begin + jtag_write_enable <= `TRUE; + processing <= `TRUE; + state <= `LM32_JTAG_STATE_WAIT_FOR_MEMORY; + end + `LM32_DP_WRITE_CSR: + begin + jtag_csr_write_enable <= `TRUE; + processing <= `TRUE; + state <= `LM32_JTAG_STATE_WAIT_FOR_CSR; + end + endcase + end + `LM32_JTAG_STATE_WAIT_FOR_MEMORY: + begin + if (jtag_access_complete == `TRUE) + begin + jtag_read_enable <= `FALSE; + jtag_reg_d <= jtag_read_data; + jtag_write_enable <= `FALSE; + processing <= `FALSE; + state <= `LM32_JTAG_STATE_READ_COMMAND; + end + end + `LM32_JTAG_STATE_WAIT_FOR_CSR: + begin + jtag_csr_write_enable <= `FALSE; + processing <= `FALSE; + state <= `LM32_JTAG_STATE_READ_COMMAND; + end +`endif + endcase + end +end + +endmodule + +`endif diff --git a/lm32/logic/sakc/rtl/lm32/lm32_load_store_unit.v b/lm32/logic/sakc/rtl/lm32/lm32_load_store_unit.v new file mode 100644 index 0000000..76b470f --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_load_store_unit.v @@ -0,0 +1,588 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_load_store_unit.v +// Title : Load and store unit +// Dependencies : lm32_include.v +// Version : 6.0.13 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_load_store_unit ( + // ----- Inputs ------- + clk_i, + rst_i, + // From pipeline + stall_a, + stall_x, + stall_m, + kill_x, + kill_m, + exception_m, + store_operand_x, + load_store_address_x, + load_store_address_m, + load_store_address_w, + load_q_x, + load_q_m, + store_q_m, + sign_extend_x, + size_x, +`ifdef CFG_DCACHE_ENABLED + dflush, +`endif + // From Wishbone + d_dat_i, + d_ack_i, + d_err_i, + d_rty_i, + // ----- Outputs ------- + // To pipeline +`ifdef CFG_DCACHE_ENABLED + dcache_refill_request, + dcache_restart_request, + dcache_stall_request, + dcache_refilling, +`endif + load_data_w, + stall_wb_load, + // To Wishbone + d_dat_o, + d_adr_o, + d_cyc_o, + d_sel_o, + d_stb_o, + d_we_o, + d_cti_o, + d_lock_o, + d_bte_o + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter associativity = 1; // Associativity of the cache (Number of ways) +parameter sets = 512; // Number of sets +parameter bytes_per_line = 16; // Number of bytes per cache line +parameter base_address = 0; // Base address of cachable memory +parameter limit = 0; // Limit (highest address) of cachable memory + +// For bytes_per_line == 4, we set 1 so part-select range isn't reversed, even though not really used +//localparam addr_offset_width = bytes_per_line == 4 ? 1 : clogb2(bytes_per_line)-1-2; +localparam addr_offset_width = 2; +localparam addr_offset_lsb = 2; +localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +input stall_a; // A stage stall +input stall_x; // X stage stall +input stall_m; // M stage stall +input kill_x; // Kill instruction in X stage +input kill_m; // Kill instruction in M stage +input exception_m; // An exception occured in the M stage + +input [`LM32_WORD_RNG] store_operand_x; // Data read from register to store +input [`LM32_WORD_RNG] load_store_address_x; // X stage load/store address +input [`LM32_WORD_RNG] load_store_address_m; // M stage load/store address +input [1:0] load_store_address_w; // W stage load/store address (only least two significant bits are needed) +input load_q_x; // Load instruction in X stage +input load_q_m; // Load instruction in M stage +input store_q_m; // Store instruction in M stage +input sign_extend_x; // Whether load instruction in X stage should sign extend or zero extend +input [`LM32_SIZE_RNG] size_x; // Size of load or store (byte, hword, word) + +`ifdef CFG_DCACHE_ENABLED +input dflush; // Flush the data cache +`endif + +input [`LM32_WORD_RNG] d_dat_i; // Data Wishbone interface read data +input d_ack_i; // Data Wishbone interface acknowledgement +input d_err_i; // Data Wishbone interface error +input d_rty_i; // Data Wishbone interface retry + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +`ifdef CFG_DCACHE_ENABLED +output dcache_refill_request; // Request to refill data cache +wire dcache_refill_request; +output dcache_restart_request; // Request to restart the instruction that caused a data cache miss +wire dcache_restart_request; +output dcache_stall_request; // Data cache stall request +wire dcache_stall_request; +output dcache_refilling; +wire dcache_refilling; +`endif + +output [`LM32_WORD_RNG] load_data_w; // Result of a load instruction +reg [`LM32_WORD_RNG] load_data_w; +output stall_wb_load; // Request to stall pipeline due to a load from the Wishbone interface +reg stall_wb_load; + +output [`LM32_WORD_RNG] d_dat_o; // Data Wishbone interface write data +reg [`LM32_WORD_RNG] d_dat_o; +output [`LM32_WORD_RNG] d_adr_o; // Data Wishbone interface address +reg [`LM32_WORD_RNG] d_adr_o; +output d_cyc_o; // Data Wishbone interface cycle +reg d_cyc_o; +output [`LM32_BYTE_SELECT_RNG] d_sel_o; // Data Wishbone interface byte select +reg [`LM32_BYTE_SELECT_RNG] d_sel_o; +output d_stb_o; // Data Wishbone interface strobe +reg d_stb_o; +output d_we_o; // Data Wishbone interface write enable +reg d_we_o; +output [`LM32_CTYPE_RNG] d_cti_o; // Data Wishbone interface cycle type +wire [`LM32_CTYPE_RNG] d_cti_o; +output d_lock_o; // Date Wishbone interface lock bus +wire d_lock_o; +output [`LM32_BTYPE_RNG] d_bte_o; // Data Wishbone interface burst type +wire [`LM32_BTYPE_RNG] d_bte_o; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +// Microcode pipeline registers - See inputs for description +reg [`LM32_SIZE_RNG] size_m; +reg [`LM32_SIZE_RNG] size_w; +reg sign_extend_m; +reg sign_extend_w; +reg [`LM32_WORD_RNG] store_data_x; +reg [`LM32_WORD_RNG] store_data_m; +reg [`LM32_BYTE_SELECT_RNG] byte_enable_x; +reg [`LM32_BYTE_SELECT_RNG] byte_enable_m; +wire [`LM32_WORD_RNG] data_m; +reg [`LM32_WORD_RNG] data_w; + +`ifdef CFG_DCACHE_ENABLED +wire dcache_select_x; // Select data cache to load from / store to +reg dcache_select_m; +wire [`LM32_WORD_RNG] dcache_data_m; // Data read from cache +wire [`LM32_WORD_RNG] dcache_refill_address; // Address to refill data cache from +reg dcache_refill_ready; // Indicates the next word of refill data is ready +wire last_word; // Indicates if this is the last word in the cache line +wire [`LM32_WORD_RNG] first_address; // First cache refill address +`endif +`ifdef CFG_DRAM_ENABLED +wire dram_select_x; // Select data RAM to load from / store to +reg dram_select_m; +wire [`LM32_WORD_RNG] dram_data_m; // Data read from data RAM +wire [`LM32_WORD_RNG] dram_store_data_m; // Data to write to RAM +`endif +wire wb_select_x; // Select Wishbone to load from / store to +reg wb_select_m; +reg [`LM32_WORD_RNG] wb_data_m; // Data read from Wishbone +reg wb_load_complete; // Indicates when a Wishbone load is complete + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +`ifdef CFG_DRAM_ENABLED +// Data RAM +pmi_ram_dp_true #( + // ----- Parameters ------- + .pmi_addr_depth_a (1 << (clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)), + .pmi_addr_width_a ((clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)), + .pmi_data_width_a (`LM32_WORD_WIDTH), + .pmi_addr_depth_b (1 << (clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)), + .pmi_addr_width_b ((clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)), + .pmi_data_width_b (`LM32_WORD_WIDTH), + .pmi_regmode_a ("noreg"), + .pmi_regmode_b ("noreg"), + .pmi_gsr ("enable"), + .pmi_resetmode ("async"), + .pmi_init_file (`CFG_DRAM_INIT_FILE), + .pmi_init_file_format ("hex"), + .module_type ("pmi_ram_dp") + ) ram ( + // ----- Inputs ------- + .ClockA (clk_i), + .ClockB (clk_i), + .ResetA (rst_i), + .ResetB (rst_i), + .DataInA ({32{1'b0}}), + .DataInB (dram_store_data_m), + .AddressA (load_store_address_x[(clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)+2-1:2]), + .AddressB (load_store_address_m[(clogb2(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)-1)+2-1:2]), + .ClockEnA (!stall_x), + .ClockEnB (!stall_m), + .WrA (`FALSE), + .WrB (store_q_m), + // ----- Outputs ------- + .QA (dram_data_m), + .QB () + ); +`endif + +`ifdef CFG_DCACHE_ENABLED +// Data cache +lm32_dcache #( + .associativity (associativity), + .sets (sets), + .bytes_per_line (bytes_per_line), + .base_address (base_address), + .limit (limit) + ) dcache ( + // ----- Inputs ----- + .clk_i (clk_i), + .rst_i (rst_i), + .stall_a (stall_a), + .stall_x (stall_x), + .stall_m (stall_m), + .address_x (load_store_address_x), + .address_m (load_store_address_m), + .load_q_m (load_q_m & dcache_select_m), + .store_q_m (store_q_m), + .store_data (store_data_m), + .store_byte_select (byte_enable_m), + .refill_ready (dcache_refill_ready), + .refill_data (wb_data_m), + .dflush (dflush), + // ----- Outputs ----- + .stall_request (dcache_stall_request), + .restart_request (dcache_restart_request), + .refill_request (dcache_refill_request), + .refill_address (dcache_refill_address), + .refilling (dcache_refilling), + .load_data (dcache_data_m) + ); +`endif + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +// Select where data should be loaded from / stored to +`ifdef CFG_DCACHE_ENABLED +assign dcache_select_x = (load_store_address_x >= `CFG_DCACHE_BASE_ADDRESS) && (load_store_address_x <= `CFG_DCACHE_LIMIT); +//assign dcache_select_x = (load_store_address_x >= `CFG_DCACHE_BASE_ADDRESS) && ~|load_store_address_x[`LM32_WORD_WIDTH-1:clogb2(`CFG_DCACHE_LIMIT-`CFG_DCACHE_BASE_ADDRESS)-1]; +`endif +`ifdef CFG_DRAM_ENABLED +assign dram_select_x = (load_store_address_x >= `CFG_DRAM_BASE_ADDRESS) && (load_store_address_x <= `CFG_DRAM_LIMIT); +`endif +assign wb_select_x = `TRUE +`ifdef CFG_DCACHE_ENABLED + && !dcache_select_x +`endif +`ifdef CFG_DRAM_ENABLED + && !dram_select_x +`endif + ; + +// Make sure data to store is in correct byte lane +always @(*) +begin + case (size_x) + `LM32_SIZE_BYTE: store_data_x = {4{store_operand_x[7:0]}}; + `LM32_SIZE_HWORD: store_data_x = {2{store_operand_x[15:0]}}; + `LM32_SIZE_WORD: store_data_x = store_operand_x; + default: store_data_x = {`LM32_WORD_WIDTH{1'bx}}; + endcase +end + +// Generate byte enable accoring to size of load or store and address being accessed +always @(*) +begin + casez ({size_x, load_store_address_x[1:0]}) + {`LM32_SIZE_BYTE, 2'b11}: byte_enable_x = 4'b0001; + {`LM32_SIZE_BYTE, 2'b10}: byte_enable_x = 4'b0010; + {`LM32_SIZE_BYTE, 2'b01}: byte_enable_x = 4'b0100; + {`LM32_SIZE_BYTE, 2'b00}: byte_enable_x = 4'b1000; + {`LM32_SIZE_HWORD, 2'b1?}: byte_enable_x = 4'b0011; + {`LM32_SIZE_HWORD, 2'b0?}: byte_enable_x = 4'b1100; + {`LM32_SIZE_WORD, 2'b??}: byte_enable_x = 4'b1111; + default: byte_enable_x = 4'bxxxx; + endcase +end + +`ifdef CFG_DRAM_ENABLED +// Only replace selected bytes +assign dram_store_data_m[`LM32_BYTE_0_RNG] = byte_enable_m[0] ? store_data_m[`LM32_BYTE_0_RNG] : dram_data_m[`LM32_BYTE_0_RNG]; +assign dram_store_data_m[`LM32_BYTE_1_RNG] = byte_enable_m[1] ? store_data_m[`LM32_BYTE_1_RNG] : dram_data_m[`LM32_BYTE_1_RNG]; +assign dram_store_data_m[`LM32_BYTE_2_RNG] = byte_enable_m[2] ? store_data_m[`LM32_BYTE_2_RNG] : dram_data_m[`LM32_BYTE_2_RNG]; +assign dram_store_data_m[`LM32_BYTE_3_RNG] = byte_enable_m[3] ? store_data_m[`LM32_BYTE_3_RNG] : dram_data_m[`LM32_BYTE_3_RNG]; +`endif + +// Select data from selected source +`ifdef CFG_DCACHE_ENABLED +`ifdef CFG_DRAM_ENABLED +assign data_m = wb_select_m == `TRUE + ? wb_data_m + : dram_select_m == `TRUE + ? dram_data_m + : dcache_data_m; +`else +assign data_m = wb_select_m == `TRUE ? wb_data_m : dcache_data_m; +`endif +`else +`ifdef CFG_DRAM_ENABLED +assign data_m = wb_select_m == `TRUE ? wb_data_m : dram_data_m; +`else +assign data_m = wb_data_m; +`endif +`endif + +// Sub-word selection and sign/zero-extension for loads +always @(*) +begin + casez ({size_w, load_store_address_w[1:0]}) + {`LM32_SIZE_BYTE, 2'b11}: load_data_w = {{24{sign_extend_w & data_w[7]}}, data_w[7:0]}; + {`LM32_SIZE_BYTE, 2'b10}: load_data_w = {{24{sign_extend_w & data_w[15]}}, data_w[15:8]}; + {`LM32_SIZE_BYTE, 2'b01}: load_data_w = {{24{sign_extend_w & data_w[23]}}, data_w[23:16]}; + {`LM32_SIZE_BYTE, 2'b00}: load_data_w = {{24{sign_extend_w & data_w[31]}}, data_w[31:24]}; + {`LM32_SIZE_HWORD, 2'b1?}: load_data_w = {{16{sign_extend_w & data_w[15]}}, data_w[15:0]}; + {`LM32_SIZE_HWORD, 2'b0?}: load_data_w = {{16{sign_extend_w & data_w[31]}}, data_w[31:16]}; + {`LM32_SIZE_WORD, 2'b??}: load_data_w = data_w; + default: load_data_w = {`LM32_WORD_WIDTH{1'bx}}; + endcase +end + +// Unused Wishbone signals +assign d_cti_o = `LM32_CTYPE_WIDTH'd0; +assign d_lock_o = `FALSE; +assign d_bte_o = `LM32_BTYPE_WIDTH'd0; + +`ifdef CFG_DCACHE_ENABLED +// Generate signal to indicate last word in cache line +generate + if (bytes_per_line > 4) + begin +assign first_address = {dcache_refill_address[`LM32_WORD_WIDTH-1:addr_offset_msb+1], {addr_offset_width{1'b0}}, 2'b00}; +assign last_word = (&d_adr_o[addr_offset_msb:addr_offset_lsb]) == 1'b1; + end + else + begin +assign first_address = {dcache_refill_address[`LM32_WORD_WIDTH-1:2], 2'b00}; +assign last_word = `TRUE; + end +endgenerate +`endif + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +// Data Wishbone interface +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + d_cyc_o <= `FALSE; + d_stb_o <= `FALSE; + d_dat_o <= {`LM32_WORD_WIDTH{1'b0}}; + d_adr_o <= {`LM32_WORD_WIDTH{1'b0}}; + d_sel_o <= {`LM32_BYTE_SELECT_WIDTH{`FALSE}}; + d_we_o <= `FALSE; + wb_data_m <= {`LM32_WORD_WIDTH{1'b0}}; + wb_load_complete <= `FALSE; + stall_wb_load <= `FALSE; +`ifdef CFG_DCACHE_ENABLED + dcache_refill_ready <= `FALSE; +`endif + end + else + begin +`ifdef CFG_DCACHE_ENABLED + // Refill ready should only be asserted for a single cycle + dcache_refill_ready <= `FALSE; +`endif + // Is a Wishbone cycle already in progress? + if (d_cyc_o == `TRUE) + begin + // Is the cycle complete? + if ((d_ack_i == `TRUE) || (d_err_i == `TRUE)) + begin +`ifdef CFG_DCACHE_ENABLED + if ((dcache_refilling == `TRUE) && (!last_word)) + begin + // Fetch next word of cache line + d_adr_o[addr_offset_msb:addr_offset_lsb] <= d_adr_o[addr_offset_msb:addr_offset_lsb] + 1'b1; + end + else +`endif + begin + // Refill/access complete + d_cyc_o <= `FALSE; + d_stb_o <= `FALSE; + end +`ifdef CFG_DCACHE_ENABLED + // If we are performing a refill, indicate to cache next word of data is ready + dcache_refill_ready <= dcache_refilling; +`endif + // Register data read from Wishbone interface + wb_data_m <= d_dat_i; + // Don't set when stores complete - otherwise we'll deadlock if load in m stage + wb_load_complete <= !d_we_o; + end + // synthesis translate_off + if (d_err_i == `TRUE) + $display ("Data bus error. Address: %x", d_adr_o); + // synthesis translate_on + end + else + begin +`ifdef CFG_DCACHE_ENABLED + if (dcache_refill_request == `TRUE) + begin + // Start cache refill + d_adr_o <= first_address; + d_cyc_o <= `TRUE; + d_sel_o <= {`LM32_WORD_WIDTH/8{`TRUE}}; + d_stb_o <= `TRUE; + d_we_o <= `FALSE; + end + else +`endif + if ( (store_q_m == `TRUE) + && (stall_m == `FALSE) +`ifdef CFG_DRAM_ENABLED + && !dram_select_m +`endif + ) + begin + // Data cache is write through, so all stores go to memory + d_dat_o <= store_data_m; + d_adr_o <= load_store_address_m; + d_cyc_o <= `TRUE; + d_sel_o <= byte_enable_m; + d_stb_o <= `TRUE; + d_we_o <= `TRUE; + end + else if ( (load_q_m == `TRUE) + && (wb_select_m == `TRUE) + && (wb_load_complete == `FALSE) + /* stall_m will be TRUE, because stall_wb_load will be TRUE */ + ) + begin + // Read requested address + stall_wb_load <= `FALSE; + d_adr_o <= load_store_address_m; + d_cyc_o <= `TRUE; + d_sel_o <= byte_enable_m; + d_stb_o <= `TRUE; + d_we_o <= `FALSE; + end + end + // Clear load/store complete flag when instruction leaves M stage + if (stall_m == `FALSE) + wb_load_complete <= `FALSE; + // When a Wishbone load first enters the M stage, we need to stall it + if ((load_q_x == `TRUE) && (wb_select_x == `TRUE) && (stall_x == `FALSE)) + stall_wb_load <= `TRUE; + // Clear stall request if load instruction is killed + if ((kill_m == `TRUE) || (exception_m == `TRUE)) + stall_wb_load <= `FALSE; + end +end + +// Pipeline registers + +// X/M stage pipeline registers +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + sign_extend_m <= `FALSE; + size_m <= 2'b00; + byte_enable_m <= `FALSE; + store_data_m <= {`LM32_WORD_WIDTH{1'b0}}; +`ifdef CFG_DCACHE_ENABLED + dcache_select_m <= `FALSE; +`endif +`ifdef CFG_DRAM_ENABLED + dram_select_m <= `FALSE; +`endif + wb_select_m <= `FALSE; + end + else + begin + if (stall_m == `FALSE) + begin + sign_extend_m <= sign_extend_x; + size_m <= size_x; + byte_enable_m <= byte_enable_x; + store_data_m <= store_data_x; +`ifdef CFG_DCACHE_ENABLED + dcache_select_m <= dcache_select_x; +`endif +`ifdef CFG_DRAM_ENABLED + dram_select_m <= dram_select_x; +`endif + wb_select_m <= wb_select_x; + end + end +end + +// M/W stage pipeline registers +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + size_w <= 2'b00; + data_w <= {`LM32_WORD_WIDTH{1'b0}}; + sign_extend_w <= `FALSE; + end + else + begin + size_w <= size_m; + data_w <= data_m; + sign_extend_w <= sign_extend_m; + end +end + +///////////////////////////////////////////////////// +// Behavioural Logic +///////////////////////////////////////////////////// + +// synthesis translate_off + +// Check for non-aligned loads or stores +always @(posedge clk_i) +begin + if (((load_q_m == `TRUE) || (store_q_m == `TRUE)) && (stall_m == `FALSE)) + begin + if ((size_m === `LM32_SIZE_HWORD) && (load_store_address_m[0] !== 1'b0)) + $display ("Warning: Non-aligned halfword access. Address: 0x%0x Time: %0t.", load_store_address_m, $time); + if ((size_m === `LM32_SIZE_WORD) && (load_store_address_m[1:0] !== 2'b00)) + $display ("Warning: Non-aligned word access. Address: 0x%0x Time: %0t.", load_store_address_m, $time); + end +end + +// synthesis translate_on + +endmodule + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_logic_op.v b/lm32/logic/sakc/rtl/lm32/lm32_logic_op.v new file mode 100644 index 0000000..ff1f702 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_logic_op.v @@ -0,0 +1,71 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_logic_op.v +// Title : Logic operations (and / or / not etc) +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_logic_op ( + // ----- Inputs ------- + logic_op_x, + operand_0_x, + operand_1_x, + // ----- Outputs ------- + logic_result_x + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input [`LM32_LOGIC_OP_RNG] logic_op_x; +input [`LM32_WORD_RNG] operand_0_x; +input [`LM32_WORD_RNG] operand_1_x; + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [`LM32_WORD_RNG] logic_result_x; +reg [`LM32_WORD_RNG] logic_result_x; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +integer logic_idx; + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +always @* +begin + for(logic_idx = 0; logic_idx < `LM32_WORD_WIDTH; logic_idx = logic_idx + 1) + logic_result_x[logic_idx] = logic_op_x[{operand_1_x[logic_idx], operand_0_x[logic_idx]}]; +end + +endmodule + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_mc_arithmetic.v b/lm32/logic/sakc/rtl/lm32/lm32_mc_arithmetic.v new file mode 100644 index 0000000..fca4fb4 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_mc_arithmetic.v @@ -0,0 +1,283 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm_mc_arithmetic.v +// Title : Multi-cycle arithmetic unit. +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +`define LM32_MC_STATE_RNG 2:0 +`define LM32_MC_STATE_IDLE 3'b000 +`define LM32_MC_STATE_MULTIPLY 3'b001 +`define LM32_MC_STATE_MODULUS 3'b010 +`define LM32_MC_STATE_DIVIDE 3'b011 +`define LM32_MC_STATE_SHIFT_LEFT 3'b100 +`define LM32_MC_STATE_SHIFT_RIGHT 3'b101 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_mc_arithmetic ( + // ----- Inputs ----- + clk_i, + rst_i, + stall_d, + kill_x, +`ifdef CFG_MC_DIVIDE_ENABLED + divide_d, + modulus_d, +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + multiply_d, +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + shift_left_d, + shift_right_d, + sign_extend_d, +`endif + operand_0_d, + operand_1_d, + // ----- Ouputs ----- + result_x, +`ifdef CFG_MC_DIVIDE_ENABLED + divide_by_zero_x, +`endif + stall_request_x + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset +input stall_d; // Stall instruction in D stage +input kill_x; // Kill instruction in X stage +`ifdef CFG_MC_DIVIDE_ENABLED +input divide_d; // Perform divide +input modulus_d; // Perform modulus +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED +input multiply_d; // Perform multiply +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +input shift_left_d; // Perform left shift +input shift_right_d; // Perform right shift +input sign_extend_d; // Whether to sign-extend (arithmetic) or zero-extend (logical) +`endif +input [`LM32_WORD_RNG] operand_0_d; +input [`LM32_WORD_RNG] operand_1_d; + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [`LM32_WORD_RNG] result_x; // Result of operation +reg [`LM32_WORD_RNG] result_x; +`ifdef CFG_MC_DIVIDE_ENABLED +output divide_by_zero_x; // A divide by zero was attempted +reg divide_by_zero_x; +`endif +output stall_request_x; // Request to stall pipeline from X stage back +wire stall_request_x; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +reg [`LM32_WORD_RNG] p; // Temporary registers +reg [`LM32_WORD_RNG] a; +reg [`LM32_WORD_RNG] b; +`ifdef CFG_MC_DIVIDE_ENABLED +wire [32:0] t; +`endif + +reg [`LM32_MC_STATE_RNG] state; // Current state of FSM +reg [5:0] cycles; // Number of cycles remaining in the operation + +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +reg sign_extend_x; // Whether to sign extend of zero extend right shifts +wire fill_value; // Value to fill with for right barrel-shifts +`endif + +///////////////////////////////////////////////////// +// Combinational logic +///////////////////////////////////////////////////// + +// Stall pipeline while any operation is being performed +assign stall_request_x = state != `LM32_MC_STATE_IDLE; + +`ifdef CFG_MC_DIVIDE_ENABLED +// Subtraction +assign t = {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]} - b; +`endif + +`ifdef CFG_MC_BARREL_SHIFT_ENABLED +// Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift +assign fill_value = (sign_extend_x == `TRUE) & b[`LM32_WORD_WIDTH-1]; +`endif + +///////////////////////////////////////////////////// +// Sequential logic +///////////////////////////////////////////////////// + +// Perform right shift +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + cycles <= {6{1'b0}}; + p <= {`LM32_WORD_WIDTH{1'b0}}; + a <= {`LM32_WORD_WIDTH{1'b0}}; + b <= {`LM32_WORD_WIDTH{1'b0}}; +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + sign_extend_x <= 1'b0; +`endif +`ifdef CFG_MC_DIVIDE_ENABLED + divide_by_zero_x <= `FALSE; +`endif + result_x <= {`LM32_WORD_WIDTH{1'b0}}; + state <= `LM32_MC_STATE_IDLE; + end + else + begin +`ifdef CFG_MC_DIVIDE_ENABLED + divide_by_zero_x <= `FALSE; +`endif + case (state) + `LM32_MC_STATE_IDLE: + begin + if (stall_d == `FALSE) + begin + cycles <= `LM32_WORD_WIDTH; + p <= 32'b0; + a <= operand_0_d; + b <= operand_1_d; +`ifdef CFG_MC_DIVIDE_ENABLED + if (divide_d == `TRUE) + state <= `LM32_MC_STATE_DIVIDE; + if (modulus_d == `TRUE) + state <= `LM32_MC_STATE_MODULUS; +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + if (multiply_d == `TRUE) + state <= `LM32_MC_STATE_MULTIPLY; +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + if (shift_left_d == `TRUE) + begin + state <= `LM32_MC_STATE_SHIFT_LEFT; + sign_extend_x <= sign_extend_d; + cycles <= operand_1_d[4:0]; + a <= operand_0_d; + b <= operand_0_d; + end + if (shift_right_d == `TRUE) + begin + state <= `LM32_MC_STATE_SHIFT_RIGHT; + sign_extend_x <= sign_extend_d; + cycles <= operand_1_d[4:0]; + a <= operand_0_d; + b <= operand_0_d; + end +`endif + end + end +`ifdef CFG_MC_DIVIDE_ENABLED + `LM32_MC_STATE_DIVIDE: + begin + if (t[32] == 1'b0) + begin + p <= t[31:0]; + a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1}; + end + else + begin + p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]}; + a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0}; + end + result_x <= a; + if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE)) + begin + // Check for divide by zero + divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}}; + state <= `LM32_MC_STATE_IDLE; + end + cycles <= cycles - 1'b1; + end + `LM32_MC_STATE_MODULUS: + begin + if (t[32] == 1'b0) + begin + p <= t[31:0]; + a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1}; + end + else + begin + p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]}; + a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0}; + end + result_x <= p; + if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE)) + begin + // Check for divide by zero + divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}}; + state <= `LM32_MC_STATE_IDLE; + end + cycles <= cycles - 1'b1; + end +`endif +`ifdef CFG_MC_MULTIPLY_ENABLED + `LM32_MC_STATE_MULTIPLY: + begin + if (b[0] == 1'b1) + p <= p + a; + b <= {1'b0, b[`LM32_WORD_WIDTH-1:1]}; + a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0}; + result_x <= p; + if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE)) + state <= `LM32_MC_STATE_IDLE; + cycles <= cycles - 1'b1; + end +`endif +`ifdef CFG_MC_BARREL_SHIFT_ENABLED + `LM32_MC_STATE_SHIFT_LEFT: + begin + a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0}; + result_x <= a; + if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE)) + state <= `LM32_MC_STATE_IDLE; + cycles <= cycles - 1'b1; + end + `LM32_MC_STATE_SHIFT_RIGHT: + begin + b <= {fill_value, b[`LM32_WORD_WIDTH-1:1]}; + result_x <= b; + if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE)) + state <= `LM32_MC_STATE_IDLE; + cycles <= cycles - 1'b1; + end +`endif + endcase + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_monitor.v b/lm32/logic/sakc/rtl/lm32/lm32_monitor.v new file mode 100644 index 0000000..12749b6 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_monitor.v @@ -0,0 +1,164 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_monitor.v +// Title : Debug monitor memory Wishbone interface +// Version : 6.1.17 +// ============================================================================= + +`include "system_conf.v" +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_monitor ( + // ----- Inputs ------- + clk_i, + rst_i, + MON_ADR_I, + MON_CYC_I, + MON_DAT_I, + MON_SEL_I, + MON_STB_I, + MON_WE_I, + MON_LOCK_I, + MON_CTI_I, + MON_BTE_I, + // ----- Outputs ------- + MON_ACK_O, + MON_RTY_O, + MON_DAT_O, + MON_ERR_O + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Wishbone clock +input rst_i; // Wishbone reset +input [`LM32_WORD_RNG] MON_ADR_I; // Wishbone address +input MON_STB_I; // Wishbone strobe +input MON_CYC_I; // Wishbone cycle +input [`LM32_WORD_RNG] MON_DAT_I; // Wishbone write data +input [`LM32_BYTE_SELECT_RNG] MON_SEL_I; // Wishbone byte select +input MON_WE_I; // Wishbone write enable +input MON_LOCK_I; // Wishbone locked transfer +input [`LM32_CTYPE_RNG] MON_CTI_I; // Wishbone cycle type +input [`LM32_BTYPE_RNG] MON_BTE_I; // Wishbone burst type + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output MON_ACK_O; // Wishbone acknowlege +reg MON_ACK_O; +output [`LM32_WORD_RNG] MON_DAT_O; // Wishbone data output +reg [`LM32_WORD_RNG] MON_DAT_O; +output MON_RTY_O; // Wishbone retry +wire MON_RTY_O; +output MON_ERR_O; // Wishbone error +wire MON_ERR_O; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +reg [1:0] state; // Current state of FSM +wire [`LM32_WORD_RNG] data; // Data read from RAM +reg write_enable; // RAM write enable +reg [`LM32_WORD_RNG] write_data; // RAM write data + +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +lm32_monitor_ram ram ( + // ----- Inputs ------- + .ClockA (clk_i), + .ClockB (clk_i), + .ResetA (rst_i), + .ResetB (rst_i), + .ClockEnA (`TRUE), + .ClockEnB (`FALSE), + .AddressA (MON_ADR_I[10:2]), + .DataInA (write_data), + .WrA (write_enable), + .WrB (`FALSE), + // ----- Outputs ------- + .QA (data) + ); + +///////////////////////////////////////////////////// +// Combinational Logic +///////////////////////////////////////////////////// + +assign MON_RTY_O = `FALSE; +assign MON_ERR_O = `FALSE; + +///////////////////////////////////////////////////// +// Sequential Logic +///////////////////////////////////////////////////// + +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + write_enable <= `FALSE; + MON_ACK_O <= `FALSE; + MON_DAT_O <= {`LM32_WORD_WIDTH{1'bx}}; + state <= 2'b00; + end + else + begin + case (state) + 2'b00: + begin + // Wait for a Wishbone access + if ((MON_STB_I == `TRUE) && (MON_CYC_I == `TRUE)) + state <= 2'b01; + end + 2'b01: + begin + // Output read data to Wishbone + MON_ACK_O <= `TRUE; + MON_DAT_O <= data; + // Sub-word writes are performed using read-modify-write + // as the Lattice EBRs don't support byte enables + if (MON_WE_I == `TRUE) + write_enable <= `TRUE; + write_data[7:0] <= MON_SEL_I[0] ? MON_DAT_I[7:0] : data[7:0]; + write_data[15:8] <= MON_SEL_I[1] ? MON_DAT_I[15:8] : data[15:8]; + write_data[23:16] <= MON_SEL_I[2] ? MON_DAT_I[23:16] : data[23:16]; + write_data[31:24] <= MON_SEL_I[3] ? MON_DAT_I[31:24] : data[31:24]; + state <= 2'b10; + end + 2'b10: + begin + // Wishbone access occurs in this cycle + write_enable <= `FALSE; + MON_ACK_O <= `FALSE; + MON_DAT_O <= {`LM32_WORD_WIDTH{1'bx}}; + state <= 2'b00; + end + endcase + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_monitor_ram.v b/lm32/logic/sakc/rtl/lm32/lm32_monitor_ram.v new file mode 100644 index 0000000..fcfe643 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_monitor_ram.v @@ -0,0 +1,1397 @@ +`include "system_conf.v" + +`timescale 1 ns / 1 ps +module lm32_monitor_ram (DataInA, DataInB, AddressA, AddressB, ClockA, + ClockB, ClockEnA, ClockEnB, WrA, WrB, ResetA, ResetB, QA, QB); + input [31:0] DataInA; + input [31:0] DataInB; + input [8:0] AddressA; + input [8:0] AddressB; + input ClockA; + input ClockB; + input ClockEnA; + input ClockEnB; + input WrA; + input WrB; + input ResetA; + input ResetB; + output [31:0] QA; + output [31:0] QB; + + parameter lat_family = `LATTICE_FAMILY; + + generate + if (lat_family == "EC" || lat_family == "ECP" || lat_family == "XP") begin + /* Verilog netlist generated by SCUBA ispLever_v51_SP2_Build (10) */ + /* Module Version: 2.0 */ + /* c:\applications\ispTools5.1\ispfpga\bin\nt\scuba.exe -w -lang verilog -synth synplify -bus_exp 7 -bb -arch ep5g00 -type bram -wp 11 -rp 1010 -addr_width 9 -data_width 32 -num_rows 512 -gsr ENABLED -writemode NORMAL -resetmode ASYNC -memfile ../../source/jtag_rom_monitor/rom.mem -memformat hex */ + + // synopsys translate_off + defparam lm32_monitor_ram_0_0_1.INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_17 = 320'h00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B; + defparam lm32_monitor_ram_0_0_1.INITVAL_16 = 320'h1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB; + defparam lm32_monitor_ram_0_0_1.INITVAL_15 = 320'h0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3; + defparam lm32_monitor_ram_0_0_1.INITVAL_14 = 320'h00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019; + defparam lm32_monitor_ram_0_0_1.INITVAL_13 = 320'h00035100180003510013000301001200030100110003010010000301000900030100080003010007; + defparam lm32_monitor_ram_0_0_1.INITVAL_12 = 320'h010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004; + defparam lm32_monitor_ram_0_0_1.INITVAL_11 = 320'h000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3; + defparam lm32_monitor_ram_0_0_1.INITVAL_10 = 320'h10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF; + defparam lm32_monitor_ram_0_0_1.INITVAL_0F = 320'h0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008; + defparam lm32_monitor_ram_0_0_1.INITVAL_0E = 320'h100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008; + defparam lm32_monitor_ram_0_0_1.INITVAL_0D = 320'h100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002; + defparam lm32_monitor_ram_0_0_1.INITVAL_0C = 320'h10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090; + defparam lm32_monitor_ram_0_0_1.INITVAL_0B = 320'h300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048; + defparam lm32_monitor_ram_0_0_1.INITVAL_0A = 320'h10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008; + defparam lm32_monitor_ram_0_0_1.INITVAL_09 = 320'h100040000000070200802000020090200002008C20000200883007C100743006C200681006400060; + defparam lm32_monitor_ram_0_0_1.INITVAL_08 = 320'h3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020; + defparam lm32_monitor_ram_0_0_1.INITVAL_07 = 320'h3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001; + defparam lm32_monitor_ram_0_0_1.INITVAL_06 = 320'h100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068; + defparam lm32_monitor_ram_0_0_1.INITVAL_05 = 320'h10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028; + defparam lm32_monitor_ram_0_0_1.INITVAL_04 = 320'h10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000; + defparam lm32_monitor_ram_0_0_1.INITVAL_03 = 320'h000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_02 = 320'h000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_01 = 320'h0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000; + defparam lm32_monitor_ram_0_0_1.INITVAL_00 = 320'h0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000; + defparam lm32_monitor_ram_0_0_1.CSDECODE_B = "000"; + defparam lm32_monitor_ram_0_0_1.CSDECODE_A = "000"; + defparam lm32_monitor_ram_0_0_1.WRITEMODE_B = "NORMAL"; + defparam lm32_monitor_ram_0_0_1.WRITEMODE_A = "NORMAL"; + defparam lm32_monitor_ram_0_0_1.GSR = "ENABLED"; + defparam lm32_monitor_ram_0_0_1.RESETMODE = "ASYNC"; + defparam lm32_monitor_ram_0_0_1.REGMODE_B = "NOREG"; + defparam lm32_monitor_ram_0_0_1.REGMODE_A = "NOREG"; + defparam lm32_monitor_ram_0_0_1.DATA_WIDTH_B = 18; + defparam lm32_monitor_ram_0_0_1.DATA_WIDTH_A = 18; + // synopsys translate_on + DP8KA lm32_monitor_ram_0_0_1 (.CEA(ClockEnA), .CLKA(ClockA), .WEA(WrA), + .CSA0(scuba_vlo), .CSA1(scuba_vlo), .CSA2(scuba_vlo), .RSTA(ResetA), + .CEB(ClockEnB), .CLKB(ClockB), .WEB(WrB), .CSB0(scuba_vlo), .CSB1(scuba_vlo), + .CSB2(scuba_vlo), .RSTB(ResetB), .DIA0(DataInA[0]), .DIA1(DataInA[1]), + .DIA2(DataInA[2]), .DIA3(DataInA[3]), .DIA4(DataInA[4]), .DIA5(DataInA[5]), + .DIA6(DataInA[6]), .DIA7(DataInA[7]), .DIA8(DataInA[8]), .DIA9(DataInA[9]), + .DIA10(DataInA[10]), .DIA11(DataInA[11]), .DIA12(DataInA[12]), .DIA13(DataInA[13]), + .DIA14(DataInA[14]), .DIA15(DataInA[15]), .DIA16(DataInA[16]), .DIA17(DataInA[17]), + .ADA0(scuba_vhi), .ADA1(scuba_vhi), .ADA2(scuba_vlo), .ADA3(scuba_vlo), + .ADA4(AddressA[0]), .ADA5(AddressA[1]), .ADA6(AddressA[2]), .ADA7(AddressA[3]), + .ADA8(AddressA[4]), .ADA9(AddressA[5]), .ADA10(AddressA[6]), .ADA11(AddressA[7]), + .ADA12(AddressA[8]), .DIB0(DataInB[0]), .DIB1(DataInB[1]), .DIB2(DataInB[2]), + .DIB3(DataInB[3]), .DIB4(DataInB[4]), .DIB5(DataInB[5]), .DIB6(DataInB[6]), + .DIB7(DataInB[7]), .DIB8(DataInB[8]), .DIB9(DataInB[9]), .DIB10(DataInB[10]), + .DIB11(DataInB[11]), .DIB12(DataInB[12]), .DIB13(DataInB[13]), .DIB14(DataInB[14]), + .DIB15(DataInB[15]), .DIB16(DataInB[16]), .DIB17(DataInB[17]), .ADB0(scuba_vhi), + .ADB1(scuba_vhi), .ADB2(scuba_vlo), .ADB3(scuba_vlo), .ADB4(AddressB[0]), + .ADB5(AddressB[1]), .ADB6(AddressB[2]), .ADB7(AddressB[3]), .ADB8(AddressB[4]), + .ADB9(AddressB[5]), .ADB10(AddressB[6]), .ADB11(AddressB[7]), .ADB12(AddressB[8]), + .DOA0(QA[0]), .DOA1(QA[1]), .DOA2(QA[2]), .DOA3(QA[3]), .DOA4(QA[4]), + .DOA5(QA[5]), .DOA6(QA[6]), .DOA7(QA[7]), .DOA8(QA[8]), .DOA9(QA[9]), + .DOA10(QA[10]), .DOA11(QA[11]), .DOA12(QA[12]), .DOA13(QA[13]), + .DOA14(QA[14]), .DOA15(QA[15]), .DOA16(QA[16]), .DOA17(QA[17]), + .DOB0(QB[0]), .DOB1(QB[1]), .DOB2(QB[2]), .DOB3(QB[3]), .DOB4(QB[4]), + .DOB5(QB[5]), .DOB6(QB[6]), .DOB7(QB[7]), .DOB8(QB[8]), .DOB9(QB[9]), + .DOB10(QB[10]), .DOB11(QB[11]), .DOB12(QB[12]), .DOB13(QB[13]), + .DOB14(QB[14]), .DOB15(QB[15]), .DOB16(QB[16]), .DOB17(QB[17])) + /* synthesis INITVAL_1F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_19="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_18="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_17="0x00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B" */ + /* synthesis INITVAL_16="0x1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB" */ + /* synthesis INITVAL_15="0x0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3" */ + /* synthesis INITVAL_14="0x00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019" */ + /* synthesis INITVAL_13="0x00035100180003510013000301001200030100110003010010000301000900030100080003010007" */ + /* synthesis INITVAL_12="0x010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004" */ + /* synthesis INITVAL_11="0x000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3" */ + /* synthesis INITVAL_10="0x10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF" */ + /* synthesis INITVAL_0F="0x0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008" */ + /* synthesis INITVAL_0E="0x100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008" */ + /* synthesis INITVAL_0D="0x100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002" */ + /* synthesis INITVAL_0C="0x10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090" */ + /* synthesis INITVAL_0B="0x300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048" */ + /* synthesis INITVAL_0A="0x10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008" */ + /* synthesis INITVAL_09="0x100040000000070200802000020090200002008C20000200883007C100743006C200681006400060" */ + /* synthesis INITVAL_08="0x3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020" */ + /* synthesis INITVAL_07="0x3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001" */ + /* synthesis INITVAL_06="0x100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068" */ + /* synthesis INITVAL_05="0x10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028" */ + /* synthesis INITVAL_04="0x10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000" */ + /* synthesis INITVAL_03="0x000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000" */ + /* synthesis INITVAL_02="0x000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000" */ + /* synthesis INITVAL_01="0x0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000" */ + /* synthesis INITVAL_00="0x0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000" */ + /* synthesis CSDECODE_B="000" */ + /* synthesis CSDECODE_A="000" */ + /* synthesis WRITEMODE_B="NORMAL" */ + /* synthesis WRITEMODE_A="NORMAL" */ + /* synthesis GSR="ENABLED" */ + /* synthesis RESETMODE="ASYNC" */ + /* synthesis REGMODE_B="NOREG" */ + /* synthesis REGMODE_A="NOREG" */ + /* synthesis DATA_WIDTH_B="18" */ + /* synthesis DATA_WIDTH_A="18" */; + + VHI scuba_vhi_inst (.Z(scuba_vhi)); + + VLO scuba_vlo_inst (.Z(scuba_vlo)); + + // synopsys translate_off + defparam lm32_monitor_ram_0_1_0.INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + defparam lm32_monitor_ram_0_1_0.INITVAL_17 = 320'h0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF; + defparam lm32_monitor_ram_0_1_0.INITVAL_16 = 320'h00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF; + defparam lm32_monitor_ram_0_1_0.INITVAL_15 = 320'h00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363; + defparam lm32_monitor_ram_0_1_0.INITVAL_14 = 320'h00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10; + defparam lm32_monitor_ram_0_1_0.INITVAL_13 = 320'h0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08; + defparam lm32_monitor_ram_0_1_0.INITVAL_12 = 320'h02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7; + defparam lm32_monitor_ram_0_1_0.INITVAL_11 = 320'h00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708; + defparam lm32_monitor_ram_0_1_0.INITVAL_10 = 320'h01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708; + defparam lm32_monitor_ram_0_1_0.INITVAL_0F = 320'h024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7; + defparam lm32_monitor_ram_0_1_0.INITVAL_0E = 320'h00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0; + defparam lm32_monitor_ram_0_1_0.INITVAL_0D = 320'h00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108; + defparam lm32_monitor_ram_0_1_0.INITVAL_0C = 320'h01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7; + defparam lm32_monitor_ram_0_1_0.INITVAL_0B = 320'h0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4; + defparam lm32_monitor_ram_0_1_0.INITVAL_0A = 320'h00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0; + defparam lm32_monitor_ram_0_1_0.INITVAL_09 = 320'h00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6; + defparam lm32_monitor_ram_0_1_0.INITVAL_08 = 320'h00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2; + defparam lm32_monitor_ram_0_1_0.INITVAL_07 = 320'h00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008; + defparam lm32_monitor_ram_0_1_0.INITVAL_06 = 320'h0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE; + defparam lm32_monitor_ram_0_1_0.INITVAL_05 = 320'h016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA; + defparam lm32_monitor_ram_0_1_0.INITVAL_04 = 320'h016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8; + defparam lm32_monitor_ram_0_1_0.INITVAL_03 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600; + defparam lm32_monitor_ram_0_1_0.INITVAL_02 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600; + defparam lm32_monitor_ram_0_1_0.INITVAL_01 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600; + defparam lm32_monitor_ram_0_1_0.INITVAL_00 = 320'h00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600; + defparam lm32_monitor_ram_0_1_0.CSDECODE_B = "000"; + defparam lm32_monitor_ram_0_1_0.CSDECODE_A = "000"; + defparam lm32_monitor_ram_0_1_0.WRITEMODE_B = "NORMAL"; + defparam lm32_monitor_ram_0_1_0.WRITEMODE_A = "NORMAL"; + defparam lm32_monitor_ram_0_1_0.GSR = "ENABLED"; + defparam lm32_monitor_ram_0_1_0.RESETMODE = "ASYNC"; + defparam lm32_monitor_ram_0_1_0.REGMODE_B = "NOREG"; + defparam lm32_monitor_ram_0_1_0.REGMODE_A = "NOREG"; + defparam lm32_monitor_ram_0_1_0.DATA_WIDTH_B = 18; + defparam lm32_monitor_ram_0_1_0.DATA_WIDTH_A = 18; + // synopsys translate_on + DP8KA lm32_monitor_ram_0_1_0 (.CEA(ClockEnA), .CLKA(ClockA), .WEA(WrA), + .CSA0(scuba_vlo), .CSA1(scuba_vlo), .CSA2(scuba_vlo), .RSTA(ResetA), + .CEB(ClockEnB), .CLKB(ClockB), .WEB(WrB), .CSB0(scuba_vlo), .CSB1(scuba_vlo), + .CSB2(scuba_vlo), .RSTB(ResetB), .DIA0(DataInA[18]), .DIA1(DataInA[19]), + .DIA2(DataInA[20]), .DIA3(DataInA[21]), .DIA4(DataInA[22]), .DIA5(DataInA[23]), + .DIA6(DataInA[24]), .DIA7(DataInA[25]), .DIA8(DataInA[26]), .DIA9(DataInA[27]), + .DIA10(DataInA[28]), .DIA11(DataInA[29]), .DIA12(DataInA[30]), .DIA13(DataInA[31]), + .DIA14(scuba_vlo), .DIA15(scuba_vlo), .DIA16(scuba_vlo), .DIA17(scuba_vlo), + .ADA0(scuba_vhi), .ADA1(scuba_vhi), .ADA2(scuba_vlo), .ADA3(scuba_vlo), + .ADA4(AddressA[0]), .ADA5(AddressA[1]), .ADA6(AddressA[2]), .ADA7(AddressA[3]), + .ADA8(AddressA[4]), .ADA9(AddressA[5]), .ADA10(AddressA[6]), .ADA11(AddressA[7]), + .ADA12(AddressA[8]), .DIB0(DataInB[18]), .DIB1(DataInB[19]), .DIB2(DataInB[20]), + .DIB3(DataInB[21]), .DIB4(DataInB[22]), .DIB5(DataInB[23]), .DIB6(DataInB[24]), + .DIB7(DataInB[25]), .DIB8(DataInB[26]), .DIB9(DataInB[27]), .DIB10(DataInB[28]), + .DIB11(DataInB[29]), .DIB12(DataInB[30]), .DIB13(DataInB[31]), .DIB14(scuba_vlo), + .DIB15(scuba_vlo), .DIB16(scuba_vlo), .DIB17(scuba_vlo), .ADB0(scuba_vhi), + .ADB1(scuba_vhi), .ADB2(scuba_vlo), .ADB3(scuba_vlo), .ADB4(AddressB[0]), + .ADB5(AddressB[1]), .ADB6(AddressB[2]), .ADB7(AddressB[3]), .ADB8(AddressB[4]), + .ADB9(AddressB[5]), .ADB10(AddressB[6]), .ADB11(AddressB[7]), .ADB12(AddressB[8]), + .DOA0(QA[18]), .DOA1(QA[19]), .DOA2(QA[20]), .DOA3(QA[21]), .DOA4(QA[22]), + .DOA5(QA[23]), .DOA6(QA[24]), .DOA7(QA[25]), .DOA8(QA[26]), .DOA9(QA[27]), + .DOA10(QA[28]), .DOA11(QA[29]), .DOA12(QA[30]), .DOA13(QA[31]), + .DOA14(), .DOA15(), .DOA16(), .DOA17(), .DOB0(QB[18]), .DOB1(QB[19]), + .DOB2(QB[20]), .DOB3(QB[21]), .DOB4(QB[22]), .DOB5(QB[23]), .DOB6(QB[24]), + .DOB7(QB[25]), .DOB8(QB[26]), .DOB9(QB[27]), .DOB10(QB[28]), .DOB11(QB[29]), + .DOB12(QB[30]), .DOB13(QB[31]), .DOB14(), .DOB15(), .DOB16(), .DOB17()) + /* synthesis INITVAL_1F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_19="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_18="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_17="0x0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF" */ + /* synthesis INITVAL_16="0x00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF" */ + /* synthesis INITVAL_15="0x00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363" */ + /* synthesis INITVAL_14="0x00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10" */ + /* synthesis INITVAL_13="0x0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08" */ + /* synthesis INITVAL_12="0x02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7" */ + /* synthesis INITVAL_11="0x00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708" */ + /* synthesis INITVAL_10="0x01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708" */ + /* synthesis INITVAL_0F="0x024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7" */ + /* synthesis INITVAL_0E="0x00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0" */ + /* synthesis INITVAL_0D="0x00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108" */ + /* synthesis INITVAL_0C="0x01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7" */ + /* synthesis INITVAL_0B="0x0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4" */ + /* synthesis INITVAL_0A="0x00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0" */ + /* synthesis INITVAL_09="0x00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6" */ + /* synthesis INITVAL_08="0x00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2" */ + /* synthesis INITVAL_07="0x00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008" */ + /* synthesis INITVAL_06="0x0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE" */ + /* synthesis INITVAL_05="0x016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA" */ + /* synthesis INITVAL_04="0x016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8" */ + /* synthesis INITVAL_03="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_02="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_01="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_00="0x00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600" */ + /* synthesis CSDECODE_B="000" */ + /* synthesis CSDECODE_A="000" */ + /* synthesis WRITEMODE_B="NORMAL" */ + /* synthesis WRITEMODE_A="NORMAL" */ + /* synthesis GSR="ENABLED" */ + /* synthesis RESETMODE="ASYNC" */ + /* synthesis REGMODE_B="NOREG" */ + /* synthesis REGMODE_A="NOREG" */ + /* synthesis DATA_WIDTH_B="18" */ + /* synthesis DATA_WIDTH_A="18" */; + + + + // exemplar begin + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_1F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_1E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_1D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_1C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_1B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_1A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_19 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_18 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_17 0x00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_16 0x1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_15 0x0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_14 0x00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_13 0x00035100180003510013000301001200030100110003010010000301000900030100080003010007 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_12 0x010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_11 0x000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_10 0x10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_0F 0x0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_0E 0x100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_0D 0x100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_0C 0x10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_0B 0x300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_0A 0x10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_09 0x100040000000070200802000020090200002008C20000200883007C100743006C200681006400060 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_08 0x3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_07 0x3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_06 0x100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_05 0x10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_04 0x10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_03 0x000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_02 0x000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_01 0x0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000 + // exemplar attribute lm32_monitor_ram_0_0_1 INITVAL_00 0x0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000 + // exemplar attribute lm32_monitor_ram_0_0_1 CSDECODE_B 000 + // exemplar attribute lm32_monitor_ram_0_0_1 CSDECODE_A 000 + // exemplar attribute lm32_monitor_ram_0_0_1 WRITEMODE_B NORMAL + // exemplar attribute lm32_monitor_ram_0_0_1 WRITEMODE_A NORMAL + // exemplar attribute lm32_monitor_ram_0_0_1 GSR ENABLED + // exemplar attribute lm32_monitor_ram_0_0_1 RESETMODE ASYNC + // exemplar attribute lm32_monitor_ram_0_0_1 REGMODE_B NOREG + // exemplar attribute lm32_monitor_ram_0_0_1 REGMODE_A NOREG + // exemplar attribute lm32_monitor_ram_0_0_1 DATA_WIDTH_B 18 + // exemplar attribute lm32_monitor_ram_0_0_1 DATA_WIDTH_A 18 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_1F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_1E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_1D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_1C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_1B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_1A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_19 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_18 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_17 0x0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_16 0x00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_15 0x00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_14 0x00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_13 0x0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_12 0x02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_11 0x00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_10 0x01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_0F 0x024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_0E 0x00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_0D 0x00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_0C 0x01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_0B 0x0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_0A 0x00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_09 0x00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_08 0x00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_07 0x00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_06 0x0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_05 0x016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_04 0x016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_03 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_02 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_01 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute lm32_monitor_ram_0_1_0 INITVAL_00 0x00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600 + // exemplar attribute lm32_monitor_ram_0_1_0 CSDECODE_B 000 + // exemplar attribute lm32_monitor_ram_0_1_0 CSDECODE_A 000 + // exemplar attribute lm32_monitor_ram_0_1_0 WRITEMODE_B NORMAL + // exemplar attribute lm32_monitor_ram_0_1_0 WRITEMODE_A NORMAL + // exemplar attribute lm32_monitor_ram_0_1_0 GSR ENABLED + // exemplar attribute lm32_monitor_ram_0_1_0 RESETMODE ASYNC + // exemplar attribute lm32_monitor_ram_0_1_0 REGMODE_B NOREG + // exemplar attribute lm32_monitor_ram_0_1_0 REGMODE_A NOREG + // exemplar attribute lm32_monitor_ram_0_1_0 DATA_WIDTH_B 18 + // exemplar attribute lm32_monitor_ram_0_1_0 DATA_WIDTH_A 18 + // exemplar end + end else if (lat_family == "ECP2" || lat_family == "ECP2M") begin + /* Verilog netlist generated by SCUBA ispLever_v60_PROD_Build (36) */ + /* Module Version: 3.0 */ + /* c:\ispTOOLS6_0\ispFPGA\bin\nt\scuba.exe -w -lang verilog -synth synplify -bus_exp 7 -bb -arch ep5a00 -type bram -wp 11 -rp 1010 -addr_width 9 -data_width 32 -num_rows 512 -gsr ENABLED -writemode NORMAL -resetmode ASYNC -memfile ./rom.mem -memformat hex -e -n lm32_monitor_ram_ecp2 */ + // synopsys translate_off + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_17 = 320'h00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_16 = 320'h1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_15 = 320'h0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_14 = 320'h00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_13 = 320'h00035100180003510013000301001200030100110003010010000301000900030100080003010007 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_12 = 320'h010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_11 = 320'h000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_10 = 320'h10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_0F = 320'h0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_0E = 320'h100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_0D = 320'h100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_0C = 320'h10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_0B = 320'h300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_0A = 320'h10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_09 = 320'h100040000000070200802000020090200002008C20000200883007C100743006C200681006400060 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_08 = 320'h3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_07 = 320'h3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_06 = 320'h100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_05 = 320'h10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_04 = 320'h10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_03 = 320'h000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_02 = 320'h000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_01 = 320'h0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.INITVAL_00 = 320'h0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.CSDECODE_B = 3'b000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.CSDECODE_A = 3'b000 ; + defparam lm32_monitor_ram_ecp2_0_0_1.WRITEMODE_B = "NORMAL" ; + defparam lm32_monitor_ram_ecp2_0_0_1.WRITEMODE_A = "NORMAL" ; + defparam lm32_monitor_ram_ecp2_0_0_1.GSR = "ENABLED" ; + defparam lm32_monitor_ram_ecp2_0_0_1.RESETMODE = "ASYNC" ; + defparam lm32_monitor_ram_ecp2_0_0_1.REGMODE_B = "NOREG" ; + defparam lm32_monitor_ram_ecp2_0_0_1.REGMODE_A = "NOREG" ; + defparam lm32_monitor_ram_ecp2_0_0_1.DATA_WIDTH_B = 18 ; + defparam lm32_monitor_ram_ecp2_0_0_1.DATA_WIDTH_A = 18 ; + // synopsys translate_on + DP16KB lm32_monitor_ram_ecp2_0_0_1 (.DIA0(DataInA[0]), .DIA1(DataInA[1]), + .DIA2(DataInA[2]), .DIA3(DataInA[3]), .DIA4(DataInA[4]), .DIA5(DataInA[5]), + .DIA6(DataInA[6]), .DIA7(DataInA[7]), .DIA8(DataInA[8]), .DIA9(DataInA[9]), + .DIA10(DataInA[10]), .DIA11(DataInA[11]), .DIA12(DataInA[12]), .DIA13(DataInA[13]), + .DIA14(DataInA[14]), .DIA15(DataInA[15]), .DIA16(DataInA[16]), .DIA17(DataInA[17]), + .ADA0(scuba_vhi), .ADA1(scuba_vhi), .ADA2(scuba_vlo), .ADA3(scuba_vlo), + .ADA4(AddressA[0]), .ADA5(AddressA[1]), .ADA6(AddressA[2]), .ADA7(AddressA[3]), + .ADA8(AddressA[4]), .ADA9(AddressA[5]), .ADA10(AddressA[6]), .ADA11(AddressA[7]), + .ADA12(AddressA[8]), .ADA13(scuba_vlo), .CEA(ClockEnA), .CLKA(ClockA), + .WEA(WrA), .CSA0(scuba_vlo), .CSA1(scuba_vlo), .CSA2(scuba_vlo), + .RSTA(ResetA), .DIB0(DataInB[0]), .DIB1(DataInB[1]), .DIB2(DataInB[2]), + .DIB3(DataInB[3]), .DIB4(DataInB[4]), .DIB5(DataInB[5]), .DIB6(DataInB[6]), + .DIB7(DataInB[7]), .DIB8(DataInB[8]), .DIB9(DataInB[9]), .DIB10(DataInB[10]), + .DIB11(DataInB[11]), .DIB12(DataInB[12]), .DIB13(DataInB[13]), .DIB14(DataInB[14]), + .DIB15(DataInB[15]), .DIB16(DataInB[16]), .DIB17(DataInB[17]), .ADB0(scuba_vhi), + .ADB1(scuba_vhi), .ADB2(scuba_vlo), .ADB3(scuba_vlo), .ADB4(AddressB[0]), + .ADB5(AddressB[1]), .ADB6(AddressB[2]), .ADB7(AddressB[3]), .ADB8(AddressB[4]), + .ADB9(AddressB[5]), .ADB10(AddressB[6]), .ADB11(AddressB[7]), .ADB12(AddressB[8]), + .ADB13(scuba_vlo), .CEB(ClockEnB), .CLKB(ClockB), .WEB(WrB), .CSB0(scuba_vlo), + .CSB1(scuba_vlo), .CSB2(scuba_vlo), .RSTB(ResetB), .DOA0(QA[0]), + .DOA1(QA[1]), .DOA2(QA[2]), .DOA3(QA[3]), .DOA4(QA[4]), .DOA5(QA[5]), + .DOA6(QA[6]), .DOA7(QA[7]), .DOA8(QA[8]), .DOA9(QA[9]), .DOA10(QA[10]), + .DOA11(QA[11]), .DOA12(QA[12]), .DOA13(QA[13]), .DOA14(QA[14]), + .DOA15(QA[15]), .DOA16(QA[16]), .DOA17(QA[17]), .DOB0(QB[0]), .DOB1(QB[1]), + .DOB2(QB[2]), .DOB3(QB[3]), .DOB4(QB[4]), .DOB5(QB[5]), .DOB6(QB[6]), + .DOB7(QB[7]), .DOB8(QB[8]), .DOB9(QB[9]), .DOB10(QB[10]), .DOB11(QB[11]), + .DOB12(QB[12]), .DOB13(QB[13]), .DOB14(QB[14]), .DOB15(QB[15]), + .DOB16(QB[16]), .DOB17(QB[17])) + /* synthesis MEM_LPC_FILE="lm32_monitor_ram_ecp2.lpc" */ + /* synthesis MEM_INIT_FILE="rom.mem" */ + /* synthesis INITVAL_3F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_39="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_38="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_37="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_36="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_35="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_34="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_33="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_32="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_31="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_30="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_29="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_28="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_27="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_26="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_25="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_24="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_23="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_22="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_21="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_20="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_19="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_18="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_17="0x00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B" */ + /* synthesis INITVAL_16="0x1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB" */ + /* synthesis INITVAL_15="0x0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3" */ + /* synthesis INITVAL_14="0x00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019" */ + /* synthesis INITVAL_13="0x00035100180003510013000301001200030100110003010010000301000900030100080003010007" */ + /* synthesis INITVAL_12="0x010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004" */ + /* synthesis INITVAL_11="0x000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3" */ + /* synthesis INITVAL_10="0x10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF" */ + /* synthesis INITVAL_0F="0x0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008" */ + /* synthesis INITVAL_0E="0x100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008" */ + /* synthesis INITVAL_0D="0x100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002" */ + /* synthesis INITVAL_0C="0x10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090" */ + /* synthesis INITVAL_0B="0x300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048" */ + /* synthesis INITVAL_0A="0x10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008" */ + /* synthesis INITVAL_09="0x100040000000070200802000020090200002008C20000200883007C100743006C200681006400060" */ + /* synthesis INITVAL_08="0x3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020" */ + /* synthesis INITVAL_07="0x3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001" */ + /* synthesis INITVAL_06="0x100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068" */ + /* synthesis INITVAL_05="0x10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028" */ + /* synthesis INITVAL_04="0x10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000" */ + /* synthesis INITVAL_03="0x000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000" */ + /* synthesis INITVAL_02="0x000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000" */ + /* synthesis INITVAL_01="0x0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000" */ + /* synthesis INITVAL_00="0x0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000" */ + /* synthesis CSDECODE_B="0b000" */ + /* synthesis CSDECODE_A="0b000" */ + /* synthesis WRITEMODE_B="NORMAL" */ + /* synthesis WRITEMODE_A="NORMAL" */ + /* synthesis GSR="ENABLED" */ + /* synthesis RESETMODE="ASYNC" */ + /* synthesis REGMODE_B="NOREG" */ + /* synthesis REGMODE_A="NOREG" */ + /* synthesis DATA_WIDTH_B="18" */ + /* synthesis DATA_WIDTH_A="18" */; + + VHI scuba_vhi_inst (.Z(scuba_vhi)); + + VLO scuba_vlo_inst (.Z(scuba_vlo)); + + // synopsys translate_off + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_17 = 320'h0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_16 = 320'h00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_15 = 320'h00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_14 = 320'h00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_13 = 320'h0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_12 = 320'h02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_11 = 320'h00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_10 = 320'h01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_0F = 320'h024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_0E = 320'h00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_0D = 320'h00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_0C = 320'h01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_0B = 320'h0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_0A = 320'h00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_09 = 320'h00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_08 = 320'h00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_07 = 320'h00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_06 = 320'h0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_05 = 320'h016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_04 = 320'h016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_03 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_02 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_01 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 ; + defparam lm32_monitor_ram_ecp2_0_1_0.INITVAL_00 = 320'h00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600 ; + defparam lm32_monitor_ram_ecp2_0_1_0.CSDECODE_B = 3'b000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.CSDECODE_A = 3'b000 ; + defparam lm32_monitor_ram_ecp2_0_1_0.WRITEMODE_B = "NORMAL" ; + defparam lm32_monitor_ram_ecp2_0_1_0.WRITEMODE_A = "NORMAL" ; + defparam lm32_monitor_ram_ecp2_0_1_0.GSR = "ENABLED" ; + defparam lm32_monitor_ram_ecp2_0_1_0.RESETMODE = "ASYNC" ; + defparam lm32_monitor_ram_ecp2_0_1_0.REGMODE_B = "NOREG" ; + defparam lm32_monitor_ram_ecp2_0_1_0.REGMODE_A = "NOREG" ; + defparam lm32_monitor_ram_ecp2_0_1_0.DATA_WIDTH_B = 18 ; + defparam lm32_monitor_ram_ecp2_0_1_0.DATA_WIDTH_A = 18 ; + // synopsys translate_on + DP16KB lm32_monitor_ram_ecp2_0_1_0 (.DIA0(DataInA[18]), .DIA1(DataInA[19]), + .DIA2(DataInA[20]), .DIA3(DataInA[21]), .DIA4(DataInA[22]), .DIA5(DataInA[23]), + .DIA6(DataInA[24]), .DIA7(DataInA[25]), .DIA8(DataInA[26]), .DIA9(DataInA[27]), + .DIA10(DataInA[28]), .DIA11(DataInA[29]), .DIA12(DataInA[30]), .DIA13(DataInA[31]), + .DIA14(scuba_vlo), .DIA15(scuba_vlo), .DIA16(scuba_vlo), .DIA17(scuba_vlo), + .ADA0(scuba_vhi), .ADA1(scuba_vhi), .ADA2(scuba_vlo), .ADA3(scuba_vlo), + .ADA4(AddressA[0]), .ADA5(AddressA[1]), .ADA6(AddressA[2]), .ADA7(AddressA[3]), + .ADA8(AddressA[4]), .ADA9(AddressA[5]), .ADA10(AddressA[6]), .ADA11(AddressA[7]), + .ADA12(AddressA[8]), .ADA13(scuba_vlo), .CEA(ClockEnA), .CLKA(ClockA), + .WEA(WrA), .CSA0(scuba_vlo), .CSA1(scuba_vlo), .CSA2(scuba_vlo), + .RSTA(ResetA), .DIB0(DataInB[18]), .DIB1(DataInB[19]), .DIB2(DataInB[20]), + .DIB3(DataInB[21]), .DIB4(DataInB[22]), .DIB5(DataInB[23]), .DIB6(DataInB[24]), + .DIB7(DataInB[25]), .DIB8(DataInB[26]), .DIB9(DataInB[27]), .DIB10(DataInB[28]), + .DIB11(DataInB[29]), .DIB12(DataInB[30]), .DIB13(DataInB[31]), .DIB14(scuba_vlo), + .DIB15(scuba_vlo), .DIB16(scuba_vlo), .DIB17(scuba_vlo), .ADB0(scuba_vhi), + .ADB1(scuba_vhi), .ADB2(scuba_vlo), .ADB3(scuba_vlo), .ADB4(AddressB[0]), + .ADB5(AddressB[1]), .ADB6(AddressB[2]), .ADB7(AddressB[3]), .ADB8(AddressB[4]), + .ADB9(AddressB[5]), .ADB10(AddressB[6]), .ADB11(AddressB[7]), .ADB12(AddressB[8]), + .ADB13(scuba_vlo), .CEB(ClockEnB), .CLKB(ClockB), .WEB(WrB), .CSB0(scuba_vlo), + .CSB1(scuba_vlo), .CSB2(scuba_vlo), .RSTB(ResetB), .DOA0(QA[18]), + .DOA1(QA[19]), .DOA2(QA[20]), .DOA3(QA[21]), .DOA4(QA[22]), .DOA5(QA[23]), + .DOA6(QA[24]), .DOA7(QA[25]), .DOA8(QA[26]), .DOA9(QA[27]), .DOA10(QA[28]), + .DOA11(QA[29]), .DOA12(QA[30]), .DOA13(QA[31]), .DOA14(), .DOA15(), + .DOA16(), .DOA17(), .DOB0(QB[18]), .DOB1(QB[19]), .DOB2(QB[20]), + .DOB3(QB[21]), .DOB4(QB[22]), .DOB5(QB[23]), .DOB6(QB[24]), .DOB7(QB[25]), + .DOB8(QB[26]), .DOB9(QB[27]), .DOB10(QB[28]), .DOB11(QB[29]), .DOB12(QB[30]), + .DOB13(QB[31]), .DOB14(), .DOB15(), .DOB16(), .DOB17()) + /* synthesis MEM_LPC_FILE="lm32_monitor_ram_ecp2.lpc" */ + /* synthesis MEM_INIT_FILE="rom.mem" */ + /* synthesis INITVAL_3F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_39="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_38="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_37="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_36="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_35="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_34="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_33="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_32="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_31="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_30="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_29="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_28="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_27="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_26="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_25="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_24="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_23="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_22="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_21="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_20="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_19="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_18="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_17="0x0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF" */ + /* synthesis INITVAL_16="0x00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF" */ + /* synthesis INITVAL_15="0x00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363" */ + /* synthesis INITVAL_14="0x00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10" */ + /* synthesis INITVAL_13="0x0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08" */ + /* synthesis INITVAL_12="0x02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7" */ + /* synthesis INITVAL_11="0x00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708" */ + /* synthesis INITVAL_10="0x01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708" */ + /* synthesis INITVAL_0F="0x024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7" */ + /* synthesis INITVAL_0E="0x00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0" */ + /* synthesis INITVAL_0D="0x00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108" */ + /* synthesis INITVAL_0C="0x01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7" */ + /* synthesis INITVAL_0B="0x0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4" */ + /* synthesis INITVAL_0A="0x00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0" */ + /* synthesis INITVAL_09="0x00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6" */ + /* synthesis INITVAL_08="0x00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2" */ + /* synthesis INITVAL_07="0x00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008" */ + /* synthesis INITVAL_06="0x0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE" */ + /* synthesis INITVAL_05="0x016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA" */ + /* synthesis INITVAL_04="0x016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8" */ + /* synthesis INITVAL_03="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_02="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_01="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_00="0x00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600" */ + /* synthesis CSDECODE_B="0b000" */ + /* synthesis CSDECODE_A="0b000" */ + /* synthesis WRITEMODE_B="NORMAL" */ + /* synthesis WRITEMODE_A="NORMAL" */ + /* synthesis GSR="ENABLED" */ + /* synthesis RESETMODE="ASYNC" */ + /* synthesis REGMODE_B="NOREG" */ + /* synthesis REGMODE_A="NOREG" */ + /* synthesis DATA_WIDTH_B="18" */ + /* synthesis DATA_WIDTH_A="18" */; + + + + // exemplar begin + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 MEM_LPC_FILE lm32_monitor_ram_ecp2.lpc + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 MEM_INIT_FILE rom.mem + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_3F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_3E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_3D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_3C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_3B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_3A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_39 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_38 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_37 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_36 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_35 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_34 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_33 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_32 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_31 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_30 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_2F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_2E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_2D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_2C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_2B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_2A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_29 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_28 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_27 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_26 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_25 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_24 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_23 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_22 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_21 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_20 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_1F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_1E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_1D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_1C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_1B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_1A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_19 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_18 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_17 0x00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_16 0x1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_15 0x0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_14 0x00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_13 0x00035100180003510013000301001200030100110003010010000301000900030100080003010007 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_12 0x010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_11 0x000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_10 0x10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_0F 0x0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_0E 0x100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_0D 0x100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_0C 0x10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_0B 0x300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_0A 0x10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_09 0x100040000000070200802000020090200002008C20000200883007C100743006C200681006400060 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_08 0x3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_07 0x3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_06 0x100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_05 0x10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_04 0x10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_03 0x000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_02 0x000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_01 0x0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 INITVAL_00 0x0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 CSDECODE_B 0b000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 CSDECODE_A 0b000 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 WRITEMODE_B NORMAL + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 WRITEMODE_A NORMAL + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 GSR ENABLED + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 RESETMODE ASYNC + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 REGMODE_B NOREG + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 REGMODE_A NOREG + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 DATA_WIDTH_B 18 + // exemplar attribute lm32_monitor_ram_ecp2_0_0_1 DATA_WIDTH_A 18 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 MEM_LPC_FILE lm32_monitor_ram_ecp2.lpc + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 MEM_INIT_FILE rom.mem + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_3F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_3E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_3D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_3C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_3B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_3A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_39 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_38 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_37 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_36 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_35 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_34 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_33 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_32 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_31 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_30 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_2F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_2E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_2D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_2C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_2B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_2A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_29 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_28 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_27 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_26 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_25 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_24 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_23 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_22 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_21 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_20 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_1F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_1E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_1D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_1C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_1B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_1A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_19 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_18 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_17 0x0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_16 0x00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_15 0x00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_14 0x00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_13 0x0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_12 0x02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_11 0x00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_10 0x01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_0F 0x024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_0E 0x00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_0D 0x00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_0C 0x01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_0B 0x0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_0A 0x00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_09 0x00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_08 0x00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_07 0x00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_06 0x0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_05 0x016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_04 0x016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_03 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_02 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_01 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 INITVAL_00 0x00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 CSDECODE_B 0b000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 CSDECODE_A 0b000 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 WRITEMODE_B NORMAL + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 WRITEMODE_A NORMAL + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 GSR ENABLED + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 RESETMODE ASYNC + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 REGMODE_B NOREG + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 REGMODE_A NOREG + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 DATA_WIDTH_B 18 + // exemplar attribute lm32_monitor_ram_ecp2_0_1_0 DATA_WIDTH_A 18 + // exemplar end + end else if (lat_family == "SC" || lat_family == "SCM") begin + // synopsys translate_off + defparam sc_rom_monitor_0_0_1.INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_17 = 320'h00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B ; + defparam sc_rom_monitor_0_0_1.INITVAL_16 = 320'h1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB ; + defparam sc_rom_monitor_0_0_1.INITVAL_15 = 320'h0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3 ; + defparam sc_rom_monitor_0_0_1.INITVAL_14 = 320'h00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019 ; + defparam sc_rom_monitor_0_0_1.INITVAL_13 = 320'h00035100180003510013000301001200030100110003010010000301000900030100080003010007 ; + defparam sc_rom_monitor_0_0_1.INITVAL_12 = 320'h010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004 ; + defparam sc_rom_monitor_0_0_1.INITVAL_11 = 320'h000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3 ; + defparam sc_rom_monitor_0_0_1.INITVAL_10 = 320'h10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF ; + defparam sc_rom_monitor_0_0_1.INITVAL_0F = 320'h0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008 ; + defparam sc_rom_monitor_0_0_1.INITVAL_0E = 320'h100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008 ; + defparam sc_rom_monitor_0_0_1.INITVAL_0D = 320'h100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002 ; + defparam sc_rom_monitor_0_0_1.INITVAL_0C = 320'h10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090 ; + defparam sc_rom_monitor_0_0_1.INITVAL_0B = 320'h300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048 ; + defparam sc_rom_monitor_0_0_1.INITVAL_0A = 320'h10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008 ; + defparam sc_rom_monitor_0_0_1.INITVAL_09 = 320'h100040000000070200802000020090200002008C20000200883007C100743006C200681006400060 ; + defparam sc_rom_monitor_0_0_1.INITVAL_08 = 320'h3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020 ; + defparam sc_rom_monitor_0_0_1.INITVAL_07 = 320'h3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001 ; + defparam sc_rom_monitor_0_0_1.INITVAL_06 = 320'h100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068 ; + defparam sc_rom_monitor_0_0_1.INITVAL_05 = 320'h10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028 ; + defparam sc_rom_monitor_0_0_1.INITVAL_04 = 320'h10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_03 = 320'h000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_02 = 320'h000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_01 = 320'h0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000 ; + defparam sc_rom_monitor_0_0_1.INITVAL_00 = 320'h0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000 ; + defparam sc_rom_monitor_0_0_1.CSDECODE_B = 3'b000 ; + defparam sc_rom_monitor_0_0_1.CSDECODE_A = 3'b000 ; + defparam sc_rom_monitor_0_0_1.WRITEMODE_B = "NORMAL" ; + defparam sc_rom_monitor_0_0_1.WRITEMODE_A = "NORMAL" ; + defparam sc_rom_monitor_0_0_1.GSR = "ENABLED" ; + defparam sc_rom_monitor_0_0_1.RESETMODE = "ASYNC" ; + defparam sc_rom_monitor_0_0_1.REGMODE_B = "NOREG" ; + defparam sc_rom_monitor_0_0_1.REGMODE_A = "NOREG" ; + defparam sc_rom_monitor_0_0_1.DATA_WIDTH_B = 18 ; + defparam sc_rom_monitor_0_0_1.DATA_WIDTH_A = 18 ; + // synopsys translate_on + DP16KA sc_rom_monitor_0_0_1 (.DIA0(DataInA[0]), .DIA1(DataInA[1]), .DIA2(DataInA[2]), + .DIA3(DataInA[3]), .DIA4(DataInA[4]), .DIA5(DataInA[5]), .DIA6(DataInA[6]), + .DIA7(DataInA[7]), .DIA8(DataInA[8]), .DIA9(DataInA[9]), .DIA10(DataInA[10]), + .DIA11(DataInA[11]), .DIA12(DataInA[12]), .DIA13(DataInA[13]), .DIA14(DataInA[14]), + .DIA15(DataInA[15]), .DIA16(DataInA[16]), .DIA17(DataInA[17]), .ADA0(scuba_vhi), + .ADA1(scuba_vhi), .ADA2(scuba_vlo), .ADA3(scuba_vlo), .ADA4(AddressA[0]), + .ADA5(AddressA[1]), .ADA6(AddressA[2]), .ADA7(AddressA[3]), .ADA8(AddressA[4]), + .ADA9(AddressA[5]), .ADA10(AddressA[6]), .ADA11(AddressA[7]), .ADA12(AddressA[8]), + .ADA13(scuba_vlo), .CEA(ClockEnA), .CLKA(ClockA), .WEA(WrA), .CSA0(scuba_vlo), + .CSA1(scuba_vlo), .CSA2(scuba_vlo), .RSTA(ResetA), .DIB0(DataInB[0]), + .DIB1(DataInB[1]), .DIB2(DataInB[2]), .DIB3(DataInB[3]), .DIB4(DataInB[4]), + .DIB5(DataInB[5]), .DIB6(DataInB[6]), .DIB7(DataInB[7]), .DIB8(DataInB[8]), + .DIB9(DataInB[9]), .DIB10(DataInB[10]), .DIB11(DataInB[11]), .DIB12(DataInB[12]), + .DIB13(DataInB[13]), .DIB14(DataInB[14]), .DIB15(DataInB[15]), .DIB16(DataInB[16]), + .DIB17(DataInB[17]), .ADB0(scuba_vhi), .ADB1(scuba_vhi), .ADB2(scuba_vlo), + .ADB3(scuba_vlo), .ADB4(AddressB[0]), .ADB5(AddressB[1]), .ADB6(AddressB[2]), + .ADB7(AddressB[3]), .ADB8(AddressB[4]), .ADB9(AddressB[5]), .ADB10(AddressB[6]), + .ADB11(AddressB[7]), .ADB12(AddressB[8]), .ADB13(scuba_vlo), .CEB(ClockEnB), + .CLKB(ClockB), .WEB(WrB), .CSB0(scuba_vlo), .CSB1(scuba_vlo), .CSB2(scuba_vlo), + .RSTB(ResetB), .DOA0(QA[0]), .DOA1(QA[1]), .DOA2(QA[2]), .DOA3(QA[3]), + .DOA4(QA[4]), .DOA5(QA[5]), .DOA6(QA[6]), .DOA7(QA[7]), .DOA8(QA[8]), + .DOA9(QA[9]), .DOA10(QA[10]), .DOA11(QA[11]), .DOA12(QA[12]), .DOA13(QA[13]), + .DOA14(QA[14]), .DOA15(QA[15]), .DOA16(QA[16]), .DOA17(QA[17]), + .DOB0(QB[0]), .DOB1(QB[1]), .DOB2(QB[2]), .DOB3(QB[3]), .DOB4(QB[4]), + .DOB5(QB[5]), .DOB6(QB[6]), .DOB7(QB[7]), .DOB8(QB[8]), .DOB9(QB[9]), + .DOB10(QB[10]), .DOB11(QB[11]), .DOB12(QB[12]), .DOB13(QB[13]), + .DOB14(QB[14]), .DOB15(QB[15]), .DOB16(QB[16]), .DOB17(QB[17])) + /* synthesis MEM_LPC_FILE="sc_rom_monitor.lpc" */ + /* synthesis MEM_INIT_FILE="rom.mem" */ + /* synthesis INITVAL_3F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_39="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_38="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_37="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_36="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_35="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_34="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_33="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_32="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_31="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_30="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_29="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_28="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_27="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_26="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_25="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_24="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_23="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_22="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_21="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_20="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_19="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_18="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_17="0x00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B" */ + /* synthesis INITVAL_16="0x1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB" */ + /* synthesis INITVAL_15="0x0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3" */ + /* synthesis INITVAL_14="0x00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019" */ + /* synthesis INITVAL_13="0x00035100180003510013000301001200030100110003010010000301000900030100080003010007" */ + /* synthesis INITVAL_12="0x010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004" */ + /* synthesis INITVAL_11="0x000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3" */ + /* synthesis INITVAL_10="0x10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF" */ + /* synthesis INITVAL_0F="0x0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008" */ + /* synthesis INITVAL_0E="0x100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008" */ + /* synthesis INITVAL_0D="0x100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002" */ + /* synthesis INITVAL_0C="0x10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090" */ + /* synthesis INITVAL_0B="0x300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048" */ + /* synthesis INITVAL_0A="0x10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008" */ + /* synthesis INITVAL_09="0x100040000000070200802000020090200002008C20000200883007C100743006C200681006400060" */ + /* synthesis INITVAL_08="0x3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020" */ + /* synthesis INITVAL_07="0x3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001" */ + /* synthesis INITVAL_06="0x100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068" */ + /* synthesis INITVAL_05="0x10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028" */ + /* synthesis INITVAL_04="0x10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000" */ + /* synthesis INITVAL_03="0x000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000" */ + /* synthesis INITVAL_02="0x000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000" */ + /* synthesis INITVAL_01="0x0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000" */ + /* synthesis INITVAL_00="0x0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000" */ + /* synthesis CSDECODE_B="0b000" */ + /* synthesis CSDECODE_A="0b000" */ + /* synthesis WRITEMODE_B="NORMAL" */ + /* synthesis WRITEMODE_A="NORMAL" */ + /* synthesis GSR="ENABLED" */ + /* synthesis RESETMODE="ASYNC" */ + /* synthesis REGMODE_B="NOREG" */ + /* synthesis REGMODE_A="NOREG" */ + /* synthesis DATA_WIDTH_B="18" */ + /* synthesis DATA_WIDTH_A="18" */; + + VHI scuba_vhi_inst (.Z(scuba_vhi)); + + VLO scuba_vlo_inst (.Z(scuba_vlo)); + + // synopsys translate_off + defparam sc_rom_monitor_0_1_0.INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000 ; + defparam sc_rom_monitor_0_1_0.INITVAL_17 = 320'h0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF ; + defparam sc_rom_monitor_0_1_0.INITVAL_16 = 320'h00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF ; + defparam sc_rom_monitor_0_1_0.INITVAL_15 = 320'h00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363 ; + defparam sc_rom_monitor_0_1_0.INITVAL_14 = 320'h00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10 ; + defparam sc_rom_monitor_0_1_0.INITVAL_13 = 320'h0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08 ; + defparam sc_rom_monitor_0_1_0.INITVAL_12 = 320'h02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7 ; + defparam sc_rom_monitor_0_1_0.INITVAL_11 = 320'h00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708 ; + defparam sc_rom_monitor_0_1_0.INITVAL_10 = 320'h01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708 ; + defparam sc_rom_monitor_0_1_0.INITVAL_0F = 320'h024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7 ; + defparam sc_rom_monitor_0_1_0.INITVAL_0E = 320'h00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0 ; + defparam sc_rom_monitor_0_1_0.INITVAL_0D = 320'h00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108 ; + defparam sc_rom_monitor_0_1_0.INITVAL_0C = 320'h01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7 ; + defparam sc_rom_monitor_0_1_0.INITVAL_0B = 320'h0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4 ; + defparam sc_rom_monitor_0_1_0.INITVAL_0A = 320'h00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0 ; + defparam sc_rom_monitor_0_1_0.INITVAL_09 = 320'h00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6 ; + defparam sc_rom_monitor_0_1_0.INITVAL_08 = 320'h00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2 ; + defparam sc_rom_monitor_0_1_0.INITVAL_07 = 320'h00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008 ; + defparam sc_rom_monitor_0_1_0.INITVAL_06 = 320'h0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE ; + defparam sc_rom_monitor_0_1_0.INITVAL_05 = 320'h016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA ; + defparam sc_rom_monitor_0_1_0.INITVAL_04 = 320'h016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8 ; + defparam sc_rom_monitor_0_1_0.INITVAL_03 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 ; + defparam sc_rom_monitor_0_1_0.INITVAL_02 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 ; + defparam sc_rom_monitor_0_1_0.INITVAL_01 = 320'h00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 ; + defparam sc_rom_monitor_0_1_0.INITVAL_00 = 320'h00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600 ; + defparam sc_rom_monitor_0_1_0.CSDECODE_B = 3'b000 ; + defparam sc_rom_monitor_0_1_0.CSDECODE_A = 3'b000 ; + defparam sc_rom_monitor_0_1_0.WRITEMODE_B = "NORMAL" ; + defparam sc_rom_monitor_0_1_0.WRITEMODE_A = "NORMAL" ; + defparam sc_rom_monitor_0_1_0.GSR = "ENABLED" ; + defparam sc_rom_monitor_0_1_0.RESETMODE = "ASYNC" ; + defparam sc_rom_monitor_0_1_0.REGMODE_B = "NOREG" ; + defparam sc_rom_monitor_0_1_0.REGMODE_A = "NOREG" ; + defparam sc_rom_monitor_0_1_0.DATA_WIDTH_B = 18 ; + defparam sc_rom_monitor_0_1_0.DATA_WIDTH_A = 18 ; + // synopsys translate_on + DP16KA sc_rom_monitor_0_1_0 (.DIA0(DataInA[18]), .DIA1(DataInA[19]), + .DIA2(DataInA[20]), .DIA3(DataInA[21]), .DIA4(DataInA[22]), .DIA5(DataInA[23]), + .DIA6(DataInA[24]), .DIA7(DataInA[25]), .DIA8(DataInA[26]), .DIA9(DataInA[27]), + .DIA10(DataInA[28]), .DIA11(DataInA[29]), .DIA12(DataInA[30]), .DIA13(DataInA[31]), + .DIA14(scuba_vlo), .DIA15(scuba_vlo), .DIA16(scuba_vlo), .DIA17(scuba_vlo), + .ADA0(scuba_vhi), .ADA1(scuba_vhi), .ADA2(scuba_vlo), .ADA3(scuba_vlo), + .ADA4(AddressA[0]), .ADA5(AddressA[1]), .ADA6(AddressA[2]), .ADA7(AddressA[3]), + .ADA8(AddressA[4]), .ADA9(AddressA[5]), .ADA10(AddressA[6]), .ADA11(AddressA[7]), + .ADA12(AddressA[8]), .ADA13(scuba_vlo), .CEA(ClockEnA), .CLKA(ClockA), + .WEA(WrA), .CSA0(scuba_vlo), .CSA1(scuba_vlo), .CSA2(scuba_vlo), + .RSTA(ResetA), .DIB0(DataInB[18]), .DIB1(DataInB[19]), .DIB2(DataInB[20]), + .DIB3(DataInB[21]), .DIB4(DataInB[22]), .DIB5(DataInB[23]), .DIB6(DataInB[24]), + .DIB7(DataInB[25]), .DIB8(DataInB[26]), .DIB9(DataInB[27]), .DIB10(DataInB[28]), + .DIB11(DataInB[29]), .DIB12(DataInB[30]), .DIB13(DataInB[31]), .DIB14(scuba_vlo), + .DIB15(scuba_vlo), .DIB16(scuba_vlo), .DIB17(scuba_vlo), .ADB0(scuba_vhi), + .ADB1(scuba_vhi), .ADB2(scuba_vlo), .ADB3(scuba_vlo), .ADB4(AddressB[0]), + .ADB5(AddressB[1]), .ADB6(AddressB[2]), .ADB7(AddressB[3]), .ADB8(AddressB[4]), + .ADB9(AddressB[5]), .ADB10(AddressB[6]), .ADB11(AddressB[7]), .ADB12(AddressB[8]), + .ADB13(scuba_vlo), .CEB(ClockEnB), .CLKB(ClockB), .WEB(WrB), .CSB0(scuba_vlo), + .CSB1(scuba_vlo), .CSB2(scuba_vlo), .RSTB(ResetB), .DOA0(QA[18]), + .DOA1(QA[19]), .DOA2(QA[20]), .DOA3(QA[21]), .DOA4(QA[22]), .DOA5(QA[23]), + .DOA6(QA[24]), .DOA7(QA[25]), .DOA8(QA[26]), .DOA9(QA[27]), .DOA10(QA[28]), + .DOA11(QA[29]), .DOA12(QA[30]), .DOA13(QA[31]), .DOA14(), .DOA15(), + .DOA16(), .DOA17(), .DOB0(QB[18]), .DOB1(QB[19]), .DOB2(QB[20]), + .DOB3(QB[21]), .DOB4(QB[22]), .DOB5(QB[23]), .DOB6(QB[24]), .DOB7(QB[25]), + .DOB8(QB[26]), .DOB9(QB[27]), .DOB10(QB[28]), .DOB11(QB[29]), .DOB12(QB[30]), + .DOB13(QB[31]), .DOB14(), .DOB15(), .DOB16(), .DOB17()) + /* synthesis MEM_LPC_FILE="sc_rom_monitor.lpc" */ + /* synthesis MEM_INIT_FILE="rom.mem" */ + /* synthesis INITVAL_3F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_3A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_39="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_38="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_37="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_36="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_35="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_34="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_33="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_32="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_31="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_30="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_2A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_29="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_28="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_27="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_26="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_25="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_24="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_23="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_22="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_21="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_20="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1F="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1E="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1D="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1C="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1B="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_1A="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_19="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_18="0x00000000000000000000000000000000000000000000000000000000000000000000000000000000" */ + /* synthesis INITVAL_17="0x0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF" */ + /* synthesis INITVAL_16="0x00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF" */ + /* synthesis INITVAL_15="0x00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363" */ + /* synthesis INITVAL_14="0x00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10" */ + /* synthesis INITVAL_13="0x0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08" */ + /* synthesis INITVAL_12="0x02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7" */ + /* synthesis INITVAL_11="0x00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708" */ + /* synthesis INITVAL_10="0x01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708" */ + /* synthesis INITVAL_0F="0x024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7" */ + /* synthesis INITVAL_0E="0x00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0" */ + /* synthesis INITVAL_0D="0x00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108" */ + /* synthesis INITVAL_0C="0x01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7" */ + /* synthesis INITVAL_0B="0x0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4" */ + /* synthesis INITVAL_0A="0x00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0" */ + /* synthesis INITVAL_09="0x00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6" */ + /* synthesis INITVAL_08="0x00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2" */ + /* synthesis INITVAL_07="0x00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008" */ + /* synthesis INITVAL_06="0x0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE" */ + /* synthesis INITVAL_05="0x016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA" */ + /* synthesis INITVAL_04="0x016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8" */ + /* synthesis INITVAL_03="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_02="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_01="0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600" */ + /* synthesis INITVAL_00="0x00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600" */ + /* synthesis CSDECODE_B="0b000" */ + /* synthesis CSDECODE_A="0b000" */ + /* synthesis WRITEMODE_B="NORMAL" */ + /* synthesis WRITEMODE_A="NORMAL" */ + /* synthesis GSR="ENABLED" */ + /* synthesis RESETMODE="ASYNC" */ + /* synthesis REGMODE_B="NOREG" */ + /* synthesis REGMODE_A="NOREG" */ + /* synthesis DATA_WIDTH_B="18" */ + /* synthesis DATA_WIDTH_A="18" */; + + + + // exemplar begin + // exemplar attribute sc_rom_monitor_0_0_1 MEM_LPC_FILE sc_rom_monitor.lpc + // exemplar attribute sc_rom_monitor_0_0_1 MEM_INIT_FILE rom.mem + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_3F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_3E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_3D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_3C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_3B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_3A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_39 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_38 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_37 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_36 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_35 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_34 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_33 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_32 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_31 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_30 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_2F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_2E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_2D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_2C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_2B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_2A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_29 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_28 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_27 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_26 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_25 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_24 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_23 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_22 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_21 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_20 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_1F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_1E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_1D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_1C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_1B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_1A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_19 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_18 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_17 0x00000000000000000000000000000000000000003FF8C300003FF8E300003FF90300003FF923FF5B + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_16 0x1004F3FF95300003FF97300003FF99300003FF9B300003FF9D300003FF9F300003FFA1300003FFFB + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_15 0x0000130001100003FF691001400000068003FF7E058003FF803FFFB300013FF7800001100001FFB3 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_14 0x00000068003FF89058003FF8B3FFB93FF9B008003FFBC300000FFBE1001B000331001A0002C10019 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_13 0x00035100180003510013000301001200030100110003010010000301000900030100080003010007 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_12 0x010003FF97058003FFAA3FFFC00800078003FFDB3FFBD0080000004100063FFA2000000001C10004 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_11 0x000083000C2001010014000183001C0000000000000001000000000000000000010000100010FFF3 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_10 0x10063000481004D0003F1006D0003E1007200024100570001D10077010003FFC210000100540FFFF + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_0F 0x0080010000100540FFFF008000700010004000083000C2001010014000183001C0FFE40000000008 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_0E 0x100043FFDD100083FFDF100093FFE11000A3FFE31000B10008100040FFF8000000000C1000410008 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_0D 0x100083FFE7100093FFE91000A3FFEB1000B3FFED100040FFF400000200000FFFF010000000000002 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_0C 0x10054100000FFFF01000100FF00000100FF000000FFFE10100010000000000070300803000030090 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_0B 0x300003008C300003008820078100743006C2006810064000603005C2005810054000503004C20048 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_0A 0x10044000403003C2003810034000303002C2002810024000203001C2001810014000103000C20008 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_09 0x100040000000070200802000020090200002008C20000200883007C100743006C200681006400060 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_08 0x3005C2005810054000503004C2004810044000403003C2003810034000303002C200281002400020 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_07 0x3001C2001810014000103000C2000810004000001F9940E000000001007410000100841000110001 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_06 0x100011000110001100FF1F99410090008001008C0080010088008003007C20078000703006C20068 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_05 0x10064000603005C2005810054000503004C2004810044000403003C2003810034000303002C20028 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_04 0x10024000203001C2001810014000103000C200081000400000000001066C3FFC530000007F40E000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_03 0x000000003B000B500800200800000A00000000000000000043000BD0080020080000120000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_02 0x000000004B000C500800200800001A00000000000000000053000CD0080020080000220000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_01 0x0000000081000D500800300800002A00000000000000000063000DD0080020080000320000000000 + // exemplar attribute sc_rom_monitor_0_0_1 INITVAL_00 0x0000000091000E500800300800003A00000000000000000000000000000000000000000003F00000 + // exemplar attribute sc_rom_monitor_0_0_1 CSDECODE_B 0b000 + // exemplar attribute sc_rom_monitor_0_0_1 CSDECODE_A 0b000 + // exemplar attribute sc_rom_monitor_0_0_1 WRITEMODE_B NORMAL + // exemplar attribute sc_rom_monitor_0_0_1 WRITEMODE_A NORMAL + // exemplar attribute sc_rom_monitor_0_0_1 GSR ENABLED + // exemplar attribute sc_rom_monitor_0_0_1 RESETMODE ASYNC + // exemplar attribute sc_rom_monitor_0_0_1 REGMODE_B NOREG + // exemplar attribute sc_rom_monitor_0_0_1 REGMODE_A NOREG + // exemplar attribute sc_rom_monitor_0_0_1 DATA_WIDTH_B 18 + // exemplar attribute sc_rom_monitor_0_0_1 DATA_WIDTH_A 18 + // exemplar attribute sc_rom_monitor_0_1_0 MEM_LPC_FILE sc_rom_monitor.lpc + // exemplar attribute sc_rom_monitor_0_1_0 MEM_INIT_FILE rom.mem + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_3F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_3E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_3D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_3C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_3B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_3A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_39 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_38 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_37 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_36 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_35 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_34 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_33 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_32 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_31 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_30 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_2F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_2E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_2D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_2C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_2B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_2A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_29 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_28 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_27 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_26 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_25 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_24 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_23 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_22 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_21 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_20 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_1F 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_1E 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_1D 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_1C 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_1B 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_1A 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_19 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_18 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_17 0x0000000000000000000000000000000000000000038FF034D2038FF034C2038FF0349A038FF03EFF + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_16 0x00D00038FF034CA038FF03492038FF0348A038FF03482038FF0344A038FF03442038FF0343A038FF + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_15 0x00D6300D5A00C5803EFF0136300D0302E0803EFF02E0803EFF038FF00D5A03EFF00D630105801363 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_14 0x00D0302E0803EFF02E0803EFF038FF03EFF02E70038FF034DA0170801F100110801F100110801F10 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_13 0x0110801F100110801F100110801F100110801F100110801F100110801F100110801F100110801F08 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_12 0x02E0803EFF02E0803EFF038FF02E7802430038FF03EFF02E780110801F0803EFF030E800DE700AE7 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_11 0x00AE400AE300AE300AE300AE300AE200D0000D0000D000342000D0000D0000D000341800D0001708 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_10 0x01F100110801F100110801F100110801F100110801F100110801F0802E0803EFF0347000D0001708 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_0F 0x024700347000D00017080247002E08016E7016E4016E3016E3016E3016E3016E200DE7030E800DE7 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_0E 0x00AE703EFF010E003EFF010E003EFF010E003EFF010E0016E0016E700DE7030E800DE700AE700AE0 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_0D 0x00CE003EFF00CE003EFF00CE003EFF00CE003EFF016E700DE7030E8034700171002470030E801108 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_0C 0x01F0803470017100247000808030E80081003478011080081002478030F800AE700AE70340700AE7 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_0B 0x0344F00AE70343F00AE700AE700AE700AE600AE600AE600AE600AE500AE500AE500AE500AE400AE4 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_0A 0x00AE400AE400AE300AE300AE300AE300AE200AE200AE200AE200AE100AE100AE100AE100AE000AE0 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_09 0x00AE0030F000AE700AE70340700AE70344F00AE70343F00AE700AE700AE700AE600AE600AE600AE6 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_08 0x00AE500AE500AE500AE500AE400AE400AE400AE400AE300AE300AE300AE300AE200AE200AE200AE2 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_07 0x00AE100AE100AE100AE100AE000AE000AE0030E800DEF02EE8016E8016E800AE8016E80000800008 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_06 0x0000800008000080080800DE8016E802400016E802448016E802438016EF016EF016EF016EE016EE + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_05 0x016EE016EE016ED016ED016ED016ED016EC016EC016EC016EC016EB016EB016EB016EB016EA016EA + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_04 0x016EA016EA016E9016E9016E9016E9016E8016E8016E802600016E800DEF038FF00D0700DE702EE8 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_03 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_02 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_01 0x00D000380003E0002EE0016E703E0002EE80260000D000380003E0002EE0016E703E0002EE802600 + // exemplar attribute sc_rom_monitor_0_1_0 INITVAL_00 0x00D000380003E0002EE0016E703E0002EE80260000D0000D0000D0000D0000D0000D0003E0002600 + // exemplar attribute sc_rom_monitor_0_1_0 CSDECODE_B 0b000 + // exemplar attribute sc_rom_monitor_0_1_0 CSDECODE_A 0b000 + // exemplar attribute sc_rom_monitor_0_1_0 WRITEMODE_B NORMAL + // exemplar attribute sc_rom_monitor_0_1_0 WRITEMODE_A NORMAL + // exemplar attribute sc_rom_monitor_0_1_0 GSR ENABLED + // exemplar attribute sc_rom_monitor_0_1_0 RESETMODE ASYNC + // exemplar attribute sc_rom_monitor_0_1_0 REGMODE_B NOREG + // exemplar attribute sc_rom_monitor_0_1_0 REGMODE_A NOREG + // exemplar attribute sc_rom_monitor_0_1_0 DATA_WIDTH_B 18 + // exemplar attribute sc_rom_monitor_0_1_0 DATA_WIDTH_A 18 + // exemplar end + end + endgenerate + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_multiplier.v b/lm32/logic/sakc/rtl/lm32/lm32_multiplier.v new file mode 100644 index 0000000..bb3b287 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_multiplier.v @@ -0,0 +1,94 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_multiplier.v +// Title : Pipelined multiplier. +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_multiplier ( + // ----- Inputs ----- + clk_i, + rst_i, + stall_x, + stall_m, + operand_0, + operand_1, + // ----- Ouputs ----- + result + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset +input stall_x; // Stall instruction in X stage +input stall_m; // Stall instruction in M stage +input [`LM32_WORD_RNG] operand_0; // Muliplicand +input [`LM32_WORD_RNG] operand_1; // Multiplier + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [`LM32_WORD_RNG] result; // Product of multiplication +reg [`LM32_WORD_RNG] result; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +reg [`LM32_WORD_RNG] muliplicand; +reg [`LM32_WORD_RNG] multiplier; +reg [`LM32_WORD_RNG] product; + +///////////////////////////////////////////////////// +// Sequential logic +///////////////////////////////////////////////////// + +always @(posedge clk_i `CFG_RESET_SENSITIVITY) +begin + if (rst_i == `TRUE) + begin + muliplicand <= {`LM32_WORD_WIDTH{1'b0}}; + multiplier <= {`LM32_WORD_WIDTH{1'b0}}; + product <= {`LM32_WORD_WIDTH{1'b0}}; + result <= {`LM32_WORD_WIDTH{1'b0}}; + end + else + begin + if (stall_x == `FALSE) + begin + muliplicand <= operand_0; + multiplier <= operand_1; + end + if (stall_m == `FALSE) + product <= muliplicand * multiplier; + result <= product; + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_ram.v b/lm32/logic/sakc/rtl/lm32/lm32_ram.v new file mode 100644 index 0000000..d689c17 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_ram.v @@ -0,0 +1,105 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_ram.v +// Title : Pseudo dual-port RAM. +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_ram ( + // ----- Inputs ------- + read_clk, + write_clk, + reset, + enable_read, + read_address, + enable_write, + write_address, + write_data, + write_enable, + // ----- Outputs ------- + read_data + ); + +///////////////////////////////////////////////////// +// Parameters +///////////////////////////////////////////////////// + +parameter data_width = 1; // Width of the data ports +parameter address_width = 1; // Width of the address ports + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input read_clk; // Read clock +input write_clk; // Write clock +input reset; // Reset + +input enable_read; // Access enable +input [address_width-1:0] read_address; // Read/write address +input enable_write; // Access enable +input [address_width-1:0] write_address;// Read/write address +input [data_width-1:0] write_data; // Data to write to specified address +input write_enable; // Write enable + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +output [data_width-1:0] read_data; // Data read from specified addess +wire [data_width-1:0] read_data; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +reg [data_width-1:0] mem[0:(1<> operand_1_x[`LM32_SHIFT_RNG]; + direction_m <= direction_x; + end + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/lm32_simtrace.v b/lm32/logic/sakc/rtl/lm32/lm32_simtrace.v new file mode 100644 index 0000000..ec6b297 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_simtrace.v @@ -0,0 +1,165 @@ +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_simtrace.v +// Title : Trace excecution in simulation +// Dependencies : lm32_include.v +// Version : soc-lm32 only +// ============================================================================= + +`include "lm32_include.v" + +// Index of opcode field in an instruction +`define LM32_OPCODE_RNG 31:26 +`define LM32_OP_RNG 30:26 + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_simtrace ( + // ----- Inputs ------- + clk_i, + rst_i, + // From pipeline + stall_x, + stall_m, + valid_w, + kill_w, + instruction_d, + pc_w + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; +input rst_i; +input stall_x; // +input stall_m; // +input valid_w; // +input kill_w; // +input [`LM32_INSTRUCTION_RNG] instruction_d; // Instruction to decode +input [`LM32_PC_RNG] pc_w; // PC of instruction in D stage + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// +reg [`LM32_INSTRUCTION_RNG] instruction_x; // Instruction to decode +reg [`LM32_INSTRUCTION_RNG] instruction_m; // Instruction to decode +reg [`LM32_INSTRUCTION_RNG] instruction; // Instruction to decode + +wire [`LM32_WORD_RNG] extended_immediate; // Zero or sign extended immediate +wire [`LM32_WORD_RNG] high_immediate; // Immedate as high 16 bits +wire [`LM32_WORD_RNG] immediate; // Immedate as high 16 bits +wire [`LM32_WORD_RNG] call_immediate; // Call immediate +wire [`LM32_WORD_RNG] branch_immediate; // Conditional branch immediate + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" + + +wire [4:0] r3 = instruction[25:21]; +wire [4:0] r2 = instruction[20:16]; +wire [4:0] r1 = instruction[15:11]; + +wire [ 4:0] imm5 = instruction[ 4:0]; +wire [15:0] imm16 = instruction[15:0]; +wire [26:0] imm27 = instruction[26:0]; + +//assign high_imm = {instruction[15:0], 16'h0000}; +wire [`LM32_PC_RNG] call_imm = {{ 4{instruction[25]}}, instruction[25:0]}; +wire [`LM32_PC_RNG] branch_imm = {{14{instruction[15]}}, instruction[15:0] }; + +// synopsys translate_off + +always @(posedge clk_i) +begin + if (stall_x == `FALSE) + instruction_x <= instruction_d; + if (stall_m == `FALSE) + instruction_m <= instruction_x; + instruction <= instruction_m; + + if ((valid_w == `TRUE) && (!kill_w)) begin + // $write ( $stime/10 ); + $writeh( " [", pc_w << 2); + $writeh( "]\t" ); + + case ( instruction[`LM32_OPCODE_RNG] ) + 6'h00: $display( "srui r%0d, r%0d, 0x%0x", r2, r3, imm5 ); + 6'h01: $display( "nori r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h02: $display( "muli r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h03: $display( "sh (r%0d + 0x%0x), r%0d", r3, r2, imm16 ); + 6'h04: $display( "lb r%0d, (r%0d + 0x%0x)", r2, r3, imm16 ); + 6'h05: $display( "sri r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h06: $display( "xori r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h07: $display( "lh r%0d, (r%0d + 0x%0x)", r2, r3, imm16 ); + 6'h08: $display( "andi r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h09: $display( "xnori r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h0a: $display( "lw r%0d, (r%0d + 0x%0x)", r2, r3, imm16 ); + 6'h0b: $display( "lhu r%0d, (r%0d + 0x%0x)", r2, r3, imm16 ); + 6'h0c: $display( "sb (r%0d + 0x%0x), r%0d", r3, r2, imm16 ); + 6'h0d: $display( "addi r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h0e: $display( "ori r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h0f: $display( "sli r%0d, r%0d, 0x%0x", r2, r3, imm5 ); + 6'h10: $display( "lbu r%0d, (r%0d + 0x%0x)", r2, r3, imm16 ); + 6'h11: $display( "be r%0d, r%0d, 0x%x", r2, r3, (pc_w + branch_imm ) << 2 ); + 6'h12: $display( "bg r%0d, r%0d, 0x%x", r2, r3, (pc_w + branch_imm ) << 2 ); + 6'h13: $display( "bge r%0d, r%0d, 0x%x", r2, r3, (pc_w + branch_imm ) << 2 ); + 6'h14: $display( "bgeu r%0d, r%0d, 0x%x", r2, r3, (pc_w + branch_imm ) << 2 ); + 6'h15: $display( "bgu r%0d, r%0d, 0x%x", r2, r3, (pc_w + branch_imm ) << 2 ); + 6'h16: $display( "sw (r%0d + 0x%0x), r%0d", r3, r2, imm16 ); + 6'h17: $display( "bne r%0d, r%0d, 0x%x", r2, r3, (pc_w + branch_imm ) << 2 ); + 6'h18: $display( "andhi r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h19: $display( "cmpei r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h1a: $display( "cmpgi r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h1b: $display( "cmpgei r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h1c: $display( "cmpgeui r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h1d: $display( "cmpgui r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h1e: $display( "orhi r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h1f: $display( "cmpnei r%0d, r%0d, 0x%0x", r2, r3, imm16 ); + 6'h20: $display( "sru r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h21: $display( "nor r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h22: $display( "mul r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h23: $display( "divu r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h24: $display( "rcsr r%0d, csr%0d", r1, r3 ); + 6'h25: $display( "sr r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h26: $display( "xor r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h27: $display( "div (XXX not documented XXX)" ); + 6'h28: $display( "and r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h29: $display( "xnor r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h2a: $display( "XXX" ); + 6'h2b: $display( "raise (XXX: scall or break)" ); + 6'h2c: $display( "sextb r%0d, r%0d", r1, r3 ); + 6'h2d: $display( "add r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h2e: $display( "or r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h2f: $display( "sl r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h30: $display( "b r%0d", r3 ); + 6'h31: $display( "modu r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h32: $display( "sub r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h33: $display( "XXX" ); + 6'h34: $display( "wcsr csr%0d, r%0d", r3, r2 ); + 6'h35: $display( "modu r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h36: $display( "call r%0d", r3 ); + 6'h37: $display( "sexth r%0d, r%0d", r1, r3 ); + 6'h38: $display( "bi 0x%x", (pc_w + call_imm) << 2 ); + 6'h39: $display( "cmpe r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h3a: $display( "cmpg r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h3b: $display( "cmpge r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h3c: $display( "cmpgeu r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h3d: $display( "cmpgu r%0d, r%0d, r%0d", r1, r3, r2 ); + 6'h3e: $display( "calli 0x%x", (pc_w + call_imm) << 2 ); + 6'h3f: $display( "cmpne r%0d, r%0d, r%0d", r1, r3, r2 ); + endcase + end +end + +// synopsys translate_on + +endmodule + diff --git a/lm32/logic/sakc/rtl/lm32/lm32_top.v b/lm32/logic/sakc/rtl/lm32/lm32_top.v new file mode 100644 index 0000000..d14a8a7 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/lm32_top.v @@ -0,0 +1,370 @@ +// ============================================================================= +// COPYRIGHT NOTICE +// Copyright 2006 (c) Lattice Semiconductor Corporation +// ALL RIGHTS RESERVED +// This confidential and proprietary software may be used only as authorised by +// a licensing agreement from Lattice Semiconductor Corporation. +// The entire notice above must be reproduced on all authorized copies and +// copies may only be made to the extent permitted by a licensing agreement from +// Lattice Semiconductor Corporation. +// +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) +// 5555 NE Moore Court 408-826-6000 (other locations) +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ +// U.S.A email: techsupport@latticesemi.com +// =============================================================================/ +// FILE DETAILS +// Project : LatticeMico32 +// File : lm32_top.v +// Title : Top-level of CPU. +// Dependencies : lm32_include.v +// Version : 6.1.17 +// ============================================================================= + +`include "lm32_include.v" + +///////////////////////////////////////////////////// +// Module interface +///////////////////////////////////////////////////// + +module lm32_top ( + // ----- Inputs ------- + clk_i, + rst_i, + // From external devices +`ifdef CFG_INTERRUPTS_ENABLED + interrupt_n, +`endif + // From user logic +`ifdef CFG_USER_ENABLED + user_result, + user_complete, +`endif +`ifdef CFG_IWB_ENABLED + // Instruction Wishbone master + I_DAT_I, + I_ACK_I, + I_ERR_I, + I_RTY_I, +`endif + // Data Wishbone master + D_DAT_I, + D_ACK_I, + D_ERR_I, + D_RTY_I, + // Debug Slave port WishboneInterface + DEBUG_ADR_I, + DEBUG_DAT_I, + DEBUG_SEL_I, + DEBUG_WE_I, + DEBUG_CTI_I, + DEBUG_BTE_I, + DEBUG_LOCK_I, + DEBUG_CYC_I, + DEBUG_STB_I, + // ----- Outputs ------- +`ifdef CFG_USER_ENABLED + user_valid, + user_opcode, + user_operand_0, + user_operand_1, +`endif +`ifdef CFG_IWB_ENABLED + // Instruction Wishbone master + I_DAT_O, + I_ADR_O, + I_CYC_O, + I_SEL_O, + I_STB_O, + I_WE_O, + I_CTI_O, + I_LOCK_O, + I_BTE_O, +`endif + // Data Wishbone master + D_DAT_O, + D_ADR_O, + D_CYC_O, + D_SEL_O, + D_STB_O, + D_WE_O, + D_CTI_O, + D_LOCK_O, + D_BTE_O, + // Debug Slave port WishboneInterface + DEBUG_ACK_O, + DEBUG_ERR_O, + DEBUG_RTY_O, + DEBUG_DAT_O + ); + +///////////////////////////////////////////////////// +// Inputs +///////////////////////////////////////////////////// + +input clk_i; // Clock +input rst_i; // Reset + +`ifdef CFG_INTERRUPTS_ENABLED +input [`LM32_INTERRUPT_RNG] interrupt_n; // Interrupt pins, active-low +`endif + +`ifdef CFG_USER_ENABLED +input [`LM32_WORD_RNG] user_result; // User-defined instruction result +input user_complete; // Indicates the user-defined instruction result is valid +`endif + +`ifdef CFG_IWB_ENABLED +input [`LM32_WORD_RNG] I_DAT_I; // Instruction Wishbone interface read data +input I_ACK_I; // Instruction Wishbone interface acknowledgement +input I_ERR_I; // Instruction Wishbone interface error +input I_RTY_I; // Instruction Wishbone interface retry +`endif + +input [`LM32_WORD_RNG] D_DAT_I; // Data Wishbone interface read data +input D_ACK_I; // Data Wishbone interface acknowledgement +input D_ERR_I; // Data Wishbone interface error +input D_RTY_I; // Data Wishbone interface retry + +input [`LM32_WORD_RNG] DEBUG_ADR_I; // Debug monitor Wishbone interface address +input [`LM32_WORD_RNG] DEBUG_DAT_I; // Debug monitor Wishbone interface write data +input [`LM32_BYTE_SELECT_RNG] DEBUG_SEL_I; // Debug monitor Wishbone interface byte select +input DEBUG_WE_I; // Debug monitor Wishbone interface write enable +input [`LM32_CTYPE_RNG] DEBUG_CTI_I; // Debug monitor Wishbone interface cycle type +input [`LM32_BTYPE_RNG] DEBUG_BTE_I; // Debug monitor Wishbone interface burst type +input DEBUG_LOCK_I; // Debug monitor Wishbone interface locked transfer +input DEBUG_CYC_I; // Debug monitor Wishbone interface cycle +input DEBUG_STB_I; // Debug monitor Wishbone interface strobe + +///////////////////////////////////////////////////// +// Outputs +///////////////////////////////////////////////////// + +`ifdef CFG_USER_ENABLED +output user_valid; // Indicates that user_opcode and user_operand_* are valid +wire user_valid; +output [`LM32_USER_OPCODE_RNG] user_opcode; // User-defined instruction opcode +reg [`LM32_USER_OPCODE_RNG] user_opcode; +output [`LM32_WORD_RNG] user_operand_0; // First operand for user-defined instruction +wire [`LM32_WORD_RNG] user_operand_0; +output [`LM32_WORD_RNG] user_operand_1; // Second operand for user-defined instruction +wire [`LM32_WORD_RNG] user_operand_1; +`endif + +`ifdef CFG_IWB_ENABLED +output [`LM32_WORD_RNG] I_DAT_O; // Instruction Wishbone interface write data +wire [`LM32_WORD_RNG] I_DAT_O; +output [`LM32_WORD_RNG] I_ADR_O; // Instruction Wishbone interface address +wire [`LM32_WORD_RNG] I_ADR_O; +output I_CYC_O; // Instruction Wishbone interface cycle +wire I_CYC_O; +output [`LM32_BYTE_SELECT_RNG] I_SEL_O; // Instruction Wishbone interface byte select +wire [`LM32_BYTE_SELECT_RNG] I_SEL_O; +output I_STB_O; // Instruction Wishbone interface strobe +wire I_STB_O; +output I_WE_O; // Instruction Wishbone interface write enable +wire I_WE_O; +output [`LM32_CTYPE_RNG] I_CTI_O; // Instruction Wishbone interface cycle type +wire [`LM32_CTYPE_RNG] I_CTI_O; +output I_LOCK_O; // Instruction Wishbone interface lock bus +wire I_LOCK_O; +output [`LM32_BTYPE_RNG] I_BTE_O; // Instruction Wishbone interface burst type +wire [`LM32_BTYPE_RNG] I_BTE_O; +`endif + +output [`LM32_WORD_RNG] D_DAT_O; // Data Wishbone interface write data +wire [`LM32_WORD_RNG] D_DAT_O; +output [`LM32_WORD_RNG] D_ADR_O; // Data Wishbone interface address +wire [`LM32_WORD_RNG] D_ADR_O; +output D_CYC_O; // Data Wishbone interface cycle +wire D_CYC_O; +output [`LM32_BYTE_SELECT_RNG] D_SEL_O; // Data Wishbone interface byte select +wire [`LM32_BYTE_SELECT_RNG] D_SEL_O; +output D_STB_O; // Data Wishbone interface strobe +wire D_STB_O; +output D_WE_O; // Data Wishbone interface write enable +wire D_WE_O; +output [`LM32_CTYPE_RNG] D_CTI_O; // Data Wishbone interface cycle type +wire [`LM32_CTYPE_RNG] D_CTI_O; +output D_LOCK_O; // Date Wishbone interface lock bus +wire D_LOCK_O; +output [`LM32_BTYPE_RNG] D_BTE_O; // Data Wishbone interface burst type +wire [`LM32_BTYPE_RNG] D_BTE_O; + +output DEBUG_ACK_O; // Debug monitor Wishbone ack +wire DEBUG_ACK_O; +output DEBUG_ERR_O; // Debug monitor Wishbone error +wire DEBUG_ERR_O; +output DEBUG_RTY_O; // Debug monitor Wishbone retry +wire DEBUG_RTY_O; +output [`LM32_WORD_RNG] DEBUG_DAT_O; // Debug monitor Wishbone read data +wire [`LM32_WORD_RNG] DEBUG_DAT_O; + +///////////////////////////////////////////////////// +// Internal nets and registers +///////////////////////////////////////////////////// + +`ifdef CFG_JTAG_ENABLED +// Signals between JTAG interface and CPU +wire [`LM32_BYTE_RNG] jtag_reg_d; +wire [`LM32_BYTE_RNG] jtag_reg_q; +wire jtag_update; +wire [2:0] jtag_reg_addr_d; +wire [2:0] jtag_reg_addr_q; +wire jtck; +wire jrstn; +`endif + +`ifdef CFG_TRACE_ENABLED +// PC trace signals +wire [`LM32_PC_RNG] trace_pc; // PC to trace (address of next non-sequential instruction) +wire trace_pc_valid; // Indicates that a new trace PC is valid +wire trace_exception; // Indicates an exception has occured +wire [`LM32_EID_RNG] trace_eid; // Indicates what type of exception has occured +wire trace_eret; // Indicates an eret instruction has been executed +`ifdef CFG_DEBUG_ENABLED +wire trace_bret; // Indicates a bret instruction has been executed +`endif +`endif + +///////////////////////////////////////////////////// +// Functions +///////////////////////////////////////////////////// + +`include "lm32_functions.v" +///////////////////////////////////////////////////// +// Instantiations +///////////////////////////////////////////////////// + +// LM32 CPU +lm32_cpu cpu ( + // ----- Inputs ------- + .clk_i (clk_i), +`ifdef CFG_EBR_NEGEDGE_REGISTER_FILE + .clk_n_i (clk_n), +`endif + .rst_i (rst_i), + // From external devices +`ifdef CFG_INTERRUPTS_ENABLED + .interrupt_n (interrupt_n), +`endif + // From user logic +`ifdef CFG_USER_ENABLED + .user_result (user_result), + .user_complete (user_complete), +`endif +`ifdef CFG_JTAG_ENABLED + // From JTAG + .jtag_clk (jtck), + .jtag_update (jtag_update), + .jtag_reg_q (jtag_reg_q), + .jtag_reg_addr_q (jtag_reg_addr_q), +`endif +`ifdef CFG_IWB_ENABLED + // Instruction Wishbone master + .I_DAT_I (I_DAT_I), + .I_ACK_I (I_ACK_I), + .I_ERR_I (I_ERR_I), + .I_RTY_I (I_RTY_I), +`endif + // Data Wishbone master + .D_DAT_I (D_DAT_I), + .D_ACK_I (D_ACK_I), + .D_ERR_I (D_ERR_I), + .D_RTY_I (D_RTY_I), + // ----- Outputs ------- +`ifdef CFG_TRACE_ENABLED + .trace_pc (trace_pc), + .trace_pc_valid (trace_pc_valid), + .trace_exception (trace_exception), + .trace_eid (trace_eid), + .trace_eret (trace_eret), +`ifdef CFG_DEBUG_ENABLED + .trace_bret (trace_bret), +`endif +`endif +`ifdef CFG_JTAG_ENABLED + .jtag_reg_d (jtag_reg_d), + .jtag_reg_addr_d (jtag_reg_addr_d), +`endif +`ifdef CFG_USER_ENABLED + .user_valid (user_valid), + .user_opcode (user_opcode), + .user_operand_0 (user_operand_0), + .user_operand_1 (user_operand_1), +`endif +`ifdef CFG_IWB_ENABLED + // Instruction Wishbone master + .I_DAT_O (I_DAT_O), + .I_ADR_O (I_ADR_O), + .I_CYC_O (I_CYC_O), + .I_SEL_O (I_SEL_O), + .I_STB_O (I_STB_O), + .I_WE_O (I_WE_O), + .I_CTI_O (I_CTI_O), + .I_LOCK_O (I_LOCK_O), + .I_BTE_O (I_BTE_O), + `endif + // Data Wishbone master + .D_DAT_O (D_DAT_O), + .D_ADR_O (D_ADR_O), + .D_CYC_O (D_CYC_O), + .D_SEL_O (D_SEL_O), + .D_STB_O (D_STB_O), + .D_WE_O (D_WE_O), + .D_CTI_O (D_CTI_O), + .D_LOCK_O (D_LOCK_O), + .D_BTE_O (D_BTE_O) + ); + +`ifdef DEBUG_ROM +// ROM monitor +lm32_monitor debug_rom ( + // ----- Inputs ------- + .clk_i (clk_i), + .rst_i (rst_i), + .MON_ADR_I (DEBUG_ADR_I), + .MON_STB_I (DEBUG_STB_I), + .MON_CYC_I (DEBUG_CYC_I), + .MON_WE_I (DEBUG_WE_I), + .MON_SEL_I (DEBUG_SEL_I), + .MON_DAT_I (DEBUG_DAT_I), + .MON_CTI_I (DEBUG_CTI_I), + .MON_BTE_I (DEBUG_BTE_I), + .MON_LOCK_I (DEBUG_LOCK_I), + // ----- Outputs ------ + .MON_RTY_O (DEBUG_RTY_O), + .MON_ERR_O (DEBUG_ERR_O), + .MON_ACK_O (DEBUG_ACK_O), + .MON_DAT_O (DEBUG_DAT_O) + ); +`endif + +`ifdef CFG_JTAG_ENABLED +// JTAG cores +jtag_cores jtag_cores ( + // ----- Inputs ----- +`ifdef INCLUDE_LM32 + .reg_d (jtag_reg_d), + .reg_addr_d (jtag_reg_addr_d), +`endif +`ifdef INCLUDE_SPI + .spi_q (spi_q), +`endif + // ----- Outputs ----- +`ifdef INCLUDE_LM32 + .reg_update (jtag_update), + .reg_q (jtag_reg_q), + .reg_addr_q (jtag_reg_addr_q), +`endif +`ifdef INCLUDE_SPI + .spi_c (spi_c), + .spi_d (spi_d), + .spi_sn (spi_sn), +`endif + .jtck (jtck), + .jrstn (jrstn) + ); +`endif + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/spiprog.v b/lm32/logic/sakc/rtl/lm32/spiprog.v new file mode 100644 index 0000000..ef3a02a --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/spiprog.v @@ -0,0 +1,159 @@ +//--------------------------------------------------------------------------- +// +//Name : SPIPROG.v +// +//Description: +// +// This module contains the ER2 regsiters of SPI Serial FLASH programmer IP +// core. There are only three ER2 registers, one control register and two +// data registers, in this IP core. The control register is a 8-bit wide +// register for selecting which data register will be accessed when the +// Control/Data# bit in ER1 register is low. Data register 0 is a readonly +// ID register. It is composed of three register fields -- an 8-bit +// "implementer", a 16-bit "IP_functionality", and a 12-bit "revision". +// Data register 1 is a variable length register for sending commands to or +// receiving readback data from the SPI Serial FLASH device. +// +//$Log: spiprog.vhd,v $ +//Revision 1.2 2004-09-09 11:43:26-07 jhsin +//1. Reduced the the ID register (DR0) length from 36 bits to 8 bits. +//2. Same as TYPEA and TYPEB modules, use falling edge clock +// for all TCK Flip-Flops. +// +//Revision 1.1 2004-08-12 13:22:05-07 jhsin +//Added 7 delay Flip-Flops so that the DR1 readback data from SPI Serial FLASH is in the byte boundary. +// +//Revision 1.0 2004-08-03 18:35:56-07 jhsin +//Initial revision +// +// +//$Header: \\\\hqfs2\\ip\040cores\\rcs\\hqfs2\\ip\040cores\\rcswork\\isptracy\\VHDL\\Implementation\\spiprog.vhd,v 1.2 2004-09-09 11:43:26-07 jhsin Exp $ +// +//Copyright (C) 2004 Lattice Semiconductor Corp. All rights reserved. +// +//--------------------------------------------------------------------------- + +module SPIPROG (input JTCK , + input JTDI , + output JTDO2 , + input JSHIFT , + input JUPDATE , + input JRSTN , + input JCE2 , + input SPIPROG_ENABLE , + input CONTROL_DATAN , + output SPI_C , + output SPI_D , + output SPI_SN , + input SPI_Q); + + wire er2Cr_enable ; + wire er2Dr0_enable; + wire er2Dr1_enable; + + wire tdo_er2Cr ; + wire tdo_er2Dr0; + wire tdo_er2Dr1; + + wire [7:0] encodedDrSelBits ; + wire [8:0] er2CrTdiBit ; + wire [8:0] er2Dr0TdiBit ; + + wire captureDrER2; + reg spi_s ; + reg [6:0] spi_q_dly; + + wire [7:0] ip_functionality_id; + + genvar i; + + // ------ Control Register 0 ------ + + assign er2Cr_enable = JCE2 & SPIPROG_ENABLE & CONTROL_DATAN; + + assign tdo_er2Cr = er2CrTdiBit[0]; + + // CR_BIT0_BIT7 + generate + for(i=0; i<=7; i=i+1) + begin:CR_BIT0_BIT7 + TYPEA BIT_N (.CLK (JTCK), + .RESET_N (JRSTN), + .CLKEN (er2Cr_enable), + .TDI (er2CrTdiBit[i + 1]), + .TDO (er2CrTdiBit[i]), + .DATA_OUT (encodedDrSelBits[i]), + .DATA_IN (encodedDrSelBits[i]), + .CAPTURE_DR (captureDrER2), + .UPDATE_DR (JUPDATE)); + end + endgenerate // CR_BIT0_BIT7 + + assign er2CrTdiBit[8] = JTDI; + +// ------ Data Register 0 ------ + assign er2Dr0_enable = (JCE2 & SPIPROG_ENABLE & ~CONTROL_DATAN & (encodedDrSelBits == 8'b00000000)) ? 1'b1 : 1'b0; + + assign tdo_er2Dr0 = er2Dr0TdiBit[0]; + + assign ip_functionality_id = 8'b00000001; //-- SPI Serial FLASH Programmer (0x01) + +// DR0_BIT0_BIT7 + generate + for(i=0; i<=7; i=i+1) + begin:DR0_BIT0_BIT7 + TYPEB BIT_N (.CLK (JTCK), + .RESET_N (JRSTN), + .CLKEN (er2Dr0_enable), + .TDI (er2Dr0TdiBit[i + 1]), + .TDO (er2Dr0TdiBit[i]), + .DATA_IN (ip_functionality_id[i]), + .CAPTURE_DR (captureDrER2)); + end + endgenerate // DR0_BIT0_BIT7 + + assign er2Dr0TdiBit[8] = JTDI; + +// ------ Data Register 1 ------ + + assign er2Dr1_enable = (JCE2 & JSHIFT & SPIPROG_ENABLE & ~CONTROL_DATAN & (encodedDrSelBits == 8'b00000001)) ? 1'b1 : 1'b0; + + assign SPI_C = ~ (JTCK & er2Dr1_enable & spi_s); + + assign SPI_D = JTDI & er2Dr1_enable; + + // SPI_S_Proc + always @(negedge JTCK or negedge JRSTN) + begin + if (~JRSTN) + spi_s <= 1'b0; + else + if (JUPDATE) + spi_s <= 1'b0; + else + spi_s <= er2Dr1_enable; + end + + assign SPI_SN = ~spi_s; + + // SPI_Q_Proc + always @(negedge JTCK or negedge JRSTN) + begin + if (~JRSTN) + spi_q_dly <= 'b0; + else + if (er2Dr1_enable) + spi_q_dly <= {spi_q_dly[5:0],SPI_Q}; + end + + assign tdo_er2Dr1 = spi_q_dly[6]; + + // ------ JTDO2 MUX ------ + + assign JTDO2 = CONTROL_DATAN ? tdo_er2Cr : + (encodedDrSelBits == 8'b00000000) ? tdo_er2Dr0 : + (encodedDrSelBits == 8'b00000001) ? tdo_er2Dr1 : 1'b0; + + assign captureDrER2 = ~JSHIFT & JCE2; + +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/system.sdc b/lm32/logic/sakc/rtl/lm32/system.sdc new file mode 100755 index 0000000..22950be --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/system.sdc @@ -0,0 +1,58 @@ +# Synplicity, Inc. constraint file +# C:\ispTOOLS6_0\micosystem\components\lm32_top\rtl\verilog\system.sdc +# Written on Thu Apr 06 13:56:58 2006 +# by Synplify for Lattice, Synplify for Lattice 8.5D Scope Editor + +# +# Clocks +# +define_clock -name {clk_i} -freq 25.000 -clockgroup default_clkgroup_0 + +# +# Clock to Clock +# + +# +# Inputs/Outputs +# + +# +# Registers +# + +# +# Multicycle Path +# + +# +# False Path +# + +# +# Path Delay +# + +# +# Attributes +# +define_attribute {clk_i} loc {a10} +define_attribute {reset_n} loc {h6} +define_attribute {uartSIN} loc {m2} +define_attribute {uartSOUT} loc {l1} +define_attribute {sramsram_csn} loc {y4} +define_attribute {sramsram_oen} loc {aa6} +define_attribute {sramsram_wen} loc {ab6} +define_attribute {sramsram_be[3:0]} loc {aa3,ab3,aa4,ab4} +define_attribute {sramsram_data[31:0]} loc {v7,w7,y7,aa7,ab7,v8,w8,y8,aa8,ab8,v9,w9,y9,aa9,ab9,v10,w10,y10,aa10,w11,y11,aa11,y13,aa13,w14,y14,aa14,ab14,u15,v15,w15,y15} +define_attribute {sramsram_addr[22:0]} loc {u16,v16,w16,y16,aa16,ab16,u17,v17,w17,y17,aa17,ab17,w18,y18,aa18,ab18,y19,aa19,ab19,aa20,ab20,y20,w20} +define_attribute {gpio_LCDPIO_OUT[15:0]} loc {h5,t13,t17,u13,v13,p5,p3,p4,n5,n4,n3,n2,n1,m5,m4,m3} +define_attribute {gpio_LEDPIO_OUT[9:0]} loc {u11,v5,u6,u4,g5,g4,f5,f4,e5,e4} +define_attribute {gpio_KeypadPIO_IN[3:0]} loc {R1,T3,T2,T1} + +# +# I/O standards +# + +# +# Other Constraints +# diff --git a/lm32/logic/sakc/rtl/lm32/typea.v b/lm32/logic/sakc/rtl/lm32/typea.v new file mode 100644 index 0000000..6327fdb --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/typea.v @@ -0,0 +1,74 @@ +/*-- --------------------------------------------------------------------------- +-- +-- Name : TYPEA.v +-- +-- Description: +-- +-- This is one of the two types of cells that are used to create ER1/ER2 +-- register bits. +-- +-- $Log: typea.vhd,v $ +-- Revision 1.2 2002-11-13 18:33:59-08 jhsin +-- The SHIFT_DR_CAPTURE_DR and ENABLE_ER1/2 signals of the +-- dedicate logic JTAG_PORT didn't act as what their names implied. +-- The SHIFT_DR_CAPTURE_DR actually acts as SHIFT_DR. +-- The ENABLE_ER1/2 actually acts as SHIFT_DR_CAPTURE_DR. +-- These had caused a lot of headaches for a long time and now they are +-- fixed by: +-- (1) Use SHIFT_DR_CAPTURE_DR and ENABLE_ER1/2 to create +-- CAPTURE_DR for all typeA, typeB bits in the ER1, ER2 registers. +-- (2) Use ENABLE_ER1 or the enESR, enCSR, enBAR (these 3 signals +-- have the same waveform of ENABLE_ER2) directly to be the CLKEN +-- of all typeA, typeB bits in the ER1, ER2 registers. +-- (3) Modify typea.vhd to use only UPDATE_DR signal for the clock enable +-- of the holding flip-flop. +-- These changes caused ispTracy.vhd and cge.dat changes and the new +-- CGE.exe version will be 1.3.5. +-- +-- Revision 1.1 2002-05-01 18:13:51-07 jhsin +-- Added RCS version control header to file. No code changes. +-- +-- $Header: \\\\hqfile2\\ipcores\\rcs\\hqfile2\\ipcores\\rcswork\\isptracy\\VHDL\\Implementation\\typea.vhd,v 1.2 2002-11-13 18:33:59-08 jhsin Exp $ +-- +-- Copyright (C) 2002 Lattice Semiconductor Corp. All rights reserved. +-- +-- ---------------------------------------------------------------------------*/ + +module TYPEA( + input CLK, + input RESET_N, + input CLKEN, + input TDI, + output TDO, + output reg DATA_OUT, + input DATA_IN, + input CAPTURE_DR, + input UPDATE_DR + ); + + reg tdoInt; + + + always @ (negedge CLK or negedge RESET_N) + begin + if (RESET_N == 1'b0) + tdoInt <= 1'b0; + else if (CLK == 1'b0) + if (CLKEN == 1'b1) + if (CAPTURE_DR == 1'b0) + tdoInt <= TDI; + else + tdoInt <= DATA_IN; + end + + assign TDO = tdoInt; + + always @ (negedge CLK or negedge RESET_N) + begin + if (RESET_N == 1'b0) + DATA_OUT <= 1'b0; + else if (CLK == 1'b0) + if (UPDATE_DR == 1'b1) + DATA_OUT <= tdoInt; + end +endmodule diff --git a/lm32/logic/sakc/rtl/lm32/typeb.v b/lm32/logic/sakc/rtl/lm32/typeb.v new file mode 100644 index 0000000..be99989 --- /dev/null +++ b/lm32/logic/sakc/rtl/lm32/typeb.v @@ -0,0 +1,50 @@ +/*-- --------------------------------------------------------------------------- +-- +-- Name : TYPEB.vhd +-- +-- Description: +-- +-- This is one of the two types of cells that are used to create ER1/ER2 +-- register bits. +-- +-- $Log: typeb.vhd,v $ +-- Revision 1.2 2002-08-01 16:39:33-07 jhsin +-- Modified typeb module to remove redundant DATA_OUT port. +-- +-- Revision 1.1 2002-05-01 18:13:51-07 jhsin +-- Added RCS version control header to file. No code changes. +-- +-- $Header: \\\\hqfile2\\ipcores\\rcs\\hqfile2\\ipcores\\rcswork\\isptracy\\VHDL\\Implementation\\typeb.vhd,v 1.2 2002-08-01 16:39:33-07 jhsin Exp $ +-- +-- Copyright (C) 2002 Lattice Semiconductor Corp. All rights reserved. +-- +-- ---------------------------------------------------------------------------*/ +module TYPEB + ( + input CLK, + input RESET_N, + input CLKEN, + input TDI, + output TDO, + input DATA_IN, + input CAPTURE_DR + ); + + reg tdoInt; + + always @ (negedge CLK or negedge RESET_N) + begin + if (RESET_N== 1'b0) + tdoInt <= 1'b0; + else if (CLK == 1'b0) + if (CLKEN==1'b1) + if (CAPTURE_DR==1'b0) + tdoInt <= TDI; + else + tdoInt <= DATA_IN; + end + + assign TDO = tdoInt; + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_bram/wb_bram.v b/lm32/logic/sakc/rtl/wb_bram/wb_bram.v new file mode 100644 index 0000000..cf204ed --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_bram/wb_bram.v @@ -0,0 +1,62 @@ +//----------------------------------------------------------------- +// Wishbone BlockRAM +//----------------------------------------------------------------- + +module wb_bram #( + parameter mem_file_name = "none", + parameter adr_width = 11 +) ( + input clk_i, + input rst_i, + // + input wb_stb_i, + input wb_cyc_i, + input wb_we_i, + output wb_ack_o, + input [31:0] wb_adr_i, + output reg [31:0] wb_dat_o, + input [31:0] wb_dat_i, + input [ 3:0] wb_sel_i +); + +//----------------------------------------------------------------- +// Storage depth in 32 bit words +//----------------------------------------------------------------- +parameter word_width = adr_width - 2; +parameter word_depth = (1 << word_width); + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- +reg [31:0] ram [0:word_depth-1]; // actual RAM +reg ack; +wire [word_width-1:0] adr; + + +assign adr = wb_adr_i[adr_width-1:2]; // +assign wb_ack_o = wb_stb_i & ack; + +always @(posedge clk_i) +begin + if (wb_stb_i && wb_cyc_i) + begin + if (wb_we_i) + ram[ adr ] <= wb_dat_i; + + wb_dat_o <= ram[ adr ]; + ack <= ~ack; + end else + ack <= 0; + +end + +initial +begin + if (mem_file_name != "none") + begin + $readmemh(mem_file_name, ram); + end +end + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_arb.v b/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_arb.v new file mode 100644 index 0000000..4368a25 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_arb.v @@ -0,0 +1,252 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// General Round Robin Arbiter //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/wb_conmax/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +// +// copy from wb_conmax +// +// +// +// +// + +`include "wb_conbus_defines.v" + +module wb_conbus_arb(clk, rst, req, gnt); + +input clk; +input rst; +input [7:0] req; // Req input +output [2:0] gnt; // Grant output +//input next; // Next Target + +/////////////////////////////////////////////////////////////////////// +// +// Parameters +// + + +parameter [2:0] + grant0 = 3'h0, + grant1 = 3'h1, + grant2 = 3'h2, + grant3 = 3'h3, + grant4 = 3'h4, + grant5 = 3'h5, + grant6 = 3'h6, + grant7 = 3'h7; + +/////////////////////////////////////////////////////////////////////// +// +// Local Registers and Wires +// + +reg [2:0] state, next_state; + +/////////////////////////////////////////////////////////////////////// +// +// Misc Logic +// + +assign gnt = state; + +always@(posedge clk or posedge rst) + if(rst) state <= grant0; + else state <= next_state; + +/////////////////////////////////////////////////////////////////////// +// +// Next State Logic +// - implements round robin arbitration algorithm +// - switches grant if current req is dropped or next is asserted +// - parks at last grant +// + +always@(state or req ) + begin + next_state = state; // Default Keep State + case(state) // synopsys parallel_case full_case + grant0: + // if this req is dropped or next is asserted, check for other req's + if(!req[0] ) + begin + if(req[1]) next_state = grant1; + else + if(req[2]) next_state = grant2; + else + if(req[3]) next_state = grant3; + else + if(req[4]) next_state = grant4; + else + if(req[5]) next_state = grant5; + else + if(req[6]) next_state = grant6; + else + if(req[7]) next_state = grant7; + end + grant1: + // if this req is dropped or next is asserted, check for other req's + if(!req[1] ) + begin + if(req[2]) next_state = grant2; + else + if(req[3]) next_state = grant3; + else + if(req[4]) next_state = grant4; + else + if(req[5]) next_state = grant5; + else + if(req[6]) next_state = grant6; + else + if(req[7]) next_state = grant7; + else + if(req[0]) next_state = grant0; + end + grant2: + // if this req is dropped or next is asserted, check for other req's + if(!req[2] ) + begin + if(req[3]) next_state = grant3; + else + if(req[4]) next_state = grant4; + else + if(req[5]) next_state = grant5; + else + if(req[6]) next_state = grant6; + else + if(req[7]) next_state = grant7; + else + if(req[0]) next_state = grant0; + else + if(req[1]) next_state = grant1; + end + grant3: + // if this req is dropped or next is asserted, check for other req's + if(!req[3] ) + begin + if(req[4]) next_state = grant4; + else + if(req[5]) next_state = grant5; + else + if(req[6]) next_state = grant6; + else + if(req[7]) next_state = grant7; + else + if(req[0]) next_state = grant0; + else + if(req[1]) next_state = grant1; + else + if(req[2]) next_state = grant2; + end + grant4: + // if this req is dropped or next is asserted, check for other req's + if(!req[4] ) + begin + if(req[5]) next_state = grant5; + else + if(req[6]) next_state = grant6; + else + if(req[7]) next_state = grant7; + else + if(req[0]) next_state = grant0; + else + if(req[1]) next_state = grant1; + else + if(req[2]) next_state = grant2; + else + if(req[3]) next_state = grant3; + end + grant5: + // if this req is dropped or next is asserted, check for other req's + if(!req[5] ) + begin + if(req[6]) next_state = grant6; + else + if(req[7]) next_state = grant7; + else + if(req[0]) next_state = grant0; + else + if(req[1]) next_state = grant1; + else + if(req[2]) next_state = grant2; + else + if(req[3]) next_state = grant3; + else + if(req[4]) next_state = grant4; + end + grant6: + // if this req is dropped or next is asserted, check for other req's + if(!req[6] ) + begin + if(req[7]) next_state = grant7; + else + if(req[0]) next_state = grant0; + else + if(req[1]) next_state = grant1; + else + if(req[2]) next_state = grant2; + else + if(req[3]) next_state = grant3; + else + if(req[4]) next_state = grant4; + else + if(req[5]) next_state = grant5; + end + grant7: + // if this req is dropped or next is asserted, check for other req's + if(!req[7] ) + begin + if(req[0]) next_state = grant0; + else + if(req[1]) next_state = grant1; + else + if(req[2]) next_state = grant2; + else + if(req[3]) next_state = grant3; + else + if(req[4]) next_state = grant4; + else + if(req[5]) next_state = grant5; + else + if(req[6]) next_state = grant6; + end + endcase + end + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_defines.v b/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_defines.v new file mode 100644 index 0000000..0a5f101 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_defines.v @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE Connection ShareBus Definitions //// +//// //// +//// //// +//// Author: Johny Chi //// +//// chisuhua@yahoo.com.cn //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/wb_conmax/ //// +//// //// +///////////////////////////////////////////////////////////////////// +/// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + + + +`timescale 1ns / 10ps + diff --git a/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_top.v b/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_top.v new file mode 100644 index 0000000..56a26be --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_conbus/wb_conbus_top.v @@ -0,0 +1,655 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE Connection Bus Top Level //// +//// //// +//// //// +//// Author: Johny Chi //// +//// chisuhua@yahoo.com.cn //// +//// //// +//// //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// Description +// 1. Up to 8 masters and 8 slaves share bus Wishbone connection +// 2. no priorty arbitor , 8 masters are processed in a round +// robin way, +// 3. if WB_USE_TRISTATE was defined, the share bus is a tristate +// bus, and use less logic resource. +// 4. wb_conbus was synthesis to XC2S100-5-PQ208 using synplify, +// Max speed >60M , and 374 SLICE if using Multiplexor bus +// or 150 SLICE if using tri-state bus. +// +`include "wb_conbus_defines.v" +`define dw 32 // Data bus Width +`define aw 32 // Address bus Width +`define sw `dw / 8 // Number of Select Lines +`define mbusw `aw + `sw + `dw +4 //address width + byte select width + dat width + cyc + we + stb +cab , input from master interface +`define sbusw 3 // ack + err + rty, input from slave interface +`define mselectw 8 // number of masters +`define sselectw 8 // number of slavers + +//`define WB_USE_TRISTATE + + +module wb_conbus_top #( + parameter s0_addr_w = 4 , // slave 0 address decode width -- bit 31 is always ignored! + parameter s0_addr = 4'h0, // slave 0 address + parameter s1_addr_w = 4 , // slave 1 address decode width -- bit 31 is always ignored! + parameter s1_addr = 4'h1, // slave 1 address + parameter s27_addr_w = 8 , // slave 2 to slave 7 address decode width -- bit 31 is always ignored! + parameter s2_addr = 8'h92, // slave 2 address + parameter s3_addr = 8'h93, // slave 3 address + parameter s4_addr = 8'h94, // slave 4 address + parameter s5_addr = 8'h95, // slave 5 address + parameter s6_addr = 8'h96, // slave 6 address + parameter s7_addr = 8'h97 // slave 7 address +) ( + clk_i, rst_i, + + // Master 0 Interface + m0_dat_i, m0_dat_o, m0_adr_i, m0_sel_i, m0_we_i, m0_cyc_i, + m0_stb_i, m0_ack_o, m0_err_o, m0_rty_o, m0_cab_i, + + // Master 1 Interface + m1_dat_i, m1_dat_o, m1_adr_i, m1_sel_i, m1_we_i, m1_cyc_i, + m1_stb_i, m1_ack_o, m1_err_o, m1_rty_o, m1_cab_i, + + // Master 2 Interface + m2_dat_i, m2_dat_o, m2_adr_i, m2_sel_i, m2_we_i, m2_cyc_i, + m2_stb_i, m2_ack_o, m2_err_o, m2_rty_o, m2_cab_i, + + // Master 3 Interface + m3_dat_i, m3_dat_o, m3_adr_i, m3_sel_i, m3_we_i, m3_cyc_i, + m3_stb_i, m3_ack_o, m3_err_o, m3_rty_o, m3_cab_i, + + // Master 4 Interface + m4_dat_i, m4_dat_o, m4_adr_i, m4_sel_i, m4_we_i, m4_cyc_i, + m4_stb_i, m4_ack_o, m4_err_o, m4_rty_o, m4_cab_i, + + // Master 5 Interface + m5_dat_i, m5_dat_o, m5_adr_i, m5_sel_i, m5_we_i, m5_cyc_i, + m5_stb_i, m5_ack_o, m5_err_o, m5_rty_o, m5_cab_i, + + // Master 6 Interface + m6_dat_i, m6_dat_o, m6_adr_i, m6_sel_i, m6_we_i, m6_cyc_i, + m6_stb_i, m6_ack_o, m6_err_o, m6_rty_o, m6_cab_i, + + // Master 7 Interface + m7_dat_i, m7_dat_o, m7_adr_i, m7_sel_i, m7_we_i, m7_cyc_i, + m7_stb_i, m7_ack_o, m7_err_o, m7_rty_o, m7_cab_i, + + // Slave 0 Interface + s0_dat_i, s0_dat_o, s0_adr_o, s0_sel_o, s0_we_o, s0_cyc_o, + s0_stb_o, s0_ack_i, s0_err_i, s0_rty_i, s0_cab_o, + + // Slave 1 Interface + s1_dat_i, s1_dat_o, s1_adr_o, s1_sel_o, s1_we_o, s1_cyc_o, + s1_stb_o, s1_ack_i, s1_err_i, s1_rty_i, s1_cab_o, + + // Slave 2 Interface + s2_dat_i, s2_dat_o, s2_adr_o, s2_sel_o, s2_we_o, s2_cyc_o, + s2_stb_o, s2_ack_i, s2_err_i, s2_rty_i, s2_cab_o, + + // Slave 3 Interface + s3_dat_i, s3_dat_o, s3_adr_o, s3_sel_o, s3_we_o, s3_cyc_o, + s3_stb_o, s3_ack_i, s3_err_i, s3_rty_i, s3_cab_o, + + // Slave 4 Interface + s4_dat_i, s4_dat_o, s4_adr_o, s4_sel_o, s4_we_o, s4_cyc_o, + s4_stb_o, s4_ack_i, s4_err_i, s4_rty_i, s4_cab_o, + + // Slave 5 Interface + s5_dat_i, s5_dat_o, s5_adr_o, s5_sel_o, s5_we_o, s5_cyc_o, + s5_stb_o, s5_ack_i, s5_err_i, s5_rty_i, s5_cab_o, + + // Slave 6 Interface + s6_dat_i, s6_dat_o, s6_adr_o, s6_sel_o, s6_we_o, s6_cyc_o, + s6_stb_o, s6_ack_i, s6_err_i, s6_rty_i, s6_cab_o, + + // Slave 7 Interface + s7_dat_i, s7_dat_o, s7_adr_o, s7_sel_o, s7_we_o, s7_cyc_o, + s7_stb_o, s7_ack_i, s7_err_i, s7_rty_i, s7_cab_o + + ); + +//////////////////////////////////////////////////////////////////// +// +// Module Parameters +// + + + +//////////////////////////////////////////////////////////////////// +// +// Module IOs +// + +input clk_i, rst_i; + +// Master 0 Interface +input [`dw-1:0] m0_dat_i; +output [`dw-1:0] m0_dat_o; +input [`aw-1:0] m0_adr_i; +input [`sw-1:0] m0_sel_i; +input m0_we_i; +input m0_cyc_i; +input m0_stb_i; +input m0_cab_i; +output m0_ack_o; +output m0_err_o; +output m0_rty_o; + +// Master 1 Interface +input [`dw-1:0] m1_dat_i; +output [`dw-1:0] m1_dat_o; +input [`aw-1:0] m1_adr_i; +input [`sw-1:0] m1_sel_i; +input m1_we_i; +input m1_cyc_i; +input m1_stb_i; +input m1_cab_i; +output m1_ack_o; +output m1_err_o; +output m1_rty_o; + +// Master 2 Interface +input [`dw-1:0] m2_dat_i; +output [`dw-1:0] m2_dat_o; +input [`aw-1:0] m2_adr_i; +input [`sw-1:0] m2_sel_i; +input m2_we_i; +input m2_cyc_i; +input m2_stb_i; +input m2_cab_i; +output m2_ack_o; +output m2_err_o; +output m2_rty_o; + +// Master 3 Interface +input [`dw-1:0] m3_dat_i; +output [`dw-1:0] m3_dat_o; +input [`aw-1:0] m3_adr_i; +input [`sw-1:0] m3_sel_i; +input m3_we_i; +input m3_cyc_i; +input m3_stb_i; +input m3_cab_i; +output m3_ack_o; +output m3_err_o; +output m3_rty_o; + +// Master 4 Interface +input [`dw-1:0] m4_dat_i; +output [`dw-1:0] m4_dat_o; +input [`aw-1:0] m4_adr_i; +input [`sw-1:0] m4_sel_i; +input m4_we_i; +input m4_cyc_i; +input m4_stb_i; +input m4_cab_i; +output m4_ack_o; +output m4_err_o; +output m4_rty_o; + +// Master 5 Interface +input [`dw-1:0] m5_dat_i; +output [`dw-1:0] m5_dat_o; +input [`aw-1:0] m5_adr_i; +input [`sw-1:0] m5_sel_i; +input m5_we_i; +input m5_cyc_i; +input m5_stb_i; +input m5_cab_i; +output m5_ack_o; +output m5_err_o; +output m5_rty_o; + +// Master 6 Interface +input [`dw-1:0] m6_dat_i; +output [`dw-1:0] m6_dat_o; +input [`aw-1:0] m6_adr_i; +input [`sw-1:0] m6_sel_i; +input m6_we_i; +input m6_cyc_i; +input m6_stb_i; +input m6_cab_i; +output m6_ack_o; +output m6_err_o; +output m6_rty_o; + +// Master 7 Interface +input [`dw-1:0] m7_dat_i; +output [`dw-1:0] m7_dat_o; +input [`aw-1:0] m7_adr_i; +input [`sw-1:0] m7_sel_i; +input m7_we_i; +input m7_cyc_i; +input m7_stb_i; +input m7_cab_i; +output m7_ack_o; +output m7_err_o; +output m7_rty_o; + +// Slave 0 Interface +input [`dw-1:0] s0_dat_i; +output [`dw-1:0] s0_dat_o; +output [`aw-1:0] s0_adr_o; +output [`sw-1:0] s0_sel_o; +output s0_we_o; +output s0_cyc_o; +output s0_stb_o; +output s0_cab_o; +input s0_ack_i; +input s0_err_i; +input s0_rty_i; + +// Slave 1 Interface +input [`dw-1:0] s1_dat_i; +output [`dw-1:0] s1_dat_o; +output [`aw-1:0] s1_adr_o; +output [`sw-1:0] s1_sel_o; +output s1_we_o; +output s1_cyc_o; +output s1_stb_o; +output s1_cab_o; +input s1_ack_i; +input s1_err_i; +input s1_rty_i; + +// Slave 2 Interface +input [`dw-1:0] s2_dat_i; +output [`dw-1:0] s2_dat_o; +output [`aw-1:0] s2_adr_o; +output [`sw-1:0] s2_sel_o; +output s2_we_o; +output s2_cyc_o; +output s2_stb_o; +output s2_cab_o; +input s2_ack_i; +input s2_err_i; +input s2_rty_i; + +// Slave 3 Interface +input [`dw-1:0] s3_dat_i; +output [`dw-1:0] s3_dat_o; +output [`aw-1:0] s3_adr_o; +output [`sw-1:0] s3_sel_o; +output s3_we_o; +output s3_cyc_o; +output s3_stb_o; +output s3_cab_o; +input s3_ack_i; +input s3_err_i; +input s3_rty_i; + +// Slave 4 Interface +input [`dw-1:0] s4_dat_i; +output [`dw-1:0] s4_dat_o; +output [`aw-1:0] s4_adr_o; +output [`sw-1:0] s4_sel_o; +output s4_we_o; +output s4_cyc_o; +output s4_stb_o; +output s4_cab_o; +input s4_ack_i; +input s4_err_i; +input s4_rty_i; + +// Slave 5 Interface +input [`dw-1:0] s5_dat_i; +output [`dw-1:0] s5_dat_o; +output [`aw-1:0] s5_adr_o; +output [`sw-1:0] s5_sel_o; +output s5_we_o; +output s5_cyc_o; +output s5_stb_o; +output s5_cab_o; +input s5_ack_i; +input s5_err_i; +input s5_rty_i; + +// Slave 6 Interface +input [`dw-1:0] s6_dat_i; +output [`dw-1:0] s6_dat_o; +output [`aw-1:0] s6_adr_o; +output [`sw-1:0] s6_sel_o; +output s6_we_o; +output s6_cyc_o; +output s6_stb_o; +output s6_cab_o; +input s6_ack_i; +input s6_err_i; +input s6_rty_i; + +// Slave 7 Interface +input [`dw-1:0] s7_dat_i; +output [`dw-1:0] s7_dat_o; +output [`aw-1:0] s7_adr_o; +output [`sw-1:0] s7_sel_o; +output s7_we_o; +output s7_cyc_o; +output s7_stb_o; +output s7_cab_o; +input s7_ack_i; +input s7_err_i; +input s7_rty_i; + + +//////////////////////////////////////////////////////////////////// +// +// Local wires +// + +wire [`mselectw -1:0] i_gnt_arb; +wire [2:0] gnt; +reg [`sselectw -1:0] i_ssel_dec; +`ifdef WB_USE_TRISTATE +wire [`mbusw -1:0] i_bus_m; +`else +reg [`mbusw -1:0] i_bus_m; // internal share bus, master data and control to slave +`endif +wire [`dw -1:0] i_dat_s; // internal share bus , slave data to master +wire [`sbusw -1:0] i_bus_s; // internal share bus , slave control to master + + + +//////////////////////////////////////////////////////////////////// +// +// Master output Interfaces +// + +// master0 +assign m0_dat_o = i_dat_s; +assign {m0_ack_o, m0_err_o, m0_rty_o} = i_bus_s & {3{i_gnt_arb[0]}}; + +// master1 +assign m1_dat_o = i_dat_s; +assign {m1_ack_o, m1_err_o, m1_rty_o} = i_bus_s & {3{i_gnt_arb[1]}}; + +// master2 + +assign m2_dat_o = i_dat_s; +assign {m2_ack_o, m2_err_o, m2_rty_o} = i_bus_s & {3{i_gnt_arb[2]}}; + +// master3 + +assign m3_dat_o = i_dat_s; +assign {m3_ack_o, m3_err_o, m3_rty_o} = i_bus_s & {3{i_gnt_arb[3]}}; + +// master4 + +assign m4_dat_o = i_dat_s; +assign {m4_ack_o, m4_err_o, m4_rty_o} = i_bus_s & {3{i_gnt_arb[4]}}; + +// master5 + +assign m5_dat_o = i_dat_s; +assign {m5_ack_o, m5_err_o, m5_rty_o} = i_bus_s & {3{i_gnt_arb[5]}}; + +// master6 + +assign m6_dat_o = i_dat_s; +assign {m6_ack_o, m6_err_o, m6_rty_o} = i_bus_s & {3{i_gnt_arb[6]}}; + +// master7 + +assign m7_dat_o = i_dat_s; +assign {m7_ack_o, m7_err_o, m7_rty_o} = i_bus_s & {3{i_gnt_arb[7]}}; + + +assign i_bus_s = {s0_ack_i | s1_ack_i | s2_ack_i | s3_ack_i | s4_ack_i | s5_ack_i | s6_ack_i | s7_ack_i , + s0_err_i | s1_err_i | s2_err_i | s3_err_i | s4_err_i | s5_err_i | s6_err_i | s7_err_i , + s0_rty_i | s1_rty_i | s2_rty_i | s3_rty_i | s4_rty_i | s5_rty_i | s6_rty_i | s7_rty_i }; + +//////////////////////////////// +// Slave output interface +// +// slave0 +assign {s0_adr_o, s0_sel_o, s0_dat_o, s0_we_o, s0_cab_o,s0_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s0_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[0]; // stb_o = cyc_i & stb_i & i_ssel_dec + +// slave1 + +assign {s1_adr_o, s1_sel_o, s1_dat_o, s1_we_o, s1_cab_o, s1_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s1_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[1]; + +// slave2 + +assign {s2_adr_o, s2_sel_o, s2_dat_o, s2_we_o, s2_cab_o, s2_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s2_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[2]; + +// slave3 + +assign {s3_adr_o, s3_sel_o, s3_dat_o, s3_we_o, s3_cab_o, s3_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s3_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[3]; + +// slave4 + +assign {s4_adr_o, s4_sel_o, s4_dat_o, s4_we_o, s4_cab_o, s4_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s4_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[4]; + +// slave5 + +assign {s5_adr_o, s5_sel_o, s5_dat_o, s5_we_o, s5_cab_o, s5_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s5_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[5]; + +// slave6 + +assign {s6_adr_o, s6_sel_o, s6_dat_o, s6_we_o, s6_cab_o, s6_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s6_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[6]; + +// slave7 + +assign {s7_adr_o, s7_sel_o, s7_dat_o, s7_we_o, s7_cab_o, s7_cyc_o} = i_bus_m[`mbusw -1:1]; +assign s7_stb_o = i_bus_m[1] & i_bus_m[0] & i_ssel_dec[7]; + +/////////////////////////////////////// +// Master and Slave input interface +// + +`ifdef WB_USE_TRISTATE +// input from master interface +assign i_bus_m = i_gnt_arb[0] ? {m0_adr_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cab_i, m0_cyc_i, m0_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[1] ? {m1_adr_i, m1_sel_i, m1_dat_i, m1_we_i, m1_cab_i,m1_cyc_i, m1_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[2] ? {m2_adr_i, m2_sel_i, m2_dat_i, m2_we_i, m2_cab_i, m2_cyc_i, m2_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[3] ? {m3_adr_i, m3_sel_i, m3_dat_i, m3_we_i, m3_cab_i, m3_cyc_i, m3_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[4] ? {m4_adr_i, m4_sel_i, m4_dat_i, m4_we_i, m4_cab_i, m4_cyc_i, m4_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[5] ? {m5_adr_i, m5_sel_i, m5_dat_i, m5_we_i, m5_cab_i, m5_cyc_i, m5_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[6] ? {m6_adr_i, m6_sel_i, m6_dat_i, m6_we_i, m6_cab_i, m6_cyc_i, m6_stb_i} : 72'bz ; +assign i_bus_m = i_gnt_arb[7] ? {m7_adr_i, m7_sel_i, m7_dat_i, m7_we_i, m7_cab_i, m7_cyc_i,m7_stb_i} : 72'bz ; +// input from slave interface +assign i_dat_s = i_ssel_dec[0] ? s0_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[1] ? s1_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[2] ? s2_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[3] ? s3_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[4] ? s4_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[5] ? s5_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[6] ? s6_dat_i: 32'bz; +assign i_dat_s = i_ssel_dec[7] ? s7_dat_i: 32'bz; + +`else + +always @(gnt , m0_adr_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cab_i, m0_cyc_i,m0_stb_i, + m1_adr_i, m1_sel_i, m1_dat_i, m1_we_i, m1_cab_i, m1_cyc_i,m1_stb_i, + m2_adr_i, m2_sel_i, m2_dat_i, m2_we_i, m2_cab_i, m2_cyc_i,m2_stb_i, + m3_adr_i, m3_sel_i, m3_dat_i, m3_we_i, m3_cab_i, m3_cyc_i,m3_stb_i, + m4_adr_i, m4_sel_i, m4_dat_i, m4_we_i, m4_cab_i, m4_cyc_i,m4_stb_i, + m5_adr_i, m5_sel_i, m5_dat_i, m5_we_i, m5_cab_i, m5_cyc_i,m5_stb_i, + m6_adr_i, m6_sel_i, m6_dat_i, m6_we_i, m6_cab_i, m6_cyc_i,m6_stb_i, + m7_adr_i, m7_sel_i, m7_dat_i, m7_we_i, m7_cab_i, m7_cyc_i,m7_stb_i) + case(gnt) + 3'h0: i_bus_m = {m0_adr_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cab_i, m0_cyc_i,m0_stb_i}; + 3'h1: i_bus_m = {m1_adr_i, m1_sel_i, m1_dat_i, m1_we_i, m1_cab_i, m1_cyc_i,m1_stb_i}; + 3'h2: i_bus_m = {m2_adr_i, m2_sel_i, m2_dat_i, m2_we_i, m2_cab_i, m2_cyc_i,m2_stb_i}; + 3'h3: i_bus_m = {m3_adr_i, m3_sel_i, m3_dat_i, m3_we_i, m3_cab_i, m3_cyc_i,m3_stb_i}; + 3'h4: i_bus_m = {m4_adr_i, m4_sel_i, m4_dat_i, m4_we_i, m4_cab_i, m4_cyc_i,m4_stb_i}; + 3'h5: i_bus_m = {m5_adr_i, m5_sel_i, m5_dat_i, m5_we_i, m5_cab_i, m5_cyc_i,m5_stb_i}; + 3'h6: i_bus_m = {m6_adr_i, m6_sel_i, m6_dat_i, m6_we_i, m6_cab_i, m6_cyc_i,m6_stb_i}; + 3'h7: i_bus_m = {m7_adr_i, m7_sel_i, m7_dat_i, m7_we_i, m7_cab_i, m7_cyc_i,m7_stb_i}; + default:i_bus_m = 72'b0;//{m0_adr_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cab_i, m0_cyc_i,m0_stb_i}; +endcase + +assign i_dat_s = i_ssel_dec[0] ? s0_dat_i : + i_ssel_dec[1] ? s1_dat_i : + i_ssel_dec[2] ? s2_dat_i : + i_ssel_dec[3] ? s3_dat_i : + i_ssel_dec[4] ? s4_dat_i : + i_ssel_dec[5] ? s5_dat_i : + i_ssel_dec[6] ? s6_dat_i : + i_ssel_dec[7] ? s7_dat_i : {`dw{1'b0}}; +`endif +// +// arbitor +// +assign i_gnt_arb[0] = (gnt == 3'd0); +assign i_gnt_arb[1] = (gnt == 3'd1); +assign i_gnt_arb[2] = (gnt == 3'd2); +assign i_gnt_arb[3] = (gnt == 3'd3); +assign i_gnt_arb[4] = (gnt == 3'd4); +assign i_gnt_arb[5] = (gnt == 3'd5); +assign i_gnt_arb[6] = (gnt == 3'd6); +assign i_gnt_arb[7] = (gnt == 3'd7); + +wb_conbus_arb wb_conbus_arb( + .clk(clk_i), + .rst(rst_i), + .req({ m7_cyc_i, + m6_cyc_i, + m5_cyc_i, + m4_cyc_i, + m3_cyc_i, + m2_cyc_i, + m1_cyc_i, + m0_cyc_i}), + .gnt(gnt) +); + +////////////////////////////////// +// address decode logic +// +wire [7:0] m0_ssel_dec, m1_ssel_dec, m2_ssel_dec, m3_ssel_dec, m4_ssel_dec, m5_ssel_dec, m6_ssel_dec, m7_ssel_dec; +always @(gnt, m0_ssel_dec, m1_ssel_dec, m2_ssel_dec, m3_ssel_dec, m4_ssel_dec, m5_ssel_dec, m6_ssel_dec, m7_ssel_dec) + case(gnt) + 3'h0: i_ssel_dec = m0_ssel_dec; + 3'h1: i_ssel_dec = m1_ssel_dec; + 3'h2: i_ssel_dec = m2_ssel_dec; + 3'h3: i_ssel_dec = m3_ssel_dec; + 3'h4: i_ssel_dec = m4_ssel_dec; + 3'h5: i_ssel_dec = m5_ssel_dec; + 3'h6: i_ssel_dec = m6_ssel_dec; + 3'h7: i_ssel_dec = m7_ssel_dec; + default: i_ssel_dec = 7'b0; +endcase +// +// decode all master address before arbitor for running faster +// +assign m0_ssel_dec[0] = (m0_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m0_ssel_dec[1] = (m0_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m0_ssel_dec[2] = (m0_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m0_ssel_dec[3] = (m0_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m0_ssel_dec[4] = (m0_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m0_ssel_dec[5] = (m0_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m0_ssel_dec[6] = (m0_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m0_ssel_dec[7] = (m0_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m1_ssel_dec[0] = (m1_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m1_ssel_dec[1] = (m1_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m1_ssel_dec[2] = (m1_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m1_ssel_dec[3] = (m1_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m1_ssel_dec[4] = (m1_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m1_ssel_dec[5] = (m1_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m1_ssel_dec[6] = (m1_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m1_ssel_dec[7] = (m1_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m2_ssel_dec[0] = (m2_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m2_ssel_dec[1] = (m2_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m2_ssel_dec[2] = (m2_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m2_ssel_dec[3] = (m2_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m2_ssel_dec[4] = (m2_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m2_ssel_dec[5] = (m2_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m2_ssel_dec[6] = (m2_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m2_ssel_dec[7] = (m2_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m3_ssel_dec[0] = (m3_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m3_ssel_dec[1] = (m3_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m3_ssel_dec[2] = (m3_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m3_ssel_dec[3] = (m3_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m3_ssel_dec[4] = (m3_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m3_ssel_dec[5] = (m3_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m3_ssel_dec[6] = (m3_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m3_ssel_dec[7] = (m3_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m4_ssel_dec[0] = (m4_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m4_ssel_dec[1] = (m4_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m4_ssel_dec[2] = (m4_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m4_ssel_dec[3] = (m4_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m4_ssel_dec[4] = (m4_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m4_ssel_dec[5] = (m4_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m4_ssel_dec[6] = (m4_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m4_ssel_dec[7] = (m4_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m5_ssel_dec[0] = (m5_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m5_ssel_dec[1] = (m5_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m5_ssel_dec[2] = (m5_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m5_ssel_dec[3] = (m5_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m5_ssel_dec[4] = (m5_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m5_ssel_dec[5] = (m5_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m5_ssel_dec[6] = (m5_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m5_ssel_dec[7] = (m5_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m6_ssel_dec[0] = (m6_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m6_ssel_dec[1] = (m6_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m6_ssel_dec[2] = (m6_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m6_ssel_dec[3] = (m6_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m6_ssel_dec[4] = (m6_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m6_ssel_dec[5] = (m6_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m6_ssel_dec[6] = (m6_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m6_ssel_dec[7] = (m6_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +assign m7_ssel_dec[0] = (m7_adr_i[`aw -2 : `aw -1 - s0_addr_w ] == s0_addr); +assign m7_ssel_dec[1] = (m7_adr_i[`aw -2 : `aw -1 - s1_addr_w ] == s1_addr); +assign m7_ssel_dec[2] = (m7_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s2_addr); +assign m7_ssel_dec[3] = (m7_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s3_addr); +assign m7_ssel_dec[4] = (m7_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s4_addr); +assign m7_ssel_dec[5] = (m7_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s5_addr); +assign m7_ssel_dec[6] = (m7_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s6_addr); +assign m7_ssel_dec[7] = (m7_adr_i[`aw -2 : `aw -1 - s27_addr_w ] == s7_addr); + +//assign i_ssel_dec[0] = (i_bus_m[`mbusw -1 : `mbusw - s0_addr_w ] == s0_addr); +//assign i_ssel_dec[1] = (i_bus_m[`mbusw -1 : `mbusw - s1_addr_w ] == s1_addr); +//assign i_ssel_dec[2] = (i_bus_m[`mbusw -1 : `mbusw - s27_addr_w ] == s2_addr); +//assign i_ssel_dec[3] = (i_bus_m[`mbusw -1 : `mbusw - s27_addr_w ] == s3_addr); +//assign i_ssel_dec[4] = (i_bus_m[`mbusw -1 : `mbusw - s27_addr_w ] == s4_addr); +//assign i_ssel_dec[5] = (i_bus_m[`mbusw -1 : `mbusw - s27_addr_w ] == s5_addr); +//assign i_ssel_dec[6] = (i_bus_m[`mbusw -1 : `mbusw - s27_addr_w ] == s6_addr); +//assign i_ssel_dec[7] = (i_bus_m[`mbusw -1 : `mbusw - s27_addr_w ] == s7_addr); + + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_ddr/async_fifo.v b/lm32/logic/sakc/rtl/wb_ddr/async_fifo.v new file mode 100644 index 0000000..885dfbe --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/async_fifo.v @@ -0,0 +1,116 @@ +//========================================== +// Function : Asynchronous FIFO (w/ 2 asynchronous clocks). +// Coder : Alex Claros F. +// Date : 15/May/2005. +// Notes : This implementation is based on the article +// 'Asynchronous FIFO in Virtex-II FPGAs' +// writen by Peter Alfke. This TechXclusive +// article can be downloaded from the +// Xilinx website. It has some minor modifications. +//========================================= + +`timescale 1ns / 1ps + +module async_fifo + #(parameter DATA_WIDTH = 8, + ADDRESS_WIDTH = 4, + FIFO_DEPTH = (1 << ADDRESS_WIDTH)) + //Reading port + (output wire [DATA_WIDTH-1:0] Data_out, + output reg Empty_out, + input wire ReadEn_in, + input wire RClk, + //Writing port. + input wire [DATA_WIDTH-1:0] Data_in, + output reg Full_out, + input wire WriteEn_in, + input wire WClk, + + input wire Clear_in); + + /////Internal connections & variables////// + reg [DATA_WIDTH-1:0] Mem [FIFO_DEPTH-1:0]; + wire [ADDRESS_WIDTH-1:0] pNextWordToWrite, pNextWordToRead; + wire EqualAddresses; + wire NextWriteAddressEn, NextReadAddressEn; + wire Set_Status, Rst_Status; + reg Status; + wire PresetFull, PresetEmpty; + + //////////////Code/////////////// + //Data ports logic: + //(Uses a dual-port RAM). + //'Data_out' logic: + assign Data_out = Mem[pNextWordToRead]; +// always @ (posedge RClk) +// if (!PresetEmpty) +// Data_out <= Mem[pNextWordToRead]; +// if (ReadEn_in & !Empty_out) + + //'Data_in' logic: + always @ (posedge WClk) + if (WriteEn_in & !Full_out) + Mem[pNextWordToWrite] <= Data_in; + + //Fifo addresses support logic: + //'Next Addresses' enable logic: + assign NextWriteAddressEn = WriteEn_in & ~Full_out; + assign NextReadAddressEn = ReadEn_in & ~Empty_out; + + //Addreses (Gray counters) logic: + GrayCounter #( + .COUNTER_WIDTH( ADDRESS_WIDTH ) + ) GrayCounter_pWr ( + .GrayCount_out(pNextWordToWrite), + .Enable_in(NextWriteAddressEn), + .Clear_in(Clear_in), + + .Clk(WClk) + ); + + GrayCounter #( + .COUNTER_WIDTH( ADDRESS_WIDTH ) + ) GrayCounter_pRd ( + .GrayCount_out(pNextWordToRead), + .Enable_in(NextReadAddressEn), + .Clear_in(Clear_in), + .Clk(RClk) + ); + + + //'EqualAddresses' logic: + assign EqualAddresses = (pNextWordToWrite == pNextWordToRead); + + //'Quadrant selectors' logic: + assign Set_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ~^ pNextWordToRead[ADDRESS_WIDTH-1]) & + (pNextWordToWrite[ADDRESS_WIDTH-1] ^ pNextWordToRead[ADDRESS_WIDTH-2]); + + assign Rst_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ^ pNextWordToRead[ADDRESS_WIDTH-1]) & + (pNextWordToWrite[ADDRESS_WIDTH-1] ~^ pNextWordToRead[ADDRESS_WIDTH-2]); + + //'Status' latch logic: + always @ (Set_Status, Rst_Status, Clear_in) //D Latch w/ Asynchronous Clear & Preset. + if (Rst_Status | Clear_in) + Status = 0; //Going 'Empty'. + else if (Set_Status) + Status = 1; //Going 'Full'. + + //'Full_out' logic for the writing port: + assign PresetFull = Status & EqualAddresses; //'Full' Fifo. + + always @ (posedge WClk, posedge PresetFull) //D Flip-Flop w/ Asynchronous Preset. + if (PresetFull) + Full_out <= 1; + else + Full_out <= 0; + + //'Empty_out' logic for the reading port: + assign PresetEmpty = ~Status & EqualAddresses; //'Empty' Fifo. + + always @ (posedge RClk, posedge PresetEmpty) //D Flip-Flop w/ Asynchronous Preset. + if (PresetEmpty) + Empty_out <= 1; + else + Empty_out <= 0; + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_clkgen.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_clkgen.v new file mode 100644 index 0000000..52ebba7 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_clkgen.v @@ -0,0 +1,224 @@ +//--------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//--------------------------------------------------------------------------- + +`timescale 1ns / 1ps +`include "ddr_include.v" + +module ddr_clkgen +#( + parameter phase_shift = 0, + parameter clk_multiply = 13, + parameter clk_divide = 5 +) ( + input clk, + input reset, + output locked, + // + output read_clk, + output write_clk, + output write_clk90, + // DCM phase shift control + output reg ps_ready, + input ps_up, + input ps_down +); + + +//---------------------------------------------------------------------------- +// ~133 MHz DDR Clock generator +//---------------------------------------------------------------------------- +wire read_clk_u; +wire dcm_fx_locked; + +DCM #( + .CLKDV_DIVIDE(2.0), // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 + // 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 + .CLKFX_DIVIDE(clk_divide), // Can be any integer from 1 to 32 + .CLKFX_MULTIPLY(clk_multiply), // Can be any integer from 2 to 32 + .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature + .CLKIN_PERIOD(), // Specify period of input clock + .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE + .CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X + .DESKEW_ADJUST("SOURCE_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or + // an integer from 0 to 15 + .DFS_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for frequency synthesis + .DLL_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for DLL + .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE + .FACTORY_JF(16'hC080), // FACTORY JF values + .PHASE_SHIFT(0), // Amount of fixed phase shift from -255 to 255 + .STARTUP_WAIT("FALSE") // Delay configuration DONE until DCM LOCK, TRUE/FALSE +) dcm_fx ( + .DSSEN(), + .CLK0(), // 0 degree DCM CLK output + .CLK180(), // 180 degree DCM CLK output + .CLK270(), // 270 degree DCM CLK output + .CLK2X(), // 2X DCM CLK output + .CLK2X180(), // 2X, 180 degree DCM CLK out + .CLK90(), // 90 degree DCM CLK output + .CLKDV(), // Divided DCM CLK out (CLKDV_DIVIDE) + .CLKFX( read_clk_u ), // DCM CLK synthesis out (M/D) + .CLKFX180(), // 180 degree CLK synthesis out + .LOCKED( dcm_fx_locked), // DCM LOCK status output + .PSDONE(), // Dynamic phase adjust done output + .STATUS(), // 8-bit DCM status bits output + .CLKFB(), // DCM clock feedback + .CLKIN( clk ), // Clock input (from IBUFG, BUFG or DCM) + .PSCLK( gnd ), // Dynamic phase adjust clock input + .PSEN( gnd ), // Dynamic phase adjust enable input + .PSINCDEC( gnd ), // Dynamic phase adjust increment/decrement + .RST( reset ) // DCM asynchronous reset input +); + +//---------------------------------------------------------------------------- +// BUFG read clock +//---------------------------------------------------------------------------- +BUFG bufg_fx_clk ( + .O(read_clk), // Clock buffer output + .I(read_clk_u) // Clock buffer input +); + +//---------------------------------------------------------------------------- +// Phase shifted clock for write path +//---------------------------------------------------------------------------- +wire phase_dcm_reset; +wire phase_dcm_locked; +wire write_clk_u, write_clk90_u, write_clk180_u, write_clk270_u; +reg psen, psincdec; +wire psdone; + +DCM #( + .CLKDV_DIVIDE(2.0), // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 + // 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 + .CLKFX_DIVIDE(2), // Can be any integer from 1 to 32 + .CLKFX_MULTIPLY(2), // Can be any integer from 2 to 32 + .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature + .CLKIN_PERIOD(), // Specify period of input clock + .CLK_FEEDBACK("1X"), // Specify clock feedback of NONE, 1X or 2X + .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or + // an integer from 0 to 15 + .DFS_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for frequency synthesis + .DLL_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for DLL + .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE + .FACTORY_JF(16'hC080), // FACTORY JF values + .CLKOUT_PHASE_SHIFT("VARIABLE"), // Specify phase shift of NONE, FIXED or VARIABLE + .PHASE_SHIFT( phase_shift ), // Amount of fixed phase shift from -255 to 255 + .STARTUP_WAIT("FALSE") // Delay configuration DONE until DCM LOCK, TRUE/FALSE +) dcm_phase ( + .DSSEN(), + .CLK0( write_clk_u ), // 0 degree DCM CLK output + .CLK90( write_clk90_u ), // 90 degree DCM CLK output + .CLK180( write_clk180_u ), // 180 degree DCM CLK output + .CLK270( write_clk270_u ), // 270 degree DCM CLK output + .CLK2X(), // 2X DCM CLK output + .CLK2X180(), // 2X, 180 degree DCM CLK out + .CLKDV(), // Divided DCM CLK out (CLKDV_DIVIDE) + .CLKFX(), // DCM CLK synthesis out (M/D) + .CLKFX180(), // 180 degree CLK synthesis out + .LOCKED( phase_dcm_locked ), // DCM LOCK status output + .STATUS(), // 8-bit DCM status bits output + .CLKFB( write_clk ), // DCM clock feedback + .CLKIN( read_clk ), // Clock input (from IBUFG, BUFG or DCM) + .PSCLK( clk ), // Dynamic phase adjust clock input + .PSEN( psen ), // Dynamic phase adjust enable input + .PSINCDEC( psincdec ), // Dynamic phase adjust increment/decrement + .PSDONE( psdone ), // Dynamic phase adjust done output + .RST( phase_dcm_reset ) // DCM asynchronous reset input +); + +// delayed reset for phase shifting DCM +reg [3:0] reset_counter; +assign phase_dcm_reset = reset | (reset_counter != 0); + +always @(posedge clk) +begin + if (reset) + reset_counter <= 1; + else begin + if (dcm_fx_locked & (reset_counter != 0)) + reset_counter <= reset_counter + 1; + end +end + +//---------------------------------------------------------------------------- +// DCM phase shifting state machine +//---------------------------------------------------------------------------- +parameter s_init = 0; +parameter s_idle = 1; +parameter s_waitdone = 2; +parameter s_waitdone2= 3; + +reg [1:0] state; + +always @(posedge clk) +begin + if (reset) begin + state <= s_init; + psen <= 0; + ps_ready <= 0; + end else begin + case (state) + s_init: begin + if (phase_dcm_locked) begin + ps_ready <= 1; + state <= s_idle; + end + end + s_idle: begin + if (ps_up) begin + ps_ready <= 0; + psen <= 1; + psincdec <= 1; + state <= s_waitdone; + end else if (ps_down) begin + ps_ready <= 0; + psen <= 1; + psincdec <= 0; + state <= s_waitdone; + end + end + s_waitdone: begin + psen <= 0; + if (psdone) begin + state <= s_waitdone2; + end + end + s_waitdone2: begin + if (~ps_up && ~ps_down) begin + ps_ready <= 1; + state <= s_idle; + end + end + endcase + end +end + +//---------------------------------------------------------------------------- +// BUFG write clock +//---------------------------------------------------------------------------- +BUFG bufg_write_clk ( + .O(write_clk ), // Clock buffer output + .I(write_clk_u) // Clock buffer input +); + +BUFG bufg_write_clk90 ( + .O(write_clk90 ), // Clock buffer output + .I(write_clk90_u) // Clock buffer input +); + +//---------------------------------------------------------------------------- +// LOCKED logic +//---------------------------------------------------------------------------- +reg phase_dcm_locked_delayed; + +always @(posedge write_clk) +begin + phase_dcm_locked_delayed <= phase_dcm_locked; +end + +assign locked = ~reset & phase_dcm_locked_delayed; + + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_ctrl.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_ctrl.v new file mode 100644 index 0000000..51f279c --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_ctrl.v @@ -0,0 +1,370 @@ +//---------------------------------------------------------------------------- +// Pipelined, asyncronous DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +module ddr_ctrl +#( + parameter phase_shift = 0, + parameter clk_freq = 100000000, + parameter clk_multiply = 12, + parameter clk_divide = 5, + parameter wait200_init = 26 +) ( + input clk, + input reset, + // DDR ports + output [2:0] ddr_clk, + output [2:0] ddr_clk_n, + input ddr_clk_fb, + output ddr_ras_n, + output ddr_cas_n, + output ddr_we_n, + output [1:0] ddr_cke, + output [1:0] ddr_cs_n, + output [ `A_RNG] ddr_a, + output [ `BA_RNG] ddr_ba, + inout [ `DQ_RNG] ddr_dq, + inout [`DQS_RNG] ddr_dqs, + output [ `DM_RNG] ddr_dm, + // FML (FastMemoryLink) + output reg fml_done, + input [`FML_ADR_RNG] fml_adr, + input fml_rd, + input fml_wr, + input [`FML_DAT_RNG] fml_wdat, + input [`FML_BE_RNG] fml_wbe, + input fml_wnext, + output fml_rempty, + input fml_rnext, + output [`FML_DAT_RNG] fml_rdat, + // DCM phase shift control + output ps_ready, + input ps_up, + input ps_down, + // Logic Probe + output probe_clk, + input [7:0] probe_sel, + output reg [7:0] probe +); + +wire [ `DQ_RNG] ddr_dq_i, ddr_dq_o; +wire [`DQS_RNG] ddr_dqs_i, ddr_dqs_o; +wire ddr_dqs_oe; + +//---------------------------------------------------------------------------- +// clock generator +//---------------------------------------------------------------------------- +wire clk_locked; +wire write_clk, write_clk90; +wire read_clk; + +wire reset_int = reset | ~clk_locked; + +ddr_clkgen #( + .phase_shift( phase_shift ), + .clk_multiply( clk_multiply ), + .clk_divide( clk_divide ) +) clkgen ( + .clk( clk ), + .reset( reset ), + .locked( clk_locked ), + // ddr-clk + .read_clk( read_clk ), + .write_clk( write_clk ), + .write_clk90( write_clk90 ), + // phase shift control + .ps_ready( ps_ready ), + .ps_up( ps_up ), + .ps_down( ps_down ) +); + +//---------------------------------------------------------------------------- +// async_fifos (cmd, wdata, rdata) +//---------------------------------------------------------------------------- +wire cba_fifo_full; +reg [`CBA_RNG] cba_fifo_din; +reg cba_fifo_we; + +wire wfifo_full; +wire [`WFIFO_RNG] wfifo_din; +wire wfifo_we; + +wire [`RFIFO_RNG] rfifo_dout; +wire rfifo_empty; +wire rfifo_next; + +assign wfifo_din = { ~fml_wbe, fml_wdat }; +assign wfifo_we = fml_wnext; + +assign fml_rdat = rfifo_dout; +assign fml_rempty = rfifo_empty; +assign rfifo_next = fml_rnext; + +//---------------------------------------------------------------------------- +// High-speed cmd, write and read datapath +//---------------------------------------------------------------------------- +ddr_wpath wpath0 ( + .clk( write_clk ), + .clk90( write_clk90 ), + .reset( reset_int ), + // CBA async fifo + .cba_clk( clk ), + .cba_din( cba_fifo_din ), + .cba_wr( cba_fifo_we ), + .cba_full( cba_fifo_full ), + // WDATA async fifo + .wdata_clk( clk ), + .wdata_din( wfifo_din ), + .wdata_wr( wfifo_we ), + .wdata_full( wfifo_full ), + // + .sample( sample ), + // DDR + .ddr_clk( ddr_clk ), + .ddr_clk_n( ddr_clk_n ), + .ddr_ras_n( ddr_ras_n ), + .ddr_cas_n( ddr_cas_n ), + .ddr_we_n( ddr_we_n ), + .ddr_a( ddr_a ), + .ddr_ba( ddr_ba ), + .ddr_dm( ddr_dm ), + .ddr_dq( ddr_dq_o ), + .ddr_dqs( ddr_dqs_o ), + .ddr_dqs_oe( ddr_dqs_oe ) +); + +ddr_rpath rpath0 ( + .clk( read_clk ), + .reset( reset_int ), + // + .sample( sample ), + // + .rfifo_clk( clk ), + .rfifo_empty( rfifo_empty), + .rfifo_dout( rfifo_dout ), + .rfifo_next( rfifo_next ), + // DDR + .ddr_dq( ddr_dq_i ), + .ddr_dqs( ddr_dqs_i ) +); + +//---------------------------------------------------------------------------- +// 7.8 us pulse generator +//---------------------------------------------------------------------------- +wire pulse78; +reg ar_req; +reg ar_done; + +ddr_pulse78 #( + .clk_freq( clk_freq ) +) pulse78_gen ( + .clk( clk ), + .reset( reset_int ), + .pulse78( pulse78 ) +); + +//---------------------------------------------------------------------------- +// Auto Refresh request generator +//---------------------------------------------------------------------------- +always @(posedge clk) + if (reset_int) + ar_req <= 0; + else + ar_req <= pulse78 | (ar_req & ~ar_done); + +// operations we might want to submit +wire [`CBA_RNG] ar_pre_cba; +wire [`CBA_RNG] ar_ar_cba; + +assign ar_pre_cba = { `DDR_CMD_PRE, 2'b00, 13'b1111111111111 }; +assign ar_ar_cba = { `DDR_CMD_AR, 2'b00, 13'b0000000000000 }; + +//---------------------------------------------------------------------------- +// Init & management +//---------------------------------------------------------------------------- +wire init_req; +reg init_ack; +wire [`CBA_RNG] init_cba; +wire init_done; +wire wait200; + +ddr_init #( + .wait200_init( wait200_init ) +) init ( + .clk( clk ), + .reset( reset_int ), + .pulse78( pulse78 ), + .wait200( wait200 ), + .init_done( init_done ), + // + .mngt_req( init_req ), + .mngt_ack( init_ack ), + .mngt_cba( init_cba ) +); + +//---------------------------------------------------------------------------- +// Active Bank Information +//---------------------------------------------------------------------------- +reg [`ROW_RNG] ba_row [3:0]; +reg [3:0] ba_active; + +//---------------------------------------------------------------------------- +// FML decoding +//---------------------------------------------------------------------------- +wire [`FML_ADR_BA_RNG] fml_ba = fml_adr[`FML_ADR_BA_RNG]; +wire [`FML_ADR_ROW_RNG] fml_row = fml_adr[`FML_ADR_ROW_RNG]; +wire [`FML_ADR_COL_RNG] fml_col = fml_adr[`FML_ADR_COL_RNG]; + +wire [`FML_ADR_ROW_RNG] fml_cur_row; // current active row in sel. bank +assign fml_cur_row = ba_row[fml_ba]; + +wire fml_row_active; // is row in selected ba really active? +assign fml_row_active = ba_active[fml_ba]; + + +/* +wire fml_row_active = (fml_ba == 0) ? ba0_active : // is row in selected + (fml_ba == 1) ? ba1_active : // bank really active? + (fml_ba == 2) ? ba2_active : + ba3_active ; +*/ + +// request operation iff correct bank is active +wire fml_req = fml_rd | fml_wr; +wire fml_row_match = (fml_row == fml_cur_row) & fml_row_active; +wire fml_pre_req = fml_req & ~fml_row_match & fml_row_active; +wire fml_act_req = fml_req & ~fml_row_active; +wire fml_read_req = fml_rd & fml_row_match & ~fml_done; +wire fml_write_req = fml_wr & fml_row_match & ~fml_done; + +// actual operations we might want to submit +wire [`CBA_RNG] fml_pre_cba; +wire [`CBA_RNG] fml_act_cba; +wire [`CBA_RNG] fml_read_cba; +wire [`CBA_RNG] fml_write_cba; + +assign fml_pre_cba = { `DDR_CMD_PRE, fml_ba, 13'b0 }; +assign fml_act_cba = { `DDR_CMD_ACT, fml_ba, fml_row }; +assign fml_read_cba = { `DDR_CMD_READ, fml_ba, {3'b000}, fml_col, {3'b000} }; +assign fml_write_cba = { `DDR_CMD_WRITE, fml_ba, {3'b000}, fml_col, {3'b000} }; + +//---------------------------------------------------------------------------- +// Schedule and issue commands +//---------------------------------------------------------------------------- + +parameter s_init = 0; +parameter s_idle = 1; +parameter s_ar = 2; +parameter s_reading = 3; + +reg [1:0] state; + +always @(posedge clk) +begin + if (reset_int) begin + state <= s_init; + ba_active <= 0; + ba_row[0] <= 0; + ba_row[1] <= 0; + ba_row[2] <= 0; + ba_row[3] <= 0; + + fml_done <= 0; + init_ack <= 0; + cba_fifo_we <= 0; + ar_done <= 0; + end else begin + fml_done <= 0; + init_ack <= 0; + cba_fifo_we <= 0; + ar_done <= 0; + + case (state) + s_init: begin + if (init_done) + state <= s_idle; + + if (init_req & ~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= init_cba; + init_ack <= 1; + end + end + s_idle: begin + if (fml_read_req & ~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= fml_read_cba; + fml_done <= 1; + end else if (fml_write_req & ~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= fml_write_cba; + fml_done <= 1; + end else if (ar_req & ~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= ar_pre_cba; + ar_done <= 1; + ba_active <= 'b0; + state <= s_ar; + end else if (fml_pre_req & ~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= fml_pre_cba; + ba_active[fml_ba] <= 0; + end else if (fml_act_req & ~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= fml_act_cba; + ba_active[fml_ba] <= 1; + ba_row[fml_ba] <= fml_row; + end + end + s_ar: begin + if (~cba_fifo_full) begin + cba_fifo_we <= 1; + cba_fifo_din <= ar_ar_cba; + state <= s_idle; + end + end + endcase + end +end + +//---------------------------------------------------------------------------- +// Demux dqs and dq +//---------------------------------------------------------------------------- +assign ddr_cke = {~wait200, ~wait200}; // bring up CKE as soon 200us wait is finished + +assign ddr_dqs = ddr_dqs_oe!=1'b0 ? ddr_dqs_o : 'bz; +assign ddr_dq = ddr_dqs_oe!=1'b0 ? ddr_dq_o : 'bz; + +assign ddr_dqs_i = ddr_dqs; +assign ddr_dq_i = ddr_dq; + +assign ddr_cs_n = 2'b00; + +//---------------------------------------------------------------------------- +// Probes +//---------------------------------------------------------------------------- +assign probe_clk = clk; + +always @(*) +begin + case (probe_sel) + 8'h00: probe <= { cba_fifo_we, wfifo_we, rfifo_next, 1'b0, cba_fifo_full, wfifo_full, rfifo_empty, 1'b0 }; + 8'h01: probe <= { write_clk, write_clk90, read_clk, 5'b00000 }; + 8'h10: probe <= { rfifo_empty, rfifo_next, rfifo_dout[ 5: 0] }; + 8'h11: probe <= { rfifo_empty, rfifo_next, rfifo_dout[13: 8] }; + 8'h12: probe <= { rfifo_empty, rfifo_next, rfifo_dout[21:16] }; + 8'h13: probe <= { rfifo_empty, rfifo_next, rfifo_dout[29:24] }; + 8'h20: probe <= wfifo_din[ 7:0]; + 8'h21: probe <= wfifo_din[15:8]; + 8'h20: probe <= wfifo_din[23:16]; + 8'h21: probe <= wfifo_din[31:24]; + 8'h30: probe <= cba_fifo_din[17:10]; + 8'h31: probe <= cba_fifo_din[ 9:2]; + default: probe <= 0'b0; + endcase +end + + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_include.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_include.v new file mode 100644 index 0000000..f57c1ad --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_include.v @@ -0,0 +1,122 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- + +`ifdef WBDDR_INCLUDE_V +`else +`define WBDDR_INCLUDE_V + +`timescale 1ns/10ps + +//---------------------------------------------------------------------------- +// Frequency and timeouts +//---------------------------------------------------------------------------- +`define SYS_CLK_FREQUENCY 50000 // in kHz +`define DDR_CLK_MULTIPLY 5 +`define DDR_CLK_DIVIDE 2 + +//---------------------------------------------------------------------------- +// Width +//---------------------------------------------------------------------------- +`define CMD_WIDTH 3 +`define A_WIDTH 13 +`define BA_WIDTH 2 +`define DQ_WIDTH 16 +`define DQS_WIDTH 2 +`define DM_WIDTH 2 + +`define RFIFO_WIDTH (2 * `DQ_WIDTH ) +`define WFIFO_WIDTH (2 * (`DQ_WIDTH + `DM_WIDTH)) +`define CBA_WIDTH (`CMD_WIDTH+`BA_WIDTH+`A_WIDTH) + +// Ranges +`define CMD_RNG (`CMD_WIDTH-1):0 +`define A_RNG (`A_WIDTH-1):0 +`define BA_RNG (`BA_WIDTH-1):0 +`define DQ_RNG (`DQ_WIDTH-1):0 +`define DQS_RNG (`DQS_WIDTH-1):0 +`define DM_RNG (`DM_WIDTH-1):0 + +`define RFIFO_RNG (`RFIFO_WIDTH-1):0 +`define WFIFO_RNG (`WFIFO_WIDTH-1):0 +`define WFIFO_D0_RNG (1*`DQ_WIDTH-1):0 +`define WFIFO_D1_RNG (2*`DQ_WIDTH-1):(`DQ_WIDTH) +`define WFIFO_M0_RNG (2*`DQ_WIDTH+1*`DM_WIDTH-1):(2*`DQ_WIDTH+0*`DM_WIDTH) +`define WFIFO_M1_RNG (2*`DQ_WIDTH+2*`DM_WIDTH-1):(2*`DQ_WIDTH+1*`DM_WIDTH) +`define CBA_RNG (`CBA_WIDTH-1):0 +`define CBA_CMD_RNG (`CBA_WIDTH-1):(`CBA_WIDTH-3) +`define CBA_BA_RNG (`CBA_WIDTH-4):(`CBA_WIDTH-5) +`define CBA_A_RNG (`CBA_WIDTH-6):0 + +`define ROW_RNG 12:0 + +//---------------------------------------------------------------------------- +// Configuration registers +//---------------------------------------------------------------------------- +`define DDR_INIT_EMRS `A_WIDTH'b0000000000000 // DLL enable +`define DDR_INIT_MRS1 `A_WIDTH'b0000101100011 // BURST=8, CL=2.5, DLL RESET +`define DDR_INIT_MRS2 `A_WIDTH'b0000001100011 // BURST=8, CL=2.5 + +//---------------------------------------------------------------------------- +// FML constants +//---------------------------------------------------------------------------- +`define FML_ADR_RNG 25:4 +`define FML_ADR_BA_RNG 25:24 +`define FML_ADR_ROW_RNG 23:11 +`define FML_ADR_COL_RNG 10:4 +`define FML_DAT_RNG 31:0 +`define FML_BE_RNG 3:0 + +//---------------------------------------------------------------------------- +// DDR constants +//---------------------------------------------------------------------------- +`define DDR_CMD_NOP 3'b111 +`define DDR_CMD_ACT 3'b011 +`define DDR_CMD_READ 3'b101 +`define DDR_CMD_WRITE 3'b100 +`define DDR_CMD_TERM 3'b110 +`define DDR_CMD_PRE 3'b010 +`define DDR_CMD_AR 3'b001 +`define DDR_CMD_MRS 3'b000 + +`define ADR_BA_RNG 25:24 +`define ADR_ROW_RNG 23:11 +`define ADR_COL_RNG 10:4 + +`define T_MRD 2 // Mode register set +`define T_RP 2 // Precharge Command Period +`define T_RFC 8 // Precharge Command Period + +//---------------------------------------------------------------------------- +// Buffer Cache +//---------------------------------------------------------------------------- +`define WAY_WIDTH (`WB_DAT_WIDTH + `WB_SEL_WIDTH) +`define WAY_LINE_RNG (`WAY_WIDTH-1):0 +`define WAY_DAT_RNG 31:0 +`define WAY_VALID_RNG 35:32 + +`define TAG_LINE_RNG 32:0 +`define TAG_LINE_TAG0_RNG 14:0 +`define TAG_LINE_TAG1_RNG 29:15 +`define TAG_LINE_DIRTY0_RNG 30 +`define TAG_LINE_DIRTY1_RNG 31 +`define TAG_LINE_LRU_RNG 32 + +//---------------------------------------------------------------------------- +// Whishbone constants +//---------------------------------------------------------------------------- +`define WB_ADR_WIDTH 32 +`define WB_DAT_WIDTH 32 +`define WB_SEL_WIDTH 4 + +`define WB_ADR_RNG (`WB_ADR_WIDTH-1):0 +`define WB_DAT_RNG (`WB_DAT_WIDTH-1):0 +`define WB_SEL_RNG (`WB_SEL_WIDTH-1):0 + +`define WB_WORD_RNG 3:2 +`define WB_SET_RNG 10:4 +`define WB_TAG_RNG 25:11 + +`endif diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_init.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_init.v new file mode 100644 index 0000000..b98a198 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_init.v @@ -0,0 +1,164 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +`include "ddr_include.v" + +module ddr_init +#( + parameter wait200_init = 26 +) ( + input clk, + input reset, + input pulse78, + output wait200, + output init_done, + // + output mngt_req, + input mngt_ack, + output [`CBA_RNG] mngt_cba // CMD, BA and ADDRESS +); + +reg cmd_req_reg; +reg [`CMD_RNG] cmd_cmd_reg; +reg [ `BA_RNG] cmd_ba_reg; +reg [ `A_RNG] cmd_a_reg; +reg [7:0] cmd_idle_reg; + +//--------------------------------------------------------------------------- +// Initial 200us delay +//--------------------------------------------------------------------------- + +// `define WAIT200_INIT 26 +// `define WAIT200_INIT 1 + +reg [4:0] wait200_counter; +reg wait200_reg; + +always @(posedge clk) +begin + if (reset) begin + wait200_reg <= 1; + wait200_counter <= wait200_init; + end else begin + if (wait200_counter == 0) + wait200_reg <= 0; + + if (wait200_reg & pulse78) + wait200_counter <= wait200_counter - 1; + end +end + +assign wait200 = wait200_reg; + +//---------------------------------------------------------------------------- +// DDR Initialization State Machine +//---------------------------------------------------------------------------- + +parameter s_wait200 = 0; +parameter s_init1 = 1; +parameter s_init2 = 2; +parameter s_init3 = 3; +parameter s_init4 = 4; +parameter s_init5 = 5; +parameter s_init6 = 6; +parameter s_waitack = 7; +parameter s_idle = 8; + +reg [3:0] state; +reg init_done_reg; + +assign mngt_cba = {cmd_cmd_reg, cmd_ba_reg, cmd_a_reg}; +assign mngt_req = cmd_req_reg; +assign mngt_pri_req = ~init_done_reg; +assign init_done = init_done_reg; + +always @(posedge clk or posedge reset) +begin + if (reset) begin + init_done_reg <= 0; + state <= s_wait200; + cmd_idle_reg <= 0; + cmd_req_reg <= 0; + cmd_cmd_reg <= 'b0; + cmd_ba_reg <= 'b0; + cmd_a_reg <= 'b0; + end else begin + case (state) + s_wait200: begin + if (~wait200_reg) begin + state <= s_init1; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_PRE; // PRE ALL + cmd_a_reg[10] <= 1'b1; + end + end + s_init1: begin + if (mngt_ack) begin + state <= s_init2; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_MRS; // EMRS + cmd_ba_reg <= 2'b01; + cmd_a_reg <= `DDR_INIT_EMRS; + end + end + s_init2: begin + if (mngt_ack) begin + state <= s_init3; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_MRS; // MRS + cmd_ba_reg <= 2'b00; + cmd_a_reg <= `DDR_INIT_MRS1; + end + end + s_init3: begin + if (mngt_ack) begin + state <= s_init4; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_PRE; // PRE ALL + cmd_a_reg[10] <= 1'b1; + end + end + s_init4: begin + if (mngt_ack) begin + state <= s_init5; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_AR; // AR + end + end + s_init5: begin + if (mngt_ack) begin + state <= s_init6; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_AR; // AR + end + end + s_init6: begin + if (mngt_ack) begin + init_done_reg <= 1; + state <= s_waitack; + cmd_req_reg <= 1; + cmd_cmd_reg <= `DDR_CMD_MRS; // MRS + cmd_ba_reg <= 2'b00; + cmd_a_reg <= `DDR_INIT_MRS2; + end + end + s_waitack: begin + if (mngt_ack) begin + state <= s_idle; + cmd_req_reg <= 0; + cmd_cmd_reg <= 'b0; + cmd_ba_reg <= 'b0; + cmd_a_reg <= 'b0; + end + end + s_idle: begin + end + endcase ///////////////////////////////////////// INIT STATE MACHINE /// + end +end + + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_pulse78.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_pulse78.v new file mode 100644 index 0000000..396576e --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_pulse78.v @@ -0,0 +1,43 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +`include "ddr_include.v" + +module ddr_pulse78 #( + parameter clk_freq = 50000000 +) ( + input clk, + input reset, + // + output reg pulse78 +); + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +`define PULSE78_RNG 10:0 + +parameter pulse78_init = 78 * (clk_freq/10000000); + +reg [`PULSE78_RNG] counter; + +always @(posedge clk) +begin + if (reset) begin + counter <= pulse78_init; + pulse78 <= 0; + end else begin + if (counter == 0) begin + counter <= pulse78_init; + pulse78 <= 1'b1; + end else begin + counter <= counter - 1; + pulse78 <= 0; + end + end +end + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_rpath.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_rpath.v new file mode 100644 index 0000000..b558dc8 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_rpath.v @@ -0,0 +1,112 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- + +`include "ddr_include.v" + +module ddr_rpath +( + input clk, + input reset, + // sample activate + input sample, + // RDATA async fifo + input rfifo_clk, + output rfifo_empty, + output [`RFIFO_RNG] rfifo_dout, + input rfifo_next, + // DDR + input [ `DQ_RNG] ddr_dq, + input [`DQS_RNG] ddr_dqs +); + +//---------------------------------------------------------------------------- +// RDATA async. fifo +//---------------------------------------------------------------------------- + +wire [`RFIFO_RNG] rfifo_din; +wire rfifo_wr; +wire rfifo_full; + +async_fifo #( + .DATA_WIDTH( `RFIFO_WIDTH ), + .ADDRESS_WIDTH( 4 ) +) rfifo ( + .Data_out( rfifo_dout ), + .Empty_out( rfifo_empty ), + .ReadEn_in( rfifo_next ), + .RClk( rfifo_clk ), + // + .Data_in( rfifo_din ), + .WriteEn_in( rfifo_wr ), + .Full_out( rfifo_full ), + .WClk( ~clk ), + .Clear_in( reset ) +); + + +//---------------------------------------------------------------------------- +// Clean up incoming 'sample' signal and generate sample_dq +//---------------------------------------------------------------------------- + +// anti-meta-state +//reg sample180; +//always @(negedge clk) sample180 <= sample; +wire sample180 = sample; + + +reg sample_dq; // authoritive sample flag (after cleanup) +reg sample_dq_delayed; // write to rfifo? +reg [3:0] sample_count; // make sure sample_dq is up exactly + // BURSTLENGTH/2 cycles + +always @(posedge clk or posedge reset) +begin + if (reset) begin + sample_dq <= 0; + sample_dq_delayed <= 0; + sample_count <= 0; + end else begin + sample_dq_delayed <= sample_dq; + if (sample_count == 0) begin + if (sample180) begin + sample_dq <= 1; + sample_count <= 1; + end + end else if (sample_count == 4) begin + sample_dq <= 0; + sample_count <= 0; + end else + sample_count <= sample_count + 1; + + end +end + +//---------------------------------------------------------------------------- +// Sampe DQ and fill RFIFO +//---------------------------------------------------------------------------- +reg [15:0] ddr_dq_low, ddr_dq_high; + +always @(negedge clk ) +begin + if (reset) + ddr_dq_low <= 'b0; + else + ddr_dq_low <= ddr_dq; +end + +always @(posedge clk) +begin + if (reset) + ddr_dq_high <= 'b0; + else + ddr_dq_high <= ddr_dq; +end + +assign rfifo_wr = sample_dq_delayed; +assign rfifo_din = { ddr_dq_high, ddr_dq_low }; + +endmodule + diff --git a/lm32/logic/sakc/rtl/wb_ddr/ddr_wpath.v b/lm32/logic/sakc/rtl/wb_ddr/ddr_wpath.v new file mode 100644 index 0000000..45ced50 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/ddr_wpath.v @@ -0,0 +1,286 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller -- fast write data-path +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +`include "ddr_include.v" + +module ddr_wpath ( + input clk, + input clk90, + input reset, + // CBA async fifo + input cba_clk, + input [`CBA_RNG] cba_din, + input cba_wr, + output cba_full, + // WDATA async fifo + input wdata_clk, + input [`WFIFO_RNG] wdata_din, + input wdata_wr, + output wdata_full, + // sample to rdata + output sample, + // DDR + output [2:0] ddr_clk, + output [2:0] ddr_clk_n, + output ddr_ras_n, + output ddr_cas_n, + output ddr_we_n, + output [ `A_RNG] ddr_a, + output [ `BA_RNG] ddr_ba, + output [ `DM_RNG] ddr_dm, + output [ `DQ_RNG] ddr_dq, + output [`DQS_RNG] ddr_dqs, + output ddr_dqs_oe +); + +wire gnd = 1'b0; +wire vcc = 1'b1; + +//---------------------------------------------------------------------------- +// CBA async. fifo +//---------------------------------------------------------------------------- +wire [`CBA_RNG] cba_data; +wire cba_empty; +wire cba_ack; + +wire cba_avail = ~cba_empty; + +async_fifo #( + .DATA_WIDTH( `CBA_WIDTH ), + .ADDRESS_WIDTH( 4 ) +) cba_fifo ( + .Data_out( cba_data ), + .Empty_out( cba_empty ), + .ReadEn_in( cba_ack ), + .RClk( clk ), + // + .Data_in( cba_din ), + .WriteEn_in( cba_wr ), + .Full_out( cba_full ), + .WClk( cba_clk ), + .Clear_in( reset ) +); + +//---------------------------------------------------------------------------- +// WDATA async. fifo +//---------------------------------------------------------------------------- +wire [`WFIFO_RNG] wdata_data; +wire wdata_empty; +wire wdata_ack; + +wire wdata_avail = ~wdata_empty; + +async_fifo #( + .DATA_WIDTH( `WFIFO_WIDTH ), + .ADDRESS_WIDTH( 4 ) +) wdata_fifo ( + .Data_out( wdata_data ), + .Empty_out( wdata_empty ), + .ReadEn_in( wdata_ack ), + .RClk( ~clk90 ), + // + .Data_in( wdata_din ), + .WriteEn_in( wdata_wr ), + .Full_out( wdata_full ), + .WClk( wdata_clk ), + .Clear_in( reset ) +); + + +//---------------------------------------------------------------------------- +// Handle CBA +//---------------------------------------------------------------------------- +reg [3:0] delay_count; + +reg [`CBA_RNG] ddr_cba; +wire [`CBA_RNG] CBA_NOP = { `DDR_CMD_NOP, 15'b0 }; + +assign cba_ack = cba_avail & (delay_count == 0); + +wire [`CMD_RNG] cba_cmd = cba_data[(`CBA_WIDTH-1):(`CBA_WIDTH-3)]; + +always @(posedge clk) +begin + if (reset) begin + delay_count <= 0; + ddr_cba <= CBA_NOP; + end else begin + if (delay_count != 0) begin + delay_count <= delay_count - 1; + ddr_cba <= CBA_NOP; + end + + if (!cba_ack) begin + ddr_cba <= CBA_NOP; + end else begin + ddr_cba <= cba_data; + + case (cba_cmd) + `DDR_CMD_MRS : delay_count <= 2; + `DDR_CMD_AR : delay_count <= 14; + `DDR_CMD_ACT : delay_count <= 4; + `DDR_CMD_PRE : delay_count <= 2; + `DDR_CMD_READ : delay_count <= 6; // XXX + `DDR_CMD_WRITE : delay_count <= 8; // XXX + endcase + end + end +end + + +//---------------------------------------------------------------------------- +// READ-SHIFT-REGISTER +//---------------------------------------------------------------------------- +reg [7:0] read_shr; +wire read_cmd = (cba_cmd == `DDR_CMD_READ) & cba_ack; +assign sample = read_shr[6]; + +always @(posedge clk) +begin + if (reset) + read_shr <= 'b0; + else begin + if (read_cmd) + read_shr <= { 8'b00011000 }; + else + read_shr <= { read_shr[6:0], 1'b0 }; + end +end + +//---------------------------------------------------------------------------- +// WRITE-SHIFT-REGISTER +//---------------------------------------------------------------------------- + +reg [0:4] write_shr; +wire write_cmd = (cba_cmd == `DDR_CMD_WRITE) & cba_ack; + +always @(posedge clk) +begin + if (reset) + write_shr <= 'b0; + else begin + if (write_cmd) + write_shr <= { 5'b11111 }; + else + write_shr <= { write_shr[1:4], 1'b0 }; + end +end + +//---------------------------------------------------------------------------- +// DDR_DQS, DDR_DQS_OE +//---------------------------------------------------------------------------- +genvar i; + +reg ddr_dqs_oe_reg; +assign ddr_dqs_oe = ddr_dqs_oe_reg; + +always @(negedge clk) +begin + ddr_dqs_oe_reg <= write_shr[0]; +end + +generate +for (i=0; i<3; i=i+1) begin : CLK + FDDRRSE ddr_clk_reg ( + .Q( ddr_clk[i] ), + .C0( clk90 ), + .C1( ~clk90 ), + .CE( vcc ), + .D0( vcc ), + .D1( gnd ), + .R( gnd ), + .S( gnd ) + ); + + FDDRRSE ddr_clk_n_reg ( + .Q( ddr_clk_n[i] ), + .C0( clk90 ), + .C1( ~clk90 ), + .CE( vcc ), + .D0( gnd ), + .D1( vcc ), + .R( gnd ), + .S( gnd ) + ); +end +endgenerate + +generate +for (i=0; i<`DQS_WIDTH; i=i+1) begin : DQS + FDDRRSE ddr_dqs_reg ( + .Q( ddr_dqs[i] ), + .C0( clk ), + .C1( ~clk ), + .CE( vcc ), + .D0( write_shr[1] ), + .D1( gnd ), + .R( gnd ), + .S( gnd ) + ); +end +endgenerate + + +//---------------------------------------------------------------------------- +// DQ data output +//---------------------------------------------------------------------------- +wire [`DQ_RNG] buf_d0; +wire [`DM_RNG] buf_m0; +reg [`DQ_RNG] buf_d1; // pipleine high word data +reg [`DM_RNG] buf_m1; // pipleine high word mask + +assign buf_d0 = wdata_data[`WFIFO_D0_RNG]; +assign buf_m0 = wdata_data[`WFIFO_M0_RNG]; + +always @(negedge clk90) +begin + buf_d1 <= wdata_data[`WFIFO_D1_RNG]; + buf_m1 <= wdata_data[`WFIFO_M1_RNG]; +end + +assign wdata_ack = write_shr[1]; + +// generate DDR_DQ register +generate +for (i=0; i<`DQ_WIDTH; i=i+1) begin : DQ_REG + FDDRRSE ddr_dq_reg ( + .Q( ddr_dq[i] ), + .C0( ~clk90 ), + .C1( clk90 ), + .CE( vcc ), + .D0( buf_d0[i] ), + .D1( buf_d1[i] ), + .R( gnd ), + .S( gnd ) + ); +end +endgenerate + +// generate DDR_DM register +generate +for (i=0; i<`DM_WIDTH; i=i+1) begin : DM_REG + FDDRRSE ddr_dm_reg ( + .Q( ddr_dm[i] ), + .C0( ~clk90 ), + .C1( clk90 ), + .CE( vcc ), + .D0( buf_m0[i] ), + .D1( buf_m1[i] ), + .R( gnd ), + .S( gnd ) + ); +end +endgenerate + +//---------------------------------------------------------------------------- +// Connect ddr_cba to actual DDR pins +//---------------------------------------------------------------------------- +assign ddr_a = ddr_cba[(`A_WIDTH-1):0]; +assign ddr_ba = ddr_cba[(`A_WIDTH+`BA_WIDTH-1):(`A_WIDTH)]; +assign ddr_ras_n = ddr_cba[(`CBA_WIDTH-1)]; +assign ddr_cas_n = ddr_cba[(`CBA_WIDTH-2)]; +assign ddr_we_n = ddr_cba[(`CBA_WIDTH-3)]; + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_ddr/dpram.v b/lm32/logic/sakc/rtl/wb_ddr/dpram.v new file mode 100644 index 0000000..00903d6 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_ddr/dpram.v @@ -0,0 +1,64 @@ + +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- + +module dpram +#( + parameter adr_width = 9, + parameter dat_width = 36 +) ( + input clk, + // Port 0 + input [adr_width-1:0] adr0, + input we0, + input [dat_width-1:0] din0, + output reg [dat_width-1:0] dout0, + // Port 1 + input [adr_width-1:0] adr1, + input we1, + input [dat_width-1:0] din1, + output reg [dat_width-1:0] dout1 +); + +parameter depth = (1 << adr_width); + +// actual ram +reg [dat_width-1:0] ram [0:depth-1]; + +//------------------------------------------------------------------ +// Syncronous Dual Port RAM Access +//------------------------------------------------------------------ +always @(posedge clk) +begin + // Frst port + if (we0) + ram[adr0] <= din0; + + dout0 <= ram[adr0]; +end + + +always @(posedge clk) +begin + // Second port + if (we1) + ram[adr1] <= din1; + + dout1 <= ram[adr1]; +end + +//------------------------------------------------------------------ +// Initialize content to Zero +//------------------------------------------------------------------ +integer i; + +initial +begin + for(i=0; i) +//---------------------------------------------------------------------------- + +`include "ddr_include.v" + +module wb_ddr +#( + parameter clk_freq = 100000000, + parameter clk_multiply = 12, + parameter clk_divide = 5, + parameter phase_shift = 0, + parameter wait200_init = 26 +) ( + input clk, + input reset, + // DDR ports + output [2:0] ddr_clk, + output [2:0] ddr_clk_n, + input ddr_clk_fb, + output ddr_ras_n, + output ddr_cas_n, + output ddr_we_n, + output [1:0] ddr_cke, + output [1:0] ddr_cs_n, + output [ `A_RNG] ddr_a, + output [ `BA_RNG] ddr_ba, + inout [ `DQ_RNG] ddr_dq, + inout [`DQS_RNG] ddr_dqs, + output [ `DM_RNG] ddr_dm, + // Wishbone Slave Interface + input [`WB_ADR_RNG] wb_adr_i, + input [`WB_DAT_RNG] wb_dat_i, + output reg [`WB_DAT_RNG] wb_dat_o, + input [`WB_SEL_RNG] wb_sel_i, + input wb_cyc_i, + input wb_stb_i, + input wb_we_i, + output reg wb_ack_o, + // XXX Temporary DCM control input XXX + output ps_ready, + input ps_up, + input ps_down, + // XXX probe wires XXX + output probe_clk, + input [7:0] probe_sel, + output reg [7:0] probe +); + +//---------------------------------------------------------------------------- +// Wishbone handling +//---------------------------------------------------------------------------- +wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i; +wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i; + +wire [`WB_WORD_RNG] wb_adr_word = wb_adr_i[`WB_WORD_RNG]; // word in bufferline +wire [`WB_SET_RNG] wb_adr_set = wb_adr_i[`WB_SET_RNG]; // index into wayX_ram +wire [`WB_TAG_RNG] wb_adr_tag = wb_adr_i[`WB_TAG_RNG]; // more significant bits + +//---------------------------------------------------------------------------- +// TAG RAM (2-way set assioziative) +//---------------------------------------------------------------------------- +wire [`TAG_LINE_RNG] tag_load; +wire [`TAG_LINE_RNG] tag_store; +wire tag_we; + +wire [`WB_TAG_RNG] tag_load_set0 = tag_load[`TAG_LINE_TAG0_RNG]; +wire [`WB_TAG_RNG] tag_load_set1 = tag_load[`TAG_LINE_TAG1_RNG]; +wire tag_load_dirty0 = tag_load[`TAG_LINE_DIRTY0_RNG]; +wire tag_load_dirty1 = tag_load[`TAG_LINE_DIRTY1_RNG]; +wire tag_load_lru = tag_load[`TAG_LINE_LRU_RNG]; + +reg [`WB_TAG_RNG] tag_store_set0; +reg [`WB_TAG_RNG] tag_store_set1; +reg tag_store_dirty0; +reg tag_store_dirty1; +reg tag_store_lru; + +assign tag_store[`TAG_LINE_TAG0_RNG] = tag_store_set0; +assign tag_store[`TAG_LINE_TAG1_RNG] = tag_store_set1; +assign tag_store[`TAG_LINE_DIRTY0_RNG] = tag_store_dirty0; +assign tag_store[`TAG_LINE_DIRTY1_RNG] = tag_store_dirty1; +assign tag_store[`TAG_LINE_LRU_RNG] = tag_store_lru; + +wire [`WB_SET_RNG] ls_tag_adr; +wire [`TAG_LINE_RNG] ls_tag_load; +reg [`TAG_LINE_RNG] ls_tag_store; +reg ls_tag_we; + +dpram #( + .adr_width( 7 ), + .dat_width( 33 ) +) tag_ram ( + .clk ( clk ), + // + .adr0( wb_adr_set ), + .dout0( tag_load ), + .din0( tag_store ), + .we0( tag_we ), + // + .adr1( ls_tag_adr ), + .dout1( ls_tag_load ), + .din1( ls_tag_store ), + .we1( ls_tag_we ) +); + +wire tag_load_match0 = (tag_load_set0 == wb_adr_tag); +wire tag_load_match1 = (tag_load_set1 == wb_adr_tag); +wire tag_load_match = tag_load_match0 | tag_load_match1; + +//---------------------------------------------------------------------------- +// Buffer cache ram (2 ways) +//---------------------------------------------------------------------------- +wire [8:0] wayX_adr = { wb_adr_set, wb_adr_word }; + +wire [`WAY_LINE_RNG] way0_load, way1_load; +wire [`WAY_LINE_RNG] wayX_store; + +wire [31:0] way0_load_dat = way0_load[`WAY_DAT_RNG]; +wire [31:0] way1_load_dat = way1_load[`WAY_DAT_RNG]; +wire [3:0] way0_load_valid = way0_load[`WAY_VALID_RNG]; +wire [3:0] way1_load_valid = way1_load[`WAY_VALID_RNG]; + +wire way0_we; +wire way1_we; +reg [31:0] wayX_store_dat; +reg [3:0] wayX_store_valid; + +assign wayX_store[`WAY_DAT_RNG] = wayX_store_dat; +assign wayX_store[`WAY_VALID_RNG] = wayX_store_valid; + +wire [8:0] ls_wayX_adr; +wire [`WAY_LINE_RNG] ls_way0_load; +wire [`WAY_LINE_RNG] ls_way1_load; +wire [`WAY_LINE_RNG] ls_wayX_store; +wire ls_way0_we; +wire ls_way1_we; +reg ls_wayX_we; + +wire way0_sel_valid = ( (~way0_load_valid & wb_sel_i) == 'b0); +wire way1_sel_valid = ( (~way1_load_valid & wb_sel_i) == 'b0); +wire wayX_sel_valid = (tag_load_match0) ? way0_sel_valid : way1_sel_valid; + +// synthesis attribute ram_style of way0_ram is block +dpram #( + .adr_width( 9 ), + .dat_width( 36 ) +) way0_ram ( + .clk( clk ), + // + .adr0( wayX_adr ), + .dout0( way0_load ), + .din0( wayX_store ), + .we0( way0_we ), + // + .adr1( ls_wayX_adr ), + .dout1( ls_way0_load ), + .we1( ls_way0_we ), + .din1( ls_wayX_store ) +); + +// synthesis attribute ram_style of way1_ram is block +dpram #( + .adr_width( 9 ), + .dat_width( 36 ) +) way1_ram ( + .clk( clk ), + // + .adr0( wayX_adr ), + .dout0( way1_load ), + .din0( wayX_store ), + .we0( way1_we ), + // + .adr1( ls_wayX_adr ), + .dout1( ls_way1_load ), + .we1( ls_way1_we ), + .din1( ls_wayX_store ) +); + +//---------------------------------------------------------------------------- +// Write/update buffer cache from wishbone side +//---------------------------------------------------------------------------- +wire store_to_way0 = tag_load_lru & ~tag_load_dirty0; // store new data into way0? XXX spill_done XXX +wire store_to_way1 = ~tag_load_lru & ~tag_load_dirty1; // store new data into way1? XXX spill_done XXX +wire store_to_way = store_to_way0 | store_to_way1; + +reg update_lru0; // +reg update_lru1; + +reg update_way0; // +reg update_way1; + +assign way0_we = update_way0; +assign way1_we = update_way1; +assign tag_we = way0_we | way1_we | update_lru0 | update_lru1; + +//---------------------------------------------------------------------------- +// MUX wayX_store input +//---------------------------------------------------------------------------- + +integer i; +always @(*) +begin +/* + for(i=0; i<4; i=i+1) begin + if (wb_sel_i[i]) begin + wayX_store_dat[8*i+7:8*i] = wb_dat_i[8*i+7:8*i]; + wayX_store_valid[i] = 1; + end else if (update_way0) begin + wayX_store_dat[8*i+7:8*i] = way0_load_dat[8*i+7:8*i]; + wayX_store_valid[i] = way0_load_valid[i]; + end else begin + wayX_store_dat[8*i+7:8*i] = way1_load_dat[8*i+7:8*i]; + wayX_store_valid[i] = way1_load_valid[i]; + end + end +*/ + + if (wb_sel_i[0]) begin + wayX_store_dat[8*0+7:8*0] = wb_dat_i[8*0+7:8*0]; + wayX_store_valid[0] = 1; + end else if (update_way0) begin + wayX_store_dat[8*0+7:8*0] = way0_load_dat[8*0+7:8*0]; + wayX_store_valid[0] = way0_load_valid[0]; + end else begin + wayX_store_dat[8*0+7:8*0] = way1_load_dat[8*0+7:8*0]; + wayX_store_valid[0] = way1_load_valid[0]; + end + + if (wb_sel_i[1]) begin + wayX_store_dat[8*1+7:8*1] = wb_dat_i[8*1+7:8*1]; + wayX_store_valid[1] = 1; + end else if (update_way0) begin + wayX_store_dat[8*1+7:8*1] = way0_load_dat[8*1+7:8*1]; + wayX_store_valid[1] = way0_load_valid[1]; + end else begin + wayX_store_dat[8*1+7:8*1] = way1_load_dat[8*1+7:8*1]; + wayX_store_valid[1] = way1_load_valid[1]; + end + + if (wb_sel_i[2]) begin + wayX_store_dat[8*2+7:8*2] = wb_dat_i[8*2+7:8*2]; + wayX_store_valid[2] = 1; + end else if (update_way0) begin + wayX_store_dat[8*2+7:8*2] = way0_load_dat[8*2+7:8*2]; + wayX_store_valid[2] = way0_load_valid[2]; + end else begin + wayX_store_dat[8*2+7:8*2] = way1_load_dat[8*2+7:8*2]; + wayX_store_valid[2] = way1_load_valid[2]; + end + + if (wb_sel_i[3]) begin + wayX_store_dat[8*3+7:8*3] = wb_dat_i[8*3+7:8*3]; + wayX_store_valid[3] = 1; + end else if (update_way0) begin + wayX_store_dat[8*3+7:8*3] = way0_load_dat[8*3+7:8*3]; + wayX_store_valid[3] = way0_load_valid[3]; + end else begin + wayX_store_dat[8*3+7:8*3] = way1_load_dat[8*3+7:8*3]; + wayX_store_valid[3] = way1_load_valid[3]; + end +end + +always @(*) +begin + if (update_way0) begin + tag_store_set0 = wb_adr_tag; + tag_store_dirty0 = 1; + end else begin + tag_store_set0 = tag_load_set0; + tag_store_dirty0 = tag_load_dirty0; + end + + if (update_way1) begin + tag_store_set1 = wb_adr_tag; + tag_store_dirty1 = 1; + end else begin + tag_store_set1 = tag_load_set1; + tag_store_dirty1 = tag_load_dirty1; + end + + if (update_lru0) + tag_store_lru = 0; + else if (update_lru1) + tag_store_lru = 1; + else + tag_store_lru = tag_load_lru; +end + +//---------------------------------------------------------------------------- +// Wishbone FSM +//---------------------------------------------------------------------------- +reg ls_fill; +reg ls_spill; +reg ls_way; +wire ls_busy; + +reg [`WB_TAG_RNG] ls_adr_tag; +reg [`WB_SET_RNG] ls_adr_set; +reg [`WB_WORD_RNG] ls_adr_word; + +reg [2:0] state; + +parameter s_idle = 0; +parameter s_read = 1; +parameter s_rspill = 2; +parameter s_rfill = 3; +parameter s_write = 4; +parameter s_wspill = 5; + +// Syncronous part of FSM +always @(posedge clk) +begin + if (reset) begin + state <= s_idle; + ls_spill <= 0; + ls_fill <= 0; + ls_way <= 0; + end else begin + ls_fill <= 0; + ls_spill <= 0; + + case (state) + s_idle: begin + if (wb_rd) + state <= s_read; + + if (wb_wr) + state <= s_write; + end + s_read: begin + if ((tag_load_match0 & way0_sel_valid) | (tag_load_match1 & way1_sel_valid)) begin + state <= s_idle; + end else if (store_to_way & ~ls_busy) begin + state <= s_rfill; + ls_fill <= 1; + ls_way <= ~tag_load_lru; + ls_adr_tag <= wb_adr_tag; + ls_adr_set <= wb_adr_set; + end else if (~ls_busy) begin + state <= s_rspill; + ls_spill <= 1; + ls_way <= ~tag_load_lru; + ls_adr_set <= wb_adr_set; + if (tag_load_lru == 1) + ls_adr_tag <= tag_load_set0; + else + ls_adr_tag <= tag_load_set1; + end + end + s_rspill: begin + if (~ls_busy) begin + state <= s_rfill; + ls_fill <= 1; + ls_way <= ~tag_load_lru; + ls_adr_tag <= wb_adr_tag; + ls_adr_set <= wb_adr_set; + end + end + s_rfill: begin + if (tag_load_match & wayX_sel_valid) + state <= s_idle; + end + s_write: begin + if (tag_load_match | store_to_way) begin + state <= s_idle; + end else if (~ls_busy) begin + state <= s_wspill; + ls_spill <= 1; + ls_way <= ~tag_load_lru; + ls_adr_set <= wb_adr_set; + if (tag_load_lru == 1) + ls_adr_tag <= tag_load_set0; + else + ls_adr_tag <= tag_load_set1; + end + end + s_wspill: begin + if (tag_load_match | store_to_way) begin + state <= s_idle; + end + end + default: + state <= s_idle; + endcase + end +end + +// Asyncronous part of FSM +always @(*) +begin + update_lru0 <= 0; + update_lru1 <= 0; + update_way0 <= 0; + update_way1 <= 0; + wb_dat_o <= 0; + wb_ack_o <= 0; + + case (state) + s_idle: begin end + s_read: begin + if (tag_load_match0 & way0_sel_valid) begin + update_lru0 <= 1; + wb_dat_o <= way0_load_dat; + wb_ack_o <= 1; + end else if (tag_load_match1 & way1_sel_valid) begin + update_lru1 <= 1; + wb_dat_o <= way1_load_dat; + wb_ack_o <= 1; + end + end + s_write: begin + if (tag_load_match0 | store_to_way0) begin + update_lru0 <= 1; + update_way0 <= 1; + wb_ack_o <= 1; + end else if (tag_load_match1 | store_to_way1) begin + update_lru1 <= 1; + update_way1 <= 1; + wb_ack_o <= 1; + end + end + endcase +end + + + +//---------------------------------------------------------------------------- +// DDR Controller Engine (including clkgen, [rw]-path) +//---------------------------------------------------------------------------- +reg fml_rd; +reg fml_wr; +wire fml_done; +wire [`FML_ADR_RNG] fml_adr; +wire [`FML_DAT_RNG] fml_wdat; +wire [`FML_BE_RNG] fml_wbe; +reg fml_wnext; +reg fml_wnext2; +wire fml_rempty; +reg fml_rnext; +wire [`FML_DAT_RNG] fml_rdat; + +ddr_ctrl #( + .phase_shift( phase_shift ), + .clk_multiply( clk_multiply ), + .clk_divide( clk_divide ), + .wait200_init( wait200_init ) +) ctrl0 ( + .clk( clk ), + .reset( reset ), + // DDR Ports + .ddr_clk( ddr_clk ), + .ddr_clk_n( ddr_clk_n ), + .ddr_clk_fb( ddr_clk_fb ), + .ddr_ras_n( ddr_ras_n ), + .ddr_cas_n( ddr_cas_n ), + .ddr_we_n( ddr_we_n ), + .ddr_cke( ddr_cke ), + .ddr_cs_n( ddr_cs_n ), + .ddr_a( ddr_a ), + .ddr_ba( ddr_ba ), + .ddr_dq( ddr_dq ), + .ddr_dqs( ddr_dqs ), + .ddr_dm( ddr_dm ), + // FML (FastMemoryLink) + .fml_rd( fml_rd ), + .fml_wr( fml_wr ), + .fml_done( fml_done ), + .fml_adr( fml_adr ), + .fml_wdat( fml_wdat ), + .fml_wbe( fml_wbe ), + .fml_wnext( fml_wnext2 ), + .fml_rempty( fml_rempty ), + .fml_rdat( fml_rdat ), + .fml_rnext( fml_rnext ), + // DCM phase shift control + .ps_ready( ps_ready ), + .ps_up( ps_up ), + .ps_down( ps_down ) +); + +assign fml_adr = { ls_adr_tag, ls_adr_set }; + +assign fml_wdat = (ls_way) ? ls_way1_load[`WAY_DAT_RNG] : + ls_way0_load[`WAY_DAT_RNG]; + +assign fml_wbe = (ls_way) ? ls_way1_load[`WAY_VALID_RNG] : + ls_way0_load[`WAY_VALID_RNG]; + +assign ls_tag_adr = { ls_adr_set }; +assign ls_wayX_adr = { ls_adr_set, ls_adr_word }; +assign ls_way0_we = ls_wayX_we & ~ls_way; +assign ls_way1_we = ls_wayX_we & ls_way; + +assign ls_wayX_store[`WAY_DAT_RNG] = fml_rdat; +assign ls_wayX_store[`WAY_VALID_RNG] = 4'b1111; + + +//---------------------------------------------------------------------------- +// LS (Load and Store) Engine +//---------------------------------------------------------------------------- +parameter l_idle = 0; +parameter l_fill = 1; +parameter l_spill = 2; +parameter l_waitdone = 3; + +reg [2:0] ls_state; +assign ls_busy = (ls_state != l_idle) || ls_fill || ls_spill; + +// Syncronous part FSM +always @(posedge clk) +begin + if (reset) begin + ls_state <= l_idle; + ls_adr_word <= 0; + fml_wr <= 0; + fml_rd <= 0; + end else begin + fml_wnext2 <= fml_wnext; + + case (ls_state) + l_idle: begin + ls_adr_word <= 0; + + if (ls_spill) begin + ls_state <= l_spill; + ls_adr_word <= ls_adr_word + 1; + end + if (ls_fill) begin + ls_state <= l_fill; + fml_rd <= 1; + end + end + l_spill: begin + ls_adr_word <= ls_adr_word + 1; + + if (ls_adr_word == 3) begin + ls_state <= l_waitdone; + fml_wr <= 1; + end + end + l_waitdone: begin + ls_adr_word <= 0; + + if (fml_done) begin + ls_state <= l_idle; + fml_wr <= 0; + end + end + l_fill: begin + if (fml_done) + fml_rd <= 0; + + if (~fml_rempty) + ls_adr_word <= ls_adr_word + 1; + + if (~fml_rempty & (ls_adr_word == 3)) + ls_state <= l_idle; + end + endcase + end +end + +always @(*) +begin + fml_wnext <= 0; + fml_rnext <= 0; + ls_tag_we <= 0; + ls_tag_store <= ls_tag_load; + ls_wayX_we <= 0; + + case (ls_state) + l_idle: begin + if (ls_spill) begin + fml_wnext <= 1; + end + end + l_spill: begin + fml_wnext <= 1; + end + l_waitdone: begin + if (ls_way == 0) + ls_tag_store[`TAG_LINE_DIRTY0_RNG] <= 0; + else + ls_tag_store[`TAG_LINE_DIRTY1_RNG] <= 0; + + if (fml_done) + ls_tag_we <= 1; + end + l_fill: begin + if (ls_way == 0) begin + ls_tag_store[`TAG_LINE_DIRTY0_RNG] <= 0; + ls_tag_store[`TAG_LINE_TAG0_RNG] <= ls_adr_tag; + end else begin + ls_tag_store[`TAG_LINE_DIRTY1_RNG] <= 0; + ls_tag_store[`TAG_LINE_TAG1_RNG] <= ls_adr_tag; + end + + if (~fml_rempty) begin + ls_wayX_we <= 1; + fml_rnext <= 1; + end + + if (~fml_rempty & (ls_adr_word == 3)) + ls_tag_we <= 1; + end + endcase +end + +always @(posedge clk) +begin + if (ls_fill) + $display ("At time %t WB_DDR fill cacheline: TAG = %h, SET = %h)", $time, ls_adr_tag, ls_adr_set); + + if (ls_spill) + $display ("At time %t WB_DDR spill cacheline: TAG = %h, SET = %h)", $time, ls_adr_tag, ls_adr_set); +end + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_gpio/wb_gpio.v b/lm32/logic/sakc/rtl/wb_gpio/wb_gpio.v new file mode 100644 index 0000000..7841939 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_gpio/wb_gpio.v @@ -0,0 +1,77 @@ +//--------------------------------------------------------------------------- +// Wishbone General Pupose IO Component +// +// 0x00 +// 0x10 gpio_in (read-only) +// 0x14 gpio_out (read/write) +// 0x18 gpio_oe (read/write) +// +//--------------------------------------------------------------------------- + +module wb_gpio ( + input clk, + input reset, + // Wishbone interface + input wb_stb_i, + input wb_cyc_i, + output wb_ack_o, + input wb_we_i, + input [31:0] wb_adr_i, + input [3:0] wb_sel_i, + input [31:0] wb_dat_i, + output reg [31:0] wb_dat_o, + // + output intr, + // IO Wires + input [31:0] gpio_in, + output reg [31:0] gpio_out, + output reg [31:0] gpio_oe +); + +//--------------------------------------------------------------------------- +// +//--------------------------------------------------------------------------- + +wire [31:0] gpiocr = 32'b0; + +// Wishbone +reg ack; +assign wb_ack_o = wb_stb_i & wb_cyc_i & ack; + +wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i; +wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i; + +always @(posedge clk) +begin + if (reset) begin + ack <= 0; + gpio_out <= 'b0; + end else begin + // Handle WISHBONE access + ack <= 0; + + if (wb_rd & ~ack) begin // read cycle + ack <= 1; + + case (wb_adr_i[7:0]) + 'h00: wb_dat_o <= gpiocr; + 'h10: wb_dat_o <= gpio_in; + 'h14: wb_dat_o <= gpio_out; + 'h18: wb_dat_o <= gpio_oe; + default: wb_dat_o <= 32'b0; + endcase + end else if (wb_wr & ~ack ) begin // write cycle + ack <= 1; + + case (wb_adr_i[7:0]) + 'h00: begin + end + 'h14: gpio_out <= wb_dat_i; + 'h18: gpio_oe <= wb_dat_i; + endcase + end + end +end + + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_spi/wb_spi.v b/lm32/logic/sakc/rtl/wb_spi/wb_spi.v new file mode 100644 index 0000000..f69186c --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_spi/wb_spi.v @@ -0,0 +1,101 @@ +//----------------------------------------------------------------- +// SPI Master +//----------------------------------------------------------------- + +module wb_spi( + input clk; + input reset; + // Wishbone bus + input [31:0] wb_adr_i; + input [31:0] wb_dat_i; + output reg [31:0] wb_dat_o; + input [ 3:0] wb_sel_i; + input wb_cyc_i; + input wb_stb_i; + output wb_ack_o; + input wb_we_i; + // SPI + output spi_sck; + output spi_mosi; + input spi_miso; + output reg [7:0] spi_cs; +); + + + reg ack; + assign wb_ack_o = wb_stb_i & wb_cyc_i & ack; + + wire wb_rd = wb_stb_i & wb_cyc_i & ~ack & ~wb_we_i; + wire wb_wr = wb_stb_i & wb_cyc_i & ~ack & wb_we_i; + + + reg [2:0] bitcount; + reg ilatch; + reg run; + + reg sck; + + //prescaler registers for sclk + reg [7:0] prescaler; + reg [7:0] divisor; + + //data shift register + reg [7:0] sreg; + + assign spi_sck = sck; + assign spi_mosi = sreg[7]; + + always @(posedge clk) begin + if (reset == 1'b1) begin + ack <= 0; + sck <= 1'b0; + bitcount <= 3'b000; + run <= 1'b0; + prescaler <= 8'h00; + divisor <= 8'hff; + end else begin + prescaler <= prescaler + 1; + if (prescaler == divisor) begin + prescaler <= 8'h00; + if (run == 1'b1) begin + sck <= ~sck; + if(sck == 1'b1) begin + bitcount <= bitcount + 1; + if(bitcount == 3'b111) begin + run <= 1'b0; + end + + sreg [7:0] <= {sreg[6:0], ilatch}; + end else begin + ilatch <= spi_miso; + end + end + end + + ack <= wb_stb_i & wb_cyc_i; + + if (wb_rd) begin // read cycle + case (wb_adr_i[5:2]) + 4'b0000: wb_dat_o <= sreg; + 4'b0001: wb_dat_o <= {7'b0000000 , run}; + endcase + end + + + if (wb_wr) begin // write cycle + case (wb_adr_i[5:2]) + 4'b0000: begin + sreg <= wb_dat_i[7:0]; + run <= 1'b1; + end + 4'b0010: + spi_cs <= wb_dat_i[7:0]; + 4'b0100: + divisor <= wb_dat_i[7:0]; + endcase + end + end + end + + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_sram/wb_sram16.v b/lm32/logic/sakc/rtl/wb_sram/wb_sram16.v new file mode 100644 index 0000000..86aeb31 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_sram/wb_sram16.v @@ -0,0 +1,163 @@ +//---------------------------------------------------------------------------- +// Wishbone SRAM controller +//---------------------------------------------------------------------------- +module wb_sram16 #( + parameter adr_width = 18, + parameter latency = 0 // 0 .. 7 +) ( + input clk, + input reset, + // Wishbone interface + input wb_stb_i, + input wb_cyc_i, + output reg wb_ack_o, + input wb_we_i, + input [31:0] wb_adr_i, + input [3:0] wb_sel_i, + input [31:0] wb_dat_i, + output reg [31:0] wb_dat_o, + // SRAM connection + output reg [adr_width-1:0] sram_adr, + inout [15:0] sram_dat, + output reg [1:0] sram_be_n, // Byte Enable + output reg sram_ce_n, // Chip Enable + output reg sram_oe_n, // Output Enable + output reg sram_we_n // Write Enable +); + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +// Wishbone handling +wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; +wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i & ~wb_ack_o; + +// Translate wishbone address to sram address +wire [adr_width-1:0] adr1 = { wb_adr_i[adr_width:2], 1'b0 }; +wire [adr_width-1:0] adr2 = { wb_adr_i[adr_width:2], 1'b1 }; + +// Tri-State-Driver +reg [15:0] wdat; +reg wdat_oe; + +assign sram_dat = wdat_oe ? wdat : 16'bz; + + +// Latency countdown +reg [2:0] lcount; + +//---------------------------------------------------------------------------- +// State Machine +//---------------------------------------------------------------------------- +parameter s_idle = 0; +parameter s_read1 = 1; +parameter s_read2 = 2; +parameter s_write1 = 3; +parameter s_write2 = 4; +parameter s_write3 = 5; + +reg [2:0] state; + +always @(posedge clk) +begin + if (reset) begin + state <= s_idle; + lcount <= 0; + wb_ack_o <= 0; + end else begin + case (state) + s_idle: begin + wb_ack_o <= 0; + + if (wb_rd) begin + sram_ce_n <= 0; + sram_oe_n <= 0; + sram_we_n <= 1; + sram_adr <= adr1; + sram_be_n <= 2'b00; + wdat_oe <= 0; + lcount <= latency; + state <= s_read1; + end else if (wb_wr) begin + sram_ce_n <= 0; + sram_oe_n <= 1; + sram_we_n <= 0; + sram_adr <= adr1; + sram_be_n <= ~wb_sel_i[1:0]; + wdat <= wb_dat_i[15:0]; + wdat_oe <= 1; + lcount <= latency; + state <= s_write1; + end else begin + sram_ce_n <= 1; + sram_oe_n <= 1; + sram_we_n <= 1; + end + end + s_read1: begin + if (lcount != 0) begin + lcount <= lcount - 1; + end else begin + wb_dat_o[15:0] <= sram_dat; + sram_ce_n <= 0; + sram_oe_n <= 0; + sram_we_n <= 1; + sram_adr <= adr2; + sram_be_n <= 2'b00; + wdat_oe <= 0; + lcount <= latency; + state <= s_read2; + end + end + s_read2: begin + if (lcount != 0) begin + lcount <= lcount - 1; + end else begin + wb_dat_o[31:16] <= sram_dat; + wb_ack_o <= 1; + sram_ce_n <= 1; + sram_oe_n <= 1; + sram_we_n <= 1; + state <= s_idle; + end + end + s_write1: begin + if (lcount != 0) begin + lcount <= lcount - 1; + end else begin + sram_ce_n <= 0; + sram_oe_n <= 1; + sram_we_n <= 1; + state <= s_write2; + end + end + s_write2: begin + sram_ce_n <= 0; + sram_oe_n <= 1; + sram_we_n <= 0; + sram_adr <= adr2; + sram_be_n <= ~wb_sel_i[3:2]; + wdat <= wb_dat_i[31:16]; + wdat_oe <= 1; + lcount <= latency; + wb_ack_o <= 1; + state <= s_write3; + end + s_write3: begin + wb_ack_o <= 0; + if (lcount != 0) begin + lcount <= lcount - 1; + end else begin + sram_ce_n <= 1; + sram_oe_n <= 1; + sram_we_n <= 1; + wdat_oe <= 0; + state <= s_idle; + end + end + endcase + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_sram/wb_sram32.v b/lm32/logic/sakc/rtl/wb_sram/wb_sram32.v new file mode 100644 index 0000000..4132f01 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_sram/wb_sram32.v @@ -0,0 +1,122 @@ +//---------------------------------------------------------------------------- +// Wishbone SRAM controller +//---------------------------------------------------------------------------- +module wb_sram32 #( + parameter adr_width = 18, + parameter latency = 0 // 0 .. 7 +) ( + input clk, + input reset, + // Wishbone interface + input wb_stb_i, + input wb_cyc_i, + output reg wb_ack_o, + input wb_we_i, + input [31:0] wb_adr_i, + input [3:0] wb_sel_i, + input [31:0] wb_dat_i, + output reg [31:0] wb_dat_o, + // SRAM connection + output reg [adr_width-1:0] sram_adr, + inout [31:0] sram_dat, + output reg [3:0] sram_be_n, // Byte Enable + output reg sram_ce_n, // Chip Enable + output reg sram_oe_n, // Output Enable + output reg sram_we_n // Write Enable +); + +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- + +// Wishbone handling +wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; +wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i & ~wb_ack_o; + +// Translate wishbone address to sram address +wire [adr_width-1:0] adr = wb_adr_i[adr_width+1:2]; + +// Tri-State-Driver +reg [31:0] wdat; +reg wdat_oe; + +assign sram_dat = wdat_oe ? wdat : 32'bz; + + +// Latency countdown +reg [2:0] lcount; + +//---------------------------------------------------------------------------- +// State Machine +//---------------------------------------------------------------------------- +parameter s_idle = 0; +parameter s_read = 1; +parameter s_write = 2; + +reg [2:0] state; + +always @(posedge clk) +begin + if (reset) begin + state <= s_idle; + lcount <= 0; + wb_ack_o <= 0; + end else begin + case (state) + s_idle: begin + wb_ack_o <= 0; + + if (wb_rd) begin + sram_ce_n <= 0; + sram_oe_n <= 0; + sram_we_n <= 1; + sram_adr <= adr; + sram_be_n <= 4'b0000; + wdat_oe <= 0; + lcount <= latency; + state <= s_read; + end else if (wb_wr) begin + sram_ce_n <= 0; + sram_oe_n <= 1; + sram_we_n <= 0; + sram_adr <= adr; + sram_be_n <= ~wb_sel_i; + wdat <= wb_dat_i; + wdat_oe <= 1; + lcount <= latency; + state <= s_write; + end else begin + sram_ce_n <= 1; + sram_oe_n <= 1; + sram_we_n <= 1; + wdat_oe <= 0; + end + end + s_read: begin + if (lcount != 0) begin + lcount <= lcount - 1; + end else begin + sram_ce_n <= 1; + sram_oe_n <= 1; + sram_we_n <= 1; + wb_dat_o <= sram_dat; + wb_ack_o <= 1; + state <= s_idle; + end + end + s_write: begin + if (lcount != 0) begin + lcount <= lcount - 1; + end else begin + sram_ce_n <= 1; + sram_oe_n <= 1; + sram_we_n <= 1; + wb_ack_o <= 1; // XXX We could acknoledge write XXX + state <= s_idle; // XXX requests 1 cycle ahead XXX + end + end + endcase + end +end + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_timer/wb_timer.v b/lm32/logic/sakc/rtl/wb_timer/wb_timer.v new file mode 100644 index 0000000..9f48a14 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_timer/wb_timer.v @@ -0,0 +1,144 @@ +//--------------------------------------------------------------------------- +// +// Wishbone Timer +// +// Register Description: +// +// 0x00 TCR0 +// 0x04 COMPARE0 +// 0x08 COUNTER0 +// 0x0C TCR1 +// 0x10 COMPARE1 +// 0x14 COUNTER1 +// +// TCRx: +// +-------------------+-------+-------+-------+-------+ +// | 28'b0 | EN | AR | IRQEN | TRIG | +// +-------------------+-------+-------+-------+-------+ +// +// EN i (rw) if set to '1', COUNTERX counts upwards until it reaches +// COMPAREX +// AR (rw) AutoRecwstartload -- if COUNTER reaches COMPAREX, shall we +// restart at 1, or disable this counter? +// IRQEN (rw) Indicate interrupt condition when triggered? +// TRIG (ro) +// +//--------------------------------------------------------------------------- + +module wb_timer #( + parameter clk_freq = 50000000 +) ( + input clk, + input reset, + // Wishbone interface + input wb_stb_i, + input wb_cyc_i, + output wb_ack_o, + input wb_we_i, + input [31:0] wb_adr_i, + input [3:0] wb_sel_i, + input [31:0] wb_dat_i, + output reg [31:0] wb_dat_o, + // + output [1:0] intr +); + +//--------------------------------------------------------------------------- +// +//--------------------------------------------------------------------------- + +reg irqen0, irqen1; +reg trig0, trig1; +reg en0, en1; +reg ar0, ar1; + +wire [31:0] tcr0 = { 28'b0, en0, ar0, irqen0, trig0 }; +wire [31:0] tcr1 = { 28'b0, en1, ar1, irqen1, trig1 }; + +reg [31:0] counter0; +reg [31:0] counter1; + +reg [31:0] compare0; +reg [31:0] compare1; + +wire match0 = (counter0 == compare0); +wire match1 = (counter1 == compare1); + +assign intr = { trig1, trig0 }; + +reg ack; +assign wb_ack_o = wb_stb_i & wb_cyc_i & ack; + +wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i; +wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i; + +always @(posedge clk) +begin + if (reset) begin + ack <= 0; + en0 <= 0; + en1 <= 0; + ar0 <= 0; + ar1 <= 0; + trig0 <= 0; + trig1 <= 0; + counter0 <= 0; + counter1 <= 0; + compare0 <= 32'hFFFFFFFF; + compare1 <= 32'hFFFFFFFF; + end else begin + + // Handle counter 0 + if ( en0 & ~match0) counter0 <= counter0 + 1; + if ( en0 & match0) trig0 <= 1; + if ( ar0 & match0) counter0 <= 1; + if (~ar0 & match0) en0 <= 0; + + // Handle counter 1 + if ( en1 & ~match1) counter1 <= counter1 + 1; + if ( en1 & match1) trig1 <= 1; + if ( ar1 & match1) counter1 <= 1; + if (~ar1 & match1) en1 <= 0; + + // Handle WISHBONE access + ack <= 0; + + if (wb_rd & ~ack) begin // read cycle + ack <= 1; + + case (wb_adr_i[7:0]) + 'h00: wb_dat_o <= tcr0; + 'h04: wb_dat_o <= compare0; + 'h08: wb_dat_o <= counter0; + 'h0c: wb_dat_o <= tcr1; + 'h10: wb_dat_o <= compare1; + 'h14: wb_dat_o <= counter1; + default: wb_dat_o <= 32'b0; + endcase + end else if (wb_wr & ~ack ) begin // write cycle + ack <= 1; + + case (wb_adr_i[7:0]) + 'h00: begin + trig0 <= 0; + irqen0 <= wb_dat_i[1]; + ar0 <= wb_dat_i[2]; + en0 <= wb_dat_i[3]; + end + 'h04: compare0 <= wb_dat_i; + 'h08: counter0 <= wb_dat_i; + 'h0c: begin + trig1 <= 0; + irqen1 <= wb_dat_i[1]; + ar1 <= wb_dat_i[2]; + en1 <= wb_dat_i[3]; + end + 'h10: compare1 <= wb_dat_i; + 'h14: counter1 <= wb_dat_i; + endcase + end + end +end + + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_uart/uart.v b/lm32/logic/sakc/rtl/wb_uart/uart.v new file mode 100644 index 0000000..41b3744 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_uart/uart.v @@ -0,0 +1,160 @@ +//----------------------------------------------------- +// Design Name : uart +// File Name : uart.v +//----------------------------------------------------- +module uart #( + parameter freq_hz = 100000000, + parameter baud = 115200 +) ( + input reset, + input clk, + // UART lines + input uart_rxd, + output reg uart_txd, + // + output reg [7:0] rx_data, + output reg rx_avail, + output reg rx_error, + input rx_ack, + input [7:0] tx_data, + input tx_wr, + output reg tx_busy +); + +parameter divisor = freq_hz/baud/16; + +//----------------------------------------------------------------- +// enable16 generator +//----------------------------------------------------------------- +reg [15:0] enable16_counter; + +wire enable16; +assign enable16 = (enable16_counter == 0); + +always @(posedge clk) +begin + if (reset) begin + enable16_counter <= divisor-1; + end else begin + enable16_counter <= enable16_counter - 1; + if (enable16_counter == 0) begin + enable16_counter <= divisor-1; + end + end +end + +//----------------------------------------------------------------- +// syncronize uart_rxd +//----------------------------------------------------------------- +reg uart_rxd1; +reg uart_rxd2; + +always @(posedge clk) +begin + uart_rxd1 <= uart_rxd; + uart_rxd2 <= uart_rxd1; +end + +//----------------------------------------------------------------- +// UART RX Logic +//----------------------------------------------------------------- +reg rx_busy; +reg [3:0] rx_count16; +reg [3:0] rx_bitcount; +reg [7:0] rxd_reg; + +always @ (posedge clk) +begin + if (reset) begin + rx_busy <= 0; + rx_count16 <= 0; + rx_bitcount <= 0; + rx_avail <= 0; + rx_error <= 0; + end else begin + if (rx_ack) begin + rx_avail <= 0; + rx_error <= 0; + end + + if (enable16) begin + if (!rx_busy) begin // look for start bit + if (!uart_rxd2) begin // start bit found + rx_busy <= 1; + rx_count16 <= 7; + rx_bitcount <= 0; + end + end else begin + rx_count16 <= rx_count16 + 1; + + if (rx_count16 == 0) begin // sample + rx_bitcount <= rx_bitcount + 1; + + if (rx_bitcount == 0) begin // verify startbit + if (uart_rxd2) begin + rx_busy <= 0; + end + end else if (rx_bitcount == 9) begin // look for stop bit + rx_busy <= 0; + if (uart_rxd2) begin // stop bit ok + rx_data <= rxd_reg; + rx_avail <= 1; + rx_error <= 0; + end else begin // bas stop bit + rx_error <= 1; + end + end else begin + rxd_reg <= { uart_rxd2, rxd_reg[7:1] }; + end + end + end + end + end +end + +//----------------------------------------------------------------- +// UART TX Logic +//----------------------------------------------------------------- +reg [3:0] tx_bitcount; +reg [3:0] tx_count16; +reg [7:0] txd_reg; + +always @ (posedge clk) +begin + if (reset) begin + tx_busy <= 0; + uart_txd <= 1; + tx_count16 <= 0; + end else begin + if (tx_wr && !tx_busy) begin + txd_reg <= tx_data; + tx_bitcount <= 0; + tx_count16 <= 0; + tx_busy <= 1; + end + + if (enable16) begin + tx_count16 <= tx_count16 + 1; + + if ((tx_count16 == 0) && tx_busy) begin + tx_bitcount <= tx_bitcount + 1; + + if (tx_bitcount == 0) begin + uart_txd <= 'b0; + end else if (tx_bitcount == 9) begin + uart_txd <= 'b1; + end else if (tx_bitcount == 10) begin + tx_bitcount <= 0; + tx_busy <= 0; + end else begin + uart_txd <= txd_reg[0]; + txd_reg <= { 1'b0, txd_reg[7:1] }; + end + end + + end + end +end + + +endmodule diff --git a/lm32/logic/sakc/rtl/wb_uart/wb_uart.v b/lm32/logic/sakc/rtl/wb_uart/wb_uart.v new file mode 100644 index 0000000..6333588 --- /dev/null +++ b/lm32/logic/sakc/rtl/wb_uart/wb_uart.v @@ -0,0 +1,114 @@ +//--------------------------------------------------------------------------- +// Wishbone UART +// +// Register Description: +// +// 0x00 UCR [ 0 | 0 | 0 | tx_busy | 0 | 0 | rx_error | rx_avail ] +// 0x04 DATA +// +//--------------------------------------------------------------------------- + +module wb_uart #( + parameter clk_freq = 50000000, + parameter baud = 115200 +) ( + input clk, + input reset, + // Wishbone interface + input wb_stb_i, + input wb_cyc_i, + output wb_ack_o, + input wb_we_i, + input [31:0] wb_adr_i, + input [3:0] wb_sel_i, + input [31:0] wb_dat_i, + output reg [31:0] wb_dat_o, + // Serial Wires + input uart_rxd, + output uart_txd +); + +//--------------------------------------------------------------------------- +// Actual UART engine +//--------------------------------------------------------------------------- +wire [7:0] rx_data; +wire rx_avail; +wire rx_error; +reg rx_ack; +wire [7:0] tx_data; +reg tx_wr; +wire tx_busy; + +uart #( + .freq_hz( clk_freq ), + .baud( baud ) +) uart0 ( + .clk( clk ), + .reset( reset ), + // + .uart_rxd( uart_rxd ), + .uart_txd( uart_txd ), + // + .rx_data( rx_data ), + .rx_avail( rx_avail ), + .rx_error( rx_error ), + .rx_ack( rx_ack ), + .tx_data( tx_data ), + .tx_wr( tx_wr ), + .tx_busy( tx_busy ) +); + +//--------------------------------------------------------------------------- +// +//--------------------------------------------------------------------------- +wire [7:0] ucr = { 3'b0, tx_busy, 2'b0, rx_error, rx_avail }; + +wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i; +wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i & wb_sel_i[0]; + +reg ack; + +assign wb_ack_o = wb_stb_i & wb_cyc_i & ack; + +assign tx_data = wb_dat_i[7:0]; + +always @(posedge clk) +begin + if (reset) begin + wb_dat_o[31:8] <= 24'b0; + tx_wr <= 0; + rx_ack <= 0; + ack <= 0; + end else begin + wb_dat_o[31:8] <= 24'b0; + tx_wr <= 0; + rx_ack <= 0; + ack <= 0; + + if (wb_rd & ~ack) begin + ack <= 1; + + case (wb_adr_i[3:2]) + 2'b00: begin + wb_dat_o[7:0] <= ucr; + end + 2'b01: begin + wb_dat_o[7:0] <= rx_data; + rx_ack <= 1; + end + default: begin + wb_dat_o[7:0] <= 8'b0; + end + endcase + end else if (wb_wr & ~ack ) begin + ack <= 1; + + if ((wb_adr_i[3:2] == 2'b01) && ~tx_busy) begin + tx_wr <= 1; + end + end + end +end + + +endmodule diff --git a/lm32/logic/sakc/sim/ddr/ddr.v b/lm32/logic/sakc/sim/ddr/ddr.v new file mode 100644 index 0000000..8a32ff8 --- /dev/null +++ b/lm32/logic/sakc/sim/ddr/ddr.v @@ -0,0 +1,1379 @@ +/**************************************************************************************** +* +* File Name: ddr.v +* Version: 5.7 +* Model: BUS Functional +* +* Dependencies: ddr_parameters.v +* +* Description: Micron SDRAM DDR (Double Data Rate) +* +* Limitation: - Doesn't check for 8K-cycle refresh. +* - Doesn't check power-down entry/exit +* - Doesn't check self-refresh entry/exit. +* +* Note: - Set simulator resolution to "ps" accuracy +* - Set Debug = 0 to disable $display messages +* - Model assume Clk and Clk# crossing at both edge +* +* Disclaimer This software code and all associated documentation, comments or other +* of Warranty: information (collectively "Software") is provided "AS IS" without +* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY +* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES +* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT +* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE +* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. +* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR +* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, +* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE +* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, +* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, +* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, +* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, +* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE +* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGES. Because some jurisdictions prohibit the exclusion or +* limitation of liability for consequential or incidental damages, the +* above limitation may not apply to you. +* +* Copyright 2003 Micron Technology, Inc. All rights reserved. +* +* Rev Author Date Changes +* --- ------ ---------- --------------------------------------- +* 2.1 SPH 03/19/2002 - Second Release +* - Fix tWR and several incompatability +* between different simulators +* 3.0 TFK 02/18/2003 - Added tDSS and tDSH timing checks. +* - Added tDQSH and tDQSL timing checks. +* 3.1 CAH 05/28/2003 - update all models to release version 3.1 +* (no changes to this model) +* 3.2 JMK 06/16/2003 - updated all DDR400 models to support CAS Latency 3 +* 3.3 JMK 09/11/2003 - Added initialization sequence checks. +* 4.0 JMK 12/01/2003 - Grouped parameters into "ddr_parameters.v" +* - Fixed tWTR check +* 4.1 JMK 01/14/2004 - Grouped specify parameters by speed grade +* - Fixed mem_sizes parameter +* 4.2 JMK 03/19/2004 - Fixed pulse width checking on Dqs +* 4.3 JMK 04/27/2004 - Changed BL wire size in tb module +* - Changed Dq_buf size to [15:0] +* 5.0 JMK 06/16/2004 - Added read to write checking. +* - Added read with precharge truncation to write checking. +* - Added associative memory array to reduce memory consumption. +* - Added checking for required DQS edges during write. +* 5.1 JMK 08/16/2004 - Fixed checking for required DQS edges during write. +* - Fixed wdqs_valid window. +* 5.2 JMK 09/24/2004 - Read or Write without activate will be ignored. +* 5.3 JMK 10/27/2004 - Added tMRD checking during Auto Refresh and Activate. +* - Added tRFC checking during Load Mode and Precharge. +* 5.4 JMK 12/13/2004 - The model will not respond to illegal command sequences. +* 5.5 SPH 01/13/2005 - The model will issue a halt on illegal command sequences. +* JMK 02/11/2005 - Changed the display format for numbers to hex. +* 5.6 JMK 04/22/2005 - Fixed Write with auto precharge calculation. +* 5.7 JMK 08/05/2005 - Changed conditions for read with precharge truncation error. +* - Renamed parameters file with .vh extension. +****************************************************************************************/ + +// DO NOT CHANGE THE TIMESCALE +// MAKE SURE YOUR SIMULATOR USE "PS" RESOLUTION +`timescale 1ns / 1ps + +module ddr (Dq, Dqs, Addr, Ba, Clk, Clk_n, Cke, Cs_n, Ras_n, Cas_n, We_n, Dm); + + `include "ddr_parameters.vh" + + // Port Declarations + inout [DQ_BITS - 1 : 0] Dq; + inout [DQS_BITS - 1 : 0] Dqs; + input [ADDR_BITS - 1 : 0] Addr; + input [1 : 0] Ba; + input Clk; + input Clk_n; + input Cke; + input Cs_n; + input Ras_n; + input Cas_n; + input We_n; + input [DM_BITS - 1 : 0] Dm; + + // Internal Wires (fixed width) + wire [15 : 0] Dq_in; + wire [1 : 0] Dqs_in; + wire [1 : 0] Dm_in; + + assign Dq_in [DQ_BITS - 1 : 0] = Dq; + assign Dqs_in [DQS_BITS - 1 : 0] = Dqs; + assign Dm_in [DM_BITS - 1 : 0] = Dm; + + // Data pair + reg [15 : 0] dq_rise; + reg [1 : 0] dm_rise; + reg [15 : 0] dq_fall; + reg [1 : 0] dm_fall; + reg [3 : 0] dm_pair; + reg [15 : 0] Dq_buf; + + // Mode Register + reg [ADDR_BITS - 1 : 0] Mode_reg; + + // Internal System Clock + reg CkeZ, Sys_clk; + + // Internal Dqs initialize + reg Dqs_int; + + // Dqs buffer + reg [DQS_BITS - 1 : 0] Dqs_out; + + // Dq buffer + reg [DQ_BITS - 1 : 0] Dq_out; + + // Read pipeline variables + reg Read_cmnd [0 : 6]; + reg [1 : 0] Read_bank [0 : 6]; + reg [COL_BITS - 1 : 0] Read_cols [0 : 6]; + + // Write pipeline variables + reg Write_cmnd [0 : 3]; + reg [1 : 0] Write_bank [0 : 3]; + reg [COL_BITS - 1 : 0] Write_cols [0 : 3]; + + // Auto precharge variables + reg Read_precharge [0 : 3]; + reg Write_precharge [0 : 3]; + integer Count_precharge [0 : 3]; + + // Manual precharge variables + reg A10_precharge [0 : 6]; + reg [1 : 0] Bank_precharge [0 : 6]; + reg Cmnd_precharge [0 : 6]; + + // Burst terminate variables + reg Cmnd_bst [0 : 6]; + + // Memory Banks +`ifdef FULL_MEM + reg [DQ_BITS - 1 : 0] mem_array [0 : (1<= 2) begin + if (Debug) $display ("%m: at time %t MEMORY: Power Up and Initialization Sequence is complete", $time); + power_up_done = 1; + end else begin + aref_count = 0; + @ (aref_count >= 2) begin + if (Debug) $display ("%m: at time %t MEMORY: Power Up and Initialization Sequence is complete", $time); + power_up_done = 1; + end + end + end + end + end + end + end + + // Write Memory + task write_mem; + input [full_mem_bits - 1 : 0] addr; + input [DQ_BITS - 1 : 0] data; + reg [part_mem_bits : 0] i; + begin +`ifdef FULL_MEM + mem_array[addr] = data; +`else + begin : loop + for (i = 0; i < mem_used; i = i + 1) begin + if (addr_array[i] === addr) begin + disable loop; + end + end + end + if (i === mem_used) begin + if (i === (1<= burst_length) begin + Data_in_enable = 1'b0; + Data_out_enable = 1'b0; + read_precharge_truncation = 4'h0; + end + + end + endtask + + // Manual Precharge Pipeline + task Manual_Precharge_Pipeline; + begin + // A10 Precharge Pipeline + A10_precharge[0] = A10_precharge[1]; + A10_precharge[1] = A10_precharge[2]; + A10_precharge[2] = A10_precharge[3]; + A10_precharge[3] = A10_precharge[4]; + A10_precharge[4] = A10_precharge[5]; + A10_precharge[5] = A10_precharge[6]; + A10_precharge[6] = 1'b0; + + // Bank Precharge Pipeline + Bank_precharge[0] = Bank_precharge[1]; + Bank_precharge[1] = Bank_precharge[2]; + Bank_precharge[2] = Bank_precharge[3]; + Bank_precharge[3] = Bank_precharge[4]; + Bank_precharge[4] = Bank_precharge[5]; + Bank_precharge[5] = Bank_precharge[6]; + Bank_precharge[6] = 2'b0; + + // Command Precharge Pipeline + Cmnd_precharge[0] = Cmnd_precharge[1]; + Cmnd_precharge[1] = Cmnd_precharge[2]; + Cmnd_precharge[2] = Cmnd_precharge[3]; + Cmnd_precharge[3] = Cmnd_precharge[4]; + Cmnd_precharge[4] = Cmnd_precharge[5]; + Cmnd_precharge[5] = Cmnd_precharge[6]; + Cmnd_precharge[6] = 1'b0; + + // Terminate a Read if same bank or all banks + if (Cmnd_precharge[0] === 1'b1) begin + if (Bank_precharge[0] === Bank_addr || A10_precharge[0] === 1'b1) begin + if (Data_out_enable === 1'b1) begin + Data_out_enable = 1'b0; + read_precharge_truncation = 4'hF; + end + end + end + end + endtask + + // Burst Terminate Pipeline + task Burst_Terminate_Pipeline; + begin + // Command Precharge Pipeline + Cmnd_bst[0] = Cmnd_bst[1]; + Cmnd_bst[1] = Cmnd_bst[2]; + Cmnd_bst[2] = Cmnd_bst[3]; + Cmnd_bst[3] = Cmnd_bst[4]; + Cmnd_bst[4] = Cmnd_bst[5]; + Cmnd_bst[5] = Cmnd_bst[6]; + Cmnd_bst[6] = 1'b0; + + // Terminate a Read regardless of banks + if (Cmnd_bst[0] === 1'b1 && Data_out_enable === 1'b1) begin + Data_out_enable = 1'b0; + end + end + endtask + + // Dq and Dqs Drivers + task Dq_Dqs_Drivers; + begin + // read command pipeline + Read_cmnd [0] = Read_cmnd [1]; + Read_cmnd [1] = Read_cmnd [2]; + Read_cmnd [2] = Read_cmnd [3]; + Read_cmnd [3] = Read_cmnd [4]; + Read_cmnd [4] = Read_cmnd [5]; + Read_cmnd [5] = Read_cmnd [6]; + Read_cmnd [6] = 1'b0; + + // read bank pipeline + Read_bank [0] = Read_bank [1]; + Read_bank [1] = Read_bank [2]; + Read_bank [2] = Read_bank [3]; + Read_bank [3] = Read_bank [4]; + Read_bank [4] = Read_bank [5]; + Read_bank [5] = Read_bank [6]; + Read_bank [6] = 2'b0; + + // read column pipeline + Read_cols [0] = Read_cols [1]; + Read_cols [1] = Read_cols [2]; + Read_cols [2] = Read_cols [3]; + Read_cols [3] = Read_cols [4]; + Read_cols [4] = Read_cols [5]; + Read_cols [5] = Read_cols [6]; + Read_cols [6] = 0; + + // Initialize Read command + if (Read_cmnd [0] === 1'b1) begin + Data_out_enable = 1'b1; + Bank_addr = Read_bank [0]; + Cols_addr = Read_cols [0]; + Cols_brst = Cols_addr [2 : 0]; + Burst_counter = 0; + + // Row Address Mux + case (Bank_addr) + 2'd0 : Rows_addr = B0_row_addr; + 2'd1 : Rows_addr = B1_row_addr; + 2'd2 : Rows_addr = B2_row_addr; + 2'd3 : Rows_addr = B3_row_addr; + default : $display ("At time %t ERROR: Invalid Bank Address", $time); + endcase + end + + // Toggle Dqs during Read command + if (Data_out_enable === 1'b1) begin + Dqs_int = 1'b0; + if (Dqs_out === {DQS_BITS{1'b0}}) begin + Dqs_out = {DQS_BITS{1'b1}}; + end else if (Dqs_out === {DQS_BITS{1'b1}}) begin + Dqs_out = {DQS_BITS{1'b0}}; + end else begin + Dqs_out = {DQS_BITS{1'b0}}; + end + end else if (Data_out_enable === 1'b0 && Dqs_int === 1'b0) begin + Dqs_out = {DQS_BITS{1'bz}}; + end + + // Initialize dqs for Read command + if (Read_cmnd [2] === 1'b1) begin + if (Data_out_enable === 1'b0) begin + Dqs_int = 1'b1; + Dqs_out = {DQS_BITS{1'b0}}; + end + end + + // Read latch + if (Data_out_enable === 1'b1) begin + // output data + read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_out); + if (Debug) begin + $display ("At time %t READ : Bank = %h, Row = %h, Col = %h, Data = %h", $time, Bank_addr, Rows_addr, Cols_addr, Dq_out); + end + end else begin + Dq_out = {DQ_BITS{1'bz}}; + end + end + endtask + + // Write FIFO and DM Mask Logic + task Write_FIFO_DM_Mask_Logic; + begin + // Write command pipeline + Write_cmnd [0] = Write_cmnd [1]; + Write_cmnd [1] = Write_cmnd [2]; + Write_cmnd [2] = Write_cmnd [3]; + Write_cmnd [3] = 1'b0; + + // Write command pipeline + Write_bank [0] = Write_bank [1]; + Write_bank [1] = Write_bank [2]; + Write_bank [2] = Write_bank [3]; + Write_bank [3] = 2'b0; + + // Write column pipeline + Write_cols [0] = Write_cols [1]; + Write_cols [1] = Write_cols [2]; + Write_cols [2] = Write_cols [3]; + Write_cols [3] = {COL_BITS{1'b0}}; + + // Initialize Write command + if (Write_cmnd [0] === 1'b1) begin + Data_in_enable = 1'b1; + Bank_addr = Write_bank [0]; + Cols_addr = Write_cols [0]; + Cols_brst = Cols_addr [2 : 0]; + Burst_counter = 0; + + // Row address mux + case (Bank_addr) + 2'd0 : Rows_addr = B0_row_addr; + 2'd1 : Rows_addr = B1_row_addr; + 2'd2 : Rows_addr = B2_row_addr; + 2'd3 : Rows_addr = B3_row_addr; + default : $display ("At time %t ERROR: Invalid Row Address", $time); + endcase + end + + // Write data + if (Data_in_enable === 1'b1) begin + + // Data Buffer + read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf); + + // write negedge Dqs on posedge Sys_clk + if (Sys_clk) begin + if (!dm_fall[0]) begin + Dq_buf [ 7 : 0] = dq_fall [ 7 : 0]; + end + if (!dm_fall[1]) begin + Dq_buf [15 : 8] = dq_fall [15 : 8]; + end + if (~&dm_fall) begin + if (Debug) begin + $display ("At time %t WRITE: Bank = %h, Row = %h, Col = %h, Data = %h", $time, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]); + end + end + // write posedge Dqs on negedge Sys_clk + end else begin + if (!dm_rise[0]) begin + Dq_buf [ 7 : 0] = dq_rise [ 7 : 0]; + end + if (!dm_rise[1]) begin + Dq_buf [15 : 8] = dq_rise [15 : 8]; + end + if (~&dm_rise) begin + if (Debug) begin + $display ("At time %t WRITE: Bank = %h, Row = %h, Col = %h, Data = %h", $time, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]); + end + end + end + + // Write Data + write_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf); + + // tWR start and tWTR check + if (Sys_clk && &dm_pair === 1'b0) begin + case (Bank_addr) + 2'd0 : WR_chk0 = $time; + 2'd1 : WR_chk1 = $time; + 2'd2 : WR_chk2 = $time; + 2'd3 : WR_chk3 = $time; + default : $display ("At time %t ERROR: Invalid Bank Address (tWR)", $time); + endcase + + // tWTR check + if (Read_enable === 1'b1) begin + $display ("At time %t ERROR: tWTR violation during Read", $time); + end + end + end + end + endtask + + // Auto Precharge Calculation + task Auto_Precharge_Calculation; + begin + // Precharge counter + if (Read_precharge [0] === 1'b1 || Write_precharge [0] === 1'b1) begin + Count_precharge [0] = Count_precharge [0] + 1; + end + if (Read_precharge [1] === 1'b1 || Write_precharge [1] === 1'b1) begin + Count_precharge [1] = Count_precharge [1] + 1; + end + if (Read_precharge [2] === 1'b1 || Write_precharge [2] === 1'b1) begin + Count_precharge [2] = Count_precharge [2] + 1; + end + if (Read_precharge [3] === 1'b1 || Write_precharge [3] === 1'b1) begin + Count_precharge [3] = Count_precharge [3] + 1; + end + + // Read with AutoPrecharge Calculation + // The device start internal precharge when: + // 1. Meet tRAS requirement + // 2. BL/2 cycles after command + if ((Read_precharge[0] === 1'b1) && ($time - RAS_chk0 >= tRAS)) begin + if (Count_precharge[0] >= burst_length/2) begin + Pc_b0 = 1'b1; + Act_b0 = 1'b0; + RP_chk0 = $time; + Read_precharge[0] = 1'b0; + end + end + if ((Read_precharge[1] === 1'b1) && ($time - RAS_chk1 >= tRAS)) begin + if (Count_precharge[1] >= burst_length/2) begin + Pc_b1 = 1'b1; + Act_b1 = 1'b0; + RP_chk1 = $time; + Read_precharge[1] = 1'b0; + end + end + if ((Read_precharge[2] === 1'b1) && ($time - RAS_chk2 >= tRAS)) begin + if (Count_precharge[2] >= burst_length/2) begin + Pc_b2 = 1'b1; + Act_b2 = 1'b0; + RP_chk2 = $time; + Read_precharge[2] = 1'b0; + end + end + if ((Read_precharge[3] === 1'b1) && ($time - RAS_chk3 >= tRAS)) begin + if (Count_precharge[3] >= burst_length/2) begin + Pc_b3 = 1'b1; + Act_b3 = 1'b0; + RP_chk3 = $time; + Read_precharge[3] = 1'b0; + end + end + + // Write with AutoPrecharge Calculation + // The device start internal precharge when: + // 1. Meet tRAS requirement + // 2. Write Latency PLUS BL/2 cycles PLUS tWR after Write command + + if ((Write_precharge[0] === 1'b1) && ($time - RAS_chk0 >= tRAS)) begin + if ((Count_precharge[0] >= burst_length/2+1) && ($time - WR_chk0 >= tWR)) begin + Pc_b0 = 1'b1; + Act_b0 = 1'b0; + RP_chk0 = $time; + Write_precharge[0] = 1'b0; + end + end + if ((Write_precharge[1] === 1'b1) && ($time - RAS_chk1 >= tRAS)) begin + if ((Count_precharge[1] >= burst_length/2+1) && ($time - WR_chk1 >= tWR)) begin + Pc_b1 = 1'b1; + Act_b1 = 1'b0; + RP_chk1 = $time; + Write_precharge[1] = 1'b0; + end + end + if ((Write_precharge[2] === 1'b1) && ($time - RAS_chk2 >= tRAS)) begin + if ((Count_precharge[2] >= burst_length/2+1) && ($time - WR_chk2 >= tWR)) begin + Pc_b2 = 1'b1; + Act_b2 = 1'b0; + RP_chk2 = $time; + Write_precharge[2] = 1'b0; + end + end + if ((Write_precharge[3] === 1'b1) && ($time - RAS_chk3 >= tRAS)) begin + if ((Count_precharge[3] >= burst_length/2+1) && ($time - WR_chk3 >= tWR)) begin + Pc_b3 = 1'b1; + Act_b3 = 1'b0; + RP_chk3 = $time; + Write_precharge[3] = 1'b0; + end + end + end + endtask + + // DLL Counter + task DLL_Counter; + begin + if (DLL_reset === 1'b1 && DLL_done === 1'b0) begin + DLL_count = DLL_count + 1; + if (DLL_count >= 200) begin + DLL_done = 1'b1; + end + end + end + endtask + + // Control Logic + task Control_Logic; + begin + // Auto Refresh + if (Aref_enable === 1'b1) begin + // Display Debug Message + if (Debug) begin + $display ("At time %t AREF : Auto Refresh", $time); + end + + // Precharge to Auto Refresh + if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || + ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin + $display ("At time %t ERROR: tRP violation during Auto Refresh", $time); + end + + // LMR/EMR to Auto Refresh + if ($time - MRD_chk < tMRD) begin + $display ("At time %t ERROR: tMRD violation during Auto Refresh", $time); + end + + // Auto Refresh to Auto Refresh + if ($time - RFC_chk < tRFC) begin + $display ("At time %t ERROR: tRFC violation during Auto Refresh", $time); + end + + // Precharge to Auto Refresh + if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin + $display ("At time %t ERROR: All banks must be Precharged before Auto Refresh", $time); + if (!no_halt) $stop (0); + end else begin + aref_count = aref_count + 1; + RFC_chk = $time; + end + end + + // Extended Mode Register + if (Ext_mode_enable === 1'b1) begin + if (Debug) begin + $display ("At time %t EMR : Extended Mode Register", $time); + end + + // Precharge to LMR/EMR + if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || + ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin + $display ("At time %t ERROR: tRP violation during Extended Mode Register", $time); + end + + // LMR/EMR to LMR/EMR + if ($time - MRD_chk < tMRD) begin + $display ("At time %t ERROR: tMRD violation during Extended Mode Register", $time); + end + + // Auto Refresh to LMR/EMR + if ($time - RFC_chk < tRFC) begin + $display ("At time %t ERROR: tRFC violation during Extended Mode Register", $time); + end + + // Precharge to LMR/EMR + if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin + $display ("At time %t ERROR: all banks must be Precharged before Extended Mode Register", $time); + if (!no_halt) $stop (0); + end else begin + if (Addr[0] === 1'b0) begin + DLL_enable = 1'b1; + if (Debug) begin + $display ("At time %t EMR : Enable DLL", $time); + end + end else begin + DLL_enable = 1'b0; + if (Debug) begin + $display ("At time %t EMR : Disable DLL", $time); + end + end + MRD_chk = $time; + end + end + + // Load Mode Register + if (Mode_reg_enable === 1'b1) begin + if (Debug) begin + $display ("At time %t LMR : Load Mode Register", $time); + end + + // Precharge to LMR/EMR + if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) || + ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin + $display ("At time %t ERROR: tRP violation during Load Mode Register", $time); + end + + // LMR/EMR to LMR/EMR + if ($time - MRD_chk < tMRD) begin + $display ("At time %t ERROR: tMRD violation during Load Mode Register", $time); + end + + // Auto Refresh to LMR/EMR + if ($time - RFC_chk < tRFC) begin + $display ("At time %t ERROR: tRFC violation during Load Mode Register", $time); + end + + // Precharge to LMR/EMR + if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin + $display ("At time %t ERROR: all banks must be Precharged before Load Mode Register", $time); + end else begin + // Register Mode + Mode_reg = Addr; + + // DLL Reset + if (DLL_enable === 1'b1 && Addr [8] === 1'b1) begin + DLL_reset = 1'b1; + DLL_done = 1'b0; + DLL_count = 0; + end else if (DLL_enable === 1'b1 && DLL_reset === 1'b0 && Addr [8] === 1'b0) begin + $display ("At time %t ERROR: DLL is ENABLE: DLL RESET is required.", $time); + end else if (DLL_enable === 1'b0 && Addr [8] === 1'b1) begin + $display ("At time %t ERROR: DLL is DISABLE: DLL RESET will be ignored.", $time); + end + + // Burst Length + case (Addr [2 : 0]) + 3'b001 : $display ("At time %t LMR : Burst Length = 2", $time); + 3'b010 : $display ("At time %t LMR : Burst Length = 4", $time); + 3'b011 : $display ("At time %t LMR : Burst Length = 8", $time); + default : $display ("At time %t ERROR: Burst Length not supported", $time); + endcase + + // CAS Latency + case (Addr [6 : 4]) + 3'b010 : $display ("At time %t LMR : CAS Latency = 2", $time); + 3'b110 : $display ("At time %t LMR : CAS Latency = 2.5", $time); + 3'b011 : $display ("At time %t LMR : CAS Latency = 3", $time); + default : $display ("At time %t ERROR: CAS Latency not supported", $time); + endcase + + // Record current tMRD time + MRD_chk = $time; + end + end + + // Activate Block + if (Active_enable === 1'b1) begin + if (!(power_up_done)) begin + $display ("%m: at time %t ERROR: Power Up and Initialization Sequence not completed before executing Activate command", $time); + end + // Display Debug Message + if (Debug) begin + $display ("At time %t ACT : Bank = %h, Row = %h", $time, Ba, Addr); + end + + // Activate to Activate (different bank) + if ((Prev_bank != Ba) && ($time - RRD_chk < tRRD)) begin + $display ("At time %t ERROR: tRRD violation during Activate bank %h", $time, Ba); + end + + // LMR/EMR to Activate + if ($time - MRD_chk < tMRD) begin + $display ("At time %t ERROR: tMRD violation during Activate bank %h", $time, Ba); + end + + // AutoRefresh to Activate + if ($time - RFC_chk < tRFC) begin + $display ("At time %t ERROR: tRFC violation during Activate bank %h", $time, Ba); + end + + // Precharge to Activate + if ((Ba === 2'b00 && Pc_b0 === 1'b0) || (Ba === 2'b01 && Pc_b1 === 1'b0) || + (Ba === 2'b10 && Pc_b2 === 1'b0) || (Ba === 2'b11 && Pc_b3 === 1'b0)) begin + $display ("At time %t ERROR: Bank = %h is already activated - Command Ignored", $time, Ba); + if (!no_halt) $stop (0); + end else begin + // Activate Bank 0 + if (Ba === 2'b00 && Pc_b0 === 1'b1) begin + // Activate to Activate (same bank) + if ($time - RC_chk0 < tRC) begin + $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba); + end + + // Precharge to Activate + if ($time - RP_chk0 < tRP) begin + $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba); + end + + // Record variables for checking violation + Act_b0 = 1'b1; + Pc_b0 = 1'b0; + B0_row_addr = Addr; + RC_chk0 = $time; + RCD_chk0 = $time; + RAS_chk0 = $time; + RAP_chk0 = $time; + end + + // Activate Bank 1 + if (Ba === 2'b01 && Pc_b1 === 1'b1) begin + // Activate to Activate (same bank) + if ($time - RC_chk1 < tRC) begin + $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba); + end + + // Precharge to Activate + if ($time - RP_chk1 < tRP) begin + $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba); + end + + // Record variables for checking violation + Act_b1 = 1'b1; + Pc_b1 = 1'b0; + B1_row_addr = Addr; + RC_chk1 = $time; + RCD_chk1 = $time; + RAS_chk1 = $time; + RAP_chk1 = $time; + end + + // Activate Bank 2 + if (Ba === 2'b10 && Pc_b2 === 1'b1) begin + // Activate to Activate (same bank) + if ($time - RC_chk2 < tRC) begin + $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba); + end + + // Precharge to Activate + if ($time - RP_chk2 < tRP) begin + $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba); + end + + // Record variables for checking violation + Act_b2 = 1'b1; + Pc_b2 = 1'b0; + B2_row_addr = Addr; + RC_chk2 = $time; + RCD_chk2 = $time; + RAS_chk2 = $time; + RAP_chk2 = $time; + end + + // Activate Bank 3 + if (Ba === 2'b11 && Pc_b3 === 1'b1) begin + // Activate to Activate (same bank) + if ($time - RC_chk3 < tRC) begin + $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba); + end + + // Precharge to Activate + if ($time - RP_chk3 < tRP) begin + $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba); + end + + // Record variables for checking violation + Act_b3 = 1'b1; + Pc_b3 = 1'b0; + B3_row_addr = Addr; + RC_chk3 = $time; + RCD_chk3 = $time; + RAS_chk3 = $time; + RAP_chk3 = $time; + end + // Record variable for checking violation + RRD_chk = $time; + Prev_bank = Ba; + read_precharge_truncation[Ba] = 1'b0; + end + end + + // Precharge Block - consider NOP if bank already precharged or in process of precharging + if (Prech_enable === 1'b1) begin + // Display Debug Message + if (Debug) begin + $display ("At time %t PRE : Addr[10] = %b, Bank = %b", $time, Addr[10], Ba); + end + + // LMR/EMR to Precharge + if ($time - MRD_chk < tMRD) begin + $display ("At time %t ERROR: tMRD violation during Precharge", $time); + end + + // AutoRefresh to Precharge + if ($time - RFC_chk < tRFC) begin + $display ("At time %t ERROR: tRFC violation during Precharge", $time); + end + + // Precharge bank 0 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin + Act_b0 = 1'b0; + Pc_b0 = 1'b1; + RP_chk0 = $time; + + // Activate to Precharge Bank + if ($time - RAS_chk0 < tRAS) begin + $display ("At time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for Write + if ($time - WR_chk0 < tWR) begin + $display ("At time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge bank 1 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin + Act_b1 = 1'b0; + Pc_b1 = 1'b1; + RP_chk1 = $time; + + // Activate to Precharge Bank 1 + if ($time - RAS_chk1 < tRAS) begin + $display ("At time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for Write + if ($time - WR_chk1 < tWR) begin + $display ("At time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge bank 2 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin + Act_b2 = 1'b0; + Pc_b2 = 1'b1; + RP_chk2 = $time; + + // Activate to Precharge Bank 2 + if ($time - RAS_chk2 < tRAS) begin + $display ("At time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for Write + if ($time - WR_chk2 < tWR) begin + $display ("At time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Precharge bank 3 + if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin + Act_b3 = 1'b0; + Pc_b3 = 1'b1; + RP_chk3 = $time; + + // Activate to Precharge Bank 3 + if ($time - RAS_chk3 < tRAS) begin + $display ("At time %t ERROR: tRAS violation during Precharge", $time); + end + + // tWR violation check for Write + if ($time - WR_chk3 < tWR) begin + $display ("At time %t ERROR: tWR violation during Precharge", $time); + end + end + + // Prech_count is to make sure we have met part of the initialization sequence + Prech_count = Prech_count + 1; + + // Pipeline for READ + A10_precharge [cas_latency_x2] = Addr[10]; + Bank_precharge[cas_latency_x2] = Ba; + Cmnd_precharge[cas_latency_x2] = 1'b1; + end + + // Burst terminate + if (Burst_term === 1'b1) begin + // Display Debug Message + if (Debug) begin + $display ("At time %t BST : Burst Terminate",$time); + end + + if (Data_in_enable === 1'b1) begin + // Illegal to burst terminate a Write + $display ("At time %t ERROR: It's illegal to burst terminate a Write", $time); + if (!no_halt) $stop (0); + end else if (Read_precharge[0] === 1'b1 || Read_precharge[1] === 1'b1 || + // Illegal to burst terminate a Read with Auto Precharge + Read_precharge[2] === 1'b1 || Read_precharge[3] === 1'b1) begin + $display ("At time %t ERROR: It's illegal to burst terminate a Read with Auto Precharge", $time); + if (!no_halt) $stop (0); + end else begin + // Burst Terminate Command Pipeline for Read + Cmnd_bst[cas_latency_x2] = 1'b1; + end + + end + + // Read Command + if (Read_enable === 1'b1) begin + if (!(power_up_done)) begin + $display ("%m: at time %t ERROR: Power Up and Initialization Sequence not completed before executing Read Command", $time); + end + // Check for DLL reset before Read + if (DLL_reset === 1 && DLL_done === 0) begin + $display ("%m: at time %t ERROR: You need to wait 200 tCK after DLL Reset Enable to Read, Not %0d clocks.", $time, DLL_count); + end + // Display Debug Message + if (Debug) begin + $display ("At time %t READ : Bank = %h, Col = %h", $time, Ba, {Addr [11], Addr [9 : 0]}); + end + + // Terminate a Write + if (Data_in_enable === 1'b1) begin + Data_in_enable = 1'b0; + end + + // Activate to Read without Auto Precharge + if ((Addr [10] === 1'b0 && Ba === 2'b00 && $time - RCD_chk0 < tRCD) || + (Addr [10] === 1'b0 && Ba === 2'b01 && $time - RCD_chk1 < tRCD) || + (Addr [10] === 1'b0 && Ba === 2'b10 && $time - RCD_chk2 < tRCD) || + (Addr [10] === 1'b0 && Ba === 2'b11 && $time - RCD_chk3 < tRCD)) begin + $display("At time %t ERROR: tRCD violation during Read", $time); + end + + // Activate to Read with Auto Precharge + if ((Addr [10] === 1'b1 && Ba === 2'b00 && $time - RAP_chk0 < tRAP) || + (Addr [10] === 1'b1 && Ba === 2'b01 && $time - RAP_chk1 < tRAP) || + (Addr [10] === 1'b1 && Ba === 2'b10 && $time - RAP_chk2 < tRAP) || + (Addr [10] === 1'b1 && Ba === 2'b11 && $time - RAP_chk3 < tRAP)) begin + $display ("At time %t ERROR: tRAP violation during Read", $time); + end + + // Interrupt a Read with Auto Precharge (same bank only) + if (Read_precharge [Ba] === 1'b1) begin + $display ("At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge", $time); + if (!no_halt) $stop (0); + // Cancel Auto Precharge + if (Addr[10] === 1'b0) begin + Read_precharge [Ba]= 1'b0; + end + end + // Activate to Read + if ((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) || + (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) begin + $display("At time %t ERROR: Bank is not Activated for Read", $time); + if (!no_halt) $stop (0); + end else begin + // CAS Latency pipeline + Read_cmnd[cas_latency_x2] = 1'b1; + Read_bank[cas_latency_x2] = Ba; + Read_cols[cas_latency_x2] = {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}; + // Auto Precharge + if (Addr[10] === 1'b1) begin + Read_precharge [Ba]= 1'b1; + Count_precharge [Ba]= 0; + end + end + end + + // Write Command + if (Write_enable === 1'b1) begin + if (!(power_up_done)) begin + $display ("%m: at time %t ERROR: Power Up and Initialization Sequence not completed before executing Write Command", $time); + if (!no_halt) $stop (0); + end + // display debug message + if (Debug) begin + $display ("At time %t WRITE: Bank = %h, Col = %h", $time, Ba, {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}); + end + + // Activate to Write + if ((Ba === 2'b00 && $time - RCD_chk0 < tRCD) || + (Ba === 2'b01 && $time - RCD_chk1 < tRCD) || + (Ba === 2'b10 && $time - RCD_chk2 < tRCD) || + (Ba === 2'b11 && $time - RCD_chk3 < tRCD)) begin + $display("At time %t ERROR: tRCD violation during Write to Bank %h", $time, Ba); + end + + // Read to Write + if (Read_cmnd[0] || Read_cmnd[1] || Read_cmnd[2] || Read_cmnd[3] || + Read_cmnd[4] || Read_cmnd[5] || Read_cmnd[6] || (Burst_counter < burst_length)) begin + if (Data_out_enable || read_precharge_truncation[Ba]) begin + $display("At time %t ERROR: Read to Write violation", $time); + end + end + + // Interrupt a Write with Auto Precharge (same bank only) + if (Write_precharge [Ba] === 1'b1) begin + $display ("At time %t ERROR: it's illegal to interrupt a Write with Auto Precharge", $time); + if (!no_halt) $stop (0); + // Cancel Auto Precharge + if (Addr[10] === 1'b0) begin + Write_precharge [Ba]= 1'b0; + end + end + // Activate to Write + if ((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) || + (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) begin + $display("At time %t ERROR: Bank is not Activated for Write", $time); + if (!no_halt) $stop (0); + end else begin + // Pipeline for Write + Write_cmnd [3] = 1'b1; + Write_bank [3] = Ba; + Write_cols [3] = {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}; + // Auto Precharge + if (Addr[10] === 1'b1) begin + Write_precharge [Ba]= 1'b1; + Count_precharge [Ba]= 0; + end + end + end + end + endtask + + task check_neg_dqs; + begin + if (Write_cmnd[2] || Write_cmnd[1] || Data_in_enable) begin + for (i=0; i 255)) begin + $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT); + $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT); + $finish; + end + + case (STARTUP_WAIT) + "false" : ; + "FALSE" : ; + "true" : ; + "TRUE" : ; + default : begin + $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT); + $finish; + end + endcase +end + +// +// fx parameters +// + +initial begin + gcd = 1; + for (i = 2; i <= CLKFX_MULTIPLY; i = i + 1) begin + if (((CLKFX_MULTIPLY % i) == 0) && ((CLKFX_DIVIDE % i) == 0)) + gcd = i; + end + numerator = CLKFX_MULTIPLY / gcd; + denominator = CLKFX_DIVIDE / gcd; +end + +// +// input wire delays +// + +buf b_clkin (clkin_in, CLKIN); +buf b_clkfb (clkfb_in, CLKFB); +buf b_dssen (dssen_in, DSSEN); +buf b_psclk (psclk_in, PSCLK); +buf b_psen (psen_in, PSEN); +buf b_psincdec (psincdec_in, PSINCDEC); +buf b_rst (rst_in, RST); +buf #100 b_locked (LOCKED, locked_out_out); +buf #100 b_psdone (PSDONE, psdone_out); +buf b_ps_overflow (STATUS[0], ps_overflow_out_ext); +buf b_clkin_lost (STATUS[1], clkin_lost_out_ext); +buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext); + +assign STATUS[7:3] = 5'b0; + +dcm_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in); + +dcm_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in); +dcm_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in); + +dcm_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in); +dcm_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in); + +always @(rst_in or en_status or clkfx_lost_out or clkin_lost_out or ps_overflow_out) + if (rst_in == 1 || en_status == 0) begin + ps_overflow_out_ext = 0; + clkin_lost_out_ext = 0; + clkfx_lost_out_ext = 0; + end + else + begin + ps_overflow_out_ext = ps_overflow_out; + clkin_lost_out_ext = clkin_lost_out; + clkfx_lost_out_ext = clkfx_lost_out; + end + +always @(posedge rst_in or posedge LOCKED) + if (rst_in == 1) + en_status <= 0; + else + en_status <= 1; + + +always @(clkin_div) + clkin_ps <= #(ps_delay) clkin_div; + +always @(clkin_ps or lock_fb) + clkin_fb = clkin_ps & lock_fb; + + +always @(negedge clkfb_in or posedge rst_in) + if (rst_in) + clkfb_div_en <= 0; + else + if (lock_fb_dly && lock_period && lock_fb && ~clkin_ps) + clkfb_div_en <= 1; + +always @(posedge clkfb_in or posedge rst_in) + if (rst_in) + clkfb_div <= 0; + else + if (clkfb_div_en ) + clkfb_div <= ~clkfb_div; + +always @(clkfb_in or clkfb_div) + if (clkfb_type == 2'b10 ) + clkfb_chk = clkfb_div; + else + clkfb_chk = clkfb_in & lock_fb_dly; + +always @(posedge clkin_fb or posedge chk_rst) + if (chk_rst) + clkin_chkin <= 0; + else + clkin_chkin <= 1; + +always @(posedge clkfb_chk or posedge chk_rst) + if (chk_rst) + clkfb_chkin <= 0; + else + clkfb_chkin <= 1; + + assign chk_rst = (rst_in==1 || clock_stopped==1 ) ? 1 : 0; + assign chk_enable = (clkin_chkin == 1 && clkfb_chkin == 1 && + lock_ps ==1 && lock_fb ==1 && lock_fb_dly == 1) ? 1 : 0; + +always @(posedge clkin_div or posedge rst_in) + if (rst_in) begin + period_div <= 0; + clkin_div_edge <= 0; + end + else + if ( clkin_div ==1 ) begin + clkin_div_edge <= $time; + if (($time - clkin_div_edge) <= (1.5 * period_div)) + period_div <= $time - clkin_div_edge; + else if ((period_div == 0) && (clkin_div_edge != 0)) + period_div <= $time - clkin_div_edge; + end + +always @(posedge clkin_ps or posedge rst_in) + if (rst_in) begin + period_ps <= 0; + clkin_ps_edge <= 0; + end + else + if (clkin_ps == 1 ) begin + clkin_ps_edge <= $time; + if (($time - clkin_ps_edge) <= (1.5 * period_ps)) + period_ps <= $time - clkin_ps_edge; + else if ((period_ps == 0) && (clkin_ps_edge != 0)) + period_ps <= $time - clkin_ps_edge; + end + +always @(posedge clkin_ps) begin + lock_ps <= lock_period; + lock_ps_dly <= lock_ps; + lock_fb <= lock_ps_dly; + lock_fb_dly_tmp <= lock_fb; +end + +always @(negedge clkin_ps or posedge rst_in) + if (rst_in) + lock_fb_dly <= 1'b0; + else +// lock_fb_dly <= #(period/4) lock_fb_dly_tmp; + lock_fb_dly <= #(period * 0.75) lock_fb_dly_tmp; + + +always @(period or fb_delay ) + if (fb_delay == 0) + clkout_delay = 0; + else + clkout_delay = period - fb_delay; + +// +// generate master reset signal +// + +always @(posedge clkin_in) begin + rst_reg[0] <= rst_in; + rst_reg[1] <= rst_reg[0] & rst_in; + rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst_in; +end + +reg rst_tmp1, rst_tmp2; +initial +begin +rst_tmp1 = 0; +rst_tmp2 = 0; +rst_flag = 0; +end + +always @(rst_in) +begin + if (rst_in) + rst_flag = 0; + + rst_tmp1 = rst_in; + if (rst_tmp1 == 0 && rst_tmp2 == 1) begin + if ((rst_reg[2] & rst_reg[1] & rst_reg[0]) == 0) begin + rst_flag = 1; + $display("Input Error : RST on instance %m must be asserted for 3 CLKIN clock cycles."); + end + end + rst_tmp2 = rst_tmp1; +end + +initial begin + CLK0 = 0; + CLK180 = 0; + CLK270 = 0; + CLK2X = 0; + CLK2X180 = 0; + CLK90 = 0; + CLKDV = 0; + CLKFX = 0; + CLKFX180 = 0; + clk0_out = 0; + clk2x_out = 0; + clkdv_out = 0; + clkdv_cnt = 0; + clkfb_window = 0; + clkfx_out = 0; + clkfx180_en = 0; + clkin_div_edge = 0; + clkin_period[0] = 0; + clkin_period[1] = 0; + clkin_period[2] = 0; + clkin_edge = 0; + clkin_ps_edge = 0; + clkin_window = 0; + clkout_delay = 0; + clock_stopped = 1; + fb_delay = 0; + fb_delay_found = 0; + lock_clkfb = 0; + lock_clkin = 0; + lock_delay = 0; + lock_fb = 0; + lock_fb_dly = 0; + lock_out = 2'b00; + lock_out1_neg = 0; + lock_period = 0; + lock_ps = 0; + lock_ps_dly = 0; + locked_out = 0; + period = 0; + period_div = 0; + period_fx = 0; + period_orig = 0; + period_ps = 0; + psdone_out = 0; + ps_delay = 0; + ps_lock = 0; + ps_overflow_out = 0; + ps_overflow_out_ext = 0; + clkin_lost_out_ext = 0; + clkfx_lost_out_ext = 0; + rst_reg = 3'b000; + first_time_locked = 0; + en_status = 0; + clkfb_div = 0; + clkin_chkin = 0; + clkfb_chkin = 0; +end + +// RST less than 3 cycles, lock = x + + assign locked_out_out = (rst_flag) ? 1'bx : locked_out; + +// +// detect_first_time_locked +// +always @(posedge locked_out) + if (first_time_locked == 0) + first_time_locked <= 1; + +// +// phase shift parameters +// + +always @(posedge lock_period) begin + if (ps_type == 2'b01) + FINE_SHIFT_RANGE = 10000; + else if (ps_type == 2'b10) + FINE_SHIFT_RANGE = 5000; + if (PHASE_SHIFT > 0) begin + if ((ps_in * period_orig / 256) > period_orig + FINE_SHIFT_RANGE) begin + $display("Function Error : Instance %m Requested Phase Shift = PHASE_SHIFT * PERIOD / 256 = %d * %1.3f / 256 = %1.3f. This exceeds the FINE_SHIFT_RANGE of %1.3f ns.", PHASE_SHIFT, period_orig / 1000.0, PHASE_SHIFT * period_orig / 256 / 1000.0, FINE_SHIFT_RANGE / 1000.0); + $finish; + end + end + else if (PHASE_SHIFT < 0) begin + if ((period_orig > FINE_SHIFT_RANGE) && + ((ps_in * period_orig / 256) < period_orig - FINE_SHIFT_RANGE)) begin + $display("Function Error : Instance %m Requested Phase Shift = PHASE_SHIFT * PERIOD / 256 = %d * %1.3f / 256 = %1.3f. This exceeds the FINE_SHIFT_RANGE of %1.3f ns.", PHASE_SHIFT, period_orig / 1000.0, -(PHASE_SHIFT) * period_orig / 256 / 1000.0, FINE_SHIFT_RANGE / 1000.0); + $finish; + end + end +end + +always @(posedge lock_period_pulse or posedge rst_in or ps_in_ps) + if (rst_in) begin + ps_delay <= 0; + end + else if (lock_period_pulse) begin + ps_delay <= (ps_in * period_div / 256); + end + else begin + if (ps_type == 2'b10 && ps_lock ==1) + begin + ps_delay = (ps_in_ps * period_div / 256); + end + end + + +always @(posedge psclk_in or rst_in) + if (rst_in) begin + ps_in_ps <= ps_in; + ps_overflow_out <= 0; + end + else begin + if (ps_type == 2'b10) + if (psen_in) + if (ps_lock == 1) + $display(" Warning : Please wait for PSDONE signal before adjusting the Phase Shift."); + else + if (psincdec_in == 1) begin + if (ps_in_ps == 511) + ps_overflow_out <= 1; + else if (((ps_in_ps + 1) * period_orig / 256) > period_orig + FINE_SHIFT_RANGE) + ps_overflow_out <= 1; + else begin + ps_in_ps <= ps_in_ps + 1; + ps_overflow_out <= 0; + end + ps_lock <= 1; + end + else if (psincdec_in == 0) begin + if (ps_in_ps == 1) + ps_overflow_out <= 1; + else if ((period_orig > FINE_SHIFT_RANGE) && + (((ps_in_ps - 1) * period_orig / 256) < period_orig - FINE_SHIFT_RANGE)) + ps_overflow_out <= 1; + else begin + ps_in_ps <= ps_in_ps - 1; + ps_overflow_out <= 0; + end + ps_lock <= 1; + end +end + +always @(posedge ps_lock) begin + @(posedge clkin_ps) + @(posedge psclk_in) + @(posedge psclk_in) + @(posedge psclk_in) + psdone_out <= 1; + @(posedge psclk_in) + psdone_out <= 0; + ps_lock <= 0; +end + +// +// determine clock period +// + +always @(posedge clkin_div or negedge clkin_div or posedge rst_in) + if (rst_in == 1) begin + clkin_period[0] <= 0; + clkin_period[1] <= 0; + clkin_period[2] <= 0; + clkin_edge <= 0; + end + else + if (clkin_div == 1) begin + clkin_edge <= $time; + clkin_period[2] <= clkin_period[1]; + clkin_period[1] <= clkin_period[0]; + if (clkin_edge != 0) + clkin_period[0] <= $time - clkin_edge; + end + else if (clkin_div == 0) + if (lock_period == 1) + if (100000000 < clkin_period[0]/1000) + begin + end + else if ((period_orig * 2 < clkin_period[0]) && (clock_stopped == 0)) begin + clkin_period[0] <= clkin_period[1]; + end + +always @(negedge clkin_div or posedge rst_in) + if (rst_in == 1) begin + lock_period <= 0; + clock_stopped <= 1; + end + else begin + if (lock_period == 1'b0) begin + if ((clkin_period[0] != 0) && + (clkin_period[0] - cycle_jitter <= clkin_period[1]) && + (clkin_period[1] <= clkin_period[0] + cycle_jitter) && + (clkin_period[1] - cycle_jitter <= clkin_period[2]) && + (clkin_period[2] <= clkin_period[1] + cycle_jitter)) begin + lock_period <= 1; + period_orig <= (clkin_period[0] + + clkin_period[1] + + clkin_period[2]) / 3; + period <= clkin_period[0]; + end + end + else if (lock_period == 1'b1) begin + if (100000000 < (clkin_period[0] / 1000)) begin + $display(" Warning : CLKIN stopped toggling on instance %m exceeds %d ms. Current CLKIN Period = %1.3f ns.", 100, clkin_period[0] / 1000.0); + lock_period <= 0; + @(negedge rst_reg[2]); + end + else if ((period_orig * 2 < clkin_period[0]) && clock_stopped == 1'b0) begin + clock_stopped <= 1'b1; + end + else if ((clkin_period[0] < period_orig - period_jitter) || + (period_orig + period_jitter < clkin_period[0])) begin + $display(" Warning : Input Clock Period Jitter on instance %m exceeds %1.3f ns. Locked CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", period_jitter / 1000.0, period_orig / 1000.0, clkin_period[0] / 1000.0); + lock_period <= 0; + @(negedge rst_reg[2]); + end + else if ((clkin_period[0] < clkin_period[1] - cycle_jitter) || + (clkin_period[1] + cycle_jitter < clkin_period[0])) begin + $display(" Warning : Input Clock Cycle-Cycle Jitter on instance %m exceeds %1.3f ns. Previous CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", cycle_jitter / 1000.0, clkin_period[1] / 1000.0, clkin_period[0] / 1000.0); + lock_period <= 0; + @(negedge rst_reg[2]); + end + else begin + period <= clkin_period[0]; + clock_stopped <= 1'b0; + end + end +end + + assign #(period/2) lock_period_dly = lock_period; + assign lock_period_pulse = (lock_period==1 && lock_period_dly==0) ? 1 : 0; + +// +// determine clock delay +// + +//always @(posedge lock_period or posedge rst_in) +always @(posedge lock_ps_dly or posedge rst_in) + if (rst_in) begin + fb_delay <= 0; + fb_delay_found <= 0; + end + else begin + if (lock_period && clkfb_type != 2'b00) begin + if (clkfb_type == 2'b01) begin + @(posedge CLK0 or rst_in) + delay_edge = $time; + end + else if (clkfb_type == 2'b10) begin + @(posedge CLK2X or rst_in) + delay_edge = $time; + end + @(posedge clkfb_in or rst_in) begin + fb_delay <= ($time - delay_edge) % period_orig; + fb_delay_found <= 1; + end + end + end + +// +// determine feedback lock +// + +//always @(posedge clkfb_in or posedge rst_in) +always @(posedge clkfb_chk or posedge rst_in) + if (rst_in) + clkfb_window <= 0; + else begin + clkfb_window <= 1; + #cycle_jitter clkfb_window <= 0; + end + +always @(posedge clkin_fb or posedge rst_in) + if (rst_in) + clkin_window <= 0; + else begin + clkin_window <= 1; + #cycle_jitter clkin_window <= 0; + end + +always @(posedge clkin_fb or posedge rst_in) + if (rst_in) + lock_clkin <= 0; + else begin + #1 + if ((clkfb_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1)) + lock_clkin <= 1; + else + if (chk_enable==1) + lock_clkin <= 0; + end + +always @(posedge clkfb_chk or posedge rst_in) + if (rst_in) + lock_clkfb <= 0; + else begin + #1 + if ((clkin_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1)) + lock_clkfb <= 1; + else + if (chk_enable ==1) + lock_clkfb <= 0; + end + +always @(negedge clkin_fb or posedge rst_in) + if (rst_in) + lock_delay <= 0; + else + lock_delay <= lock_clkin || lock_clkfb; + +// +// generate lock signal +// + +always @(posedge clkin_ps or posedge rst_in) + if (rst_in) begin + lock_out <= 2'b0; + locked_out <=0; + end + else begin + if (clkfb_type == 2'b00) + lock_out[0] <= lock_period; + else + lock_out[0] <= lock_period & lock_delay & lock_fb; + lock_out[1] <= lock_out[0]; + locked_out <= lock_out[1]; + end + +always @(negedge clkin_ps or posedge rst_in) + if (rst_in) + lock_out1_neg <= 0; + else + lock_out1_neg <= lock_out[1]; + + +// +// generate the clk1x_out +// + +always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in) + if (rst_in) + clk0_out <= 0; + else + if (clkin_ps ==1) + if (clk1x_type==1 && lock_out[0]) begin + clk0_out <= 1; + #(period / 2) + clk0_out <= 0; + end + else + clk0_out <= 1; + else + if (clkin_ps == 0 && ((clk1x_type && lock_out[0]) == 0 || (lock_out[0]== 1 && lock_out[1]== 0))) + clk0_out <= 0; + +// +// generate the clk2x_out +// + +always @(posedge clkin_ps or posedge rst_in) + if (rst_in) + clk2x_out <= 0; + else begin + clk2x_out <= 1; + #(period / 4) + clk2x_out <= 0; + #(period / 4) + clk2x_out <= 1; + #(period / 4) + clk2x_out <= 0; + end + +// +// generate the clkdv_out +// + +always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in) + if (rst_in) begin + clkdv_out <= 1'b0; + clkdv_cnt <= 0; + end + else + if (lock_out1_neg) begin + if (clkdv_cnt >= divide_type -1) + clkdv_cnt <= 0; + else + clkdv_cnt <= clkdv_cnt + 1; + + if (clkdv_cnt < divide_type /2) + clkdv_out <= 1'b1; + else + if ( (divide_type[0] == 1'b1) && dll_mode_type == 1'b0) + clkdv_out <= #(period/4) 1'b0; + else + clkdv_out <= 1'b0; + end + + +// +// generate fx output signal +// + +always @(lock_period or period or denominator or numerator) begin + if (lock_period == 1'b1) begin + period_fx = (period * denominator) / (numerator * 2); + remain_fx = (period * denominator) % (numerator * 2); + end +end + +always @(posedge clkin_ps or posedge clkin_lost_out or posedge rst_in ) + if (rst_in == 1) + clkfx_out = 1'b0; + else if (clkin_lost_out == 1'b1 ) begin + if (locked_out == 1) + @(negedge rst_reg[2]); + end + else + if (lock_out[1] == 1) begin + clkfx_out = 1'b1; + for (p = 0; p < (numerator * 2 - 1); p = p + 1) begin + #(period_fx); + if (p < remain_fx) + #1; + clkfx_out = !clkfx_out; + end + if (period_fx > (period / 2)) begin + #(period_fx - (period / 2)); + end + end + +// +// generate all output signal +// + +always @(rst_in) +if (rst_in) begin + assign CLK0 = 0; + assign CLK90 = 0; + assign CLK180 = 0; + assign CLK270 = 0; + assign CLK2X = 0; + assign CLK2X180 =0; + assign CLKDV = 0; + assign CLKFX = 0; + assign CLKFX180 = 0; +end +else begin + deassign CLK0; + deassign CLK90; + deassign CLK180; + deassign CLK270; + deassign CLK2X; + deassign CLK2X180; + deassign CLKDV; + deassign CLKFX; + deassign CLKFX180; +end + +always @(clk0_out) begin + CLK0 <= #(clkout_delay) clk0_out && (clkfb_type != 2'b00); + CLK90 <= #(clkout_delay + period / 4) clk0_out && !dll_mode_type && (clkfb_type != 2'b00); + CLK180 <= #(clkout_delay) ~clk0_out && (clkfb_type != 2'b00); + CLK270 <= #(clkout_delay + period / 4) ~clk0_out && !dll_mode_type && (clkfb_type != 2'b00); + end + +always @(clk2x_out) begin + CLK2X <= #(clkout_delay) clk2x_out && !dll_mode_type && (clkfb_type != 2'b00); + CLK2X180 <= #(clkout_delay) ~clk2x_out && !dll_mode_type && (clkfb_type != 2'b00); +end + +always @(clkdv_out) + CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00); + +always @(clkfx_out ) + CLKFX <= #(clkout_delay) clkfx_out; + +always @( clkfx_out or first_time_locked or locked_out) + if ( ~first_time_locked) + CLKFX180 = 0; + else + CLKFX180 <= #(clkout_delay) ~clkfx_out; + + +endmodule + +////////////////////////////////////////////////////// + +module dcm_clock_divide_by_2 (clock, clock_type, clock_out, rst); +input clock; +input clock_type; +input rst; +output clock_out; + +reg clock_out; +reg clock_div2; +reg [2:0] rst_reg; + +wire clk_src; + +initial begin + clock_out = 1'b0; + clock_div2 = 1'b0; +end + +always @(posedge clock) + clock_div2 <= ~clock_div2; + +always @(posedge clock) begin + rst_reg[0] <= rst; + rst_reg[1] <= rst_reg[0] & rst; + rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst; +end + +assign clk_src = (clock_type) ? clock_div2 : clock; + +always @(clk_src or rst or rst_reg) + if (rst == 1'b0) + clock_out = clk_src; + else if (rst == 1'b1) begin + clock_out = 1'b0; + @(negedge rst_reg[2]); + if (clk_src == 1'b1) + @(negedge clk_src); + end + + +endmodule + +module dcm_maximum_period_check (clock); +parameter clock_name = ""; +parameter maximum_period = 0; +input clock; + +time clock_edge; +time clock_period; + +initial begin + clock_edge = 0; + clock_period = 0; +end + +always @(posedge clock) begin + clock_edge <= $time; + clock_period <= $time - clock_edge; + if (clock_period > maximum_period ) begin + $display(" Warning : Input clock period of, %1.3f ns, on the %s port of instance %m exceeds allotted value of %1.3f ns at simulation time %1.3f ns.", clock_period/1000.0, clock_name, maximum_period/1000.0, $time/1000.0); + end +end +endmodule + +module dcm_clock_lost (clock, enable, lost, rst); +input clock; +input enable; +input rst; +output lost; + +time clock_edge; +reg [63:0] period; +reg clock_low, clock_high; +reg clock_posedge, clock_negedge; +reg lost_r, lost_f, lost; +reg clock_second_pos, clock_second_neg; + +initial begin + clock_edge = 0; + clock_high = 0; + clock_low = 0; + lost_r = 0; + lost_f = 0; + period = 0; + clock_posedge = 0; + clock_negedge = 0; + clock_second_pos = 0; + clock_second_neg = 0; +end + +always @(posedge clock or posedge rst) + if (rst==1) + period <= 0; + else begin + clock_edge <= $time; + if (period != 0 && (($time - clock_edge) <= (1.5 * period))) + period <= $time - clock_edge; + else if (period != 0 && (($time - clock_edge) > (1.5 * period))) + period <= 0; + else if ((period == 0) && (clock_edge != 0) && clock_second_pos == 1) + period <= $time - clock_edge; + end + + +always @(posedge clock or posedge rst) + if (rst) + lost_r <= 0; + else + if (enable == 1 && clock_second_pos == 1) begin + #1; + if ( period != 0) + lost_r <= 0; + #((period * 9.1) / 10) + if ((clock_low != 1'b1) && (clock_posedge != 1'b1) && rst == 0) + lost_r <= 1; + end + +always @(posedge clock or negedge clock or posedge rst) + if (rst) begin + clock_second_pos <= 0; + clock_second_neg <= 0; + end + else if (clock) + clock_second_pos <= 1; + else if (~clock) + clock_second_neg <= 1; + +always @(negedge clock or posedge rst) + if (rst==1) begin + lost_f <= 0; + end + else begin + if (enable == 1 && clock_second_neg == 1) begin + if ( period != 0) + lost_f <= 0; + #((period * 9.1) / 10) + if ((clock_high != 1'b1) && (clock_negedge != 1'b1) && rst == 0) + lost_f <= 1; + end + end + +always @( lost_r or lost_f or enable) +begin + if (enable == 1) + lost = lost_r | lost_f; + else + lost = 0; +end + + +always @(posedge clock or negedge clock or posedge rst) + if (rst==1) begin + clock_low <= 1'b0; + clock_high <= 1'b0; + clock_posedge <= 1'b0; + clock_negedge <= 1'b0; + end + else begin + if (clock ==1) begin + clock_low <= 1'b0; + clock_high <= 1'b1; + clock_posedge <= 1'b0; + clock_negedge <= 1'b1; + end + else if (clock == 0) begin + clock_low <= 1'b1; + clock_high <= 1'b0; + clock_posedge <= 1'b1; + clock_negedge <= 1'b0; + end +end + + +endmodule + +`else + + +`timescale 1 ps / 1 ps + +module DCM ( + CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90, + CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS, + CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST); + + parameter real CLKDV_DIVIDE = 2.0; + parameter integer CLKFX_DIVIDE = 1; + parameter integer CLKFX_MULTIPLY = 4; + parameter CLKIN_DIVIDE_BY_2 = "FALSE"; + parameter real CLKIN_PERIOD = 10.0; + parameter CLKOUT_PHASE_SHIFT = "NONE"; + parameter CLK_FEEDBACK = "1X"; + parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; + parameter DFS_FREQUENCY_MODE = "LOW"; + parameter DLL_FREQUENCY_MODE = "LOW"; + parameter DSS_MODE = "NONE"; + parameter DUTY_CYCLE_CORRECTION = "TRUE"; + parameter [15:0] FACTORY_JF = 16'hC080; + parameter integer PHASE_SHIFT = 0; + parameter STARTUP_WAIT = "FALSE"; + + input CLKFB, CLKIN, DSSEN; + input PSCLK, PSEN, PSINCDEC, RST; + + output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90; + output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE; + output [7:0] STATUS; + + + reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90; + reg CLKDV, CLKFX, CLKFX180; + reg LOCKED_out, PSDONE = 0; + reg [7:0] STATUS = 8'b0; + wire LOCKED; + + reg [1:0] clkfb_type, ps_type; + reg clkin_type, align, clkin_divide, fbsync = 0; + reg [2:0] pos_shift, neg_shift; + reg [2:0] pos_shift_st, neg_shift_st; + reg [3:0] deskew_adjust_mode; +// reg [8:0] shift = 9'b0; + reg [1:0] clkin_cnt, old_clkin_cnt; + reg clkin_error; + reg period_updated; + reg clkin_cnt_en; + reg rst_tmp, rst_done_fx, rst_done_dv; + + integer shift; + + realtime clk_period; // = (250*CLKIN_PERIOD); + realtime clkfx_period; // = ((CLKIN_PERIOD*CLKFX_DIVIDE*1000)/(CLKFX_MULTIPLY*2)); + realtime shift_ammount; // = ((CLKIN_PERIOD*1000)/256); + realtime clkdv_period; // = ((CLKIN_PERIOD*CLKDV_DIVIDE*1000)/2); + realtime clkin_time1, clkin_time2, period_clkin; + + time start_time, delay_time; + + + initial begin + + case (CLKIN_DIVIDE_BY_2) + "false" : clkin_type <= 0; + "FALSE" : clkin_type <= 0; + "true" : clkin_type <= 1; + "TRUE" : clkin_type <= 1; + default : begin + $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2); + $finish; + end + endcase + + case (CLKDV_DIVIDE) + 1.5 : ; + 2.0 : ; + 2.5 : ; + 3.0 : ; + 3.5 : ; + 4.0 : ; + 4.5 : ; + 5.0 : ; + 5.5 : ; + 6.0 : ; + 6.5 : ; + 7.0 : ; + 7.5 : ; + 8.0 : ; + 9.0 : ; + 10.0 : ; + 11.0 : ; + 12.0 : ; + 13.0 : ; + 14.0 : ; + 15.0 : ; + 16.0 : ; + default : begin + $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM instance %m is set to %0.1f. Legal values for this attribute are 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, or 16.0.", CLKDV_DIVIDE); + $finish; + end + endcase + + if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin + $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE); + $finish; + end + + if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin + $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY); + $finish; + end + + case (CLKIN_DIVIDE_BY_2) + "false" : clkin_divide <= 0; + "FALSE" : clkin_divide <= 0; + "true" : clkin_divide <= 1; + "TRUE" : clkin_divide <= 1; + default : begin + $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2); + $finish; + end + endcase + + case (CLKOUT_PHASE_SHIFT) + "NONE" : ps_type <= 0; + "none" : ps_type <= 0; + "FIXED" : ps_type <= 1; + "fixed" : ps_type <= 1; + "VARIABLE" : ps_type <= 2; + "variable" : ps_type <= 2; + default : begin + $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT); + $finish; + end + endcase + + case (CLK_FEEDBACK) + "none" : clkfb_type <= 0; + "NONE" : clkfb_type <= 0; + "1x" : clkfb_type <= 1; + "1X" : clkfb_type <= 1; + "2x" : clkfb_type <= 2; + "2X" : clkfb_type <= 2; + default : begin + $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK); + $finish; + end + endcase + + case (DESKEW_ADJUST) + "source_synchronous" : deskew_adjust_mode <= 8; + "SOURCE_SYNCHRONOUS" : deskew_adjust_mode <= 8; + "system_synchronous" : deskew_adjust_mode <= 11; + "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode <= 11; + "0" : deskew_adjust_mode <= 0; + "1" : deskew_adjust_mode <= 1; + "2" : deskew_adjust_mode <= 2; + "3" : deskew_adjust_mode <= 3; + "4" : deskew_adjust_mode <= 4; + "5" : deskew_adjust_mode <= 5; + "6" : deskew_adjust_mode <= 6; + "7" : deskew_adjust_mode <= 7; + "8" : deskew_adjust_mode <= 8; + "9" : deskew_adjust_mode <= 9; + "10" : deskew_adjust_mode <= 10; + "11" : deskew_adjust_mode <= 11; + "12" : deskew_adjust_mode <= 12; + "13" : deskew_adjust_mode <= 13; + "14" : deskew_adjust_mode <= 14; + "15" : deskew_adjust_mode <= 15; + default : begin + $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST); + $finish; + end + endcase + + case (DFS_FREQUENCY_MODE) + "high" : ; + "HIGH" : ; + "low" : ; + "LOW" : ; + default : begin + $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE); + $finish; + end + endcase + + case (DLL_FREQUENCY_MODE) + "high" : ; + "HIGH" : ; + "low" : ; + "LOW" : ; + default : begin + $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE); + $finish; + end + endcase + + case (DSS_MODE) + "none" : ; + "NONE" : ; + default : begin + $display("Attribute Syntax Error : The attribute DSS_MODE on DCM instance %m is set to %s. The legal value for this attribute is NONE.", DSS_MODE); + $finish; + end + endcase + + case (DUTY_CYCLE_CORRECTION) + "false" : begin + $display("Unsupported Attribute Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s which is not supported in this simulation model. The legal value of DUTY_CYCLE_CORRECTION for this model is TRUE.", DUTY_CYCLE_CORRECTION); + $finish; + end + "FALSE" : begin + $display("Unsupported Attribute Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s which is not supported in this simulation model. The legal value of DUTY_CYCLE_CORRECTION for this model is TRUE.", DUTY_CYCLE_CORRECTION); + $finish; + end + "true" : ; + "TRUE" : ; + default : begin + $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION); + $finish; + end + endcase + + if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin + $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT); + $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT); + $finish; + end + + case (STARTUP_WAIT) + "false" : ; + "FALSE" : ; + "true" : ; + "TRUE" : ; + default : begin + $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT); + $finish; + end + endcase + + +// if (CLKIN_PERIOD == 0.0) begin +// $display("Attribute Syntax Error : The attribute CLKIN_PERIOD on DCM instance %m must be defined to the value of the input clock period in nano-seconds"); +// $finish; +// end +end + +// always @(posedge RST) begin +// disable main_dcm; +// disable clkdv_dcm; +// disable clkfx_dcm; +// end + + integer t; + + + assign #100 LOCKED = LOCKED_out; + + always begin: feedback_dcm + fbsync = 0; + wait (RST==0); + wait (period_updated==1) + @(posedge CLKFB); + delay_time = $time - start_time; + @(posedge CLKIN); + #(((12*clk_period)-(delay_time))); + fbsync = 1; + wait (RST==1); + end + + always begin: main_dcm + pos_shift[0] = 1'b0; + neg_shift[0] = 1'b0; + align = 0; + LOCKED_out = 1'b0; + period_updated = 0; + clkin_cnt_en = 0; + CLK0 = 1'b0; + CLK90 = 1'b0; + CLK180 = 1'b0; + CLK270 = 1'b0; + CLK2X = 1'b0; + CLK2X180 = 1'b0; + rst_tmp <= 1'b1; + wait (RST==0); + wait (rst_done_fx==1 ); + wait (rst_done_dv==1); + rst_tmp <= 1'b0; + @(posedge CLKIN); + clkin_time1 = $time; + @(posedge CLKIN); + clkin_time2 = $time; + period_clkin = clkin_time2 - clkin_time1; + + clk_period = (0.25*period_clkin); + clkfx_period = ((period_clkin*CLKFX_DIVIDE)/(CLKFX_MULTIPLY*2)); + shift_ammount = ((period_clkin)/256); + clkdv_period = ((period_clkin*CLKDV_DIVIDE)/2); + + @(posedge CLKIN); + period_updated = 1; + start_time = $time; + repeat (6) begin + CLK0 = ~CLK0; + CLK2X = ~CLK2X; + #(clk_period); + CLK2X = ~CLK2X; + #(clk_period); + end + repeat (6) begin + CLK0 = ~CLK0; + CLK2X = ~CLK2X; + #(clk_period); + CLK2X = ~CLK2X; + #(clk_period); + end + if (clkfb_type != 0) + wait(fbsync==1); + if (ps_type != 0) + if (PHASE_SHIFT > 0) + #((period_clkin*PHASE_SHIFT)/256); + else if (PHASE_SHIFT < 0) + #((period_clkin)-((period_clkin*PHASE_SHIFT)/256)); + align = 1; + CLK0 = ~CLK0; + CLK2X = ~CLK2X; + #(clk_period); + CLK90 = ~CLK90; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + #(clk_period); + repeat (7) begin + CLK0 = ~CLK0; + CLK180 = ~CLK180; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + #(clk_period); + CLK90 = ~CLK90; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + CLK270 = ~CLK270; + #(clk_period); + end + LOCKED_out = 1'b1; + clkin_cnt_en = 1'b1; +// forever begin + while (RST==0) begin + CLK0 = ~CLK0; + CLK180 = ~CLK180; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + #(clk_period); + CLK90 = ~CLK90; + CLK270 = ~CLK270; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + #(clk_period); + CLK0 = ~CLK0; + CLK180 = ~CLK180; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + #(clk_period); + CLK90 = ~CLK90; + CLK270 = ~CLK270; + CLK2X = ~CLK2X; + CLK2X180 = ~CLK2X180; + if (pos_shift_st[0]==1'b1 && pos_shift[0]==1'b0) begin + #((clk_period)+shift_ammount); +// pos_shift[0] <= 1; + pos_shift[0] = 1; + end + else if (neg_shift_st[0]==1'b1 && neg_shift[0]==1'b0) begin + #((clk_period)-shift_ammount); +// neg_shift[0] <= 1; + neg_shift[0] = 1; + end + else begin + if (pos_shift_st[0] == 1'b0) +// pos_shift[0] <= 0; + pos_shift[0] = 0; + if (neg_shift_st[0] == 1'b0) +// neg_shift[0] <= 0; + neg_shift[0] = 0; + #(clk_period); + end + if (clkin_error) + wait (0); + end + end + + always begin: clkfx_dcm + pos_shift[1]=1'b0; + neg_shift[1]=1'b0; + CLKFX = 1'b0; + CLKFX180 = 1'b0; + rst_done_fx <= 1'b1; +// wait (RST==0); + wait (rst_tmp==0 && RST==0); + wait (LOCKED_out==1); + rst_done_fx <= 1'b0; + CLKFX = 1; + CLKFX180 = 0; +// forever begin + while (RST== 0 && rst_tmp==0) begin + #(clkfx_period); + CLKFX = ~CLKFX; + CLKFX180 = ~CLKFX180; + if (pos_shift_st[1]==1'b1 && pos_shift[1]==1'b0) begin + #((clkfx_period)+shift_ammount); + pos_shift[1] <= 1; + end + else if (neg_shift_st[1]==1'b1 && neg_shift[1]==1'b0) begin + #((clkfx_period)-shift_ammount); + neg_shift[1] <= 1; + end + else begin + if (pos_shift_st[1] == 1'b0) + pos_shift[1] <= 0; + if (neg_shift_st[1] == 1'b0) + neg_shift[1] <= 0; + #(clkfx_period); + end + CLKFX = ~CLKFX; + CLKFX180 = ~CLKFX180; + if (clkin_error) + wait(0); + end + end + + always begin: clkdv_dcm + pos_shift[2] = 0; + neg_shift[2] = 0; + CLKDV = 1'b0; + rst_done_dv <= 1'b1; +// wait (RST==0); + wait (rst_tmp==0 && RST==0); + wait (LOCKED_out==1); + rst_done_dv <= 1'b0; + CLKDV = ~CLKDV; +// forever begin + while (RST==0 && rst_tmp==0) begin + if (pos_shift_st[2]==1'b1 && pos_shift[2]==1'b0) begin + #(clkdv_period+shift_ammount); + pos_shift[2] = 1; + end + else if (neg_shift_st[2]==1'b1 && neg_shift[2]==1'b0) begin + #(clkdv_period-shift_ammount); + neg_shift[2] = 1; + end + else begin + if (pos_shift_st[2] == 1'b0) + pos_shift[2] <= 0; + if (neg_shift_st[2] == 1'b0) + neg_shift[2] <= 0; + #(clkdv_period); + end + CLKDV = ~CLKDV; + if (clkin_error) + wait(0); + end + end + + initial shift = 0; + + always @(posedge PSCLK) begin: dps_dcm + PSDONE <= 1'b0; + if (ps_type==2) begin + if (PSEN) begin + if (pos_shift != 3'b000 || neg_shift != 3'b000) + $display("Warning : Please wait for PSDONE signal before adjusting the Phase Shift. %m at time %t. ", $time); + else begin + if (PSINCDEC==1'b1 && pos_shift==3'b000) begin + pos_shift_st <= 3'b111; + shift = shift + 1; + if (shift > 256) + STATUS[0] <= 1; + else + STATUS[0] <= 0; + end + else if (PSINCDEC==1'b0 && neg_shift==3'b000) begin + neg_shift_st <= 3'b111; + shift = shift - 1; + if (shift < -256) + STATUS[0] <= 1; + else + STATUS[0] <= 0; + end + end + end + if (pos_shift==3'b111) begin + pos_shift_st <= 3'b000; + PSDONE <= 1'b1; + end + if (neg_shift==3'b111) begin + neg_shift_st <= 3'b000; + PSDONE <= 1'b1; + end + end + end // block: dps_dcm + + + always @(posedge CLKIN) + if (RST) begin + clkin_cnt <= 2'b00; + end + else begin + if (clkin_cnt_en ==1) + clkin_cnt <= clkin_cnt + 1; + end + + always @(posedge CLK0 or posedge RST) begin : status_dcm + if (RST) begin + old_clkin_cnt <= 0; + clkin_error <= 1'b0; + end + else + if (clkin_cnt_en== 1'b1) begin + #1 clkin_error <= 1'b0; + @(posedge CLK0); + if (clkin_cnt == old_clkin_cnt) begin +// $display("Error: This DCM simulation for %m does not support the stopping of CLKIN or the use of frequecies to other than that specified for the CLKIN_PERIOD, %f.\nPlease use the standard DCM model to properly view this behavior.\nAll DCM outputs will be suspended until the DCM is reset.",CLKIN_PERIOD); + $display("Error: This DCM simulation for %m does not support the stopping of CLKIN.\nPlease use the standard DCM model to properly view this behavior.\nAll DCM outputs will be suspended until the DCM is reset."); + clkin_error <= 1; + wait (RST==1); + end + else + old_clkin_cnt <= clkin_cnt; + end + end + + +endmodule + +`endif diff --git a/lm32/logic/sakc/sim/unisims/DCM_SP.v b/lm32/logic/sakc/sim/unisims/DCM_SP.v new file mode 100644 index 0000000..2142fa7 --- /dev/null +++ b/lm32/logic/sakc/sim/unisims/DCM_SP.v @@ -0,0 +1,1244 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/DCM_SP.v,v 1.9.4.3 2007/04/11 20:30:19 yanx Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2004 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 9.2i (J.36) +// \ \ Description : Xilinx Function Simulation Library Component +// / / Digital Clock Manager +// /___/ /\ Filename : DCM_SP.v +// \ \ / \ Timestamp : +// \___\/\___\ +// +// Revision: +// 02/28/06 - Initial version. +// 05/09/06 - Add clkin_ps_mkup and clkin_ps_mkup_win for phase shifting (CR 229789). +// 06/14/06 - Add clkin_ps_mkup_flag for multiple cycle delays (CR233283). +// 07/21/06 - Change range of variable phase shifting to +/- integer of 20*(Period-3ns). +// Give warning not support initial phase shifting for variable phase shifting. +// (CR 235216). +// 09/22/06 - Add lock_period and lock_fb to clkfb_div block (CR 418722). +// 12/19/06 - Add clkfb_div_en for clkfb2x divider (CR431210). +// 04/06/07 - Enable the clock out in clock low time after reset in model +// clock_divide_by_2 (CR 437471). +// End Revision + + +`timescale 1 ps / 1 ps + +module DCM_SP ( + CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90, + CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS, + CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST); + +parameter CLKDV_DIVIDE = 2.0; +parameter integer CLKFX_DIVIDE = 1; +parameter integer CLKFX_MULTIPLY = 4; +parameter CLKIN_DIVIDE_BY_2 = "FALSE"; +parameter CLKIN_PERIOD = 10.0; // non-simulatable +parameter CLKOUT_PHASE_SHIFT = "NONE"; +parameter CLK_FEEDBACK = "1X"; +parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; // non-simulatable +parameter DFS_FREQUENCY_MODE = "LOW"; +parameter DLL_FREQUENCY_MODE = "LOW"; +parameter DSS_MODE = "NONE"; // non-simulatable +parameter DUTY_CYCLE_CORRECTION = "TRUE"; +parameter FACTORY_JF = 16'hC080; // non-simulatable +parameter integer MAXPERCLKIN = 1000000; // non-modifiable simulation parameter +parameter integer MAXPERPSCLK = 100000000; // non-modifiable simulation parameter +parameter integer PHASE_SHIFT = 0; +parameter integer SIM_CLKIN_CYCLE_JITTER = 300; // non-modifiable simulation parameter +parameter integer SIM_CLKIN_PERIOD_JITTER = 1000; // non-modifiable simulation parameter +parameter STARTUP_WAIT = "FALSE"; // non-simulatable + + +localparam PS_STEP = 25; + +input CLKFB, CLKIN, DSSEN; +input PSCLK, PSEN, PSINCDEC, RST; + +output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90; +output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE; +output [7:0] STATUS; + +reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90; +reg CLKDV, CLKFX, CLKFX180; + +wire locked_out_out; +wire clkfb_in, clkin_in, dssen_in; +wire psclk_in, psen_in, psincdec_in, rst_in; +reg clk0_out; +reg clk2x_out, clkdv_out; +reg clkfx_out, clkfx180_en; +reg rst_flag; +reg locked_out, psdone_out, ps_overflow_out, ps_lock; +reg clkfb_div, clkfb_chk, clkfb_div_en; +integer clkdv_cnt; + +reg [1:0] clkfb_type; +reg [8:0] divide_type; +reg clkin_type; +reg [1:0] ps_type; +reg [3:0] deskew_adjust_mode; +reg dfs_mode_type; +reg dll_mode_type; +reg clk1x_type; +integer ps_in; + +reg lock_period, lock_delay, lock_clkin, lock_clkfb; +reg first_time_locked; +reg en_status; +reg ps_overflow_out_ext; +reg clkin_lost_out_ext; +reg clkfx_lost_out_ext; +reg [1:0] lock_out; +reg lock_out1_neg; +reg lock_fb, lock_ps, lock_ps_dly, lock_fb_dly, lock_fb_dly_tmp; +reg fb_delay_found; +reg clock_stopped; +reg clkin_chkin, clkfb_chkin; + +wire chk_enable, chk_rst; +wire clkin_div; +wire lock_period_pulse; +wire lock_period_dly, lock_period_dly1; + +reg clkin_ps, clkin_ps_tmp, clkin_ps_mkup, clkin_ps_mkup_win, clkin_ps_mkup_flag; +reg clkin_fb; + +time FINE_SHIFT_RANGE; +//time ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range; +integer ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range; +integer ps_delay_last; +integer ps_acc; +time clkin_edge; +time clkin_div_edge; +time clkin_ps_edge; +time delay_edge; +time clkin_period [2:0]; +time period; +integer period_int, period_int2, period_int3, period_ps_tmp; +time period_div; +integer period_orig_int; +time period_orig; +time period_ps; +time clkout_delay; +time fb_delay; +time period_fx, remain_fx; +time period_dv_high, period_dv_low; +time cycle_jitter, period_jitter; + +reg clkin_window, clkfb_window; +reg [2:0] rst_reg; +reg [12:0] numerator, denominator, gcd; +reg [23:0] i, n, d, p; + +reg notifier; + +initial begin + #1; + if ($realtime == 0) begin + $display ("Simulator Resolution Error : Simulator resolution is set to a value greater than 1 ps."); + $display ("In order to simulate the DCM_SP, the simulator resolution must be set to 1ps or smaller."); + $finish; + end +end + +initial begin + case (2.0) + 1.5 : divide_type = 'd3; + 2.0 : divide_type = 'd4; + 2.5 : divide_type = 'd5; + 3.0 : divide_type = 'd6; + 3.5 : divide_type = 'd7; + 4.0 : divide_type = 'd8; + 4.5 : divide_type = 'd9; + 5.0 : divide_type = 'd10; + 5.5 : divide_type = 'd11; + 6.0 : divide_type = 'd12; + 6.5 : divide_type = 'd13; + 7.0 : divide_type = 'd14; + 7.5 : divide_type = 'd15; + 8.0 : divide_type = 'd16; + 9.0 : divide_type = 'd18; + 10.0 : divide_type = 'd20; + 11.0 : divide_type = 'd22; + 12.0 : divide_type = 'd24; + 13.0 : divide_type = 'd26; + 14.0 : divide_type = 'd28; + 15.0 : divide_type = 'd30; + 16.0 : divide_type = 'd32; + default : begin + $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM_SP instance %m is set to %0.1f. Legal values for this attribute are 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, or 16.0.", CLKDV_DIVIDE); + $finish; + end + endcase + + if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin + $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM_SP instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE); + $finish; + end + + if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin + $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM_SP instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY); + $finish; + end + + case (CLKIN_DIVIDE_BY_2) + "false" : clkin_type = 0; + "FALSE" : clkin_type = 0; + "true" : clkin_type = 1; + "TRUE" : clkin_type = 1; + default : begin + $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2); + $finish; + end + endcase + + case (CLKOUT_PHASE_SHIFT) + "NONE" : begin + ps_in = 256; + ps_type = 0; + end + "none" : begin + ps_in = 256; + ps_type = 0; + end + "FIXED" : begin + ps_in = PHASE_SHIFT + 256; + ps_type = 1; + end + "fixed" : begin + ps_in = PHASE_SHIFT + 256; + ps_type = 1; + end + "VARIABLE" : begin + ps_in = PHASE_SHIFT + 256; + ps_type = 2; + end + "variable" : begin + ps_in = PHASE_SHIFT + 256; + ps_type = 2; + if (PHASE_SHIFT != 0) + $display("Attribute Syntax Warning : The attribute PHASE_SHIFT on DCM_SP instance %m is set to %d. The maximum variable phase shift range is only valid when initial phase shift PHASE_SHIFT is zero.", PHASE_SHIFT); + end + default : begin + $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM_SP instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT); + $finish; + end + endcase + + + case (CLK_FEEDBACK) + "none" : clkfb_type = 2'b00; + "NONE" : clkfb_type = 2'b00; + "1x" : clkfb_type = 2'b01; + "1X" : clkfb_type = 2'b01; + "2x" : clkfb_type = 2'b10; + "2X" : clkfb_type = 2'b10; + default : begin + $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM_SP instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK); + $finish; + end + endcase + + case (DESKEW_ADJUST) + "source_synchronous" : deskew_adjust_mode = 8; + "SOURCE_SYNCHRONOUS" : deskew_adjust_mode = 8; + "system_synchronous" : deskew_adjust_mode = 11; + "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode = 11; + "0" : deskew_adjust_mode = 0; + "1" : deskew_adjust_mode = 1; + "2" : deskew_adjust_mode = 2; + "3" : deskew_adjust_mode = 3; + "4" : deskew_adjust_mode = 4; + "5" : deskew_adjust_mode = 5; + "6" : deskew_adjust_mode = 6; + "7" : deskew_adjust_mode = 7; + "8" : deskew_adjust_mode = 8; + "9" : deskew_adjust_mode = 9; + "10" : deskew_adjust_mode = 10; + "11" : deskew_adjust_mode = 11; + "12" : deskew_adjust_mode = 12; + "13" : deskew_adjust_mode = 13; + "14" : deskew_adjust_mode = 14; + "15" : deskew_adjust_mode = 15; + default : begin + $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM_SP instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST); + $finish; + end + endcase + + case (DFS_FREQUENCY_MODE) + "high" : dfs_mode_type = 1; + "HIGH" : dfs_mode_type = 1; + "low" : dfs_mode_type = 0; + "LOW" : dfs_mode_type = 0; + default : begin + $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE); + $finish; + end + endcase + + period_jitter = SIM_CLKIN_PERIOD_JITTER; + cycle_jitter = SIM_CLKIN_CYCLE_JITTER; + + case (DLL_FREQUENCY_MODE) + "high" : dll_mode_type = 1; + "HIGH" : dll_mode_type = 1; + "low" : dll_mode_type = 0; + "LOW" : dll_mode_type = 0; + default : begin + $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE); + $finish; + end + endcase + + if ((dll_mode_type ==1) && (clkfb_type == 2'b10)) begin + $display("Attribute Syntax Error : The attributes DLL_FREQUENCY_MODE on DCM_SP instance %m is set to %s and CLK_FEEDBACK is set to %s. CLK_FEEDBACK 2X is not supported when DLL_FREQUENCY_MODE is HIGH.", DLL_FREQUENCY_MODE, CLK_FEEDBACK); + $finish; + end + + case (DSS_MODE) + "none" : ; + "NONE" : ; + default : begin + $display("Attribute Syntax Error : The attribute DSS_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute is NONE.", DSS_MODE); + $finish; + end + endcase + + case (DUTY_CYCLE_CORRECTION) + "false" : clk1x_type = 0; + "FALSE" : clk1x_type = 0; + "true" : clk1x_type = 1; + "TRUE" : clk1x_type = 1; + default : begin + $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION); + $finish; + end + endcase + + if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin + $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM_SP instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT); + $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT); + $finish; + end + + case (STARTUP_WAIT) + "false" : ; + "FALSE" : ; + "true" : ; + "TRUE" : ; + default : begin + $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT); + $finish; + end + endcase +end + +// +// fx parameters +// + +initial begin + gcd = 1; + for (i = 2; i <= CLKFX_MULTIPLY; i = i + 1) begin + if (((CLKFX_MULTIPLY % i) == 0) && ((CLKFX_DIVIDE % i) == 0)) + gcd = i; + end + numerator = CLKFX_MULTIPLY / gcd; + denominator = CLKFX_DIVIDE / gcd; +end + +// +// input wire delays +// + +buf b_clkin (clkin_in, CLKIN); +buf b_clkfb (clkfb_in, CLKFB); +buf b_dssen (dssen_in, DSSEN); +buf b_psclk (psclk_in, PSCLK); +buf b_psen (psen_in, PSEN); +buf b_psincdec (psincdec_in, PSINCDEC); +buf b_rst (rst_in, RST); +buf #100 b_LOCKED (LOCKED, locked_out_out); +buf #100 b_PSDONE (PSDONE, psdone_out); +buf b_ps_overflow (STATUS[0], ps_overflow_out_ext); +buf b_clkin_lost (STATUS[1], clkin_lost_out_ext); +buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext); + +assign STATUS[7:3] = 5'b0; + +dcm_sp_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in); + +dcm_sp_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in, rst_in); +dcm_sp_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in, rst_in); + +dcm_sp_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in); +dcm_sp_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in); + +always @(rst_in or en_status or clkfx_lost_out or clkin_lost_out or ps_overflow_out) + if (rst_in == 1 || en_status == 0) begin + ps_overflow_out_ext = 0; + clkin_lost_out_ext = 0; + clkfx_lost_out_ext = 0; + end + else + begin + ps_overflow_out_ext = ps_overflow_out; + clkin_lost_out_ext = clkin_lost_out; + clkfx_lost_out_ext = clkfx_lost_out; + end + +always @(posedge rst_in or posedge LOCKED) + if (rst_in == 1) + en_status <= 0; + else + en_status <= 1; + + +always @(clkin_div) + clkin_ps_tmp <= #(ps_delay_md) clkin_div; + +always @(clkin_ps_tmp or clkin_ps_mkup or clkin_ps_mkup_win) + if (clkin_ps_mkup_win) + clkin_ps = clkin_ps_mkup; + else + clkin_ps = clkin_ps_tmp; + +always @(ps_delay_last or period_int or ps_delay) begin + period_int2 = 2 * period_int; + period_int3 = 3 * period_int; + if ((ps_delay_last >= period_int && ps_delay < period_int) || + (ps_delay_last >= period_int2 && ps_delay < period_int2) || + (ps_delay_last >= period_int3 && ps_delay < period_int3)) + clkin_ps_mkup_flag = 1; + else + clkin_ps_mkup_flag = 0; +end + +always @(posedge clkin_div or negedge clkin_div) begin + if (ps_type == 2'b10) begin + if ((ps_delay_last > 0 && ps_delay <= 0 ) || clkin_ps_mkup_flag == 1) begin + if (clkin_div) begin + clkin_ps_mkup_win <= 1; + clkin_ps_mkup <= 1; + #1; + @(negedge clkin_div) begin + clkin_ps_mkup_win <= 1; + clkin_ps_mkup <= 0; + end + end + else begin + clkin_ps_mkup_win <= 0; + clkin_ps_mkup <= 0; + #1; + @(posedge clkin_div) begin + clkin_ps_mkup_win <= 1; + clkin_ps_mkup <= 1; + end + @(negedge clkin_div) begin + clkin_ps_mkup_win <= 1; + clkin_ps_mkup <= 0; + end + end + end + else begin + clkin_ps_mkup_win <= 0; + clkin_ps_mkup <= 0; + end + ps_delay_last <= ps_delay; + end +end + +always @(clkin_ps or lock_fb) + clkin_fb = clkin_ps & lock_fb; + +always @(negedge clkfb_in or posedge rst_in) + if (rst_in) + clkfb_div_en <= 0; + else + if (lock_fb_dly && lock_period && lock_fb && ~clkin_ps) + clkfb_div_en <= 1; + +always @(posedge clkfb_in or posedge rst_in) + if (rst_in) + clkfb_div <= 0; + else + if (clkfb_div_en ) + clkfb_div <= ~clkfb_div; + +always @(clkfb_in or clkfb_div ) + if (clkfb_type == 2'b10 ) + clkfb_chk = clkfb_div; + else + clkfb_chk = clkfb_in & lock_fb_dly; + +always @(posedge clkin_fb or posedge chk_rst) + if (chk_rst) + clkin_chkin <= 0; + else + clkin_chkin <= 1; + +always @(posedge clkfb_chk or posedge chk_rst) + if (chk_rst) + clkfb_chkin <= 0; + else + clkfb_chkin <= 1; + + assign chk_rst = (rst_in==1 || clock_stopped==1 ) ? 1 : 0; + assign chk_enable = (clkin_chkin == 1 && clkfb_chkin == 1 && + lock_ps ==1 && lock_fb ==1 && lock_fb_dly == 1) ? 1 : 0; + +always @(posedge clkin_div or posedge rst_in) + if (rst_in) begin + period_div <= 0; + clkin_div_edge <= 0; + end + else + if ( clkin_div ==1 ) begin + clkin_div_edge <= $time; + if (($time - clkin_div_edge) <= (1.5 * period_div)) + period_div <= $time - clkin_div_edge; + else if ((period_div == 0) && (clkin_div_edge != 0)) + period_div <= $time - clkin_div_edge; + end + +always @(posedge clkin_ps or posedge rst_in) + if (rst_in) begin + period_ps <= 0; + clkin_ps_edge <= 0; + end + else + if (clkin_ps == 1 ) begin + clkin_ps_edge <= $time; + if (($time - clkin_ps_edge) <= (1.5 * period_ps)) + period_ps <= $time - clkin_ps_edge; + else if ((period_ps == 0) && (clkin_ps_edge != 0)) + period_ps <= $time - clkin_ps_edge; + end + +always @(posedge clkin_ps) begin + lock_ps <= lock_period; + lock_ps_dly <= lock_ps; + lock_fb <= lock_ps_dly; + lock_fb_dly_tmp <= lock_fb; +end + +always @(negedge clkin_ps or posedge rst_in) + if (rst_in) + lock_fb_dly <= 1'b0; + else + lock_fb_dly <= #(period/4) lock_fb_dly_tmp; + + +always @(period or fb_delay ) + if (fb_delay == 0) + clkout_delay = 0; + else + clkout_delay = period - fb_delay; + +// +// generate master reset signal +// + +always @(posedge clkin_in) begin + rst_reg[0] <= rst_in; + rst_reg[1] <= rst_reg[0] & rst_in; + rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst_in; +end + +reg rst_tmp1, rst_tmp2; +initial +begin +rst_tmp1 = 0; +rst_tmp2 = 0; +rst_flag = 0; +end + +always @(rst_in) +begin + if (rst_in) + rst_flag = 0; + + rst_tmp1 = rst_in; + if (rst_tmp1 == 0 && rst_tmp2 == 1) begin + if ((rst_reg[2] & rst_reg[1] & rst_reg[0]) == 0) begin + rst_flag = 1; + $display("Input Error : RST on instance %m must be asserted for 3 CLKIN clock cycles."); + end + end + rst_tmp2 = rst_tmp1; +end + +initial begin + CLK0 = 0; + CLK180 = 0; + CLK270 = 0; + CLK2X = 0; + CLK2X180 = 0; + CLK90 = 0; + CLKDV = 0; + CLKFX = 0; + CLKFX180 = 0; + clk0_out = 0; + clk2x_out = 0; + clkdv_out = 0; + clkdv_cnt = 0; + clkfb_window = 0; + clkfx_out = 0; + clkfx180_en = 0; + clkin_div_edge = 0; + clkin_period[0] = 0; + clkin_period[1] = 0; + clkin_period[2] = 0; + clkin_edge = 0; + clkin_ps_edge = 0; + clkin_window = 0; + clkout_delay = 0; + clock_stopped = 1; + fb_delay = 0; + fb_delay_found = 0; + lock_clkfb = 0; + lock_clkin = 0; + lock_delay = 0; + lock_fb = 0; + lock_fb_dly = 0; + lock_out = 2'b00; + lock_out1_neg = 0; + lock_period = 0; + lock_ps = 0; + lock_ps_dly = 0; + locked_out = 0; + period = 0; + period_int = 0; + period_int2 = 0; + period_int3 = 0; + period_div = 0; + period_fx = 0; + period_orig = 0; + period_orig_int = 0; + period_ps = 0; + psdone_out = 0; + ps_delay = 0; + ps_delay_md = 0; + ps_delay_init = 0; + ps_acc = 0; + ps_delay_all = 0; + ps_lock = 0; + ps_overflow_out = 0; + ps_overflow_out_ext = 0; + clkin_lost_out_ext = 0; + clkfx_lost_out_ext = 0; + rst_reg = 3'b000; + first_time_locked = 0; + en_status = 0; + clkfb_div = 0; + clkin_chkin = 0; + clkfb_chkin = 0; + clkin_ps_mkup = 0; + clkin_ps_mkup_win = 0; + clkin_ps_mkup_flag = 0; + ps_delay_last = 0; + clkin_ps_tmp = 0; +end + +// RST less than 3 cycles, lock = x + + assign locked_out_out = (rst_flag) ? 1'bx : locked_out; + +// +// detect_first_time_locked +// +always @(posedge locked_out) + if (first_time_locked == 0) + first_time_locked <= 1; + +// +// phase shift parameters +// + +always @(posedge lock_period) + ps_delay_init <= ps_in * period_orig /256; + + +always @(period) begin + period_int = period; + if (clkin_type==1) + period_ps_tmp = 2 * period; + else + period_ps_tmp = period; + + if (period_ps_tmp > 3000) + ps_max_range = 20 * (period_ps_tmp - 3000)/1000; + else + ps_max_range = 0; +end + +always @(ps_delay or rst_in or period_int or lock_period) + if ( rst_in) + ps_delay_md = 0; + else if (lock_period) begin + ps_delay_md = period_int + ps_delay % period_int; + end + +always @(posedge psclk_in or posedge rst_in or posedge lock_period_pulse) + if (rst_in) begin + ps_delay <= 0; + ps_overflow_out <= 0; + ps_acc <= 0; + end + else if (lock_period_pulse) + ps_delay <= ps_delay_init; + else + if (ps_type == 2'b10) + if (psen_in) begin + if (ps_lock == 1) + $display(" Warning : Please wait for PSDONE signal before adjusting the Phase Shift."); + else if (lock_ps) begin + if (psincdec_in == 1) begin + if (ps_acc > ps_max_range) + ps_overflow_out <= 1; + else begin + ps_delay <= ps_delay + PS_STEP; + ps_acc <= ps_acc + 1; + ps_overflow_out <= 0; + end + ps_lock <= 1; + end + else if (psincdec_in == 0) begin + if (ps_acc < -ps_max_range) + ps_overflow_out <= 1; + else begin + ps_delay <= ps_delay - PS_STEP; + ps_acc <= ps_acc - 1; + ps_overflow_out <= 0; + end + ps_lock <= 1; + end + end + end + +always @(posedge ps_lock) begin + @(posedge clkin_ps) + @(posedge psclk_in) + @(posedge psclk_in) + @(posedge psclk_in) + psdone_out <= 1; + @(posedge psclk_in) + psdone_out <= 0; + ps_lock <= 0; +end + +// +// determine clock period +// + +always @(posedge clkin_div or negedge clkin_div or posedge rst_in) + if (rst_in == 1) begin + clkin_period[0] <= 0; + clkin_period[1] <= 0; + clkin_period[2] <= 0; + clkin_edge <= 0; + end + else + if (clkin_div == 1) begin + clkin_edge <= $time; + clkin_period[2] <= clkin_period[1]; + clkin_period[1] <= clkin_period[0]; + if (clkin_edge != 0) + clkin_period[0] <= $time - clkin_edge; + end + else if (clkin_div == 0) + if (lock_period == 1) + if (100000000 < clkin_period[0]/1000) + begin + end + else if ((period_orig * 2 < clkin_period[0]) && (clock_stopped == 0)) begin + clkin_period[0] <= clkin_period[1]; + end + +always @(negedge clkin_div or posedge rst_in) + if (rst_in == 1) begin + lock_period <= 0; + clock_stopped <= 1; + end + else begin + if (lock_period == 1'b0) begin + if ((clkin_period[0] != 0) && + (clkin_period[0] - cycle_jitter <= clkin_period[1]) && + (clkin_period[1] <= clkin_period[0] + cycle_jitter) && + (clkin_period[1] - cycle_jitter <= clkin_period[2]) && + (clkin_period[2] <= clkin_period[1] + cycle_jitter)) begin + lock_period <= 1; + period_orig <= (clkin_period[0] + + clkin_period[1] + + clkin_period[2]) / 3; + period <= clkin_period[0]; + end + end + else if (lock_period == 1'b1) begin + if (100000000 < (clkin_period[0] / 1000)) begin + $display(" Warning : CLKIN stopped toggling on instance %m exceeds %d ms. Current CLKIN Period = %1.3f ns.", 100, clkin_period[0] / 1000.0); + lock_period <= 0; + @(negedge rst_reg[2]); + end + else if ((period_orig * 2 < clkin_period[0]) && clock_stopped == 1'b0) begin + clock_stopped <= 1'b1; + end + else if ((clkin_period[0] < period_orig - period_jitter) || + (period_orig + period_jitter < clkin_period[0])) begin + $display(" Warning : Input Clock Period Jitter on instance %m exceeds %1.3f ns. Locked CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", period_jitter / 1000.0, period_orig / 1000.0, clkin_period[0] / 1000.0); + lock_period <= 0; + @(negedge rst_reg[2]); + end + else if ((clkin_period[0] < clkin_period[1] - cycle_jitter) || + (clkin_period[1] + cycle_jitter < clkin_period[0])) begin + $display(" Warning : Input Clock Cycle-Cycle Jitter on instance %m exceeds %1.3f ns. Previous CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", cycle_jitter / 1000.0, clkin_period[1] / 1000.0, clkin_period[0] / 1000.0); + lock_period <= 0; + @(negedge rst_reg[2]); + end + else begin + period <= clkin_period[0]; + clock_stopped <= 1'b0; + end + end +end + + assign #1 lock_period_dly1 = lock_period; + assign #(period/2) lock_period_dly = lock_period_dly1; + assign lock_period_pulse = (lock_period_dly1==1 && lock_period_dly==0) ? 1 : 0; + +// +// determine clock delay +// + +//always @(posedge lock_period or posedge rst_in) +always @(posedge lock_ps_dly or posedge rst_in) + if (rst_in) begin + fb_delay <= 0; + fb_delay_found <= 0; + end + else begin + if (lock_period && clkfb_type != 2'b00) begin + if (clkfb_type == 2'b01) begin + @(posedge CLK0 or rst_in) + delay_edge = $time; + end + else if (clkfb_type == 2'b10) begin + @(posedge CLK2X or rst_in) + delay_edge = $time; + end + @(posedge clkfb_in or rst_in) begin + fb_delay <= ($time - delay_edge) % period_orig; + fb_delay_found <= 1; + end + end + end + +// +// determine feedback lock +// + +always @(posedge clkfb_chk or posedge rst_in) + if (rst_in) + clkfb_window <= 0; + else begin + clkfb_window <= 1; + #cycle_jitter clkfb_window <= 0; + end + +always @(posedge clkin_fb or posedge rst_in) + if (rst_in) + clkin_window <= 0; + else begin + clkin_window <= 1; + #cycle_jitter clkin_window <= 0; + end + +always @(posedge clkin_fb or posedge rst_in) + if (rst_in) + lock_clkin <= 0; + else begin + #1 + if ((clkfb_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1)) + lock_clkin <= 1; + else + if (chk_enable==1) + lock_clkin <= 0; + end + +always @(posedge clkfb_chk or posedge rst_in) + if (rst_in) + lock_clkfb <= 0; + else begin + #1 + if ((clkin_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1)) + lock_clkfb <= 1; + else + if (chk_enable ==1) + lock_clkfb <= 0; + end + +always @(negedge clkin_fb or posedge rst_in) + if (rst_in) + lock_delay <= 0; + else + lock_delay <= lock_clkin || lock_clkfb; + +// +// generate lock signal +// + +always @(posedge clkin_ps or posedge rst_in) + if (rst_in) begin + lock_out <= 2'b0; + locked_out <=0; + end + else begin + if (clkfb_type == 2'b00) + lock_out[0] <= lock_period; + else + lock_out[0] <= lock_period & lock_delay & lock_fb; + lock_out[1] <= lock_out[0]; + locked_out <= lock_out[1]; + end + +always @(negedge clkin_ps or posedge rst_in) + if (rst_in) + lock_out1_neg <= 0; + else + lock_out1_neg <= lock_out[1]; + + +// +// generate the clk1x_out +// + +always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in) + if (rst_in) + clk0_out <= 0; + else + if (clkin_ps ==1) + if (clk1x_type==1 && lock_out[0]) begin + clk0_out <= 1; + #(period / 2) + clk0_out <= 0; + end + else + clk0_out <= 1; + else + if (clkin_ps == 0 && ((clk1x_type && lock_out[0]) == 0 || (lock_out[0]== 1 && lock_out[1]== 0))) + clk0_out <= 0; + +// +// generate the clk2x_out +// + +always @(posedge clkin_ps or posedge rst_in) + if (rst_in) + clk2x_out <= 0; + else begin + clk2x_out <= 1; + #(period / 4) + clk2x_out <= 0; + #(period / 4) + clk2x_out <= 1; + #(period / 4) + clk2x_out <= 0; + end + +// +// generate the clkdv_out +// + +always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in) + if (rst_in) begin + clkdv_out <= 1'b0; + clkdv_cnt <= 0; + end + else + if (lock_out1_neg) begin + if (clkdv_cnt >= divide_type -1) + clkdv_cnt <= 0; + else + clkdv_cnt <= clkdv_cnt + 1; + + if (clkdv_cnt < divide_type /2) + clkdv_out <= 1'b1; + else + if ( (divide_type[0] == 1'b1) && dll_mode_type == 1'b0) + clkdv_out <= #(period/4) 1'b0; + else + clkdv_out <= 1'b0; + end + + +// +// generate fx output signal +// + +always @(lock_period or period or denominator or numerator) begin + if (lock_period == 1'b1) begin + period_fx = (period * denominator) / (numerator * 2); + remain_fx = (period * denominator) % (numerator * 2); + end +end + +always @(posedge clkin_ps or posedge clkin_lost_out or posedge rst_in ) + if (rst_in == 1) + clkfx_out = 1'b0; + else if (clkin_lost_out == 1'b1 ) begin + if (locked_out == 1) + @(negedge rst_reg[2]); + end + else + if (lock_out[1] == 1) begin + clkfx_out = 1'b1; + for (p = 0; p < (numerator * 2 - 1); p = p + 1) begin + #(period_fx); + if (p < remain_fx) + #1; + clkfx_out = !clkfx_out; + end + if (period_fx > (period / 2)) begin + #(period_fx - (period / 2)); + end + end + +// +// generate all output signal +// + +always @(rst_in) +if (rst_in) begin + assign CLK0 = 0; + assign CLK90 = 0; + assign CLK180 = 0; + assign CLK270 = 0; + assign CLK2X = 0; + assign CLK2X180 =0; + assign CLKDV = 0; + assign CLKFX = 0; + assign CLKFX180 = 0; +end +else begin + deassign CLK0; + deassign CLK90; + deassign CLK180; + deassign CLK270; + deassign CLK2X; + deassign CLK2X180; + deassign CLKDV; + deassign CLKFX; + deassign CLKFX180; +end + +always @(clk0_out) begin + CLK0 <= #(clkout_delay) clk0_out && (clkfb_type != 2'b00); + CLK90 <= #(clkout_delay + period / 4) clk0_out && !dll_mode_type && (clkfb_type != 2'b00); + CLK180 <= #(clkout_delay) ~clk0_out && (clkfb_type != 2'b00); + CLK270 <= #(clkout_delay + period / 4) ~clk0_out && !dll_mode_type && (clkfb_type != 2'b00); + end + +always @(clk2x_out) begin + CLK2X <= #(clkout_delay) clk2x_out && !dll_mode_type && (clkfb_type != 2'b00); + CLK2X180 <= #(clkout_delay) ~clk2x_out && !dll_mode_type && (clkfb_type != 2'b00); +end + +always @(clkdv_out) + CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00); + +always @(clkfx_out ) + CLKFX <= #(clkout_delay) clkfx_out; + +always @( clkfx_out or first_time_locked or locked_out) + if ( ~first_time_locked) + CLKFX180 = 0; + else + CLKFX180 <= #(clkout_delay) ~clkfx_out; + + +endmodule + +////////////////////////////////////////////////////// + +module dcm_sp_clock_divide_by_2 (clock, clock_type, clock_out, rst); +input clock; +input clock_type; +input rst; +output clock_out; + +reg clock_out; +reg clock_div2; +reg [2:0] rst_reg; +wire clk_src; + +initial begin + clock_out = 1'b0; + clock_div2 = 1'b0; +end + +always @(posedge clock) + clock_div2 <= ~clock_div2; + +always @(posedge clock) begin + rst_reg[0] <= rst; + rst_reg[1] <= rst_reg[0] & rst; + rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst; +end + +assign clk_src = (clock_type) ? clock_div2 : clock; + +always @(clk_src or rst or rst_reg) + if (rst == 1'b0) + clock_out = clk_src; + else if (rst == 1'b1) begin + clock_out = 1'b0; + @(negedge rst_reg[2]); + if (clk_src == 1'b1) + @(negedge clk_src); + end + + +endmodule + +module dcm_sp_maximum_period_check (clock, rst); +parameter clock_name = ""; +parameter maximum_period = 0; +input clock; +input rst; + +time clock_edge; +time clock_period; + +initial begin + clock_edge = 0; + clock_period = 0; +end + +always @(posedge clock) begin + clock_edge <= $time; +// clock_period <= $time - clock_edge; + clock_period = $time - clock_edge; + if (clock_period > maximum_period ) begin + if (rst == 0) + $display(" Warning : Input clock period of %1.3f ns, on the %s port of instance %m exceeds allowed value of %1.3f ns at time %1.3f ns.", clock_period/1000.0, clock_name, maximum_period/1000.0, $time/1000.0); + end +end +endmodule + +module dcm_sp_clock_lost (clock, enable, lost, rst); +input clock; +input enable; +input rst; +output lost; + +time clock_edge; +reg [63:0] period; +reg clock_low, clock_high; +reg clock_posedge, clock_negedge; +reg lost_r, lost_f, lost; +reg clock_second_pos, clock_second_neg; + +initial begin + clock_edge = 0; + clock_high = 0; + clock_low = 0; + lost_r = 0; + lost_f = 0; + period = 0; + clock_posedge = 0; + clock_negedge = 0; + clock_second_pos = 0; + clock_second_neg = 0; +end + +always @(posedge clock or posedge rst) + if (rst==1) + period <= 0; + else begin + clock_edge <= $time; + if (period != 0 && (($time - clock_edge) <= (1.5 * period))) + period <= $time - clock_edge; + else if (period != 0 && (($time - clock_edge) > (1.5 * period))) + period <= 0; + else if ((period == 0) && (clock_edge != 0) && clock_second_pos == 1) + period <= $time - clock_edge; + end + + +always @(posedge clock or posedge rst) + if (rst) + lost_r <= 0; + else + if (enable == 1 && clock_second_pos == 1) begin + #1; + if ( period != 0) + lost_r <= 0; + #((period * 9.1) / 10) + if ((clock_low != 1'b1) && (clock_posedge != 1'b1) && rst == 0) + lost_r <= 1; + end + +always @(posedge clock or negedge clock or posedge rst) + if (rst) begin + clock_second_pos <= 0; + clock_second_neg <= 0; + end + else if (clock) + clock_second_pos <= 1; + else if (~clock) + clock_second_neg <= 1; + +always @(negedge clock or posedge rst) + if (rst==1) begin + lost_f <= 0; + end + else begin + if (enable == 1 && clock_second_neg == 1) begin + if ( period != 0) + lost_f <= 0; + #((period * 9.1) / 10) + if ((clock_high != 1'b1) && (clock_negedge != 1'b1) && rst == 0) + lost_f <= 1; + end + end + +always @( lost_r or lost_f or enable) +begin + if (enable == 1) + lost = lost_r | lost_f; + else + lost = 0; +end + + +always @(posedge clock or negedge clock or posedge rst) + if (rst==1) begin + clock_low <= 1'b0; + clock_high <= 1'b0; + clock_posedge <= 1'b0; + clock_negedge <= 1'b0; + end + else begin + if (clock ==1) begin + clock_low <= 1'b0; + clock_high <= 1'b1; + clock_posedge <= 1'b0; + clock_negedge <= 1'b1; + end + else if (clock == 0) begin + clock_low <= 1'b1; + clock_high <= 1'b0; + clock_posedge <= 1'b1; + clock_negedge <= 1'b0; + end +end + + +endmodule diff --git a/lm32/logic/sakc/sim/unisims/FDDRRSE.v b/lm32/logic/sakc/sim/unisims/FDDRRSE.v new file mode 100644 index 0000000..0afa76b --- /dev/null +++ b/lm32/logic/sakc/sim/unisims/FDDRRSE.v @@ -0,0 +1,102 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/FDDRRSE.v,v 1.15.48.1 2007/03/09 18:13:02 patrickp Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2004 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 8.1i (I.27) +// \ \ Description : Xilinx Functional Simulation Library Component +// / / Dual Data Rate D Flip-Flop with Synchronous Reset and Set and Clock Enable +// /___/ /\ Filename : FDDRRSE.v +// \ \ / \ Timestamp : Thu Mar 25 16:42:16 PST 2004 +// \___\/\___\ +// +// Revision: +// 03/23/04 - Initial version. +// 02/04/05 - Rev 0.0.1 Remove input/output bufs; Seperate GSR from clock block. +// 05/06/05 - Remove internal input data strobe and add to the output. (CR207678) +// 10/20/05 - Add set & reset check to main block. (CR219794) +// 10/28/05 - combine strobe block and data block. (CR220298). +// 2/07/06 - Remove set & reset from main block and add specify block (CR225119) +// 2/10/06 - Change Q from reg to wire (CR 225613) +// End Revision + +`timescale 1 ps / 1 ps + + +module FDDRRSE (Q, C0, C1, CE, D0, D1, R, S); + + parameter INIT = 1'h0; + + output Q; + + input C0, C1, CE, D0, D1, R, S; + + wire Q; + reg q_out; + + reg q0_out, q1_out; + reg C0_tmp, C1_tmp; + + initial begin + q_out = INIT; + q0_out = INIT; + q1_out = INIT; + C0_tmp = 0; + C1_tmp = 0; + end + + assign Q = q_out; + + always @(posedge C0) + if (CE == 1 || R == 1 || S == 1) begin + C0_tmp <= 1; + C0_tmp <= #100 0; + end + + always @(posedge C1) + if (CE == 1 || R == 1 || S == 1) begin + C1_tmp <= 1; + C1_tmp <= #100 0; + end + + always @(posedge C0) + if (R) + q0_out <= 0; + else if (S) + q0_out <= 1; + else if (CE) + q0_out <= D0; + + always @(posedge C1) + if (R) + q1_out <= 0; + else if (S) + q1_out <= 1; + else if (CE) + q1_out <= D1; + + always @(posedge C0_tmp or posedge C1_tmp ) + if (C1_tmp) + q_out = q1_out; + else + q_out = q0_out; + + specify + if (R) + (posedge C0 => (Q +: 1'b0)) = (100, 100); + if (!R && S) + (posedge C0 => (Q +: 1'b1)) = (100, 100); + if (!R && !S && CE) + (posedge C0 => (Q +: D0)) = (100, 100); + if (R) + (posedge C1 => (Q +: 1'b0)) = (100, 100); + if (!R && S) + (posedge C1 => (Q +: 1'b1)) = (100, 100); + if (!R && !S && CE) + (posedge C1 => (Q +: D1)) = (100, 100); + endspecify + +endmodule diff --git a/lm32/logic/sakc/system.ucf b/lm32/logic/sakc/system.ucf new file mode 100644 index 0000000..18408c6 --- /dev/null +++ b/lm32/logic/sakc/system.ucf @@ -0,0 +1,40 @@ +# ==== Clock inputs (CLK) ==== +NET "clk" LOC = "P38"; +NET "clk" PERIOD = 20 HIGH 50%; +NET led LOC = "P44"; +NET rst LOC = "P30"; + +# ==== UART ==== +NET "uart_rxd" LOC = "P68"; +NET "uart_txd" LOC = "P67"; + +#ADDRESS BUS +NET "addr<12>" LOC = "P90"; +NET "addr<11>" LOC = "P91"; +NET "addr<10>" LOC = "P85"; +NET "addr<9>" LOC = "P92"; +NET "addr<8>" LOC = "P94"; +NET "addr<7>" LOC = "P95"; +NET "addr<6>" LOC = "P98"; +NET "addr<5>" LOC = "P3"; +NET "addr<4>" LOC = "P2"; +NET "addr<3>" LOC = "P78"; +NET "addr<2>" LOC = "P79"; +NET "addr<1>" LOC = "P83"; +NET "addr<0>" LOC = "P84"; + +#DATA BUS +NET "sram_data<7>" LOC = "P4"; +NET "sram_data<6>" LOC = "P5"; +NET "sram_data<5>" LOC = "P9"; +NET "sram_data<4>" LOC = "P10"; +NET "sram_data<3>" LOC = "P11"; +NET "sram_data<2>" LOC = "P12"; +NET "sram_data<1>" LOC = "P15"; +NET "sram_data<0>" LOC = "P16"; + +#CONTROL BUS + +NET "nwe" LOC = "P88"; +NET "noe" LOC = "P86"; +NET "ncs" LOC = "P69"; diff --git a/lm32/logic/sakc/system.v b/lm32/logic/sakc/system.v new file mode 100644 index 0000000..d0a9ecf --- /dev/null +++ b/lm32/logic/sakc/system.v @@ -0,0 +1,411 @@ +//--------------------------------------------------------------------------- +// LatticeMico32 System On A Chip +// +// Top Level Design for the Xilinx Spartan 3-200 Starter Kit +//--------------------------------------------------------------------------- + +module system +#( + parameter bootram_file = "../firmware/boot0-serial/image.ram", + parameter clk_freq = 50000000, + parameter uart_baud_rate = 57600 +) ( + input clk, + // Debug + output led, + input rst, + // UART + input uart_rxd, + output uart_txd, + // CPU Interface + input [12:0] addr, + input [7:0] sram_data, + input nwe, + input noe, + input ncs +); + +//------------------------------------------------------------------ +// Whishbone Wires +//------------------------------------------------------------------ +wire gnd = 1'b0; +wire [3:0] gnd4 = 4'h0; +wire [31:0] gnd32 = 32'h00000000; + + +wire [31:0] lm32i_adr, + lm32d_adr, + uart0_adr, + timer0_adr, + gpio0_adr, + bram0_adr, + sram0_adr; + + +wire [31:0] lm32i_dat_r, + lm32i_dat_w, + lm32d_dat_r, + lm32d_dat_w, + uart0_dat_r, + uart0_dat_w, + timer0_dat_r, + timer0_dat_w, + gpio0_dat_r, + gpio0_dat_w, + bram0_dat_r, + bram0_dat_w, + sram0_dat_w, + sram0_dat_r; + +wire [3:0] lm32i_sel, + lm32d_sel, + uart0_sel, + timer0_sel, + gpio0_sel, + bram0_sel, + sram0_sel; + +wire lm32i_we, + lm32d_we, + uart0_we, + timer0_we, + gpio0_we, + bram0_we, + sram0_we; + +wire lm32i_cyc, + lm32d_cyc, + uart0_cyc, + timer0_cyc, + gpio0_cyc, + bram0_cyc, + sram0_cyc; + +wire lm32i_stb, + lm32d_stb, + uart0_stb, + timer0_stb, + gpio0_stb, + bram0_stb, + sram0_stb; + +wire lm32i_ack, + lm32d_ack, + uart0_ack, + timer0_ack, + gpio0_ack, + bram0_ack, + sram0_ack; + +wire lm32i_rty, + lm32d_rty; + +wire lm32i_err, + lm32d_err; + +wire lm32i_lock, + lm32d_lock; + +wire [2:0] lm32i_cti, + lm32d_cti; + +wire [1:0] lm32i_bte, + lm32d_bte; + +//--------------------------------------------------------------------------- +// Interrupts +//--------------------------------------------------------------------------- +wire [31:0] intr_n; +wire uart0_intr = 0; +wire [1:0] timer0_intr; +wire gpio0_intr; + +assign intr_n = { 28'hFFFFFFF, ~timer0_intr[1], ~gpio0_intr, ~timer0_intr[0], ~uart0_intr }; + +//--------------------------------------------------------------------------- +// Wishbone Interconnect +//--------------------------------------------------------------------------- +wb_conbus_top #( + .s0_addr_w ( 3 ), + .s0_addr ( 3'h4 ), // sram0 + .s1_addr_w ( 3 ), + .s1_addr ( 3'h5 ), + .s27_addr_w( 15 ), + .s2_addr ( 15'h0000 ), // bram0 + .s3_addr ( 15'h7000 ), // uart0 + .s4_addr ( 15'h7001 ), // timer0 + .s5_addr ( 15'h7002 ), // gpio0 + .s6_addr ( 15'h7003 ), + .s7_addr ( 15'h7004 ) +) conmax0 ( + .clk_i( clk ), + .rst_i( ~rst ), + // Master0 + .m0_dat_i( lm32i_dat_w ), + .m0_dat_o( lm32i_dat_r ), + .m0_adr_i( lm32i_adr ), + .m0_we_i ( lm32i_we ), + .m0_sel_i( lm32i_sel ), + .m0_cyc_i( lm32i_cyc ), + .m0_stb_i( lm32i_stb ), + .m0_ack_o( lm32i_ack ), + .m0_rty_o( lm32i_rty ), + .m0_err_o( lm32i_err ), + // Master1 + .m1_dat_i( lm32d_dat_w ), + .m1_dat_o( lm32d_dat_r ), + .m1_adr_i( lm32d_adr ), + .m1_we_i ( lm32d_we ), + .m1_sel_i( lm32d_sel ), + .m1_cyc_i( lm32d_cyc ), + .m1_stb_i( lm32d_stb ), + .m1_ack_o( lm32d_ack ), + .m1_rty_o( lm32d_rty ), + .m1_err_o( lm32d_err ), + // Master2 + .m2_dat_i( gnd32 ), + .m2_adr_i( gnd32 ), + .m2_sel_i( gnd4 ), + .m2_cyc_i( gnd ), + .m2_stb_i( gnd ), + // Master3 + .m3_dat_i( gnd32 ), + .m3_adr_i( gnd32 ), + .m3_sel_i( gnd4 ), + .m3_cyc_i( gnd ), + .m3_stb_i( gnd ), + // Master4 + .m4_dat_i( gnd32 ), + .m4_adr_i( gnd32 ), + .m4_sel_i( gnd4 ), + .m4_cyc_i( gnd ), + .m4_stb_i( gnd ), + // Master5 + .m5_dat_i( gnd32 ), + .m5_adr_i( gnd32 ), + .m5_sel_i( gnd4 ), + .m5_cyc_i( gnd ), + .m5_stb_i( gnd ), + // Master6 + .m6_dat_i( gnd32 ), + .m6_adr_i( gnd32 ), + .m6_sel_i( gnd4 ), + .m6_cyc_i( gnd ), + .m6_stb_i( gnd ), + // Master7 + .m7_dat_i( gnd32 ), + .m7_adr_i( gnd32 ), + .m7_sel_i( gnd4 ), + .m7_cyc_i( gnd ), + .m7_stb_i( gnd ), + + // Slave0 + .s0_dat_i( sram0_dat_r ), + .s0_dat_o( sram0_dat_w ), + .s0_adr_o( sram0_adr ), + .s0_sel_o( sram0_sel ), + .s0_we_o( sram0_we ), + .s0_cyc_o( sram0_cyc ), + .s0_stb_o( sram0_stb ), + .s0_ack_i( sram0_ack ), + .s0_err_i( gnd ), + .s0_rty_i( gnd ), + // Slave1 + .s1_dat_i( gnd32 ), + .s1_ack_i( gnd ), + .s1_err_i( gnd ), + .s1_rty_i( gnd ), + // Slave2 + .s2_dat_i( bram0_dat_r ), + .s2_dat_o( bram0_dat_w ), + .s2_adr_o( bram0_adr ), + .s2_sel_o( bram0_sel ), + .s2_we_o( bram0_we ), + .s2_cyc_o( bram0_cyc ), + .s2_stb_o( bram0_stb ), + .s2_ack_i( bram0_ack ), + .s2_err_i( gnd ), + .s2_rty_i( gnd ), + // Slave3 + .s3_dat_i( uart0_dat_r ), + .s3_dat_o( uart0_dat_w ), + .s3_adr_o( uart0_adr ), + .s3_sel_o( uart0_sel ), + .s3_we_o( uart0_we ), + .s3_cyc_o( uart0_cyc ), + .s3_stb_o( uart0_stb ), + .s3_ack_i( uart0_ack ), + .s3_err_i( gnd ), + .s3_rty_i( gnd ), + // Slave4 + .s4_dat_i( timer0_dat_r ), + .s4_dat_o( timer0_dat_w ), + .s4_adr_o( timer0_adr ), + .s4_sel_o( timer0_sel ), + .s4_we_o( timer0_we ), + .s4_cyc_o( timer0_cyc ), + .s4_stb_o( timer0_stb ), + .s4_ack_i( timer0_ack ), + .s4_err_i( gnd ), + .s4_rty_i( gnd ), + // Slave5 + .s5_dat_i( gpio0_dat_r ), + .s5_dat_o( gpio0_dat_w ), + .s5_adr_o( gpio0_adr ), + .s5_sel_o( gpio0_sel ), + .s5_we_o( gpio0_we ), + .s5_cyc_o( gpio0_cyc ), + .s5_stb_o( gpio0_stb ), + .s5_ack_i( gpio0_ack ), + .s5_err_i( gnd ), + .s5_rty_i( gnd ), + // Slave6 + .s6_dat_i( gnd32 ), + .s6_ack_i( gnd ), + .s6_err_i( gnd ), + .s6_rty_i( gnd ), + // Slave7 + .s7_dat_i( gnd32 ), + .s7_ack_i( gnd ), + .s7_err_i( gnd ), + .s7_rty_i( gnd ) +); + + +//--------------------------------------------------------------------------- +// LM32 CPU +//--------------------------------------------------------------------------- +lm32_cpu lm0 ( + .clk_i( clk ), + .rst_i( ~rst ), + .interrupt_n( intr_n ), + // + .I_ADR_O( lm32i_adr ), + .I_DAT_I( lm32i_dat_r ), + .I_DAT_O( lm32i_dat_w ), + .I_SEL_O( lm32i_sel ), + .I_CYC_O( lm32i_cyc ), + .I_STB_O( lm32i_stb ), + .I_ACK_I( lm32i_ack ), + .I_WE_O ( lm32i_we ), + .I_CTI_O( lm32i_cti ), + .I_LOCK_O( lm32i_lock ), + .I_BTE_O( lm32i_bte ), + .I_ERR_I( lm32i_err ), + .I_RTY_I( lm32i_rty ), + // + .D_ADR_O( lm32d_adr ), + .D_DAT_I( lm32d_dat_r ), + .D_DAT_O( lm32d_dat_w ), + .D_SEL_O( lm32d_sel ), + .D_CYC_O( lm32d_cyc ), + .D_STB_O( lm32d_stb ), + .D_ACK_I( lm32d_ack ), + .D_WE_O ( lm32d_we ), + .D_CTI_O( lm32d_cti ), + .D_LOCK_O( lm32d_lock ), + .D_BTE_O( lm32d_bte ), + .D_ERR_I( lm32d_err ), + .D_RTY_I( lm32d_rty ) +); + +//--------------------------------------------------------------------------- +// Block RAM +//--------------------------------------------------------------------------- +wb_bram #( + .adr_width( 12 ), + .mem_file_name( bootram_file ) +) bram0 ( + .clk_i( clk ), + .rst_i( ~rst ), + // + .wb_adr_i( bram0_adr ), + .wb_dat_o( bram0_dat_r ), + .wb_dat_i( bram0_dat_w ), + .wb_sel_i( bram0_sel ), + .wb_stb_i( bram0_stb ), + .wb_cyc_i( bram0_cyc ), + .wb_ack_o( bram0_ack ), + .wb_we_i( bram0_we ) +); + +//--------------------------------------------------------------------------- +// uart0 +//--------------------------------------------------------------------------- +wire uart0_rxd; +wire uart0_txd; + +wb_uart #( + .clk_freq( clk_freq ), + .baud( uart_baud_rate ) +) uart0 ( + .clk( clk ), + .reset( ~rst ), + // + .wb_adr_i( uart0_adr ), + .wb_dat_i( uart0_dat_w ), + .wb_dat_o( uart0_dat_r ), + .wb_stb_i( uart0_stb ), + .wb_cyc_i( uart0_cyc ), + .wb_we_i( uart0_we ), + .wb_sel_i( uart0_sel ), + .wb_ack_o( uart0_ack ), +// .intr( uart0_intr ), + .uart_rxd( uart0_rxd ), + .uart_txd( uart0_txd ) +); + +//--------------------------------------------------------------------------- +// timer0 +//--------------------------------------------------------------------------- +wb_timer #( + .clk_freq( clk_freq ) +) timer0 ( + .clk( clk ), + .reset( ~rst ), + // + .wb_adr_i( timer0_adr ), + .wb_dat_i( timer0_dat_w ), + .wb_dat_o( timer0_dat_r ), + .wb_stb_i( timer0_stb ), + .wb_cyc_i( timer0_cyc ), + .wb_we_i( timer0_we ), + .wb_sel_i( timer0_sel ), + .wb_ack_o( timer0_ack ), + .intr( timer0_intr ) +); + +//--------------------------------------------------------------------------- +// General Purpose IO +//--------------------------------------------------------------------------- +/* +wire [31:0] gpio0_in; +wire [31:0] gpio0_out; +wire [31:0] gpio0_oe; + +wb_gpio gpio0 ( + .clk( clk ), + .reset( rst ), + // + .wb_adr_i( gpio0_adr ), + .wb_dat_i( gpio0_dat_w ), + .wb_dat_o( gpio0_dat_r ), + .wb_stb_i( gpio0_stb ), + .wb_cyc_i( gpio0_cyc ), + .wb_we_i( gpio0_we ), + .wb_sel_i( gpio0_sel ), + .wb_ack_o( gpio0_ack ), + .intr( gpio0_intr ), + // GPIO + .gpio_in( gpio0_in ), + .gpio_out( gpio0_out ), + .gpio_oe( gpio0_oe ) +); +*/ +//---------------------------------------------------------------------------- +// Mux UART wires according to sw[0] +//---------------------------------------------------------------------------- +assign uart_txd = uart0_txd; +assign uart0_rxd = uart_rxd; +assign led = ~uart_txd; +endmodule diff --git a/lm32/logic/sakc/system.xst b/lm32/logic/sakc/system.xst new file mode 100644 index 0000000..806fc3d --- /dev/null +++ b/lm32/logic/sakc/system.xst @@ -0,0 +1,11 @@ +run +-ifn system.prj +-top system +-ifmt MIXED +-opt_mode AREA +-opt_level 2 +-ofn system.ngc +-p xc3S500e-vq100-4 +-register_balancing yes +-rtlview yes + diff --git a/lm32/logic/sakc/system_conf.v b/lm32/logic/sakc/system_conf.v new file mode 100644 index 0000000..d0b519c --- /dev/null +++ b/lm32/logic/sakc/system_conf.v @@ -0,0 +1,45 @@ +//--------------------------------------------------------------------------- +// +// This file is used by ../rtl/lm32/* to configure CPU parameter +// +//--------------------------------------------------------------------------- +`ifndef SYSTEM_CONF +`define SYSTEM_CONF +`define INCLUDE_LM32 + +//`timescale 1ns / 100 ps + +`define CFG_EBA_RESET 32'h0 +`define CFG_DEBA_RESET 32'h0 + +`define CFG_PL_MULTIPLY_ENABLED +`define CFG_PL_BARREL_SHIFT_ENABLED +`define CFG_SIGN_EXTEND_ENABLED +`define CFG_MC_DIVIDE_ENABLED + +// Instruction Cache +// [0x00000000,0x80000000) cachable +// [0x80000000,0xffffffff] non-cachabel +`define CFG_ICACHE_ENABLED +`define CFG_ICACHE_ASSOCIATIVITY 1 +`define CFG_ICACHE_SETS 512 +`define CFG_ICACHE_BYTES_PER_LINE 16 +`define CFG_ICACHE_BASE_ADDRESS 32'h0 +`define CFG_ICACHE_LIMIT 32'h7fffffff + +// Data Cache +// [0x00000000,0x80000000) cachable +// [0x80000000,0xffffffff] non-cachabel +// `define CFG_DCACHE_ENABLED +`define CFG_DCACHE_ASSOCIATIVITY 1 +`define CFG_DCACHE_SETS 512 +`define CFG_DCACHE_BYTES_PER_LINE 16 +`define CFG_DCACHE_BASE_ADDRESS 32'h0 +`define CFG_DCACHE_LIMIT 32'h7fffffff + +// `define CFG_DEBUG_ENABLED +// `define CFG_ROM_DEBUG_ENABLED +// `define CFG_BREAKPOINTS 32'h1 +// `define CFG_WATCHPOINTS 32'h1 + +`endif // SYSTEM_CONF diff --git a/lm32/logic/sakc/system_tb.v b/lm32/logic/sakc/system_tb.v new file mode 100644 index 0000000..a26fc53 --- /dev/null +++ b/lm32/logic/sakc/system_tb.v @@ -0,0 +1,62 @@ +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +`timescale 1 ns / 100 ps + +module system_tb; + +//---------------------------------------------------------------------------- +// Parameter (may differ for physical synthesis) +//---------------------------------------------------------------------------- +parameter tck = 20; // clock period in ns +parameter uart_baud_rate = 1152000; // uart baud rate for simulation + +parameter clk_freq = 1000000000 / tck; // Frequenzy in HZ +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +reg clk; +reg rst; +wire led; + +//---------------------------------------------------------------------------- +// UART STUFF (testbench uart, simulating a comm. partner) +//---------------------------------------------------------------------------- +wire uart_rxd; +wire uart_txd; + +//---------------------------------------------------------------------------- +// Device Under Test +//---------------------------------------------------------------------------- +system #( + .clk_freq( clk_freq ), + .uart_baud_rate( uart_baud_rate ) +) dut ( + .clk( clk ), + // Debug + .rst( rst ), + .led( led ), + // Uart + .uart_rxd( uart_rxd ), + .uart_txd( uart_txd ) +); + +/* Clocking device */ +initial clk <= 0; +always #(tck/2) clk <= ~clk; + +/* Simulation setup */ +initial begin + $dumpfile("system_tb.vcd"); + $dumpvars(-1, dut); + + // reset + #0 rst <= 1; + #80 rst <= 0; + + #(tck*10000) $finish; +end + + + +endmodule diff --git a/lm32/logic/sakc/tools/lac-tool/lac-tool b/lm32/logic/sakc/tools/lac-tool/lac-tool new file mode 100755 index 0000000..bb14919 --- /dev/null +++ b/lm32/logic/sakc/tools/lac-tool/lac-tool @@ -0,0 +1,128 @@ +#!/usr/bin/env ruby +# +# Tool to control a LogicAnalyzerComponent +# +# You need to install ruby 1.8 (or later) and ruby-serialport +# There are various programs to view .vcd files -- e.g. GtkWave +# + +require "serialport.so" +require "optparse" + +$PORT_PATH = "/dev/ttyUSB0" +$PORT_BAUD = 115200 +$TIMESCALE = "10ns" + +opts = OptionParser.new do |o| + o.banner = "Usage: lac-tool [options] SELECT TRIGGER TRIGGERMASK FILENAME\n" + o.separator "" + o.separator " SELECT Hexadevimal select value transferred to the LAC" + o.separator " TRIGGER Hexadecimal trigger value" + o.separator " TRIGGERMASK Haxadevimal triggermask" + o.separator " FILENAME .vcd file to be written" + o.separator "" + + o.on( "-b", "--baud BAUDRATE", Integer, + "Serial port baudrate (default: #{$PORT_BAUD})" ) do |baud| + $PORT_BAUD = baud + end + + o.on( "-s", "--serial SERIALPORT", + "Path to serial port (default: #{$PORT_PATH})" ) do |port| + $PORT_PATH = port + end + + o.on( "-t", "--timescale TIMESCALE", + "Timescale announced in .vcd file (default: 10ns)" ) do |ts| + $TIMESCALE = ts + end + + o.on( "-h", "--help", "Display this help message" ) do + puts o + exit 0 + end + + o.separator "" + o.separator "Example:" + o.separator " ./lac-tool 0x00 0x02 0x03 trace.vcd -- Sets SELECT to 0 and waits for probe to be ??????10" + o.separator "" +end + +### +# Check arguments +begin + opts.parse!( ARGV ) + + raise "Missing arguments" if ARGV.length != 4; + + select = ARGV[1].hex + trig = ARGV[2].hex + trigmask = ARGV[3].hex + filename = ARGV[4] +rescue => e + STDERR.puts "\n#{e.message}" + STDERR.puts + STDERR.puts opts + exit 1 +end + +### +# Open serial port +begin + ser = SerialPort.new( $PORT_PATH, $PORT_BAUD, 8, 1, SerialPort::NONE ) + ser.flow_control=SerialPort::NONE; +rescue => e + STDERR.puts "\nCould not open serial port: #{e.message}" + exit 1 +end + +begin + f = File.open( filename, mode="w" ); +rescue => e + STDERR.puts "\nCould not open output file: #{e.message}" + exit 1 +end + +# Write VCD header +f.puts "$date" +f.puts "\t" + Time.now.to_s +f.puts "$end" +f.puts "$version" +f.puts "\tLogicAnalyzerComponent (http://www.das-labor.org/)" +f.puts "$end" +f.puts "$timescale" +f.puts "\t#{$TIMESCALE}" +f.puts "$end" + +# Declare wires +f.puts "$scope module lac $end" +f.puts "$var wire 8 P probe[7:0] $end" +f.puts "$enddefinitions $end" + +# RESET LM +6.times do + ser.putc 0x00 # CMD_DISARM +end + +# Here we go +ser.putc 0x01 # send CMD_ARM +ser.putc select # set select value +ser.putc trigmask # set trigger mask +ser.putc trig # set trigger compare value +ser.putc 0x00 # set pre-trigger value + +puts "LAC armed; waiting for trigger condition..." + +size = ser.getc; +size = 1 << size; + +printf( "TRIGGERED -- Reading 0x%x bytes...\n", size ); + +size.times { |step| + byte = ser.getc + f.puts "\##{step}" + f.printf "b%08b P\n", byte +} + +ser.close +f.close diff --git a/lm32/logic/sakc/tools/srec2vram/Makefile b/lm32/logic/sakc/tools/srec2vram/Makefile new file mode 100644 index 0000000..2741b8f --- /dev/null +++ b/lm32/logic/sakc/tools/srec2vram/Makefile @@ -0,0 +1,10 @@ +CC ?= gcc +CFLAGS ?= -O2 -Wall + +all: srec2vram + +srec2vram: srec2vram.c + $(CC) $(CFLAGS) -o srec2vram srec2vram.c + +clean: + rm -f srec2vram diff --git a/lm32/logic/sakc/tools/srec2vram/srec2vram b/lm32/logic/sakc/tools/srec2vram/srec2vram new file mode 100755 index 0000000000000000000000000000000000000000..4f535460512cdbc09db8501e934aa018d374b097 GIT binary patch literal 7835 zcmd^EeQ=b;8Q;6S-~oYz5EL}xjb1dga9$u%VgZ395HtdYV6l9>TypQ_z24(+^!$4`RgW7hi&QLqmnM0_iEn2FS>+iRFZ}R5U zY5RBg=DB@-yU#xR?C!Js?#Ba7Eo&SOhp>WElnA2XZ)vVN#M@@7oI2qaE>R=qiL1n9 zBr&h97cwAO0EH$YO#_uM54f%m`Jh?AB<4{!Nd}e$)yxor#PXtC<(HNTQTmkTA}vFK zHW2G&z7vrf`EKNqP63mc&pJrWkZ(raq()$pm3PN`i2&edf>pj1`S$wHLz2YuwEf0# zsQt!pU|~2ENv6EinwzN_oQ z{rTG8eb>#dW0*nhZ#Y#X-T@2KVE|Xz8{#iHeW8c^V?PXxSUliEyQ$d%3Nr`F9oJ-Xh#wg!dHTZx`VuMfghKbNe(G$7Ci(=TXGX2Q55T2wm^& zjz;u&!XHcMx`0b{(3O@5eccA620{@%88-ru>xqRTiJ;zLb_pXDN{C>z$B2j?BNmIs zkPQtTUCh;k{!my1jc8B=JB>tK#1pYFBy~M#QxWV4N8^U*_J_mK4p}@F2_$<&Jl^4t z1W_gc#Ym??1?#%~p@;~^3`4AKS+}}DUj&D@xVkZ}c8v3laf`iNC+L%0SJY2KOe%pd zO_s3({|+GfFo~fe6oOk%7DvD{ty1DiVz_{3O00=r6>z!4CE~XQoR}NJv~h~lzzm~U zCnm!Xj=>~41mer!lp15CyBK4VlrqMkl{1F3S2D(Ao5L6rq>3>nrJFHo@G!>YsbP$X zvw$%sk&iK2P{$Y(btz*^-eru@pv{^0Hl@#LIoh_hZ=?tQl70AMKA#_WJuxZgMQZLj zn3ubVy0>gSIg-EW0$Px-zKDO8$yc)lCfPIZpjf_|EisvQ=9I*2k;$$*Gb}M%X3img zR${i$bQ2$xm@PGHh!0527MnieUWwUqb189;#OwicCGk#)*%M|n@kWW+Bj!fpl@haO z%q_$|iP=NuPGYyj>?xBCI#Vt&d(7-1780}P%oOqHrFt2 z&0LAUJMJ_O?$unmD^T$KfeE3|@4d@gpiU%j8QO^Wg*oWezO$A1Kl-UNeb!O`W_;ct zT~DNk9ZypvUpc^RDPI3(EO&eo6*$tzw5{7m1{2qd!543!JoKl}%^9kK?7(oM;wMZ4 zGv$QlVOsvw$&q4vAb+CKqm9CFNMX=LZUtJ%v_pgAXiE`t67BzdbvB3%X=byQco=-MNzK zZ2J(D4W8+N;fkt_KbuNFUp_b%(xv zg#G#MC`{-($F9k4FExhv9nJK6s(@>U)AzZwvVo15x>Qd^>^L?v+u&kNKm1odpT6KI z8<O8sM$jq{V$DsT~zf5k3 zCc|K-LL%UfM8VDgn{fB|!B&8c#SJ&u%fa4I9ls$6{z~vu1-e^W`b%1hp%qZhxEXQ! zLdmXaz4v-nY%1%gb1JL1c}g?)szT5p2k7xnQ3#eTR+jY#F<``hN4o4Gcy(LtaP8a5 z`?9my9qAFR>`05VB-7%lB;y2APR0SIwCspRAJERQCzYp57u?9I-mJfxJ$?6)+TrXY za%_#ovpLdb11{LqcZ|aim&lxx?g>58m#9zr6x)gM%Dh~5q|tLrI_Fz9rEJeU7+rQ` zIPV#_h&nkXHMvsQ zeHXr;-2XbTADFs1?(Z~icE@8z$D&;^f46%X*~G$NC~T~7FKb8A!gharjE{%zF;-0F zkcy_()(x#UyE!pABRLg02km8Qs^jzjv#iwV9+yoeV*ZXqDAMWPTJ2k!TEM^g?iz|M z_ob>+P&uKNDekcZr3wjCMRiJ4heS+_+sBQfI}~BlM73{G%1*E{ozYx9SB`h7TCesn1x^?Vb1O6I4r$3)x= zOec6B#IqF3&jvBj56{Dcxn}i(xWe%qbp_}`zvd#JL(DBI%kezO^#DspbT86jTa-49 zB5nr;`#%SsnXN)Ep-r!XPJ=!GT>{O(*?%6$3t9nM5845WfbIwF2R#Y;0m#y`wxQu> zcg^PZWF(Pv*Lmx_ix<`ybu(m-a!f8H^7)X$vB$ zi#~lPi1UDQoHHo^&J`;~2=@BAQl3OvV`fn{jNDdoGtQ?#3Utu+x);F!B(9@jHDxWh~eH#_#7gl{U73RvL=ApuHb_C8h zg*kJDyw_G3PL9C&qcEHRf%8OR_MDmz3UgGH-z&^7G``>PABEM5O+QwcUv?q=RbjOQ zpkFGC!9t+_Da;*!5cD&Jl?TzE6vmyQEtH5W$NYfFn)qv;E#|x=cHkBjcS>XSIq*fP z0k-UOVCQiY@Mz&1?!;~KZNTzY1F=KQ6<8HHiZ&*J+dgZqI`+&Kg zAcE{n@epEr{f`45Ec7?^Jx9SppuV4jxBAE7yh6MIY_(4~E5y4+_#eR5-p1iXf5Skl zKi!y-(|~zLL{F?heOCc4 zS>J=emcLctCjUT@{7?~osR*9}K4+`%k45<(0$c4ZM|&?8<$e$fq4sIm4B-!|3l!N1$(LQd{O>nEMfNg zrrXv?>c1NJG1$*KE1WY#9q>W)$3DbtPd#Gp17to=3>~pVJdq3ry}W2|Xxq@Lx2)UL zhTDE!Z=8T`ZLnnpqIzdI+U^hQa_6c0lPQ5+Wlz{h7y<8Be2Z!YGxSg(MYI@K^VqKH zfn<00ZmXWA^^LNcHLa^|Z_+KqYAk-d7P-xpwTvB#Y4F;X4XanR=o{9o+0@jgx2;;; z(nQ0#an}8@n18o!MEE>mOOTHlLT|il{i@s7H3;sC)e{25rsKv21V~9`mMY4R--c%$2p-P?2pHdxWK!HZr%;a@#l?+I^_A>G*Xb{7GJ)Kj7#_| ztJE6|UpefV>Vd_cQuH#z7m*3sx~;+LnPoh?w(zntp5iOK&)8Gs)6RH8t-#3ggfC=E z@ZM;^=0H5EoBl`uhk8EtjEl2D(yy#B9_w?CkuZ&L4;Auu1Cltc6h=Y41x?g5@l|O& zuZ|i}8V5H%8;xfy64D>kGtzi6Y%=8Oh)-7&lJ(G%rAxecsM32n^n{s=ba~rTc$dOk Ilk_R^Z%PYJ0RR91 literal 0 HcmV?d00001 diff --git a/lm32/logic/sakc/tools/srec2vram/srec2vram.c b/lm32/logic/sakc/tools/srec2vram/srec2vram.c new file mode 100644 index 0000000..da70861 --- /dev/null +++ b/lm32/logic/sakc/tools/srec2vram/srec2vram.c @@ -0,0 +1,158 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include + +uint32_t rambase; +uint32_t ramsize; +uint8_t *ram; + +#define HAVE_STRNDUP +#ifndef HAVE_STRNDUP +char* strndup(const char* s, size_t n) { + char* ret = malloc(n + 1); + if (ret == NULL) return(ret); + ret[n] = '\0'; + return(memcpy(ret, s, n)); +} +#endif + +void help() +{ + printf( "\nUsage: srec2vram \n\n" ); + printf( " \t \n" ); + printf( " \t \n\n" ); +}; + + +uint32_t parsehex(char *line, int start, int len) +{ + char *str; + uint32_t val; + + str = strndup(line+start, len); + sscanf(str, "%x", &val); + free(str); + +// fprintf( stderr, "parsehex: %x\n", val ); + + return val; +} + +void parseline(char *line, int start, int bytes, uint32_t addr) +{ + int i; + uint8_t val; + +// fprintf( stderr, "parsline: [0x%08x, 0x%08x)\n", addr, addr+bytes ); + + for(i=0; i (%s)\n", argv[2] ); + exit(1); + } + + + err = sscanf(argv[3], "%i", &ramsize); + if (err != 1) { + printf( "ERROR: Could not parse (%s)\n", argv[3] ); + exit(1); + } + + ram = malloc( ramsize ); + fprintf( stderr, "Extracting [%08x,%08x) (size=0x%x)\n", + rambase, rambase+ramsize, ramsize ); + + // Open SREC file + infile = fopen( argv[1], "r" ); + if (infile == NULL) { + perror( "Could not open infile" ); + exit(1); + } + + // Read SREC file + while( !feof(infile) ) { + char errmsg[] = "Could not parse '%s'\n"; + char line[LINESIZE]; + uint32_t addr; + int len; + + + fgets(line, LINESIZE, infile); + + // Is this a sane SREC line? + if (strlen(line) < 4) { + fprintf( stderr, errmsg, line ); + continue; + } + + if (line[0] != 'S') { + fprintf( stderr, errmsg, line ); + continue; + } + + // record length + len = parsehex(line, 2, 2); + + switch ( line[1] ) { + case '0': + continue; + case '1': // data, 2-byte address + addr = parsehex(line, 4, 4); + parseline(line, 8, len-3, addr); + break; + case '2': // data, 3-byte address + addr = parsehex(line, 4, 6); + parseline(line, 10, len-4, addr); + break; + case '3': // data, 4-byte address + addr = parsehex(line, 4, 8); + parseline(line, 12, len-5, addr); + break; + case '7': // 4-byte start address + break; + case '8': // 3-byte start address + break; + case '9': // 2-byte start address + break; + default: + fprintf( stderr, errmsg, line ); + + } + } + + fclose( infile ); + + // Write output + int i; + + for(i = 0; i < ramsize; i+=4) { + printf( "%02x%02x%02x%02x\n", ram[i+0], ram[i+1], ram[i+2], ram[i+3] ); + } + + return 0; +} + diff --git a/lm32/logic/sakc/tools/uploader/memtest b/lm32/logic/sakc/tools/uploader/memtest new file mode 100755 index 0000000..0ed83c8 --- /dev/null +++ b/lm32/logic/sakc/tools/uploader/memtest @@ -0,0 +1,150 @@ +#!/usr/bin/env ruby + +require "serialport.so" +require "optparse" + +port_baud = 115200 +port_path = "/dev/ttyUSB0" +terminal_mode = false +verose = false + +############################################################################# +# Extend SerialPort class with low-leven binary communication +class SerialPort + BOOT_SIG = "**soc-lm32/bootloader**" + + def put_uint32(i) + putc( (i >> 24) & 0xff ) + putc( (i >> 16) & 0xff ) + putc( (i >> 8) & 0xff ) + putc( (i >> 0) & 0xff ) + end + + def download(addr, size) + a = Array.new(size) + putc 'd' + put_uint32 addr + put_uint32 size + size.times do |i| + a[i] = getc + end + return a + end + + def upload(addr, data) + putc 'u' + put_uint32 addr + put_uint32 data.length + data.each do |c| + putc c + end + end + + def find_bootloader(max_tries = 32) + old_timeout = read_timeout + read_timeout = 500 + count = 0; + begin + count = count + 1 + if (count == max_tries) then + raise "Bootloader (#{BOOT_SIG}) not not found" + end + putc '\r' + l = gets + end while l.nil? or not l.index( BOOT_SIG ) + read_timeout = old_timeout + end +end + +############################################################################# +# Main + +opts = OptionParser.new do |o| + o.banner = "Usage: upload.rb [options] " + + o.on( "-b", "--baud BAUDRATE", Integer, + "Serial port baudrate (default: #{port_baud})" ) do |baud| + port_baud = baud + end + + o.on( "-s", "--serial SERIALPORT", + "Path to serial port (default: #{port_path})" ) do |port| + port_path = port + end + + o.on( "-v", "--verbose", + "Be verbose and show serial I/O" ) do + verbose = true + end + + o.on_tail( "-h", "--help", "Display this help message" ) do + puts o + exit 0 + end +end + +# Check arguments, open serial port and file +begin + opts.parse!(ARGV) + + port = SerialPort.new(port_path, port_baud, 8, 1, SerialPort::NONE) + raise "Could not open serial port." if not port; + +rescue => e + STDERR.puts "\nERROR: #{e.message}" + STDERR.puts + STDERR.puts opts + STDERR.puts + exit 1 +end + + + +begin + BLOCK_SIZE = 0x800 + TEST_SIZE = 0x10000 + TEST_BASE = 0x40000000 + + STDOUT.sync = true + + # Find bootloader + print "Looking for soc-lm32 bootloader..." + port.find_bootloader + puts "found." + + # generate random data + data = Array.new( TEST_SIZE ) + data.map! do |e| e = rand(256) end + + # upload random data + print "Uploading 0x%X random bytes to 0x%X..." % [TEST_SIZE, TEST_BASE] + (TEST_SIZE / BLOCK_SIZE).times do |i| + print "." + offset = i*BLOCK_SIZE + block = data[ offset .. (offset+BLOCK_SIZE-1) ] + port.upload( TEST_BASE + i*BLOCK_SIZE, block ) + end + puts "done." + + # download again + print "Downloading again..." + ddata = Array.new + (TEST_SIZE / BLOCK_SIZE).times do |i| + print "." + ddata += port.download( TEST_BASE + i*BLOCK_SIZE, BLOCK_SIZE ) + end + puts "done." + + puts "Checking for memory errors..." + TEST_SIZE.times do |i| + if data[i] != ddata[i] then + puts "0x%08x: %02x %02x" % [i, data[i], ddata[i] ] + end + end + puts "done." +ensure + port.close unless port.nil? +end + + + diff --git a/lm32/logic/sakc/tools/uploader/upload b/lm32/logic/sakc/tools/uploader/upload new file mode 100755 index 0000000..f1cfaba --- /dev/null +++ b/lm32/logic/sakc/tools/uploader/upload @@ -0,0 +1,217 @@ +#!/usr/bin/env ruby + +require "serialport.so" +require "optparse" + +port_baud = 115200 +port_path = "/dev/ttyUSB0" +terminal_mode = false +verbose = false +check = false + +############################################################################# +# Extend SerialPort class with bootloader communication +class SerialPort + BOOT_SIG = "**soc-lm32/bootloader**" + + def put_uint32(i) + putc( (i >> 24) & 0xff ) + putc( (i >> 16) & 0xff ) + putc( (i >> 8) & 0xff ) + putc( (i >> 0) & 0xff ) + end + + def download(addr, size) + a = Array.new(size) + putc 'd' + put_uint32 addr + put_uint32 size + size.times do |i| + a[i] = getc + end + return a + end + + def upload(addr, data) + putc 'u' + put_uint32 addr + put_uint32 data.length + data.each do |c| + putc c + end + end + + def find_bootloader(max_tries = 32) + old_timeout = read_timeout + read_timeout = 500 + count = 0; + begin + count = count + 1 + if (count == max_tries) then + raise "Bootloader (#{BOOT_SIG}) not not found" + end + putc '\r' + l = gets + end while l.nil? or not l.index( BOOT_SIG ) + read_timeout = old_timeout + end +end + +############################################################################# +# Main + +opts = OptionParser.new do |o| + o.banner = "Usage: upload [options] " + + o.on( "-b", "--baud BAUDRATE", Integer, + "Serial port baudrate (default: #{port_baud})" ) do |baud| + port_baud = baud + end + + o.on( "-s", "--serial SERIALPORT", + "Path to serial port (default: #{port_path})" ) do |port| + port_path = port + end + + o.on( "-v", "--verbose", + "Be verbose and show serial I/O" ) do + verbose = true + end + + o.on( "-t", "--terminal", + "Switch to terminal mode after upload" ) do + terminal_mode = true + end + + o.on( "-c", "--check", + "Check RAM after upload and verify everything is correct" ) do + check = true + end + + o.on_tail( "-h", "--help", "Display this help message" ) do + puts o + exit 0 + end +end + +# Check arguments, open serial port and file +begin + opts.parse!(ARGV) + + raise "SREC file argument missing" if ARGV.length != 1; + + file_path = ARGV[0] + + uploadFile = File.open( file_path, "r" ) + raise "Could not SREC file." if not uploadFile; + + fileSize = File.size( file_path ) + + port = SerialPort.new(port_path, port_baud, 8, 1, SerialPort::NONE) + raise "Could not open serial port." if not port; + +rescue => e + STDERR.puts "\nERROR: #{e.message}" + STDERR.puts + STDERR.puts opts + STDERR.puts + exit 1 +end + +begin + STDOUT.sync = true + + print "Looking for soc-lm32 bootloader..." + port.find_bootloader + puts "found." + + data = Array.new(0x2000).map do |e| e = 0x23 end + port.upload(0x40000000, data ); + +# ist_data = port.download(0x40000000, 0x2000) +#p ist_data + + # read SREC file + startAddress = nil + + print "Uploading SREC file..." + uploadFile.each_line do |line| + line.chomp! + if line[0..1] == "S7" then + startAddress = line[4..11].hex + end + if line[0..1] == "S3" then + count = line[2..3].hex + addr = line[4..11].hex + dat = line[12..-3] + cksum = line[-2..-1].hex + + count = count - 5 + data = Array.new( count ) + count.times do |i| + data[i] = ( dat[ (2*i) .. (2*i+1) ] ).hex + end + port.upload(addr, data) + if verbose then + print " [0x%08x] " % addr + data.each do |e| print " %02x" % e; end + puts + else + print "." + end + end + end + puts "done." + + if check then + print "verifieing RAM content..." + uploadFile.seek(0) + + uploadFile.each_line do |line| + printf "." + line.chomp! + if line[0..1] == "S3" then + count = line[2..3].hex + addr = line[4..11].hex + dat = line[12..-3] + chsum = line[-2..-1].hex + + count = count/2 - 1 + soll_data = Array.new( count ) + count.times do |i| + soll_data[i] = ( dat[ (2*i) .. (2*i+1) ] ).hex + end + ist_data = port.download(addr, count) + + count.times do |i| + if soll_data[i] != ist_data[i] then + puts "0x%08x: 0x%02x <-> 0x%02x" % [addr+i, soll_data[i], ist_data[i]] + end + end + + end + end + puts "done." + end + + if not startAddress.nil? then + puts "Jumping to start address 0x%08x." % startAddress + port.putc 'g' + port.put_uint32 startAddress + end + + + if terminal_mode + puts "------ entering terminal mode ------" + while true do + a = select( [port, STDIN], nil, nil ); + + STDOUT.putc(port.getc) if a[0].include?( port ) + port.putc(STDIN.getc) if a[0].include?( STDIN ) + end + end + +ensure + uploadFile.close unless uploadFile.nil? + port.close unless port.nil? +end diff --git a/plasma/gpio/Makefile b/plasma/gpio/Makefile index 592dc80..caed95f 100644 --- a/plasma/gpio/Makefile +++ b/plasma/gpio/Makefile @@ -9,7 +9,7 @@ LD = $(CROSS)-ld DUMP = $(CROSS)-objdump OBJCOPY = $(CROSS)-objcopy INC_PATH = ../include -CFLAGS = -O2 -I$(INC_PATH) -Wall -c -s +CFLAGS = -O -I$(INC_PATH) -Wall -c -s ILDFLAGS = -Ttext 0 -eentry -Map $@.map -s -N LDFLAGS = -Ttext 0x10000000 -eentry -Map $@.map -s -N diff --git a/plasma/gpio/gpio.c b/plasma/gpio/gpio.c index 1ed421a..b9a41fd 100644 --- a/plasma/gpio/gpio.c +++ b/plasma/gpio/gpio.c @@ -13,13 +13,13 @@ int main(void) volatile unsigned short *data16; volatile unsigned int *data32; - unsigned char test8; - unsigned short test16; - unsigned int test32, tmp; + volatile unsigned char test8; + volatile unsigned short test16; + volatile unsigned int test32, tmp; - data8 = (unsigned char *)(0x20001000); - data16 = (unsigned short *)(0x20002000); - data32 = (unsigned int *)(0x20003000); + data8 = (unsigned char *)(0x20000410); + data16 = (unsigned short *)(0x20000210); + data32 = (unsigned int *)(0x20000330); *data8 = 0x10; data8++; @@ -54,11 +54,15 @@ int main(void) test32 = *data32; + data32 = (unsigned int *)(0x20000000); + *data32 = 0x55555555; + test32 = *data32; + data32 = (unsigned int *)(0x20000020); + test32 = *data32; - tmp = test8 + test16 + test32; - - *data32 = 0xAAAAAAAA; - + while(1){ + + } return 0; } diff --git a/plasma/include/plasma.h b/plasma/include/plasma.h index 4dc73cb..d3af766 100644 --- a/plasma/include/plasma.h +++ b/plasma/include/plasma.h @@ -16,9 +16,10 @@ #define RAM_INTERNAL_BASE 0x00000000 //8KB #define RAM_EXTERNAL_BASE 0x10000000 //1MB #define RAM_EXTERNAL_SIZE 0x00100000 -#define MISC_BASE 0x20000000 +#define UART_BASE 0x20000000 #define UART_WRITE 0x20000000 #define UART_READ 0x20000000 +#define UART_STATUS 0x20000010 #define IRQ_MASK 0x20000010 #define IRQ_STATUS 0x20000020 #define GPIO0_OUT 0x20000030 diff --git a/plasma/logic/Makefile b/plasma/logic/Makefile index df9e656..d3cf6cc 100644 --- a/plasma/logic/Makefile +++ b/plasma/logic/Makefile @@ -1,13 +1,14 @@ DESIGN = plasma PINS = $(DESIGN).ucf -DEVICE = xc3s500e-fg320-4 +DEVICE = xc3s500e-VQ100-4 +#DEVICE = xc3s250e-fg320-4 BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \ -g CRC:enable -g StartUpClk:CCLK SIM_CMD = /opt/cad/modeltech/bin/vsim SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE) -SRC_HDL = plasma.vhd alu.vhd control.vhd mem_ctrl.vhd mult.vhd shifter.vhd bus_mux.vhd ddr_ctrl.vhd mlite_cpu.vhd pc_next.vhd cache.vhd eth_dma.vhd mlite_pack.vhd pipeline.vhd reg_bank.vhd uart.vhd ram_image.vhd +SRC_HDL = plasma.vhd ram_image.vhd alu.vhd control.vhd mem_ctrl.vhd mult.vhd shifter.vhd bus_mux.vhd mlite_cpu.vhd pc_next.vhd mlite_pack.vhd pipeline.vhd reg_bank.vhd uart.vhd all: bits @@ -50,8 +51,8 @@ build/project.xst: build/project.src build/project.ngc: build/project.xst $(SRC) cd build && xst -ifn project.xst -ofn project.log -build/project.ngd: build/project.ngc #$(PINS) - cd build && ngdbuild -p $(DEVICE) project.ngc #-uc ../$(PINS) +build/project.ngd: build/project.ngc $(PINS) + cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS) build/project.ncd: build/project.ngd cd build && map -pr b -p $(DEVICE) project diff --git a/plasma/logic/_impact.cmd b/plasma/logic/_impact.cmd deleted file mode 100644 index 3ff6a58..0000000 --- a/plasma/logic/_impact.cmd +++ /dev/null @@ -1,15 +0,0 @@ -setMode -bs -setMode -bs -setCable -port auto -Identify -identifyMPM -assignFile -p 1 -file "/home/cain/Embedded/plasma/work/Example/logic/plasma_3e.bit" -Program -p 1 -defaultVersion 0 -Program -p 1 -defaultVersion 0 -Program -p 1 -defaultVersion 0 -Program -p 1 -defaultVersion 0 -assignFile -p 1 -file "/home/cain/Embedded/plasma/work/Example/logic/plasma_3e.bit" -Program -p 1 -defaultVersion 0 -Program -p 1 -defaultVersion 0 -Program -p 1 -defaultVersion 0 -saveProjectFile -file "/home/cain/Embedded/plasma/work/Example/logic/default.ipf" diff --git a/plasma/logic/default.ipf b/plasma/logic/default.ipf deleted file mode 100644 index e84c363e7a02c36c930d9d6f989c7dfcc212e4df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3743 zcmcgv&2QX96i>xRrICOGRWBeq0tyF|ct6sL9uV5~+O6Ac*79r;+KZX>&L(c{9n1En zEfUZhLL4f!Ao@>mL4qq6Bu*Sr4_x>gdf`T%d&t!i5}{=ByU`J4`2s9Cn78+}{l=l}QMFCAhs@>)B9nH8$ z!zf@{z;}I5lUU+^!GP=pZtI!mS@adHOvdMf+&U6$%Esk&kT}r-DD|n|{DbI*Vb(C%o19bmH&I z39GAE^zo;7byX5Jm>9vNyiQ=uoGKK$=7 z&?4G$^fa{>M$e?Np1e?Y8VWma{1W~27ce8*a_lrt%}#z5-8Ner`6-TI|aYSt*4(wz>H{hxf?ELAsL;H;96vt$PQ>a;c(L*8679n!(1n{8G2Cs#A=Y5i z)g7ZVGa&p?=bjs&(q6pU31H2*D(~HlqQIb!dHPV-j7Q}BoNy5+KI{St>xLfBPnoZy|Z^F_KszH zF9{NXj)DRSh{)eTL7OHLRq7OJ=;>0>A@Rl^b9-}V@8%+%rIBWy=Qs1__kQ!9ZQp$3 zO|){loK9GIVaau4Y$GJ*Q6f!-#rm4dOxtqR+>S^cCQpzrTNR9sr_Ust3kw z=PrAYY|O$DiwBb)+w(n^pa$~WEmVDgck5QQtr~ycUw}NOLl?w3f0Z>%0mX#&0{A}-Bj}DV50LNU|#BTnL(>B zcinMsY&X|b;m()Uy5r{9;<#$`UZ=9!rW%2t-udz6?9|GNXmyoUAWQydDNjV%0nO+< zjAE7~pb!}K{5Yo$ZQ3x*vaJbfq$vtLku$&&;4K==7&1*Uh61;Xdo-nZ+aE&}{1lA+ zS&;f8&a(_J2Uz5NeHZGZ*y*4-FEWSi!v|63WlJsRPzpQ53&X~4KzgmsmhsFizOfpy6R zfUh9G$1k7!D+--xRqmAHfvdI0#K!^ZiZ7B<-NKTfYYXxVR&#_4f&0c`5x1r(i>EYD zKbjv$)-QhnO0$qk^B|JKY+UHDsr0p+@Lh=q!%-S0>i&RO3*`vG90 roq@K;;sol0V;sr)kuj1E?gy@YKtzW{woqdB&C_pzH}bLG7Tx~=M_-md diff --git a/plasma/logic/mlite_cpu.vhd b/plasma/logic/mlite_cpu.vhd index c512661..d005a28 100644 --- a/plasma/logic/mlite_cpu.vhd +++ b/plasma/logic/mlite_cpu.vhd @@ -72,7 +72,7 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity mlite_cpu is - generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_ + generic(memory_type : string := "XILINX_16X"; mult_type : string := "DEFAULT"; --AREA_OPTIMIZED shifter_type : string := "DEFAULT"; --AREA_OPTIMIZED alu_type : string := "DEFAULT"; --AREA_OPTIMIZED diff --git a/plasma/logic/mlite_pack.vhd b/plasma/logic/mlite_pack.vhd index 1aad7db..691cb16 100644 --- a/plasma/logic/mlite_pack.vhd +++ b/plasma/logic/mlite_pack.vhd @@ -107,59 +107,6 @@ package mlite_pack is ) return std_logic_vector; function bv_inc(a : in std_logic_vector ) return std_logic_vector; - - -- For Altera - COMPONENT lpm_ram_dp - generic ( - LPM_WIDTH : natural; -- MUST be greater than 0 - LPM_WIDTHAD : natural; -- MUST be greater than 0 - LPM_NUMWORDS : natural := 0; - LPM_INDATA : string := "REGISTERED"; - LPM_OUTDATA : string := "REGISTERED"; - LPM_RDADDRESS_CONTROL : string := "REGISTERED"; - LPM_WRADDRESS_CONTROL : string := "REGISTERED"; - LPM_FILE : string := "UNUSED"; - LPM_TYPE : string := "LPM_RAM_DP"; - USE_EAB : string := "OFF"; - INTENDED_DEVICE_FAMILY : string := "UNUSED"; - RDEN_USED : string := "TRUE"; - LPM_HINT : string := "UNUSED"); - port ( - RDCLOCK : in std_logic := '0'; - RDCLKEN : in std_logic := '1'; - RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); - RDEN : in std_logic := '1'; - DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); - WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); - WREN : in std_logic; - WRCLOCK : in std_logic := '0'; - WRCLKEN : in std_logic := '1'; - Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); - END COMPONENT; - - -- For Altera - component LPM_RAM_DQ - generic ( - LPM_WIDTH : natural; -- MUST be greater than 0 - LPM_WIDTHAD : natural; -- MUST be greater than 0 - LPM_NUMWORDS : natural := 0; - LPM_INDATA : string := "REGISTERED"; - LPM_ADDRESS_CONTROL: string := "REGISTERED"; - LPM_OUTDATA : string := "REGISTERED"; - LPM_FILE : string := "UNUSED"; - LPM_TYPE : string := "LPM_RAM_DQ"; - USE_EAB : string := "OFF"; - INTENDED_DEVICE_FAMILY : string := "UNUSED"; - LPM_HINT : string := "UNUSED"); - port ( - DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); - ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); - INCLOCK : in std_logic := '0'; - OUTCLOCK : in std_logic := '0'; - WE : in std_logic; - Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); - end component; - -- For Xilinx component RAM16X1D -- synthesis translate_off @@ -362,27 +309,24 @@ package mlite_pack is end component; --cache component ram - generic(memory_type : string := "DEFAULT"); port(clk : in std_logic; enable : in std_logic; write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(31 downto 2); + address : in std_logic_vector(10 downto 0); data_write : in std_logic_vector(31 downto 0); data_read : out std_logic_vector(31 downto 0)); end component; --ram component uart - generic(log_file : string := "UNUSED"); port(clk : in std_logic; reset : in std_logic; - enable_read : in std_logic; - enable_write : in std_logic; + cs : in std_logic; + nRdWr : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); uart_read : in std_logic; uart_write : out std_logic; - busy_write : out std_logic; - data_avail : out std_logic); + addr : in std_logic_vector(3 downto 0)); end component; --uart component eth_dma @@ -413,15 +357,17 @@ package mlite_pack is end component; --eth_dma component plasma - generic(memory_type : string := "XILINX_X16"; --"DUAL_PORT_" "ALTERA_LPM"; - log_file : string := "UNUSED"); + generic(memory_type : string := "XILINX_X16"); port(clk : in std_logic; reset : in std_logic; - uart_write : out std_logic; - uart_read : in std_logic; - - data_read : in std_logic_vector(31 downto 0); - mem_pause_in : in std_logic + U_TxD : out std_logic; + U_RxD : in std_logic; + addr : in std_logic_vector(12 downto 0); + sram_data : in std_logic_vector(7 downto 0); + nwe : in std_logic; + noe : in std_logic; + ncs : in std_logic; + led : out std_logic ); end component; --plasma diff --git a/plasma/logic/plasma.vhd b/plasma/logic/plasma.vhd index 1d46897..418be4e 100644 --- a/plasma/logic/plasma.vhd +++ b/plasma/logic/plasma.vhd @@ -24,23 +24,26 @@ library ieee; use ieee.std_logic_1164.all; use work.mlite_pack.all; +library UNISIM; +use UNISIM.vcomponents.all; entity plasma is - generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; - log_file : string := "UNUSED"); - port(clk : in std_logic; - reset : in std_logic; - - uart_write : out std_logic; - uart_read : in std_logic; - - data_read : in std_logic_vector(31 downto 0); - mem_pause_in : in std_logic + generic(memory_type : string := "XILINX_16X"); + port(clk : in std_logic; + reset : in std_logic; + U_TxD : out std_logic; + U_RxD : in std_logic; + addr : in std_logic_vector(12 downto 0); + sram_data : in std_logic_vector(7 downto 0); + nwe : in std_logic; + noe : in std_logic; + ncs : in std_logic; + led : out std_logic ); end; --entity plasma architecture logic of plasma is - signal address_next : std_logic_vector(31 downto 2); + signal address_next : std_logic_vector(31 downto 0); signal byte_we_next : std_logic_vector(3 downto 0); signal cpu_address : std_logic_vector(31 downto 0); signal cpu_byte_we : std_logic_vector(3 downto 0); @@ -49,26 +52,20 @@ architecture logic of plasma is signal cpu_pause : std_logic; signal data_read_uart : std_logic_vector(7 downto 0); - signal write_enable : std_logic; - signal mem_busy : std_logic; - - signal enable_misc : std_logic; - signal enable_uart : std_logic; - signal enable_uart_read : std_logic; - signal enable_uart_write : std_logic; + signal cs_uart : std_logic; signal uart_write_busy : std_logic; signal uart_data_avail : std_logic; signal irq_mask_reg : std_logic_vector(7 downto 0); signal irq_status : std_logic_vector(7 downto 0); signal irq : std_logic; - signal ram_enable : std_logic; - signal ram_byte_we : std_logic_vector(3 downto 0); + signal cs_ram : std_logic; signal ram_address : std_logic_vector(31 downto 2); - signal ram_data_w : std_logic_vector(31 downto 0); signal ram_data_r : std_logic_vector(31 downto 0); + signal nreset : std_logic; + begin --architecture --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- PROCESSOR @@ -77,10 +74,10 @@ begin --architecture generic map (memory_type => memory_type) PORT MAP ( clk => clk, - reset_in => reset, + reset_in => nreset, intr_in => irq, - address_next => address_next, --before rising_edge(clk) + address_next => address_next(31 downto 2), --before rising_edge(clk) byte_we_next => byte_we_next, address => cpu_address(31 downto 2), --after rising_edge(clk) @@ -89,76 +86,76 @@ begin --architecture data_r => cpu_data_r, mem_pause => cpu_pause); + u2_ram: ram + port map ( + clk => clk, + enable => cs_ram, + write_byte_enable => byte_we_next, + address => ram_address(12 downto 2), + data_write => cpu_data_w, + data_read => ram_data_r); + + u3_uart: uart + port map( + clk => clk, + reset => nreset, + cs => cs_uart, + nRdWr => cpu_byte_we(0), + data_in => cpu_data_w(7 downto 0), + data_out => data_read_uart, + uart_read => U_RxD, + uart_write => U_TxD, + addr => cpu_address(7 downto 4)); + --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- ADDRESS DECODER --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - write_enable <= '1' when cpu_byte_we /= "0000" else '0'; - mem_busy <= mem_pause_in; - cpu_pause <= '0'; --(uart_write_busy and enable_uart and write_enable) or --UART busy --- (cpu_address(28) and mem_busy); --DDR or flash + cpu_pause <= '0'; --(uart_write_busy and enable_uart and write_enable) or --UART busy + ram_address <= ZERO(31 downto 13) & (address_next(12)) & address_next(11 downto 2); + cpu_address(1 downto 0) <= "00"; + address_next(1 downto 0) <= "00"; - enable_uart <= '1' when cpu_address(30 downto 28) = "010" and cpu_address(7 downto 4) = "0000" else '0'; - enable_uart_read <= enable_uart and not write_enable; - enable_uart_write <= enable_uart and write_enable; - cpu_address(1 downto 0) <= "00"; - ram_enable <= '1' when address_next(30 downto 28) = "000" else '0'; - ram_byte_we <= byte_we_next; - ram_address(31 downto 13) <= ZERO(31 downto 13); - ram_address(12 downto 2) <= (address_next(12)) & address_next(11 downto 2); - ram_data_w <= cpu_data_w; + nreset <= not(reset); - misc_proc: process(clk, reset, cpu_address, enable_misc, - ram_data_r, data_read, data_read_uart, cpu_pause, - irq_mask_reg, irq_status, write_enable, - cpu_data_w) + led <= not(reset); + + addr_dec: process (cpu_address(30 downto 4)) + begin + if (cpu_address(30 downto 28) = "000") then + cs_ram <= '1'; + cs_uart <= '0'; + elsif ( (cpu_address(30 downto 28) = "010") and ( (cpu_address(11 downto 8) = "0000") )) then + cs_ram <= '0'; + cs_uart <= '1'; + else + cs_ram <= '0'; + cs_uart <= '0'; + end if; + end process; + + misc_proc: process(clk, nreset, cpu_address, + ram_data_r, data_read_uart, cpu_pause, + irq_mask_reg, irq_status, cpu_data_w) begin case cpu_address(30 downto 28) is when "000" => --internal RAM cpu_data_r <= ram_data_r; - when "001" => --external RAM - cpu_data_r <= data_read; --DDR when "010" => --misc case cpu_address(6 downto 4) is when "000" => --uart cpu_data_r <= ZERO(31 downto 8) & data_read_uart; - when "001" => --irq_mask - cpu_data_r <= ZERO(31 downto 8) & irq_mask_reg; - when "010" => --irq_status - cpu_data_r <= ZERO(31 downto 8) & irq_status; - when others => + when "010" => --uart cpu_data_r <= ZERO(31 downto 8) & data_read_uart; + when others => + cpu_data_r <= ZERO; end case; - when "011" => --flash - cpu_data_r <= data_read; when others => cpu_data_r <= ZERO; end case; end process; - u2_ram: ram - generic map (memory_type => memory_type) - port map ( - clk => clk, - enable => ram_enable, - write_byte_enable => ram_byte_we, - address => ram_address, - data_write => ram_data_w, - data_read => ram_data_r); - u3_uart: uart - generic map (log_file => log_file) - port map( - clk => clk, - reset => reset, - enable_read => enable_uart_read, - enable_write => enable_uart_write, - data_in => cpu_data_w(7 downto 0), - data_out => data_read_uart, - uart_read => uart_read, - uart_write => uart_write, - busy_write => uart_write_busy, - data_avail => uart_data_avail); end; --architecture logic diff --git a/plasma/logic/plasma_3e.ucf b/plasma/logic/plasma_3e.ucf deleted file mode 100644 index 04c0b2d..0000000 --- a/plasma/logic/plasma_3e.ucf +++ /dev/null @@ -1,279 +0,0 @@ -##################################################### -### SPARTAN-3E STARTER KIT BOARD CONSTRAINTS FILE -##################################################### -# ==== Analog-to-Digital Converter (ADC) ==== -# some connections shared with SPI Flash, DAC, ADC, and AMP -#NET "AD_CONV" LOC = "P11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -# ==== Programmable Gain Amplifier (AMP) ==== -# some connections shared with SPI Flash, DAC, ADC, and AMP -#NET "AMP_CS" LOC = "N7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -#NET "AMP_DOUT" LOC = "E18" | IOSTANDARD = LVCMOS33 ; -#NET "AMP_SHDN" LOC = "P7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -# ==== Pushbuttons (BTN) ==== -NET "BTN_EAST" LOC = "H13" | IOSTANDARD = LVTTL | PULLDOWN ; -NET "BTN_NORTH" LOC = "V4" | IOSTANDARD = LVTTL | PULLDOWN ; -NET "BTN_SOUTH" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ; -NET "BTN_WEST" LOC = "D18" | IOSTANDARD = LVTTL | PULLDOWN ; -# ==== Clock inputs (CLK) ==== -NET "CLK_50MHZ" LOC = "C9" | IOSTANDARD = LVCMOS33 ; -# Define clock period for 50 MHz oscillator (40%/60% duty-cycle) -NET "CLK_50MHZ" PERIOD = 20 ns HIGH 40 %; -#NET "CLK_AUX" LOC = "B8" | IOSTANDARD = LVCMOS33 ; -#NET "CLK_SMA" LOC = "A10" | IOSTANDARD = LVCMOS33 ; -# ==== Digital-to-Analog Converter (DAC) ==== -# some connections shared with SPI Flash, DAC, ADC, and AMP -#NET "DAC_CLR" LOC = "P8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -#NET "DAC_CS" LOC = "N8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -# ==== 1-Wire Secure EEPROM (DS) -#NET "DS_WIRE" LOC = "U4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -# ==== Ethernet PHY (E) ==== -#NET "E_COL" LOC = "U6" | IOSTANDARD = LVCMOS33 ; -#NET "E_CRS" LOC = "U13" | IOSTANDARD = LVCMOS33 ; -NET "E_MDC" LOC = "P9" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -NET "E_MDIO" LOC = "U5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -NET "E_RX_CLK" LOC = "V3" | IOSTANDARD = LVCMOS33 ; -NET "E_RX_DV" LOC = "V2" | IOSTANDARD = LVCMOS33 ; -NET "E_RXD<0>" LOC = "V8" | IOSTANDARD = LVCMOS33 ; -NET "E_RXD<1>" LOC = "T11" | IOSTANDARD = LVCMOS33 ; -NET "E_RXD<2>" LOC = "U11" | IOSTANDARD = LVCMOS33 ; -NET "E_RXD<3>" LOC = "V14" | IOSTANDARD = LVCMOS33 ; -#NET "E_RXD<4>" LOC = "U14" | IOSTANDARD = LVCMOS33 ; -NET "E_TX_CLK" LOC = "T7" | IOSTANDARD = LVCMOS33 ; -NET "E_TX_EN" LOC = "P15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -NET "E_TXD<0>" LOC = "R11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -NET "E_TXD<1>" LOC = "T15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -NET "E_TXD<2>" LOC = "R5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -NET "E_TXD<3>" LOC = "T5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -#NET "E_TXD<4>" LOC = "R6" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -# ==== FPGA Configuration Mode, INIT_B Pins (FPGA) ==== -#NET "FPGA_M0" LOC = "M10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -#NET "FPGA_M1" LOC = "V11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -#NET "FPGA_M2" LOC = "T10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; -#NET "FPGA_INIT_B" LOC = "T3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4 ; -#NET "FPGA_RDWR_B" LOC = "U10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4 ; -#NET "FPGA_HSWAP" LOC = "B3" | IOSTANDARD = LVCMOS33 ; -# ==== FX2 Connector (FX2) ==== -#NET "FX2_CLKIN" LOC = "E10" | IOSTANDARD = LVCMOS33 ; -#NET "FX2_CLKIO" LOC = "D9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_CLKOUT" LOC = "D10" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -# These four connections are shared with the J1 6-pin accessory header -#NET "FX2_IO<1>" LOC = "B4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<2>" LOC = "A4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<3>" LOC = "D5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<4>" LOC = "C5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -# These four connections are shared with the J2 6-pin accessory header -#NET "FX2_IO<5>" LOC = "A6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<6>" LOC = "B6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<7>" LOC = "E7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<8>" LOC = "F7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -# These four connections are shared with the J4 6-pin accessory header -#NET "FX2_IO<9>" LOC = "D7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<10>" LOC = "C7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<11>" LOC = "F8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<12>" LOC = "E8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -# The discrete LEDs are shared with the following 8 FX2 connections -#NET "FX2_IO<13>" LOC = "F9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<14>" LOC = "E9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<15>" LOC = "D11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<16>" LOC = "C11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<17>" LOC = "F11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<18>" LOC = "E11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<19>" LOC = "E12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<20>" LOC = "F12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<21>" LOC = "A13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<22>" LOC = "B13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<23>" LOC = "A14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<24>" LOC = "B14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<25>" LOC = "C14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<26>" LOC = "D14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<27>" LOC = "A16" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<28>" LOC = "B16" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<29>" LOC = "E13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<30>" LOC = "C4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<31>" LOC = "B11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<32>" LOC = "A11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<33>" LOC = "A8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<34>" LOC = "G9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IP<35>" LOC = "D12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IP<36>" LOC = "C12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IP<37>" LOC = "A15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IP<38>" LOC = "B15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IO<39>" LOC = "C3" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -#NET "FX2_IP<40>" LOC = "C15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ; -# ==== 6-pin header J1 ==== -# These are shared connections with the FX2 connector -#NET "J1<0>" LOC = "B4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J1<1>" LOC = "A4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J1<2>" LOC = "D5" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J1<3>" LOC = "C5" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -# ==== 6-pin header J2 ==== -# These are shared connections with the FX2 connector -#NET "J2<0>" LOC = "A6" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J2<1>" LOC = "B6" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J2<2>" LOC = "E7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J2<3>" LOC = "F7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -# ==== 6-pin header J4 ==== -# These are shared connections with the FX2 connector -#NET "J4<0>" LOC = "D7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J4<1>" LOC = "C7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J4<2>" LOC = "F8" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -#NET "J4<3>" LOC = "E8" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ; -# ==== Character LCD (LCD) ==== -#NET "LCD_E" LOC = "M18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -#NET "LCD_RS" LOC = "L18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -#NET "LCD_RW" LOC = "L17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -# LCD data connections are shared with StrataFlash connections SF_D<11:8> -#NET "SF_D<8>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -#NET "SF_D<9>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -#NET "SF_D<10>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -#NET "SF_D<11>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -# ==== Discrete LEDs (LED) ==== -# These are shared connections with the FX2 connector -NET "LED<0>" LOC = "F12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<1>" LOC = "E12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<2>" LOC = "E11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<3>" LOC = "F11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<4>" LOC = "C11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<5>" LOC = "D11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<6>" LOC = "E9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -NET "LED<7>" LOC = "F9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; -# ==== PS/2 Mouse/Keyboard Port (PS2) ==== -NET "PS2_CLK" LOC = "G14" | IOSTANDARD = LVCMOS33 ; -NET "PS2_DATA" LOC = "G13" | IOSTANDARD = LVCMOS33 ; -# ==== Rotary Pushbutton Switch (ROT) ==== -NET "ROT_A" LOC = "K18" | IOSTANDARD = LVTTL | PULLUP ; -NET "ROT_B" LOC = "G18" | IOSTANDARD = LVTTL | PULLUP ; -NET "ROT_CENTER" LOC = "V16" | IOSTANDARD = LVTTL | PULLDOWN ; -# ==== RS-232 Serial Ports (RS232) ==== -NET "RS232_DCE_RXD" LOC = "R7" | IOSTANDARD = LVTTL ; -NET "RS232_DCE_TXD" LOC = "M14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = SLOW ; -#NET "RS232_DTE_RXD" LOC = "U8" | IOSTANDARD = LVTTL ; -#NET "RS232_DTE_TXD" LOC = "M13" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = SLOW ; -# ==== DDR SDRAM (SD) ==== (I/O Bank 3, VCCO=2.5V) -NET "SD_A<0>" LOC = "T1" | IOSTANDARD = SSTL2_I ; -NET "SD_A<1>" LOC = "R3" | IOSTANDARD = SSTL2_I ; -NET "SD_A<2>" LOC = "R2" | IOSTANDARD = SSTL2_I ; -NET "SD_A<3>" LOC = "P1" | IOSTANDARD = SSTL2_I ; -NET "SD_A<4>" LOC = "F4" | IOSTANDARD = SSTL2_I ; -NET "SD_A<5>" LOC = "H4" | IOSTANDARD = SSTL2_I ; -NET "SD_A<6>" LOC = "H3" | IOSTANDARD = SSTL2_I ; -NET "SD_A<7>" LOC = "H1" | IOSTANDARD = SSTL2_I ; -NET "SD_A<8>" LOC = "H2" | IOSTANDARD = SSTL2_I ; -NET "SD_A<9>" LOC = "N4" | IOSTANDARD = SSTL2_I ; -NET "SD_A<10>" LOC = "T2" | IOSTANDARD = SSTL2_I ; -NET "SD_A<11>" LOC = "N5" | IOSTANDARD = SSTL2_I ; -NET "SD_A<12>" LOC = "P2" | IOSTANDARD = SSTL2_I ; -NET "SD_BA<0>" LOC = "K5" | IOSTANDARD = SSTL2_I ; -NET "SD_BA<1>" LOC = "K6" | IOSTANDARD = SSTL2_I ; -NET "SD_CAS" LOC = "C2" | IOSTANDARD = SSTL2_I ; -NET "SD_CK_N" LOC = "J4" | IOSTANDARD = SSTL2_I ; -NET "SD_CK_P" LOC = "J5" | IOSTANDARD = SSTL2_I ; -NET "SD_CKE" LOC = "K3" | IOSTANDARD = SSTL2_I ; -NET "SD_CS" LOC = "K4" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<0>" LOC = "L2" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<1>" LOC = "L1" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<2>" LOC = "L3" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<3>" LOC = "L4" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<4>" LOC = "M3" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<5>" LOC = "M4" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<6>" LOC = "M5" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<7>" LOC = "M6" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<8>" LOC = "E2" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<9>" LOC = "E1" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<10>" LOC = "F1" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<11>" LOC = "F2" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<12>" LOC = "G6" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<13>" LOC = "G5" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<14>" LOC = "H6" | IOSTANDARD = SSTL2_I ; -NET "SD_DQ<15>" LOC = "H5" | IOSTANDARD = SSTL2_I ; -NET "SD_LDM" LOC = "J2" | IOSTANDARD = SSTL2_I ; -NET "SD_LDQS" LOC = "L6" | IOSTANDARD = SSTL2_I ; -NET "SD_RAS" LOC = "C1" | IOSTANDARD = SSTL2_I ; -NET "SD_UDM" LOC = "J1" | IOSTANDARD = SSTL2_I ; -NET "SD_UDQS" LOC = "G3" | IOSTANDARD = SSTL2_I ; -NET "SD_WE" LOC = "D1" | IOSTANDARD = SSTL2_I ; -# Path to allow connection to top DCM connection -#NET "SD_CK_FB" LOC = "B9" | IOSTANDARD = LVCMOS33 ; -# Prohibit VREF pins -CONFIG PROHIBIT = D2; -CONFIG PROHIBIT = G4; -CONFIG PROHIBIT = J6; -CONFIG PROHIBIT = L5; -CONFIG PROHIBIT = R4; -# ==== Intel StrataFlash Parallel NOR Flash (SF) ==== -NET "SF_A<0>" LOC = "H17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<1>" LOC = "J13" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<2>" LOC = "J12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<3>" LOC = "J14" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<4>" LOC = "J15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<5>" LOC = "J16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<6>" LOC = "J17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<7>" LOC = "K14" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<8>" LOC = "K15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<9>" LOC = "K12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<10>" LOC = "K13" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<11>" LOC = "L15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<12>" LOC = "L16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<13>" LOC = "T18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<14>" LOC = "R18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<15>" LOC = "T17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<16>" LOC = "U18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<17>" LOC = "T16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<18>" LOC = "U15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<19>" LOC = "V15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<20>" LOC = "T12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<21>" LOC = "V13" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<22>" LOC = "V12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<23>" LOC = "N11" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_A<24>" LOC = "A11" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_BYTE" LOC = "C17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_CE0" LOC = "D16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<1>" LOC = "P10" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<2>" LOC = "R10" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<3>" LOC = "V9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<4>" LOC = "U9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<5>" LOC = "R9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<6>" LOC = "M9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<7>" LOC = "N9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<8>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<9>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<10>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<11>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<12>" LOC = "M16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<13>" LOC = "P6" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<14>" LOC = "R8" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_D<15>" LOC = "T8" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_OE" LOC = "C18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "SF_STS" LOC = "B18" | IOSTANDARD = LVCMOS33 ; -NET "SF_WE" LOC = "D17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -# ==== STMicro SPI serial Flash (SPI) ==== -# some connections shared with SPI Flash, DAC, ADC, and AMP -NET "SPI_MISO" LOC = "N10" | IOSTANDARD = LVCMOS33 ; -#NET "SPI_MOSI" LOC = "T4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -#NET "SPI_SCK" LOC = "U16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -#NET "SPI_SS_B" LOC = "U3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -#NET "SPI_ALT_CS_JP11" LOC = "R12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; -# ==== Slide Switches (SW) ==== -NET "SW<0>" LOC = "L13" | IOSTANDARD = LVTTL | PULLUP ; -NET "SW<1>" LOC = "L14" | IOSTANDARD = LVTTL | PULLUP ; -NET "SW<2>" LOC = "H18" | IOSTANDARD = LVTTL | PULLUP ; -NET "SW<3>" LOC = "N17" | IOSTANDARD = LVTTL | PULLUP ; -# ==== VGA Port (VGA) ==== -NET "VGA_BLUE" LOC = "G15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; -NET "VGA_GREEN" LOC = "H15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; -NET "VGA_HSYNC" LOC = "F15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; -NET "VGA_RED" LOC = "H14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; -NET "VGA_VSYNC" LOC = "F14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; -# ==== Xilinx CPLD (XC) ==== -#NET "XC_CMD<0>" LOC = "P18" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ; -#NET "XC_CMD<1>" LOC = "N18" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ; -#NET "XC_CPLD_EN" LOC = "B10" | IOSTANDARD = LVTTL ; -#NET "XC_D<0>" LOC = "G16" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ; -#NET "XC_D<1>" LOC = "F18" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ; -#NET "XC_D<2>" LOC = "F17" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ; -#NET "XC_TRIG" LOC = "R17" | IOSTANDARD = LVCMOS33 ; -#NET "XC_GCK0" LOC = "H16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -#NET "GCLK10" LOC = "C9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; -NET "CLK_50MHZ" TNM_NET = "CLK_50MHZ"; -NET "clk_reg1" TNM_NET = "clk_reg1"; -TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 40 ns HIGH 50 %; diff --git a/plasma/logic/plasma_3e.vhd b/plasma/logic/plasma_3e.vhd deleted file mode 100644 index 45f0378..0000000 --- a/plasma/logic/plasma_3e.vhd +++ /dev/null @@ -1,277 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; -use ieee.std_logic_arith.all; ---use work.mlite_pack.all; - -entity plasma_3e is - port(CLK_50MHZ : in std_logic; - RS232_DCE_RXD : in std_logic; - RS232_DCE_TXD : out std_logic; - - SD_CK_P : out std_logic; --DDR SDRAM clock_positive - SD_CK_N : out std_logic; --clock_negative - SD_CKE : out std_logic; --clock_enable - - SD_BA : out std_logic_vector(1 downto 0); --bank_address - SD_A : out std_logic_vector(12 downto 0); --address(row or col) - SD_CS : out std_logic; --chip_select - SD_RAS : out std_logic; --row_address_strobe - SD_CAS : out std_logic; --column_address_strobe - SD_WE : out std_logic; --write_enable - - SD_DQ : inout std_logic_vector(15 downto 0); --data - SD_UDM : out std_logic; --upper_byte_enable - SD_UDQS : inout std_logic; --upper_data_strobe - SD_LDM : out std_logic; --low_byte_enable - SD_LDQS : inout std_logic; --low_data_strobe - - E_MDC : out std_logic; --Ethernet PHY - E_MDIO : inout std_logic; --management data in/out - E_RX_CLK : in std_logic; --receive clock - E_RX_DV : in std_logic; --data valid - E_RXD : in std_logic_vector(3 downto 0); - E_TX_CLK : in std_logic; --transmit clock - E_TX_EN : out std_logic; --data valid - E_TXD : out std_logic_vector(3 downto 0); - - SF_CE0 : out std_logic; --NOR flash - SF_OE : out std_logic; - SF_WE : out std_logic; - SF_BYTE : out std_logic; - SF_STS : in std_logic; --status - SF_A : out std_logic_vector(24 downto 0); - SF_D : inout std_logic_vector(15 downto 1); - SPI_MISO : inout std_logic; - - VGA_VSYNC : out std_logic; --VGA port - VGA_HSYNC : out std_logic; - VGA_RED : out std_logic; - VGA_GREEN : out std_logic; - VGA_BLUE : out std_logic; - - PS2_CLK : in std_logic; --Keyboard - PS2_DATA : in std_logic; - - LED : out std_logic_vector(7 downto 0); - ROT_CENTER : in std_logic; - ROT_A : in std_logic; - ROT_B : in std_logic; - BTN_EAST : in std_logic; - BTN_NORTH : in std_logic; - BTN_SOUTH : in std_logic; - BTN_WEST : in std_logic; - SW : in std_logic_vector(3 downto 0)); -end; --entity plasma_if - - -architecture logic of plasma_3e is - - component plasma - generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; - log_file : string := "UNUSED"; - ethernet : std_logic := '0'; - use_cache : std_logic := '0'); - port(clk : in std_logic; - reset : in std_logic; - uart_write : out std_logic; - uart_read : in std_logic; - - address : out std_logic_vector(31 downto 2); - byte_we : out std_logic_vector(3 downto 0); - data_write : out std_logic_vector(31 downto 0); - data_read : in std_logic_vector(31 downto 0); - mem_pause_in : in std_logic; - no_ddr_start : out std_logic; - no_ddr_stop : out std_logic; - - gpio0_out : out std_logic_vector(31 downto 0); - gpioA_in : in std_logic_vector(31 downto 0)); - end component; --plasma - - component ddr_ctrl - port(clk : in std_logic; - clk_2x : in std_logic; - reset_in : in std_logic; - - address : in std_logic_vector(25 downto 2); - byte_we : in std_logic_vector(3 downto 0); - data_w : in std_logic_vector(31 downto 0); - data_r : out std_logic_vector(31 downto 0); - active : in std_logic; - no_start : in std_logic; - no_stop : in std_logic; - pause : out std_logic; - - SD_CK_P : out std_logic; --clock_positive - SD_CK_N : out std_logic; --clock_negative - SD_CKE : out std_logic; --clock_enable - - SD_BA : out std_logic_vector(1 downto 0); --bank_address - SD_A : out std_logic_vector(12 downto 0); --address(row or col) - SD_CS : out std_logic; --chip_select - SD_RAS : out std_logic; --row_address_strobe - SD_CAS : out std_logic; --column_address_strobe - SD_WE : out std_logic; --write_enable - - SD_DQ : inout std_logic_vector(15 downto 0); --data - SD_UDM : out std_logic; --upper_byte_enable - SD_UDQS : inout std_logic; --upper_data_strobe - SD_LDM : out std_logic; --low_byte_enable - SD_LDQS : inout std_logic); --low_data_strobe - end component; --ddr - - signal clk_reg : std_logic; - signal address : std_logic_vector(31 downto 2); - signal data_write : std_logic_vector(31 downto 0); - signal data_read : std_logic_vector(31 downto 0); - signal data_r_ddr : std_logic_vector(31 downto 0); - signal byte_we : std_logic_vector(3 downto 0); - signal write_enable : std_logic; - signal pause_ddr : std_logic; - signal pause : std_logic; - signal no_ddr_start : std_logic; - signal no_ddr_stop : std_logic; - signal ddr_active : std_logic; - signal flash_active : std_logic; - signal flash_cnt : std_logic_vector(1 downto 0); - signal flash_we : std_logic; - signal reset : std_logic; - signal gpio0_out : std_logic_vector(31 downto 0); - signal gpio0_in : std_logic_vector(31 downto 0); - -begin --architecture - --Divide 50 MHz clock by two - clk_div: process(reset, CLK_50MHZ, clk_reg) - begin - if reset = '1' then - clk_reg <= '0'; - elsif rising_edge(CLK_50MHZ) then - clk_reg <= not clk_reg; - end if; - end process; --clk_div - - reset <= ROT_CENTER; - E_TX_EN <= gpio0_out(28); --Ethernet - E_TXD <= gpio0_out(27 downto 24); - E_MDC <= gpio0_out(23); - E_MDIO <= gpio0_out(21) when gpio0_out(22) = '1' else 'Z'; - VGA_VSYNC <= gpio0_out(20); - VGA_HSYNC <= gpio0_out(19); - VGA_RED <= gpio0_out(18); - VGA_GREEN <= gpio0_out(17); - VGA_BLUE <= gpio0_out(16); - LED <= gpio0_out(7 downto 0); - gpio0_in(31 downto 21) <= (others => '0'); - gpio0_in(20 downto 13) <= E_RX_CLK & E_RX_DV & E_RXD & E_TX_CLK & E_MDIO; - gpio0_in(12 downto 10) <= SF_STS & PS2_CLK & PS2_DATA; - gpio0_in(9 downto 0) <= ROT_A & ROT_B & BTN_EAST & BTN_NORTH & - BTN_SOUTH & BTN_WEST & SW; - ddr_active <= '1' when address(31 downto 28) = "0001" else '0'; - flash_active <= '1' when address(31 downto 28) = "0011" else '0'; - write_enable <= '1' when byte_we /= "0000" else '0'; - - u1_plama: plasma - generic map (memory_type => "XILINX_16X", - log_file => "UNUSED", - ethernet => '1', - use_cache => '1') - --generic map (memory_type => "DUAL_PORT_", - -- log_file => "output2.txt", - -- ethernet => '1') - PORT MAP ( - clk => clk_reg, - reset => reset, - uart_write => RS232_DCE_TXD, - uart_read => RS232_DCE_RXD, - - address => address, - byte_we => byte_we, - data_write => data_write, - data_read => data_read, - mem_pause_in => pause, - no_ddr_start => no_ddr_start, - no_ddr_stop => no_ddr_stop, - - gpio0_out => gpio0_out, - gpioA_in => gpio0_in); - - u2_ddr: ddr_ctrl - port map ( - clk => clk_reg, - clk_2x => CLK_50MHZ, - reset_in => reset, - - address => address(25 downto 2), - byte_we => byte_we, - data_w => data_write, - data_r => data_r_ddr, - active => ddr_active, - no_start => no_ddr_start, - no_stop => no_ddr_stop, - pause => pause_ddr, - - SD_CK_P => SD_CK_P, --clock_positive - SD_CK_N => SD_CK_N, --clock_negative - SD_CKE => SD_CKE, --clock_enable - - SD_BA => SD_BA, --bank_address - SD_A => SD_A, --address(row or col) - SD_CS => SD_CS, --chip_select - SD_RAS => SD_RAS, --row_address_strobe - SD_CAS => SD_CAS, --column_address_strobe - SD_WE => SD_WE, --write_enable - - SD_DQ => SD_DQ, --data - SD_UDM => SD_UDM, --upper_byte_enable - SD_UDQS => SD_UDQS, --upper_data_strobe - SD_LDM => SD_LDM, --low_byte_enable - SD_LDQS => SD_LDQS); --low_data_strobe - - --Flash control (only lower 16-bit data lines connected) - flash_ctrl: process(reset, clk_reg, flash_active, write_enable, - flash_cnt, pause_ddr) - begin - if reset = '1' then - flash_cnt <= "00"; - flash_we <= '1'; - elsif rising_edge(clk_reg) then - if flash_active = '0' then - flash_cnt <= "00"; - flash_we <= '1'; - else - if write_enable = '1' and flash_cnt(1) = '0' then - flash_we <= '0'; - else - flash_we <= '1'; - end if; - if flash_cnt /= "11" then - flash_cnt <= flash_cnt + 1; - end if; - end if; - end if; --rising_edge(clk_reg) - if pause_ddr = '1' or (flash_active = '1' and flash_cnt /= "11") then - pause <= '1'; - else - pause <= '0'; - end if; - end process; --flash_ctrl - - SF_CE0 <= not flash_active; - SF_OE <= write_enable or not flash_active; - SF_WE <= flash_we; - SF_BYTE <= '1'; --16-bit access - SF_A <= address(25 downto 2) & '0' when flash_active = '1' else - "0000000000000000000000000"; - SF_D <= data_write(15 downto 1) when - flash_active = '1' and write_enable = '1' - else "ZZZZZZZZZZZZZZZ"; - SPI_MISO <= data_write(0) when - flash_active = '1' and write_enable = '1' - else 'Z'; - data_read(31 downto 16) <= data_r_ddr(31 downto 16); - data_read(15 downto 0) <= data_r_ddr(15 downto 0) when flash_active = '0' - else SF_D & SPI_MISO; - -end; --architecture logic - diff --git a/plasma/logic/plasma_TB.v b/plasma/logic/plasma_TB.v deleted file mode 100644 index c92be26..0000000 --- a/plasma/logic/plasma_TB.v +++ /dev/null @@ -1,58 +0,0 @@ -`timescale 1ns / 1ps - -module plasma_TB_v; - - reg clk; - reg reset; - - - plasma uut( .clk(clk), .reset(reset)); - - - parameter PERIOD = 20; - parameter real DUTY_CYCLE = 0.5; - parameter OFFSET = 0; - parameter TSET = 3; - parameter THLD = 3; - parameter NWS = 3; - parameter CAM_OFF = 4000; - - reg [15:0] data_tx; - - - event reset_trigger; - event reset_done_trigger; - - initial begin // Reset the system, Start the image capture process - forever begin - @ (reset_trigger); - @ (negedge clk); - reset = 1; - @ (negedge clk); - reset = 0; - -> reset_done_trigger; - end - end - - - initial begin // Initialize Inputs - clk = 0; - end - - initial begin // Process for clk - #OFFSET; - forever - begin - clk = 1'b0; - #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1; - #(PERIOD*DUTY_CYCLE); - end - end - - initial begin: TEST_CASE - #10 -> reset_trigger; - @ (reset_done_trigger); - // Write data to SRAM - end -endmodule - diff --git a/plasma/logic/plasma_TB.vhd b/plasma/logic/plasma_TB.vhd index 435236f..2be526e 100644 --- a/plasma/logic/plasma_TB.vhd +++ b/plasma/logic/plasma_TB.vhd @@ -20,45 +20,35 @@ end; --entity tbench architecture logic of tbench is constant memory_type : string := "TRI_PORT_X"; --- "DUAL_PORT_"; --- "ALTERA_LPM"; --- "XILINX_16X"; - - constant log_file : string := --- "UNUSED"; - "output.txt"; signal clk : std_logic := '1'; - signal reset : std_logic := '1'; - signal interrupt : std_logic := '0'; - signal mem_write : std_logic; - signal address : std_logic_vector(31 downto 2); - signal data_write : std_logic_vector(31 downto 0); - signal data_read : std_logic_vector(31 downto 0); - signal pause1 : std_logic := '0'; - signal pause2 : std_logic := '0'; - signal pause : std_logic; - signal byte_we : std_logic_vector(3 downto 0); - signal uart_write : std_logic; - signal gpioA_in : std_logic_vector(31 downto 0) := (others => '0'); -begin --architecture - --Uncomment the line below to test interrupts - --interrupt <= '1' after 20 us when interrupt = '0' else '0' after 445 ns; + signal reset : std_logic := '0'; + signal addr : std_logic_vector(12 downto 0); + signal sram_data : std_logic_vector(7 downto 0); + signal nwe : std_logic; + signal noe : std_logic; + signal ncs : std_logic; + signal led : std_logic; + signal TxD : std_logic; +begin --architecture clk <= not clk after 50 ns; - reset <= '0' after 500 ns; - pause <= '0'; + reset <= '1' after 500 ns; + u1_plasma: plasma - generic map (memory_type => memory_type, - log_file => log_file) + generic map (memory_type => memory_type) PORT MAP ( clk => clk, reset => reset, - uart_read => uart_write, - uart_write => uart_write, - data_read => data_read, - mem_pause_in => pause + U_RxD => TxD, + U_TxD => TxD, + addr => addr, + sram_data => sram_data, + nwe => nwe, + noe => noe, + ncs => ncs, + led => led ); end; --architecture logic diff --git a/plasma/logic/plasma_if.ucf b/plasma/logic/plasma_if.ucf deleted file mode 100644 index 51b354f..0000000 --- a/plasma/logic/plasma_if.ucf +++ /dev/null @@ -1,111 +0,0 @@ -NET "clk_in" TNM_NET = "clk_in"; -TIMESPEC "TS_clk_in" = PERIOD "clk_in" 20 ns HIGH 50 %; -#NET "clk_reg1" TNM_NET = "clk_reg1"; -#TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 40 ns HIGH 50 %; -NET "clk_reg1" TNM_NET = "clk_reg1"; -TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 39.9 ns HIGH 50 %; -#PACE: Start of Constraints generated by PACE -#PACE: Start of PACE I/O Pin Assignments -NET "clk_in" LOC = "T9"; -NET "gpio0_out<0>" LOC = "K12"; -NET "gpio0_out<10>" LOC = "N15"; -NET "gpio0_out<11>" LOC = "P15"; -NET "gpio0_out<12>" LOC = "R16"; -NET "gpio0_out<13>" LOC = "F13"; -NET "gpio0_out<14>" LOC = "N16"; -NET "gpio0_out<15>" LOC = "P16"; -NET "gpio0_out<16>" LOC = "E13"; -NET "gpio0_out<17>" LOC = "F14"; -NET "gpio0_out<18>" LOC = "G14"; -NET "gpio0_out<19>" LOC = "D14"; -NET "gpio0_out<1>" LOC = "P14"; -NET "gpio0_out<24>" LOC = "R12"; -NET "gpio0_out<25>" LOC = "T12"; -NET "gpio0_out<26>" LOC = "R11"; -NET "gpio0_out<27>" LOC = "R9"; -NET "gpio0_out<28>" LOC = "T10"; -NET "gpio0_out<2>" LOC = "L12"; -NET "gpio0_out<3>" LOC = "N14"; -NET "gpio0_out<4>" LOC = "P13"; -NET "gpio0_out<5>" LOC = "N12"; -NET "gpio0_out<6>" LOC = "P12"; -NET "gpio0_out<7>" LOC = "P11"; -NET "gpio0_out<8>" LOC = "E14"; -NET "gpio0_out<9>" LOC = "G13"; -NET "gpioA_in<0>" LOC = "F12"; -NET "gpioA_in<10>" LOC = "L13"; -NET "gpioA_in<1>" LOC = "G12"; -NET "gpioA_in<2>" LOC = "H14"; -NET "gpioA_in<30>" LOC = "M15"; -NET "gpioA_in<31>" LOC = "M16"; -NET "gpioA_in<3>" LOC = "H13"; -NET "gpioA_in<4>" LOC = "J14"; -NET "gpioA_in<5>" LOC = "J13"; -NET "gpioA_in<6>" LOC = "K14"; -NET "gpioA_in<7>" LOC = "K13"; -NET "gpioA_in<8>" LOC = "M13"; -NET "gpioA_in<9>" LOC = "M14"; -NET "ram_address<10>" LOC = "E3"; -NET "ram_address<11>" LOC = "E4"; -NET "ram_address<12>" LOC = "G5"; -NET "ram_address<13>" LOC = "H3"; -NET "ram_address<14>" LOC = "H4"; -NET "ram_address<15>" LOC = "J4"; -NET "ram_address<16>" LOC = "J3"; -NET "ram_address<17>" LOC = "K3"; -NET "ram_address<18>" LOC = "K5"; -NET "ram_address<19>" LOC = "L3"; -NET "ram_address<2>" LOC = "L5"; -NET "ram_address<3>" LOC = "N3"; -NET "ram_address<4>" LOC = "M4"; -NET "ram_address<5>" LOC = "M3"; -NET "ram_address<6>" LOC = "L4"; -NET "ram_address<7>" LOC = "G4"; -NET "ram_address<8>" LOC = "F3"; -NET "ram_address<9>" LOC = "F4"; -NET "ram_ce1_n" LOC = "P7"; -NET "ram_ce2_n" LOC = "N5"; -NET "ram_data<0>" LOC = "P2"; -NET "ram_data<10>" LOC = "G1"; -NET "ram_data<11>" LOC = "F5"; -NET "ram_data<12>" LOC = "C3"; -NET "ram_data<13>" LOC = "K2"; -NET "ram_data<14>" LOC = "M1"; -NET "ram_data<15>" LOC = "N1"; -NET "ram_data<16>" LOC = "N7"; -NET "ram_data<17>" LOC = "T8"; -NET "ram_data<18>" LOC = "R6"; -NET "ram_data<19>" LOC = "T5"; -NET "ram_data<1>" LOC = "N2"; -NET "ram_data<20>" LOC = "R5"; -NET "ram_data<21>" LOC = "C2"; -NET "ram_data<22>" LOC = "C1"; -NET "ram_data<23>" LOC = "B1"; -NET "ram_data<24>" LOC = "D3"; -NET "ram_data<25>" LOC = "P8"; -NET "ram_data<26>" LOC = "F2"; -NET "ram_data<27>" LOC = "H1"; -NET "ram_data<28>" LOC = "J2"; -NET "ram_data<29>" LOC = "L2"; -NET "ram_data<2>" LOC = "M2"; -NET "ram_data<30>" LOC = "P1"; -NET "ram_data<31>" LOC = "R1"; -NET "ram_data<3>" LOC = "K1"; -NET "ram_data<4>" LOC = "J1"; -NET "ram_data<5>" LOC = "G2"; -NET "ram_data<6>" LOC = "E1"; -NET "ram_data<7>" LOC = "D1"; -NET "ram_data<8>" LOC = "D2"; -NET "ram_data<9>" LOC = "E2"; -NET "ram_lb1_n" LOC = "P6"; -NET "ram_lb2_n" LOC = "P5"; -NET "ram_oe_n" LOC = "K4"; -NET "ram_ub1_n" LOC = "T4"; -NET "ram_ub2_n" LOC = "R4"; -NET "ram_we_n" LOC = "G3"; -NET "reset" LOC = "L14"; -NET "uart_read" LOC = "T13"; -NET "uart_write" LOC = "R13"; -#PACE: Start of PACE Area Constraints -#PACE: Start of PACE Prohibit Constraints -#PACE: End of Constraints generated by PACE diff --git a/plasma/logic/plasma_if.vhd b/plasma/logic/plasma_if.vhd deleted file mode 100644 index e36530e..0000000 --- a/plasma/logic/plasma_if.vhd +++ /dev/null @@ -1,152 +0,0 @@ ---------------------------------------------------------------------- --- TITLE: Plamsa Interface (clock divider and interface to FPGA board) --- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) --- DATE CREATED: 6/6/02 --- FILENAME: plasma_if.vhd --- PROJECT: Plasma CPU core --- COPYRIGHT: Software placed into the public domain by the author. --- Software 'as is' without warranty. Author liable for nothing. --- DESCRIPTION: --- This entity divides the clock by two and interfaces to the --- Altera EP20K200EFC484-2X FPGA board. --- Xilinx Spartan-3 XC3S200FT256-4 FPGA. ---------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; ---use work.mlite_pack.all; - -entity plasma_if is - port(clk_in : in std_logic; - reset : in std_logic; - uart_read : in std_logic; - uart_write : out std_logic; - - ram_address : out std_logic_vector(31 downto 2); - ram_data : inout std_logic_vector(31 downto 0); - ram_ce1_n : out std_logic; - ram_ub1_n : out std_logic; - ram_lb1_n : out std_logic; - ram_ce2_n : out std_logic; - ram_ub2_n : out std_logic; - ram_lb2_n : out std_logic; - ram_we_n : out std_logic; - ram_oe_n : out std_logic; - - gpio0_out : out std_logic_vector(31 downto 0); - gpioA_in : in std_logic_vector(31 downto 0)); -end; --entity plasma_if - - -architecture logic of plasma_if is - - component plasma - generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; - log_file : string := "UNUSED"); - port(clk : in std_logic; - reset : in std_logic; - uart_write : out std_logic; - uart_read : in std_logic; - - address : out std_logic_vector(31 downto 2); - byte_we : out std_logic_vector(3 downto 0); - data_write : out std_logic_vector(31 downto 0); - data_read : in std_logic_vector(31 downto 0); - mem_pause_in : in std_logic; - - gpio0_out : out std_logic_vector(31 downto 0); - gpioA_in : in std_logic_vector(31 downto 0)); - end component; --plasma - - signal clk_reg : std_logic; - signal we_n_next : std_logic; - signal we_n_reg : std_logic; - signal mem_address : std_logic_vector(31 downto 2); - signal data_write : std_logic_vector(31 downto 0); - signal data_reg : std_logic_vector(31 downto 0); - signal byte_we : std_logic_vector(3 downto 0); - signal mem_pause_in : std_logic; - -begin --architecture - --Divide 50 MHz clock by two - clk_div: process(reset, clk_in, clk_reg, we_n_next) - begin - if reset = '1' then - clk_reg <= '0'; - elsif rising_edge(clk_in) then - clk_reg <= not clk_reg; - end if; - - if reset = '1' then - we_n_reg <= '1'; - data_reg <= (others => '0'); - elsif falling_edge(clk_in) then - we_n_reg <= we_n_next or not clk_reg; - data_reg <= ram_data; - end if; - end process; --clk_div - - mem_pause_in <= '0'; - ram_address <= mem_address(31 downto 2); - ram_we_n <= we_n_reg; - - --For Xilinx Spartan-3 Starter Kit - ram_control: - process(clk_reg, mem_address, byte_we, data_write) - begin - if mem_address(30 downto 28) = "001" then --RAM - ram_ce1_n <= '0'; - ram_ce2_n <= '0'; - if byte_we = "0000" then --read - ram_data <= (others => 'Z'); - ram_ub1_n <= '0'; - ram_lb1_n <= '0'; - ram_ub2_n <= '0'; - ram_lb2_n <= '0'; - we_n_next <= '1'; - ram_oe_n <= '0'; - else --write - if clk_reg = '1' then - ram_data <= (others => 'Z'); - else - ram_data <= data_write; - end if; - ram_ub1_n <= not byte_we(3); - ram_lb1_n <= not byte_we(2); - ram_ub2_n <= not byte_we(1); - ram_lb2_n <= not byte_we(0); - we_n_next <= '0'; - ram_oe_n <= '1'; - end if; - else - ram_data <= (others => 'Z'); - ram_ce1_n <= '1'; - ram_ub1_n <= '1'; - ram_lb1_n <= '1'; - ram_ce2_n <= '1'; - ram_ub2_n <= '1'; - ram_lb2_n <= '1'; - we_n_next <= '1'; - ram_oe_n <= '1'; - end if; - end process; --ram_control - - u1_plama: plasma - generic map (memory_type => "XILINX_16X", - log_file => "UNUSED") - PORT MAP ( - clk => clk_reg, - reset => reset, - uart_write => uart_write, - uart_read => uart_read, - - address => mem_address, - byte_we => byte_we, - data_write => data_write, - data_read => data_reg, - mem_pause_in => mem_pause_in, - - gpio0_out => gpio0_out, - gpioA_in => gpioA_in); - -end; --architecture logic - diff --git a/plasma/logic/ram.vhd b/plasma/logic/ram.vhd deleted file mode 100644 index 9c0f511..0000000 --- a/plasma/logic/ram.vhd +++ /dev/null @@ -1,176 +0,0 @@ ---------------------------------------------------------------------- --- TITLE: Random Access Memory --- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) --- DATE CREATED: 4/21/01 --- FILENAME: ram.vhd --- PROJECT: Plasma CPU core --- COPYRIGHT: Software placed into the public domain by the author. --- Software 'as is' without warranty. Author liable for nothing. --- DESCRIPTION: --- Implements the RAM, reads the executable from either "code.txt", --- or for Altera "code[0-3].hex". --- Modified from "The Designer's Guide to VHDL" by Peter J. Ashenden ---------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_misc.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_unsigned.all; -use ieee.std_logic_textio.all; -use std.textio.all; -use work.mlite_pack.all; - -entity ram is - generic(memory_type : string := "DEFAULT"); - port(clk : in std_logic; - enable : in std_logic; - write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(31 downto 2); - data_write : in std_logic_vector(31 downto 0); - data_read : out std_logic_vector(31 downto 0)); -end; --entity ram - -architecture logic of ram is - constant ADDRESS_WIDTH : natural := 13; -begin - - generic_ram: - if memory_type /= "ALTERA_LPM" generate - begin - --Simulate a synchronous RAM - ram_proc: process(clk, enable, write_byte_enable, - address, data_write) --mem_write, mem_sel - variable mem_size : natural := 2 ** ADDRESS_WIDTH; - variable data : std_logic_vector(31 downto 0); - subtype word is std_logic_vector(data_write'length-1 downto 0); - type storage_array is - array(natural range 0 to mem_size/4 - 1) of word; - variable storage : storage_array; - variable index : natural := 0; - file load_file : text open read_mode is "code.txt"; - variable hex_file_line : line; - begin - - --Load in the ram executable image - if index = 0 then - while not endfile(load_file) loop ---The following two lines had to be commented out for synthesis - readline(load_file, hex_file_line); - hread(hex_file_line, data); - storage(index) := data; - index := index + 1; - end loop; - end if; - - if rising_edge(clk) then - index := conv_integer(address(ADDRESS_WIDTH-1 downto 2)); - data := storage(index); - - if enable = '1' then - if write_byte_enable(0) = '1' then - data(7 downto 0) := data_write(7 downto 0); - end if; - if write_byte_enable(1) = '1' then - data(15 downto 8) := data_write(15 downto 8); - end if; - if write_byte_enable(2) = '1' then - data(23 downto 16) := data_write(23 downto 16); - end if; - if write_byte_enable(3) = '1' then - data(31 downto 24) := data_write(31 downto 24); - end if; - end if; - - if write_byte_enable /= "0000" then - storage(index) := data; - end if; - end if; - - data_read <= data; - end process; - end generate; --generic_ram - - - altera_ram: - if memory_type = "ALTERA_LPM" generate - signal byte_we : std_logic_vector(3 downto 0); - begin - byte_we <= write_byte_enable when enable = '1' else "0000"; - lpm_ram_io_component0 : lpm_ram_dq - GENERIC MAP ( - intended_device_family => "UNUSED", - lpm_width => 8, - lpm_widthad => ADDRESS_WIDTH-2, - lpm_indata => "REGISTERED", - lpm_address_control => "REGISTERED", - lpm_outdata => "UNREGISTERED", - lpm_file => "code0.hex", - use_eab => "ON", - lpm_type => "LPM_RAM_DQ") - PORT MAP ( - data => data_write(31 downto 24), - address => address(ADDRESS_WIDTH-1 downto 2), - inclock => clk, - we => byte_we(3), - q => data_read(31 downto 24)); - - lpm_ram_io_component1 : lpm_ram_dq - GENERIC MAP ( - intended_device_family => "UNUSED", - lpm_width => 8, - lpm_widthad => ADDRESS_WIDTH-2, - lpm_indata => "REGISTERED", - lpm_address_control => "REGISTERED", - lpm_outdata => "UNREGISTERED", - lpm_file => "code1.hex", - use_eab => "ON", - lpm_type => "LPM_RAM_DQ") - PORT MAP ( - data => data_write(23 downto 16), - address => address(ADDRESS_WIDTH-1 downto 2), - inclock => clk, - we => byte_we(2), - q => data_read(23 downto 16)); - - lpm_ram_io_component2 : lpm_ram_dq - GENERIC MAP ( - intended_device_family => "UNUSED", - lpm_width => 8, - lpm_widthad => ADDRESS_WIDTH-2, - lpm_indata => "REGISTERED", - lpm_address_control => "REGISTERED", - lpm_outdata => "UNREGISTERED", - lpm_file => "code2.hex", - use_eab => "ON", - lpm_type => "LPM_RAM_DQ") - PORT MAP ( - data => data_write(15 downto 8), - address => address(ADDRESS_WIDTH-1 downto 2), - inclock => clk, - we => byte_we(1), - q => data_read(15 downto 8)); - - lpm_ram_io_component3 : lpm_ram_dq - GENERIC MAP ( - intended_device_family => "UNUSED", - lpm_width => 8, - lpm_widthad => ADDRESS_WIDTH-2, - lpm_indata => "REGISTERED", - lpm_address_control => "REGISTERED", - lpm_outdata => "UNREGISTERED", - lpm_file => "code3.hex", - use_eab => "ON", - lpm_type => "LPM_RAM_DQ") - PORT MAP ( - data => data_write(7 downto 0), - address => address(ADDRESS_WIDTH-1 downto 2), - inclock => clk, - we => byte_we(0), - q => data_read(7 downto 0)); - - end generate; --altera_ram - - - --For XILINX see ram_xilinx.vhd - -end; --architecture logic diff --git a/plasma/logic/ram_image.vhd b/plasma/logic/ram_image.vhd index c4f51a3..a036101 100644 --- a/plasma/logic/ram_image.vhd +++ b/plasma/logic/ram_image.vhd @@ -27,11 +27,10 @@ library UNISIM; use UNISIM.vcomponents.all; entity ram is - generic(memory_type : string := "DEFAULT"); port(clk : in std_logic; enable : in std_logic; write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(31 downto 2); + address : in std_logic_vector(10 downto 0); data_write : in std_logic_vector(31 downto 0); data_read : out std_logic_vector(31 downto 0)); end; --entity ram @@ -45,12 +44,12 @@ INIT_00 => X"afafafafafafafafafafafafafafafaf2308000c241400ac273c243c243c273c", INIT_01 => X"8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f230c008c8c3caf00af00af2340afaf", INIT_02 => X"acacacac0003373cac038cac8cac8cac8c243c40034040033423038f038f8f8f", INIT_03 => X"000300ac0300000034038c8c8c8c8c8c8c8c8c8c8c8c3403acacacacacacacac", -INIT_04 => X"ad343434343c3ca5a5242434a534a1242434a134a0242434a034a0242434343c", -INIT_05 => X"0080afafaf270003ac001030008c343c0003ac8c34943c908d349434913434ad", -INIT_06 => X"afaf272703008f8f8f00140082000c2682000c241400100082260c0024080010", -INIT_07 => X"000caf2730038c343c240827038f8f8f8f0216260c2424142c3002242400afaf", -INIT_08 => X"000000000000000000000024038c0014ac00248c3c24243c3c2703008f8c3c10", -INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"3c34ac343c34a42434a42434a42434a02434a02434a02434a02434a024343c27", +INIT_05 => X"8cac343caf008c34a730009434a330009034af008ca730009434a3300090ac34", +INIT_06 => X"82240c00142400100080afafaf270003ac3c1030008c343c0008af008c34af00", +INIT_07 => X"26240c2608240c00102c3002242400afafafaf2727038f8f8f0000140082260c", +INIT_08 => X"2703008f8c3c10000caf2730038c343c2703008f240caf2727038f8f8f8f0216", +INIT_09 => X"000000000000000000000000000000000024038c001424ac00008c243c3c243c", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -108,7 +107,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(31 downto 24), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(31 downto 24), DIP => ZERO(0 downto 0), @@ -122,12 +121,12 @@ INIT_00 => X"b8afaeadacabaaa9a8a7a6a5a4a3a2a1bd000000a560a4a0bd1d8404a5059c1c", INIT_01 => X"b9b8afaeadacabaaa9a8a7a6a5a4a3a2a1a50086c6c406bb00bb00ba5a1abfb9", INIT_02 => X"9392919000405a1a06e0a606a606a606a6a50584e0029b401bbd60bb60bbbabf", INIT_03 => X"00e000c4e0000085a2e09f9d9c9e979695949392919002e09f9d9c9e97969594", -INIT_04 => X"8263428c8e0302634203028b238aa2030289038de2030288c387a20302868504", -INIT_05 => X"0082b1bfb0bd00e0a40040420062a30500e0a2a342860262c6844785a68382c3", -INIT_06 => X"b1b2bdbde000b0b1bf0040000240001002000004510040000210004011008040", -INIT_07 => X"0000bfbd42e06263030400bde0b0b1b2bf12111000646440624312111080bfb0", -INIT_08 => X"000000040000802400800042e0a20083404584820563440302bde000bf620340", -INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"026482420264820264820264820264a2026582026482026482026482026403bd", +INIT_05 => X"62624202a2004262a242004262a242004262a20082a242004262a24200a28242", +INIT_06 => X"04040000511180400082b0b1bfbd00e044024042006243020000a2006263a200", +INIT_07 => X"108400100084000040824412111080b0b1b2bfbdbde0b0b1bf00004000021000", +INIT_08 => X"bde000bf4202400000bfbd42e0424202bde000bf0400bfbdbde0b0b1b2bf1211", +INIT_09 => X"000000000000000000040000802400800042e0a2006463404500624402054302", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -185,7 +184,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(23 downto 16), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(23 downto 16), DIP => ZERO(0 downto 0), @@ -196,15 +195,15 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") RAMB16_S9_inst2 : RAMB16_S9 generic map ( INIT_00 => X"00000000000000000000000000000000ff00000000ff18000600060004008400", -INIT_01 => X"000000000000000000000000000000000000002000002000d800d800ff700000", +INIT_01 => X"000000000000000000000000000000000000012000002000d800d800ff700000", INIT_02 => X"0000000000000010000000000000000000010060006060000000000000000000", INIT_03 => X"0000000000201000000000000000000000000000000000000000000000000000", -INIT_04 => X"0031303030313000002221200020002000200010000000100010000000101020", -INIT_05 => X"0000000000ff00000010ff000000002010000000aa00aa000020003000102000", -INIT_06 => X"0000ff00001000000000ff000020000000000000ff0000000000002000008000", -INIT_07 => X"000000ff0000000020000000000000000010ffff00000000000010ff00900000", -INIT_08 => X"000000200000002028000000000000ff001000001004040000000000000020ff", -INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"31030030300300220200210200200200000400000400000400000400000420ff", +INIT_05 => X"000055550000000300ff000002000000000400000000ff000002000000000031", +INIT_06 => X"00000000000080000000000000ff10000020ff00000000200000000000000000", +INIT_07 => X"ff0000ff0100000000000010ff009000000000ff00000000001000ff00000000", +INIT_08 => X"000000000020ff000100ff000000002000000000000000ff00000000000010ff", +INIT_09 => X"000000000000000000200000002028000000000000ff00001000000400100400", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -262,7 +261,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(15 downto 8), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(15 downto 8), DIP => ZERO(0 downto 0), @@ -272,16 +271,16 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") RAMB16_S9_inst3 : RAMB16_S9 generic map ( -INIT_00 => X"4c4844403c3834302c2824201c181410980e008004fd2a006800800074007001", -INIT_01 => X"504c4844403c3834302c2824201c18141000f52410200060125c1058fc005450", +INIT_00 => X"4c4844403c3834302c2824201c181410980e008004fd2a00c800e000dc00d001", +INIT_01 => X"504c4844403c3834302c2824201c18141000082410200060125c1058fc005450", INIT_02 => X"0c08040000083c0048080c440840043c006000000800000801681360115c5854", INIT_03 => X"00080c000810121900082c2824201c1814100c08040000082c2824201c181410", -INIT_04 => X"0031300004313000002221040002002014000004001312030002001110010000", -INIT_05 => X"0000141810e000080021fc020000200021080000aa00aa000008000800080600", -INIT_06 => X"1418e020082110141800f5000021b0010000b00df8000d000001b0210acb2116", -INIT_07 => X"00f710e8010800200049b020081014181c06f8fcb05730020a0f06fc1c211c10", -INIT_08 => X"000000001010200000207084080000fb002104000074540000180800100000fd", -INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"31340030303000221400211200201000141400131300121200111100101000f8", +INIT_05 => X"000055550400003802ff00001800ff00001804000002ff00001600ff00000031", +INIT_06 => X"000dc800030a210d0000101418e021080000fc020000200000c6040000200400", +INIT_07 => X"fc57c8fc0030c800050a0f06fc1c211014181ce020081014182100f6000001c8", +INIT_08 => X"180800100000fd001010e801080020001808001049c810e820081014181c06f4", +INIT_09 => X"000000000000000000001010200000207084080000fa0400210000dc0000bc00", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -339,7 +338,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(7 downto 0), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(7 downto 0), DIP => ZERO(0 downto 0), diff --git a/plasma/logic/ram_xilinx.vhd b/plasma/logic/ram_xilinx.vhd index ac24e1f..c09aa9f 100644 --- a/plasma/logic/ram_xilinx.vhd +++ b/plasma/logic/ram_xilinx.vhd @@ -27,11 +27,10 @@ library UNISIM; use UNISIM.vcomponents.all; entity ram is - generic(memory_type : string := "DEFAULT"); port(clk : in std_logic; enable : in std_logic; write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(31 downto 2); + address : in std_logic_vector(10 downto 0); data_write : in std_logic_vector(31 downto 0); data_read : out std_logic_vector(31 downto 0)); end; --entity ram @@ -108,7 +107,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(31 downto 24), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(31 downto 24), DIP => ZERO(0 downto 0), @@ -185,7 +184,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(23 downto 16), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(23 downto 16), DIP => ZERO(0 downto 0), @@ -262,7 +261,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(15 downto 8), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(15 downto 8), DIP => ZERO(0 downto 0), @@ -339,7 +338,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(7 downto 0), DOP => open, - ADDR => address(12 downto 2), + ADDR => address(10 downto 0), CLK => clk, DI => data_write(7 downto 0), DIP => ZERO(0 downto 0), diff --git a/plasma/logic/reg_bank.vhd b/plasma/logic/reg_bank.vhd index f7a0552..f2b1d93 100644 --- a/plasma/logic/reg_bank.vhd +++ b/plasma/logic/reg_bank.vhd @@ -235,89 +235,4 @@ end process; data_out2 <= data_out2A when addr_read2(4)='0' else data_out2B; end generate; --xilinx_16x1d - - -- Option #4 - -- Altera LPM_RAM_DP - altera_mem: - if memory_type = "ALTERA_LPM" generate - signal clk_delayed : std_logic; - signal addr_reg : std_logic_vector(4 downto 0); - signal data_reg : std_logic_vector(31 downto 0); - signal q1 : std_logic_vector(31 downto 0); - signal q2 : std_logic_vector(31 downto 0); - begin - -- Altera dual port RAMs must have the addresses registered (sampled - -- at the rising edge). This is very unfortunate. - -- Therefore, the dual port RAM read clock must delayed so that - -- the read address signal can be sent from the mem_ctrl block. - -- This solution also delays the how fast the registers are read so the - -- maximum clock speed is cut in half (12.5 MHz instead of 25 MHz). - - clk_delayed <= not clk; --Could be delayed by 1/4 clock cycle instead - dpram_bypass: process(clk, addr_write, reg_dest_new) - begin - if rising_edge(clk) and write_enable = '1' then - addr_reg <= addr_write; - data_reg <= reg_dest_new; - end if; - end process; --dpram_bypass - - -- Bypass dpram if reading what was just written (Altera limitation) - data_out1 <= q1 when addr_read1 /= addr_reg else data_reg; - data_out2 <= q2 when addr_read2 /= addr_reg else data_reg; - - lpm_ram_dp_component1 : lpm_ram_dp - generic map ( - LPM_WIDTH => 32, - LPM_WIDTHAD => 5, - --LPM_NUMWORDS => 0, - LPM_INDATA => "REGISTERED", - LPM_OUTDATA => "UNREGISTERED", - LPM_RDADDRESS_CONTROL => "REGISTERED", - LPM_WRADDRESS_CONTROL => "REGISTERED", - LPM_FILE => "UNUSED", - LPM_TYPE => "LPM_RAM_DP", - USE_EAB => "ON", - INTENDED_DEVICE_FAMILY => "UNUSED", - RDEN_USED => "FALSE", - LPM_HINT => "UNUSED") - port map ( - RDCLOCK => clk_delayed, - RDCLKEN => '1', - RDADDRESS => addr_read1, - RDEN => '1', - DATA => reg_dest_new, - WRADDRESS => addr_write, - WREN => write_enable, - WRCLOCK => clk, - WRCLKEN => '1', - Q => q1); - lpm_ram_dp_component2 : lpm_ram_dp - generic map ( - LPM_WIDTH => 32, - LPM_WIDTHAD => 5, - --LPM_NUMWORDS => 0, - LPM_INDATA => "REGISTERED", - LPM_OUTDATA => "UNREGISTERED", - LPM_RDADDRESS_CONTROL => "REGISTERED", - LPM_WRADDRESS_CONTROL => "REGISTERED", - LPM_FILE => "UNUSED", - LPM_TYPE => "LPM_RAM_DP", - USE_EAB => "ON", - INTENDED_DEVICE_FAMILY => "UNUSED", - RDEN_USED => "FALSE", - LPM_HINT => "UNUSED") - port map ( - RDCLOCK => clk_delayed, - RDCLKEN => '1', - RDADDRESS => addr_read2, - RDEN => '1', - DATA => reg_dest_new, - WRADDRESS => addr_write, - WREN => write_enable, - WRCLOCK => clk, - WRCLKEN => '1', - Q => q2); - end generate; --altera_mem - end; --architecture ram_block diff --git a/plasma/logic/simulation/wave.do b/plasma/logic/simulation/wave.do index 68be45e..f8acb40 100644 --- a/plasma/logic/simulation/wave.do +++ b/plasma/logic/simulation/wave.do @@ -2,25 +2,30 @@ onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate -format Logic /tbench/clk add wave -noupdate -format Logic /tbench/reset -add wave -noupdate -format Logic /tbench/interrupt -add wave -noupdate -format Logic /tbench/mem_write -add wave -noupdate -format Literal -radix hexadecimal /tbench/data_read add wave -noupdate -format Logic /tbench/pause1 add wave -noupdate -format Logic /tbench/pause2 add wave -noupdate -format Logic /tbench/pause -add wave -noupdate -format Logic /tbench/u1_plasma/enable_misc -add wave -noupdate -format Logic /tbench/u1_plasma/enable_uart -add wave -noupdate -format Logic /tbench/uart_write -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_data_w -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_data_r -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/address_next -add wave -noupdate -format Literal /tbench/gpioa_in -add wave -noupdate -format Logic /tbench/u1_plasma/write_enable add wave -noupdate -format Literal /tbench/u1_plasma/cpu_byte_we add wave -noupdate -format Literal -expand /tbench/u1_plasma/byte_we_next +add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_address +add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/address_next +add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_data_w +add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_data_r +add wave -noupdate -format Logic /tbench/u1_plasma/cs_ram +add wave -noupdate -format Logic /tbench/u1_plasma/cs_uart +add wave -noupdate -format Literal /tbench/u1_plasma/u3_uart/addr +add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/enable_read +add wave -noupdate -format Literal /tbench/u1_plasma/u3_uart/addr +add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/enable_write +add wave -noupdate -format Logic /tbench/u1_plasma/u_txd +add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/busy_write +add wave -noupdate -format Logic /tbench/u1_plasma/u_rxd +add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/data_avail +add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/u3_uart/data_in +add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/u3_uart/data_out TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {75144797 ps} 0} -configure wave -namecolwidth 269 +WaveRestoreCursors {{Cursor 1} {999785196 ps} 0} +configure wave -namecolwidth 285 configure wave -valuecolwidth 40 configure wave -justifyvalue left configure wave -signalnamewidth 0 @@ -33,4 +38,4 @@ configure wave -gridperiod 1 configure wave -griddelta 40 configure wave -timeline 0 update -WaveRestoreZoom {71704646 ps} {72130128 ps} +WaveRestoreZoom {0 ps} {1050 us} diff --git a/plasma/logic/simulation/wave1.do b/plasma/logic/simulation/wave1.do index 076d7af..bf59c9a 100644 --- a/plasma/logic/simulation/wave1.do +++ b/plasma/logic/simulation/wave1.do @@ -2,16 +2,14 @@ onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate -format Logic /plasma_TB_v/clk add wave -noupdate -format Logic /plasma_TB_v/reset -add wave -noupdate -format Literal /plasma_TB_v/data_tx -add wave -noupdate -format Event /plasma_TB_v/reset_trigger add wave -noupdate -format Event /plasma_TB_v/reset_done_trigger -add wave -noupdate -format Literal /plasma_TB_v/uut/data_read -add wave -noupdate -format Logic /plasma_TB_v/uut/ram_enable add wave -noupdate -format Literal -radix hexadecimal /plasma_TB_v/uut/cpu_data_w add wave -noupdate -format Literal -radix hexadecimal /plasma_TB_v/uut/cpu_data_r -add wave -noupdate -format Literal /plasma_TB_v/uut/byte_we_next +add wave -noupdate -format Literal -radix binary -expand /plasma_TB_v/uut/byte_we_next +add wave -noupdate -format Logic /plasma_TB_v/uut/U_RxD +add wave -noupdate -format Logic /plasma_TB_v/uut/U_TxD TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {3952754 ps} 0} +WaveRestoreCursors {{Cursor 1} {138039444 ps} 0} configure wave -namecolwidth 240 configure wave -valuecolwidth 100 configure wave -justifyvalue left @@ -25,4 +23,4 @@ configure wave -gridperiod 1 configure wave -griddelta 40 configure wave -timeline 0 update -WaveRestoreZoom {3946113 ps} {4013617 ps} +WaveRestoreZoom {132508776 ps} {136643152 ps} diff --git a/plasma/logic/uart.vhd b/plasma/logic/uart.vhd index 5f576fe..7a133fc 100644 --- a/plasma/logic/uart.vhd +++ b/plasma/logic/uart.vhd @@ -19,17 +19,16 @@ use std.textio.all; use work.mlite_pack.all; entity uart is - generic(log_file : string := "UNUSED"); port(clk : in std_logic; reset : in std_logic; - enable_read : in std_logic; - enable_write : in std_logic; + cs : in std_logic; + nRdWr : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); uart_read : in std_logic; uart_write : out std_logic; - busy_write : out std_logic; - data_avail : out std_logic); + addr : in std_logic_vector(3 downto 0) + ); end; --entity uart architecture logic of uart is @@ -43,9 +42,43 @@ architecture logic of uart is signal busy_write_sig : std_logic; signal read_value_reg : std_logic_vector(6 downto 0); signal uart_read2 : std_logic; + signal enable_read : std_logic; + signal enable_write : std_logic; + signal busy_write : std_logic; + signal data_avail : std_logic; + signal data_out_sig : std_logic_vector(7 downto 0); + begin +interface_proc: process(cs, nRdWr, addr, data_out_sig, busy_write, data_avail, data_save_reg) +begin + if cs = '1' then + if nRdWr = '1' then + enable_read <= '0'; + enable_write <= '1'; + data_out_sig <= "00000000"; + else + enable_read <= '1'; + enable_write <= '0'; + case addr(3 downto 0) is + when "0000" => + data_out_sig <= data_save_reg(7 downto 0); + when "0010" => + data_out_sig(7 downto 0) <= "000000" & busy_write & data_avail; + when others => + data_out_sig <= "00000000"; + end case; + end if; + else + enable_read <= '0'; + enable_write <= '0'; + data_out_sig <= "00000000"; + end if; + data_out <= data_out_sig; +end process; + + uart_proc: process(clk, reset, enable_read, enable_write, data_in, data_write_reg, bits_write_reg, delay_write_reg, data_read_reg, bits_read_reg, delay_read_reg, @@ -53,8 +86,8 @@ uart_proc: process(clk, reset, enable_read, enable_write, data_in, busy_write_sig, uart_read) constant COUNT_VALUE : std_logic_vector(9 downto 0) := -- "0100011110"; --33MHz/2/57600Hz = 0x11e --- "1101100100"; --50MHz/57600Hz = 0x364 - "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2 + "1101100100"; --50MHz/57600Hz = 0x364 +-- "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2 -- "0011011001"; --12.5MHz/57600Hz = 0xd9 -- "0000000100"; --for debug (shorten read_value_reg) begin @@ -72,72 +105,67 @@ begin elsif rising_edge(clk) then --Write UART - if bits_write_reg = "0000" then --nothing left to write? - if enable_write = '1' then - delay_write_reg <= ZERO(9 downto 0); --delay before next bit - bits_write_reg <= "1010"; --number of bits to write - data_write_reg <= data_in & '0'; --remember data & start bit - end if; - else - if delay_write_reg /= COUNT_VALUE then - delay_write_reg <= delay_write_reg + 1; --delay before next bit - else - delay_write_reg <= ZERO(9 downto 0); --reset delay - bits_write_reg <= bits_write_reg - 1; --bits left to write - data_write_reg <= '1' & data_write_reg(8 downto 1); - end if; - end if; - - --Average uart_read signal - if uart_read = '1' then - if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then - read_value_reg <= read_value_reg + 1; - end if; - else - if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then - read_value_reg <= read_value_reg - 1; - end if; - end if; - - --Read UART - if delay_read_reg = ZERO(9 downto 0) then --done delay for read? - if bits_read_reg = "0000" then --nothing left to read? - if uart_read2 = '0' then --wait for start bit - delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period - bits_read_reg <= "1001"; --bits left to read - end if; - else - delay_read_reg <= COUNT_VALUE; --initialize delay - bits_read_reg <= bits_read_reg - 1; --bits left to read - data_read_reg <= uart_read2 & data_read_reg(7 downto 1); - end if; - else - delay_read_reg <= delay_read_reg - 1; --delay - end if; - - --Control character buffer - if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then - if data_save_reg(8) = '0' or - (enable_read = '1' and data_save_reg(17) = '0') then - --Empty buffer - data_save_reg(8 downto 0) <= '1' & data_read_reg; - else - --Second character in buffer - data_save_reg(17 downto 9) <= '1' & data_read_reg; - if enable_read = '1' then - data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); - end if; - end if; - elsif enable_read = '1' then - data_save_reg(17) <= '0'; --data_available - data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); - end if; - end if; --rising_edge(clk) + if bits_write_reg = "0000" then --nothing left to write? + if enable_write = '1' then + delay_write_reg <= ZERO(9 downto 0); --delay before next bit + bits_write_reg <= "1010"; --number of bits to write + data_write_reg <= data_in & '0'; --remember data & start bit + end if; + else + if delay_write_reg /= COUNT_VALUE then + delay_write_reg <= delay_write_reg + 1; --delay before next bit + else + delay_write_reg <= ZERO(9 downto 0); --reset delay + bits_write_reg <= bits_write_reg - 1; --bits left to write + data_write_reg <= '1' & data_write_reg(8 downto 1); + end if; + end if; + --Average uart_read signal + if uart_read = '1' then + if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then + read_value_reg <= read_value_reg + 1; + end if; + else + if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then + read_value_reg <= read_value_reg - 1; + end if; + end if; + --Read UART + if delay_read_reg = ZERO(9 downto 0) then --done delay for read? + if bits_read_reg = "0000" then --nothing left to read? + if uart_read2 = '0' then --wait for start bit + delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period + bits_read_reg <= "1001"; --bits left to read + end if; + else + delay_read_reg <= COUNT_VALUE; --initialize delay + bits_read_reg <= bits_read_reg - 1; --bits left to read + data_read_reg <= uart_read2 & data_read_reg(7 downto 1); + end if; + else + delay_read_reg <= delay_read_reg - 1; --delay + end if; + --Control character buffer + if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then + if data_save_reg(8) = '0' or + (enable_read = '1' and data_save_reg(17) = '0') then + --Empty buffer + data_save_reg(8 downto 0) <= '1' & data_read_reg; + else + --Second character in buffer + data_save_reg(17 downto 9) <= '1' & data_read_reg; + if enable_read = '1' then + data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); + end if; + end if; + elsif enable_read = '1' then + data_save_reg(17) <= '0'; --data_available + data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); + end if; + end if; --rising_edge(clk) uart_write <= data_write_reg(0); if bits_write_reg /= "0000" --- Comment out the following line for full UART simulation (much slower) - and log_file = "UNUSED" then busy_write_sig <= '1'; else @@ -145,37 +173,6 @@ begin end if; busy_write <= busy_write_sig; data_avail <= data_save_reg(8); - data_out <= data_save_reg(7 downto 0); end process; --uart_proc - --- synthesis_off - uart_logger: - if log_file /= "UNUSED" generate - uart_proc: process(clk, enable_write, data_in) - file store_file : text open write_mode is log_file; - variable hex_file_line : line; - variable c : character; - variable index : natural; - variable line_length : natural := 0; - begin - if rising_edge(clk) and busy_write_sig = '0' then - if enable_write = '1' then - index := conv_integer(data_in(6 downto 0)); - if index /= 10 then - c := character'val(index); - write(hex_file_line, c); - line_length := line_length + 1; - end if; - if index = 10 or line_length >= 72 then ---The following line may have to be commented out for synthesis - writeline(store_file, hex_file_line); - line_length := 0; - end if; - end if; --uart_sel - end if; --rising_edge(clk) - end process; --uart_proc - end generate; --uart_logger --- synthesis_on - end; --architecture logic