├── .gitignore ├── .gitmodules ├── .travis.yml ├── CONTRIBUTORS ├── Jenkinsfile ├── LICENSE.Berkeley ├── LICENSE.Cambridge ├── LICENSE.SiFive ├── LICENSE.jtag ├── Makefrag ├── Makefrag-build ├── README.md ├── bootrom ├── .gitignore ├── Makefile ├── bootrom.S ├── bootrom.img ├── hostdetect.c └── linker.ld ├── csrc ├── SimDTM.cc ├── comlog.cc ├── emulator.cc ├── float_fix.cc ├── jtag_vpi.c └── verilator.h ├── jenkins └── Makefile ├── project ├── .gitignore ├── build.properties ├── build.scala └── plugins.sbt ├── sbt-launch.jar ├── scripts ├── .gitignore ├── Makefile ├── authors ├── check_cache_trace.py ├── check_comparator_trace.py ├── copyright-file ├── debug_rom │ ├── Makefile │ ├── debug_rom.S │ └── link.ld ├── modify-copyright ├── toaxe.py ├── tracegen+check.sh ├── tracegen.py ├── tracestats.py ├── vlsi_mem_gen └── vlsi_rom_gen ├── set_env.sh ├── src ├── main │ └── verilog │ │ ├── SimJTAG_xilinx.v │ │ ├── ascii_code.v │ │ ├── axis_gmii_rx.v │ │ ├── axis_gmii_tx.v │ │ ├── chip_top.sv │ │ ├── chip_top_dummy.sv │ │ ├── config.vh │ │ ├── consts.vh │ │ ├── debug_system.sv │ │ ├── dualmem.v │ │ ├── dualmem_32K_64.sv │ │ ├── dualmem_widen.v │ │ ├── dualmem_widen8.v │ │ ├── eth_lfsr.v │ │ ├── fpga_srams_edited.v │ │ ├── framing_top.sv │ │ ├── fstore2.v │ │ ├── lfsr.v │ │ ├── mii_to_rmii_0_open.v │ │ ├── my_fifo.v │ │ ├── nasti_channel.sv │ │ ├── periph_soc.sv │ │ ├── ps2.v │ │ ├── ps2_defines.v │ │ ├── ps2_keyboard.v │ │ ├── ps2_translation_table.v │ │ ├── rachelset.v │ │ ├── rx_delay.v │ │ ├── sd_bus.sv │ │ ├── sd_clock_divider.v │ │ ├── sd_cmd_serial_host.v │ │ ├── sd_crc_16.v │ │ ├── sd_crc_7.v │ │ ├── sd_data_serial_host.sv │ │ ├── sd_defines.h │ │ ├── sd_top.sv │ │ ├── spi_wrapper.sv │ │ ├── stubs.sv │ │ └── uart.v └── test │ ├── cxx │ ├── common │ │ ├── dpi_host_behav.cpp │ │ ├── dpi_host_behav.h │ │ ├── dpi_ram_behav.cpp │ │ ├── dpi_ram_behav.h │ │ ├── elf.h │ │ ├── globals.cpp │ │ ├── globals.h │ │ ├── loadelf.cpp │ │ └── loadelf.hpp │ └── veri │ │ └── veri_top.cc │ └── verilog │ ├── chip_top_tb.sv │ ├── host_behav.sv │ ├── host_behav_dummy.sv │ ├── nasti_ram_behav.sv │ ├── nasti_ram_dummy.sv │ ├── nasti_ram_sim.sv │ └── sd_verilator_model.sv ├── unitest ├── .gitignore ├── Makefile └── vlsi_mem_gen ├── vcs ├── .gitignore └── Makefile ├── vsim ├── .gitignore ├── Makefile ├── locore.S ├── lowrisc.lds ├── tlbtest.S └── tlbtest.sh └── vsrc ├── AsyncResetReg.v ├── ClockDivider2.v ├── ClockDivider3.v ├── DebugTransportJTAG-orig.sv ├── JTAGDTM.sv ├── JTAGDummy.v ├── JtagTapController_artix.sv ├── JtagTapController_asic.sv ├── SimDTM.v ├── SimDTM_JTAG.sv ├── TestDriver.v ├── jtag_addr.v ├── jtag_dummy.v ├── jtag_modules.sv ├── jtag_rom.v ├── jtag_vpi.tab ├── jtag_vpi.v ├── jtagsm_dummy.sv ├── plusarg_reader.v ├── vsim_bscan_dummy.v └── vsim_glbl.v /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | project/target 3 | *.swp 4 | *~ 5 | .addons-dont-touch 6 | riscv/ 7 | tools/ 8 | lib/ 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "fpga"] 2 | path = fpga 3 | url = https://github.com/lowrisc/lowrisc-fpga.git 4 | [submodule "rocket-chip"] 5 | path = rocket-chip 6 | url = https://github.com/lowRISC/rocket-chip 7 | [submodule "riscv-linux"] 8 | path = riscv-linux 9 | url = https://github.com/lowRISC/riscv-linux.git 10 | [submodule "debian-riscv64"] 11 | path = debian-riscv64 12 | url = https://github.com/lowRISC/debian-riscv64.git 13 | [submodule "qemu"] 14 | path = qemu 15 | url = https://github.com/lowrisc/qemu-archive.git 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Run in container-based environment 2 | sudo: required 3 | dist: trusty 4 | group: edge # Add this 5 | git: 6 | submodules: false 7 | 8 | # Using the precompiled toolchain from docker 9 | services: 10 | - docker 11 | 12 | # define test 13 | env: 14 | global: 15 | - DOCKER_TOP=/opt/lowrisc 16 | - DOCKER_TAG=rocket-v1.0 17 | matrix: 18 | - CONFIG=LoRCDefaultConfig TEST_CASE=run-asm-tests 19 | 20 | # tag is not enabled for now 21 | # - CONFIG=TagConfig TEST_CASE=run-asm-tests 22 | # - CONFIG=TagConfig TEST_CASE=run-tag-tests 23 | 24 | # actual test build 25 | 26 | before_install: 27 | - git submodule update --init --recursive rocket-chip 28 | - docker pull lowrisc/lowrisc-docker:$DOCKER_TAG 29 | 30 | before_script: 31 | - docker create -v $PWD:/opt/lowrisc -e TOP=/opt/lowrisc -t --name=test lowrisc/lowrisc-docker:$DOCKER_TAG 32 | - docker start test 33 | 34 | script: 35 | - docker exec test make -C $DOCKER_TOP/rocket-chip/vsim CONFIG=$CONFIG $TEST_CASE 36 | 37 | after_script: 38 | - docker stop test 39 | - docker rm test 40 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Ordered by last name. 2 | 3 | Name Email Note 4 | =================================================================================================================================== 5 | Krste Asanović Team member of UC Berkeley/SiFive 6 | Scott Beamer Team member of UC Berkeley 7 | Alex Bradbury Team member of Cambridge/lowRISC 8 | Christopher Celio Team member of UC Berkeley 9 | Henry Cook Team member of UC Berkeley/SiFive 10 | Palmer Dabbelt Team member of UC Berkeley 11 | Schuyler Eldridge Contributor to Rocket chip 12 | Gary Guo Contributor to lowRISC, on-chip interconnects 13 | Adam Izraelevitz Team member of UC Berkeley 14 | Philipp Jantscher Contributor to lowRISC, adding tagged memory to debug-v0.3 15 | Sagar Karandikar Team member of UC Berkeley 16 | Ben Keller Team member of UC Berkeley 17 | Donggyu Kim Team member of UC Berkeley 18 | Jonathan Kimmitt Team member of Cambridge/lowRISC 19 | Jack Koenig Team member of UC Berkeley 20 | Jim Lawson Team member of UC Berkeley 21 | Yunsup Lee Team member of UC Berkeley/SiFive 22 | Richard Lin Team member of UC Berkeley 23 | Albert Magyar Team member of UC Berkeley 24 | Howard Mao Team member of UC Berkeley 25 | Miquel Moreto Contributor to Rocket chip 26 | Robert Mullins Team member of Cambridge/lowRISC 27 | Albert Ou Team member of UC Berkeley/Sifive 28 | Colin Schmidt Team member of UC Berkeley 29 | Wei Song Team member of Cambridge/lowRISC 30 | Furkan Turan Contributor to lowRISC, port debug-v0.3 to Zedboard 31 | Stephen Twigg Team member of UC Berkeley 32 | Huy Vo Team member of UC Berkeley 33 | Philipp Wagner Team member of OpenSocDebug 34 | Stefan Wallentowitz Team member of lowRISC/OpenSocDebug 35 | Andrew Waterman Team member of UC Berkeley/Sifive 36 | John Wright Team member of UC Berkeley 37 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | // Perform various regression runs after a checkin 2 | 3 | pipeline { 4 | agent any 5 | 6 | stages { 7 | stage('Checkout') { 8 | steps { 9 | echo 'Checkout..' 10 | sh 'make -f jenkins/Makefile Checkout' 11 | } 12 | } 13 | stage('Build') { 14 | steps { 15 | echo 'Building..' 16 | sh 'make -f jenkins/Makefile Build' 17 | } 18 | } 19 | stage('Test') { 20 | steps { 21 | echo 'Testing..' 22 | sh 'make -f jenkins/Makefile Test' 23 | } 24 | } 25 | stage('Deploy') { 26 | steps { 27 | echo 'Deploying....' 28 | sh 'make -f jenkins/Makefile Deploy' 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.Berkeley: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016, The Regents of the University of California 2 | (Regents). All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the Regents nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 16 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 17 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 18 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 | 20 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 23 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 24 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | -------------------------------------------------------------------------------- /LICENSE.Cambridge: -------------------------------------------------------------------------------- 1 | Copyright 2015-2018 University of Cambridge 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /LICENSE.jtag: -------------------------------------------------------------------------------- 1 | chisel-jtag license terms 2 | 3 | Copyright (c) 2016 The Regents of the University of 4 | California (Regents). All Rights Reserved. Redistribution and use in 5 | source and binary forms, with or without modification, are permitted 6 | provided that the following conditions are met: 7 | * Redistributions of source code must retain the above 8 | copyright notice, this list of conditions and the following 9 | two paragraphs of disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | two paragraphs of disclaimer in the documentation and/or other materials 13 | provided with the distribution. 14 | * Neither the name of the Regents nor the names of its contributors 15 | may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 18 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, 19 | ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 20 | REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF 24 | ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION 25 | TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 26 | MODIFICATIONS. 27 | -------------------------------------------------------------------------------- /Makefrag: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | # check RISCV environment variable 4 | ifndef RISCV 5 | $(error Please set environment variable RISCV. Please take a look at README) 6 | endif 7 | 8 | MODEL := TestHarness 9 | PROJECT := freechips.rocketchip.system 10 | CXX := g++ 11 | CXXFLAGS := -O1 12 | JVM_MEMORY ?= 2G 13 | 14 | SBT ?= java -Xmx$(JVM_MEMORY) -Xss8M -XX:MaxPermSize=256M -jar $(base_dir)/sbt-launch.jar 15 | SHELL := /bin/bash 16 | 17 | FIRRTL_JAR ?= $(base_dir)/firrtl/utils/bin/firrtl.jar 18 | FIRRTL ?= java -Xmx$(JVM_MEMORY) -Xss8M -XX:MaxPermSize=256M -cp $(FIRRTL_JAR) firrtl.Driver 19 | 20 | # Build firrtl.jar and put it where chisel3 can find it. 21 | $(FIRRTL_JAR): $(shell find $(base_dir)/firrtl/src/main/scala -iname "*.scala") 22 | $(MAKE) -C $(base_dir)/firrtl SBT="$(SBT)" root_dir=$(base_dir)/firrtl build-scala 23 | touch $(FIRRTL_JAR) 24 | mkdir -p $(base_dir)/lib 25 | cp -p $(FIRRTL_JAR) $(base_dir)/lib 26 | # When chisel3 pr 448 is merged, the following extraneous copy may be removed. 27 | mkdir -p $(base_dir)/chisel3/lib 28 | cp -p $(FIRRTL_JAR) $(base_dir)/chisel3/lib 29 | 30 | # specify source files 31 | src_path := src/main/scala 32 | default_submodules := . hardfloat chisel3 33 | chisel_srcs := $(foreach submodule, $(default_submodules), $(shell find $(base_dir)/$(submodule)/$(src_path) -name "*.scala")) 34 | 35 | # translate trace files generated by C++/Verilog simulation 36 | disasm := > 37 | which_disasm := $(shell which spike-dasm 2> /dev/null) 38 | ifneq ($(which_disasm),) 39 | disasm := | $(which_disasm) $(DISASM_EXTENSION) > 40 | endif 41 | 42 | # define time-out for different types of simulation 43 | timeout_cycles = 10000000 44 | long_timeout_cycles = 50000000 45 | linux_timeout_cycles = 5000000000 46 | 47 | # emacs local variable 48 | 49 | # Local Variables: 50 | # mode: makefile 51 | # End: 52 | -------------------------------------------------------------------------------- /Makefrag-build: -------------------------------------------------------------------------------- 1 | 2 | # See LICENSE.Cambridge for license details. 3 | 4 | #-------------------------------------------------------------------- 5 | # Build Verilog 6 | #-------------------------------------------------------------------- 7 | 8 | .SECONDARY: $(firrtl) $(verilog) 9 | 10 | $(generated_dir)/%.fir $(generated_dir)/%.d: $(FIRRTL_JAR) $(chisel_srcs) $(bootrom_image) 11 | mkdir -p $(dir $@) 12 | cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator $(generated_dir) $(PROJECT) $(MODEL) $(PROJECT) $(CONFIG)" 13 | 14 | $(generated_dir)/%.sv $(generated_dir)/%.conf: $(generated_dir)/%.fir $(FIRRTL_JAR) 15 | mkdir -p $(dir $@) 16 | $(FIRRTL) -i $< -o $(generated_dir)/$*.sv -X sverilog --infer-rw $(MODEL) --repl-seq-mem -c:$(MODEL):-o:$(generated_dir)/$*.conf 17 | 18 | $(generated_dir)/consts.vh: $(generated_dir)/$(PROJECT).$(CONFIG).fir 19 | cp $(generated_dir)/$(CONFIG).vh $(generated_dir)/consts.vh 20 | 21 | $(generated_dir)/%.behav_srams.sv: $(generated_dir)/%.conf 22 | $(mem_gen) $< > $@.tmp && mv -f $@.tmp $@ 23 | 24 | 25 | # emacs local variable 26 | 27 | # Local Variables: 28 | # mode: makefile 29 | # End: 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | lowRISC chip 2 | ============================================== 3 | 4 | The root git repo for lowRISC development and FPGA demos. 5 | 6 | See LICENSE.Cambridge for license details. 7 | 8 | See the [documentation](https://www.lowrisc.org/docs/) for build instructions. 9 | 10 | [master] status: [![master build status](https://travis-ci.org/lowRISC/lowrisc-chip.svg?branch=master)](https://travis-ci.org/lowRISC/lowrisc-chip) 11 | 12 | [update] status: [![update build status](https://travis-ci.org/lowRISC/lowrisc-chip.svg?branch=update)](https://travis-ci.org/lowRISC/lowrisc-chip) 13 | 14 | [dev] status: [![dev build status](https://travis-ci.org/lowRISC/lowrisc-chip.svg?branch=dev)](https://travis-ci.org/lowRISC/lowrisc-chip) 15 | 16 | Current version: Release version 0.6 (10-2018) --- lowRISC technical refresh with RV64GC, Debian+FreeBSD capable 17 | 18 | To download the repo: 19 | 20 | ~~~shell 21 | git clone -b refresh-v0.6 --recursive https://github.com/lowrisc/lowrisc-chip.git 22 | ~~~ 23 | 24 | For the previous release: 25 | 26 | ~~~shell 27 | ################ 28 | # Version 0.5: lowRISC with 100MHz Ethernet and Network filing system access (01-2018) 29 | ################ 30 | git clone -b ethernet-v0.5 --recursive https://github.com/lowrisc/lowrisc-chip.git 31 | 32 | ################ 33 | # Version 0.4: lowRISC with with tagged memory and minion core (06-2017) 34 | ################ 35 | git clone -b minion-v0.4 --recursive https://github.com/lowrisc/lowrisc-chip.git 36 | 37 | ################ 38 | # Version 0.3: lowRISC with a trace debugger (07-2016) 39 | ################ 40 | git clone -b debug-v0.3 --recursive https://github.com/lowrisc/lowrisc-chip.git 41 | 42 | ################ 43 | # Version 0.2: untethered lowRISC (12-2015) 44 | ################ 45 | git clone -b untether-v0.2 --recursive https://github.com/lowrisc/lowrisc-chip.git 46 | 47 | ################ 48 | # Version 0.1: tagged memory (04-2015) 49 | ################ 50 | git clone -b tagged-memory-v0.1 --recursive https://github.com/lowrisc/lowrisc-chip.git 51 | ~~~ 52 | 53 | [traffic statistics](http://www.cl.cam.ac.uk/~ws327/lowrisc_stat/index.html) 54 | 55 | [master]: https://github.com/lowrisc/lowrisc-chip/tree/master 56 | [update]: https://github.com/lowrisc/lowrisc-chip/tree/update 57 | [dev]: https://github.com/lowrisc/lowrisc-chip/tree/dev 58 | -------------------------------------------------------------------------------- /bootrom/.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | -------------------------------------------------------------------------------- /bootrom/Makefile: -------------------------------------------------------------------------------- 1 | bootrom_img = bootrom.img 2 | 3 | CC=riscv64-unknown-elf-gcc 4 | CFLAGS=-Wno-multichar -O3 -fno-caller-saves -fomit-frame-pointer 5 | OBJCOPY=riscv64-unknown-elf-objcopy 6 | 7 | all: $(bootrom_img) 8 | 9 | %.img: %.bin 10 | dd if=$< of=$@ bs=128 count=1 11 | 12 | %.bin: %.elf 13 | $(OBJCOPY) -O binary $< $@ 14 | 15 | %.elf: %.S linker.ld hostdetect.o 16 | $(CC) -Tlinker.ld $< hostdetect.o -nostdlib -static -Wl,--no-gc-sections -o $@ 17 | riscv64-unknown-elf-readelf -S $@ > $@.sections 18 | riscv64-unknown-elf-objdump -d $@ > $@.dis 19 | -------------------------------------------------------------------------------- /bootrom/bootrom.S: -------------------------------------------------------------------------------- 1 | #define DRAM_BASE 0x80000000 2 | 3 | .section .text.start, "ax", @progbits 4 | .globl _start 5 | _start: 6 | j _start+6 7 | 8 | .section .rodata.dtb, "a", @progbits 9 | .globl _dtb 10 | .align 5, 0 11 | _dtb: 12 | .ascii "DTB goes here" 13 | -------------------------------------------------------------------------------- /bootrom/bootrom.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lowRISC/lowrisc-chip/091fa17733c36ceaeebf348f78e9b32a051efa26/bootrom/bootrom.img -------------------------------------------------------------------------------- /bootrom/hostdetect.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | typedef __attribute__ ((__noreturn__)) void (*fptr_t)(void); 5 | 6 | __attribute__ ((__noreturn__)) void hostdetect(void) 7 | { 8 | register fptr_t ddr = (fptr_t)0x80000000; 9 | register fptr_t bram = (fptr_t)0x40000000; 10 | register char *config = (char *)0x10000; 11 | for (register int i = 128; i < 4096; i++) 12 | { 13 | register char ch = config[i] & 0x7f; 14 | if (ch == '@') 15 | { 16 | register int j = i-1; 17 | while ((config[j] >= 'a' && config[j] <= 'z') || config[j] == '-') 18 | j--; 19 | if (++j < i) 20 | { 21 | if (config[j] == 'h') 22 | ddr(); 23 | } 24 | } 25 | } 26 | bram(); 27 | } 28 | -------------------------------------------------------------------------------- /bootrom/linker.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | ROM_BASE = 0x10000; /* ... but actually position independent */ 4 | 5 | . = ROM_BASE; 6 | .text.start : { *(.text.start) } 7 | .text : { *(.text) } 8 | . = ROM_BASE + 0x80; 9 | .rodata.dtb : { *(.rodata.dtb) } 10 | } 11 | -------------------------------------------------------------------------------- /csrc/SimDTM.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | dtm_t* dtm; 8 | 9 | 10 | namespace { 11 | 12 | // Remove args that will confuse dtm, such as those that require two tokens, like VCS code coverage "-cm line+cond" 13 | std::vector filter_argv_for_dtm(int argc, char** argv) 14 | { 15 | std::vector out; 16 | for (int i = 1; i < argc; ++i) { // start with 1 to skip my executable name 17 | if (!strncmp(argv[i], "-cm", 3)) { 18 | ++i; // skip this one and the next one 19 | } 20 | else { 21 | out.push_back(argv[i]); 22 | } 23 | } 24 | return out; 25 | } 26 | 27 | } 28 | 29 | 30 | extern "C" int debug_tick 31 | ( 32 | unsigned char* debug_req_valid, 33 | unsigned char debug_req_ready, 34 | int* debug_req_bits_addr, 35 | int* debug_req_bits_op, 36 | int* debug_req_bits_data, 37 | unsigned char debug_resp_valid, 38 | unsigned char* debug_resp_ready, 39 | int debug_resp_bits_resp, 40 | int debug_resp_bits_data 41 | ) 42 | { 43 | if (!dtm) { 44 | s_vpi_vlog_info info; 45 | if (!vpi_get_vlog_info(&info)) 46 | abort(); 47 | dtm = new dtm_t(filter_argv_for_dtm(info.argc, info.argv)); 48 | } 49 | 50 | dtm_t::resp resp_bits; 51 | resp_bits.resp = debug_resp_bits_resp; 52 | resp_bits.data = debug_resp_bits_data; 53 | 54 | dtm->tick 55 | ( 56 | debug_req_ready, 57 | debug_resp_valid, 58 | resp_bits 59 | ); 60 | 61 | *debug_resp_ready = dtm->resp_ready(); 62 | *debug_req_valid = dtm->req_valid(); 63 | *debug_req_bits_addr = dtm->req_bits().addr; 64 | *debug_req_bits_op = dtm->req_bits().op; 65 | *debug_req_bits_data = dtm->req_bits().data; 66 | 67 | return dtm->done() ? (dtm->exit_code() << 1 | 1) : 0; 68 | } 69 | -------------------------------------------------------------------------------- /csrc/comlog.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | //***************************************************** 4 | // Christopher Celio 5 | // 2015 Feb 2 6 | // 7 | // Utility for taking a raw commit log from a processor and post-processing it 8 | // into a diff-able format against the spike ISA simulator's commit log. 9 | // 10 | // INPUT : a raw commit log via std::cin 11 | // OUTPUT: a cleaned up commit log via std::cout 12 | // 13 | // PROBLEM: some writebacks can occur after the commit point in a processor. 14 | // These partial entries will be marked as appropriate, and the writebacks will 15 | // be written to the log as soon as they occur (possibly out-of-order). This 16 | // program will put the writebacks in their proper place. 17 | // 18 | // FUNFACT: with processors that use renaming to break WAW hazards, it is 19 | // possible for writes to the same ISA register to also occur OoO. Thus, the 20 | // raw commit log must tell give us the physical destination (pdst) 21 | // indentifiers for matching write-backs to the appropriate partial commit 22 | // entry. 23 | 24 | /* 25 | // Typical (raw) commit log... 26 | 27 | 28 | ----------------------------------------------------------- 29 | 30 | 0 0x0000000000002ccc (0x00973423) 31 | 0 0x0000000000002cd0 (0x00a73023) 32 | 0 0x0000000000002cd4 (0x05070113) x2 0x0000000000025180 33 | 0 0x0000000000002cd8 (0xd8070713) x14 0x0000000000024eb0 34 | 0 0x0000000000002cdc (0xea5ff0ef) x1 0x0000000000002ce0 35 | 0 0x0000000000002cdc (0xea5ff0ef) x1 0x0000000000002ce0 36 | 0 0x000000000000208c (0x00b6b72f) x14 p 1 0xXXXXXXXXXXXXXXXX 37 | 0 0x0000000000002090 (0x80000eb7) x29 0xffffffff80000000 38 | x14 p 1 0xffffffff80000000 39 | 0 0x0000000000002cdc (0xea5ff0ef) x1 0x0000000000002ce0 40 | 41 | // Note: the first number is the current privileged mode of the committed 42 | // instruction. 43 | // 44 | ----------------------------------------------------------- 45 | 46 | The "x14 p 1 0xXXXXXXXXXXXXXXXX" segment needs to be replaced with the later 47 | "x14 0xffffffff80000000" segment. 48 | 49 | The physical tags must be used for matching writebacks to partial commits, 50 | as it is possible with renaming to break the write-after-write hazard and 51 | have out-of-order writebacks to the same ISA/logical register! However, the 52 | physical tag needs to be deleted in the final output, as the ISA simulator 53 | does not know or care about renamed registers. 54 | 55 | // Final (cleaned up) commit log 56 | 57 | ----------------------------------------------------------- 58 | 59 | 0 0x0000000000002ccc (0x00973423) 60 | 0 0x0000000000002cd0 (0x00a73023) 61 | 0 0x0000000000002cd4 (0x05070113) x2 0x0000000000025180 62 | 0 0x0000000000002cd8 (0xd8070713) x14 0x0000000000024eb0 63 | 0 0x0000000000002cdc (0xea5ff0ef) x1 0x0000000000002ce0 64 | 0 0x0000000000002cdc (0xea5ff0ef) x1 0x0000000000002ce0 65 | 0 0x000000000000208c (0x00b6b72f) x14 0xffffffff80000000 66 | 0 0x0000000000002090 (0x80000eb7) x29 0xffffffff80000000 67 | 0 0x0000000000002cdc (0xea5ff0ef) x1 0x0000000000002ce0 68 | 69 | ----------------------------------------------------------- 70 | */ 71 | 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | 79 | 80 | // Maximum number of physical destination registers, 64 for Rocket 81 | const int kMaxPdst = 64; 82 | 83 | // data-structures 84 | 85 | typedef struct RobEntry 86 | { 87 | bool ready; // is entry ready to be committed? 88 | int pdst; // the wb physical dest. register 89 | std::string str; // the commit string to print out 90 | } RobEntry; 91 | 92 | std::deque rob; 93 | 94 | 95 | // maps from physical destination register to rob entry waiting on it 96 | // a value of nullptr implies there is no rob entry waiting on pdst 97 | std::vector pdst_to_rob(kMaxPdst, nullptr); 98 | 99 | 100 | // functions 101 | 102 | void push (std::string& line); 103 | void commit (); 104 | void writeback (std::string& line); 105 | bool is_instruction (std::string& line); 106 | bool is_partial_commit (std::string& line); 107 | int get_ldst (std::string& line); 108 | int get_pdst (std::string& line); 109 | 110 | // add instruction to the ROB 111 | // mark as "not ready" if writeback data not ready 112 | void push (std::string& line) 113 | { 114 | bool is_partial = is_partial_commit(line); 115 | 116 | RobEntry rob_entry; 117 | rob_entry.str = line; 118 | rob_entry.ready = !(is_partial); 119 | rob_entry.pdst = is_partial ? get_pdst(line) : 0; 120 | rob.push_back(rob_entry); 121 | 122 | if (is_partial) 123 | { 124 | assert (rob_entry.pdst < kMaxPdst); 125 | assert (pdst_to_rob[rob_entry.pdst] == nullptr); 126 | pdst_to_rob[rob_entry.pdst] = &(rob.back()); 127 | } 128 | } 129 | 130 | void commit () 131 | { 132 | while (!rob.empty() && rob.front().ready) 133 | { 134 | std::cout << rob.front().str << std::endl; 135 | rob.pop_front(); 136 | } 137 | } 138 | 139 | int get_ldst (std::string& line) 140 | { 141 | assert (line.length() > 46); 142 | 143 | int idx = line.find_first_of('x'); 144 | int dst = atoi(line.substr(idx+1,2).c_str()); 145 | return dst; 146 | } 147 | 148 | int get_pdst (std::string& line) 149 | { 150 | assert (line.length() > 46); 151 | 152 | int idx = line.find_first_of('p'); 153 | int dst = atoi(line.substr(idx+1,2).c_str()); 154 | return dst; 155 | } 156 | 157 | bool is_partial_commit (std::string& line) 158 | { 159 | if (line.length() > 46 && (line.at(34) == 'x' || line.at(34) == 'f') && line.at(46) == 'X') 160 | return true; 161 | else 162 | return false; 163 | } 164 | 165 | bool is_instruction (std::string& line) 166 | { 167 | return !(line.at(0) == 'x' || line.at(0) == 'f'); 168 | } 169 | 170 | // find instruction in ROB and substitute in the writeback data 171 | // and mark it as ready for commit 172 | void writeback (std::string& line) 173 | { 174 | assert (line.at(0) == 'x' || line.at(0) == 'f'); 175 | 176 | size_t idx = line.find_first_of('p'); 177 | assert (idx != std::string::npos); 178 | int pdst = atoi(line.substr(idx+1,2).c_str()); 179 | 180 | // search the partial queue for writeback 181 | assert (pdst < kMaxPdst); 182 | RobEntry* rob_entry = pdst_to_rob[pdst]; 183 | assert (rob_entry != nullptr); 184 | pdst_to_rob[pdst] = nullptr; 185 | 186 | // update ROB 187 | assert (rob_entry->str.length() > 32); 188 | std::string* rob_str = &(rob_entry->str); 189 | 190 | // mark as ready 191 | rob_entry->ready = true; 192 | idx = line.find("0x"); 193 | std::string wbdata = line.substr(idx+2,16); 194 | idx = rob_str->find("0x",32); // actually want to find the 3rd occurrence 195 | int p_idx = rob_str->find_first_of('p'); 196 | rob_str->replace(idx+2,16,wbdata); 197 | rob_str->erase(p_idx, (idx-p_idx)); 198 | } 199 | 200 | int main (int argc, char** argv) 201 | { 202 | std::string line; 203 | 204 | // check for errno 205 | while (getline(std::cin, line)) 206 | { 207 | if (is_instruction(line)) 208 | { 209 | push(line); 210 | } 211 | else 212 | { 213 | writeback(line); 214 | } 215 | 216 | // check if head of the rob is ready, commit 217 | // instructions until either empty or not ready 218 | commit(); 219 | } 220 | 221 | if (std::cin.bad()) 222 | { 223 | // IO error 224 | std::cout << "\nIO ERROR: cin.bad()\n\n"; 225 | return 1; 226 | } 227 | 228 | return 0; 229 | } 230 | 231 | -------------------------------------------------------------------------------- /csrc/emulator.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | #include "verilated.h" 5 | #if VM_TRACE 6 | #include "verilated_vcd_c.h" 7 | #endif 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | extern dtm_t* dtm; 18 | static uint64_t trace_count = 0; 19 | bool verbose; 20 | bool done_reset; 21 | 22 | void handle_sigterm(int sig) 23 | { 24 | dtm->stop(); 25 | } 26 | 27 | double sc_time_stamp() 28 | { 29 | return trace_count; 30 | } 31 | 32 | extern "C" int vpi_get_vlog_info(void* arg) 33 | { 34 | return 0; 35 | } 36 | 37 | static void usage(const char * program_name) { 38 | printf("Usage: %s [OPTION]... BINARY [BINARY ARGS]\n", program_name); 39 | fputs("\ 40 | Run a BINARY on the Rocket Chip emulator.\n\ 41 | \n\ 42 | Mandatory arguments to long options are mandatory for short options too.\n\ 43 | -c, --cycle-count print the cycle count before exiting\n\ 44 | +cycle-count\n\ 45 | -h, --help display this help and exit\n\ 46 | -m, --max-cycles=CYCLES kill the emulation after CYCLES\n\ 47 | +max-cycles=CYCLES\n\ 48 | -s, --seed=SEED use random number seed SEED\n\ 49 | -V, --verbose enable all Chisel printfs\n\ 50 | +verbose\n\ 51 | ", stdout); 52 | #if VM_TRACE 53 | fputs("\ 54 | -v, --vcd=FILE, write vcd trace to FILE (or '-' for stdout)\n\ 55 | -x, --dump-start=CYCLE start VCD tracing at CYCLE\n\ 56 | +dump-start\n\ 57 | ", stdout); 58 | #else 59 | fputs("\ 60 | VCD options (e.g., -v, +dump-start) require a debug-enabled emulator.\n\ 61 | Try `make debug`.\n\ 62 | ", stdout); 63 | #endif 64 | } 65 | 66 | int main(int argc, char** argv) 67 | { 68 | unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid(); 69 | uint64_t max_cycles = -1; 70 | int ret = 0; 71 | bool print_cycles = false; 72 | #if VM_TRACE 73 | FILE * vcdfile = NULL; 74 | uint64_t start = 0; 75 | #endif 76 | 77 | std::vector to_dtm; 78 | while (1) { 79 | static struct option long_options[] = { 80 | {"cycle-count", no_argument, 0, 'c' }, 81 | {"help", no_argument, 0, 'h' }, 82 | {"max-cycles", required_argument, 0, 'm' }, 83 | {"seed", required_argument, 0, 's' }, 84 | {"verbose", no_argument, 0, 'V' }, 85 | #if VM_TRACE 86 | {"vcd", required_argument, 0, 'v' }, 87 | {"dump-start", required_argument, 0, 'x' }, 88 | #endif 89 | {0, 0, 0, 0} 90 | }; 91 | int option_index = 0; 92 | #if VM_TRACE 93 | int c = getopt_long(argc, argv, "-chm:s:v:Vx:", long_options, &option_index); 94 | #else 95 | int c = getopt_long(argc, argv, "-chm:s:V", long_options, &option_index); 96 | #endif 97 | if (c == -1) break; 98 | switch (c) { 99 | // Process "normal" options with '--' long options or '-' short options 100 | case '?': usage(argv[0]); return 1; 101 | case 'c': print_cycles = true; break; 102 | case 'h': usage(argv[0]); return 0; 103 | case 'm': max_cycles = atoll(optarg); break; 104 | case 's': random_seed = atoi(optarg); break; 105 | case 'V': verbose = true; break; 106 | #if VM_TRACE 107 | case 'v': { 108 | vcdfile = strcmp(optarg, "-") == 0 ? stdout : fopen(optarg, "w"); 109 | if (!vcdfile) { 110 | std::cerr << "Unable to open " << optarg << " for VCD write\n"; 111 | return 1; 112 | } 113 | break; 114 | } 115 | case 'x': start = atoll(optarg); break; 116 | #endif 117 | // Processing of legacy '+' options and recognition of when 118 | // we've hit the binary. The binary is expected to be a 119 | // non-option and not start with '-' or '+'. 120 | case 1: { 121 | std::string arg = optarg; 122 | if (arg == "+verbose") 123 | verbose = true; 124 | else if (arg.substr(0, 12) == "+max-cycles=") 125 | max_cycles = atoll(optarg+12); 126 | #if VM_TRACE 127 | else if (arg.substr(0, 12) == "+dump-start=") 128 | start = atoll(optarg+12); 129 | #endif 130 | else if (arg.substr(0, 12) == "+cycle-count") 131 | print_cycles = true; 132 | else { 133 | to_dtm.push_back(optarg); 134 | goto done_processing; 135 | } 136 | break; 137 | } 138 | } 139 | } 140 | 141 | done_processing: 142 | if (optind < argc) 143 | while (optind < argc) 144 | to_dtm.push_back(argv[optind++]); 145 | if (!to_dtm.size()) { 146 | std::cerr << "No binary specified for emulator\n"; 147 | usage(argv[0]); 148 | return 1; 149 | } 150 | 151 | if (verbose) 152 | fprintf(stderr, "using random seed %u\n", random_seed); 153 | 154 | srand(random_seed); 155 | srand48(random_seed); 156 | 157 | Verilated::randReset(2); 158 | Verilated::commandArgs(argc, argv); 159 | TEST_HARNESS *tile = new TEST_HARNESS; 160 | 161 | #if VM_TRACE 162 | Verilated::traceEverOn(true); // Verilator must compute traced signals 163 | std::unique_ptr vcdfd(new VerilatedVcdFILE(vcdfile)); 164 | std::unique_ptr tfp(new VerilatedVcdC(vcdfd.get())); 165 | if (vcdfile) { 166 | tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy 167 | tfp->open(""); 168 | } 169 | #endif 170 | 171 | dtm = new dtm_t(to_dtm); 172 | 173 | signal(SIGTERM, handle_sigterm); 174 | 175 | // reset for several cycles to handle pipelined reset 176 | for (int i = 0; i < 10; i++) { 177 | tile->reset = 1; 178 | tile->clock = 0; 179 | tile->eval(); 180 | tile->clock = 1; 181 | tile->eval(); 182 | tile->reset = 0; 183 | } 184 | done_reset = true; 185 | 186 | while (!dtm->done() && !tile->io_success && trace_count < max_cycles) { 187 | tile->clock = 0; 188 | tile->eval(); 189 | #if VM_TRACE 190 | bool dump = tfp && trace_count >= start; 191 | if (dump) 192 | tfp->dump(static_cast(trace_count * 2)); 193 | #endif 194 | 195 | tile->clock = 1; 196 | tile->eval(); 197 | #if VM_TRACE 198 | if (dump) 199 | tfp->dump(static_cast(trace_count * 2 + 1)); 200 | #endif 201 | trace_count++; 202 | } 203 | 204 | #if VM_TRACE 205 | if (tfp) 206 | tfp->close(); 207 | if (vcdfile) 208 | fclose(vcdfile); 209 | #endif 210 | 211 | if (dtm->exit_code()) 212 | { 213 | fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count); 214 | ret = dtm->exit_code(); 215 | } 216 | else if (trace_count == max_cycles) 217 | { 218 | fprintf(stderr, "*** FAILED *** (timeout, seed %d) after %ld cycles\n", random_seed, trace_count); 219 | ret = 2; 220 | } 221 | else if (verbose || print_cycles) 222 | { 223 | fprintf(stderr, "Completed after %ld cycles\n", trace_count); 224 | } 225 | 226 | if (dtm) delete dtm; 227 | if (tile) delete tile; 228 | return ret; 229 | } 230 | -------------------------------------------------------------------------------- /csrc/float_fix.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | // float_fix - Scott Beamer, 2015 12 | 13 | // This program post-processes commit logs from rocket-chip to make it easier 14 | // to diff against commit logs from spike. Rocket internally uses recoded 15 | // floating point numbers, but this is normally hidden because the commit 16 | // logging tool unrecodes (undoes the recoding) those numbers. This tool is for 17 | // the corner case (single-precision float stored and loaded from memory as a 18 | // double) when the commit logging tool is unable to recode properly on its 19 | // own. Given both a rocket commit log (already processed by comlog) and commit 20 | // log from spike, this tools attempts to fix that corner case. This tool will 21 | // only overwrite the log to hold the unrecoded float if that change will cause 22 | // it to match with the spike log (conservative). 23 | 24 | 25 | // Returns the bits in x[high:low] in the lowest positions 26 | uint64_t BitRange(uint64_t x, int high, int low) { 27 | int high_gap = 63 - high; 28 | return x << high_gap >> (low + high_gap); 29 | } 30 | 31 | 32 | // Returns uint64_t from the hex encoding within s offset by index 33 | uint64_t UIntFromHexSubstring(std::string s, int index) { 34 | uint64_t x = strtoull(s.c_str() + index, nullptr, 16); 35 | assert(errno == 0); 36 | return x; 37 | } 38 | 39 | 40 | // Is commit line for a fld instruction? 41 | bool LineIsFLDInst(std::string line) { 42 | uint32_t inst_bits = UIntFromHexSubstring(line, 22); 43 | uint32_t width_field = (inst_bits >> 12) & 7; 44 | uint32_t opcode_field = inst_bits & 127; 45 | return (width_field == 3) && (opcode_field == 7); 46 | } 47 | 48 | 49 | // Is number possibly a recoded float inside double (upper 31 bits set)? 50 | bool NestedFloatPossible(uint64_t raw_input) { 51 | const uint64_t mask = 0xfffffffe00000000; 52 | return (raw_input & mask) == mask; 53 | } 54 | 55 | 56 | // Unrecodes a single float within a double 57 | // uses magic numbers since can only handle float 58 | // logic from berkeley-hardfloat/src/main/scala/recodedFloatNToFloatN.scala 59 | uint64_t UnrecodeFloatFromDouble(uint64_t raw_input) { 60 | uint64_t recoded_float = raw_input & 0x1ffffffff; // lower 33 bits 61 | uint64_t sign = BitRange(recoded_float, 32, 32); 62 | uint64_t exp_in = BitRange(recoded_float, 31, 23); 63 | uint64_t sig_in = BitRange(recoded_float, 22, 0); 64 | 65 | bool is_high_subnormal_in = BitRange(exp_in, 6, 0) < 2; 66 | bool is_subnormal = (BitRange(exp_in, 8, 6) == 1) || 67 | ((BitRange(exp_in, 8, 7) == 1) && is_high_subnormal_in); 68 | bool is_normal = (BitRange(exp_in, 8, 7) == 1) && !is_high_subnormal_in || 69 | (BitRange(exp_in, 8, 7) == 2); 70 | bool is_special = BitRange(exp_in, 8, 7) == 3; 71 | bool is_NaN = is_special && BitRange(exp_in, 6, 6); 72 | 73 | uint64_t denorm_shift_dist = 2 - BitRange(exp_in, 4, 0); 74 | uint64_t subnormal_sig_out = (0x400000 | sig_in) >> denorm_shift_dist; 75 | uint8_t normal_exp_out = BitRange(exp_in, 7, 0) - 129; 76 | 77 | uint64_t exp_out = is_normal ? normal_exp_out : (is_special ? 255 : 0); 78 | uint64_t sig_out = is_normal || is_NaN ? sig_in : 79 | is_subnormal ? subnormal_sig_out : 0; 80 | 81 | uint64_t raw_output64 = (sign << 31) | (exp_out << 23) | sig_out; 82 | // assert((raw_output64 & 0xffffffff00000000) == uint64_t(0)); 83 | // If this is not a recoded float, this will return gibberish, however, 84 | // the output will not match spike and thus the replacement will not happen. 85 | return raw_output64; 86 | } 87 | 88 | 89 | // Best effort at replacing the float writeback with unrecoded version 90 | // will only replace if (all of following met): 91 | // - log lines differ between rocket and lspike 92 | // - log line is a fld instruction 93 | // - unrecoding the writeback data as a single float makes them match 94 | void DiffAndFix(std::string rocket_filename, std::string lspike_filename) { 95 | if (rocket_filename == "-") 96 | rocket_filename = "/dev/stdin"; 97 | std::ifstream rocket_log(rocket_filename); 98 | if (!rocket_log.is_open()) { 99 | std::cout << "Couldn't open file " << rocket_filename << std::endl; 100 | std::exit(-2); 101 | } 102 | std::ifstream lspike_log(lspike_filename); 103 | if (!lspike_log.is_open()) { 104 | std::cout << "Couldn't open file " << lspike_filename << std::endl; 105 | std::exit(-2); 106 | } 107 | std::string rocket_line, lspike_line; 108 | while (getline(rocket_log, rocket_line)) { 109 | if (getline(lspike_log, lspike_line) && (rocket_line != lspike_line) && 110 | LineIsFLDInst(rocket_line)) { 111 | std::string fixed_line(rocket_line.c_str()); // deep copy 112 | uint64_t raw_fp = UIntFromHexSubstring(fixed_line, 40); 113 | if (NestedFloatPossible(raw_fp)) { 114 | snprintf(const_cast(fixed_line.data()) + 40, 17, 115 | "%016" PRIx64, UnrecodeFloatFromDouble(raw_fp)); 116 | if (fixed_line == lspike_line) 117 | rocket_line = fixed_line; 118 | } 119 | } 120 | printf("%s\n", rocket_line.c_str()); 121 | } 122 | rocket_log.close(); 123 | lspike_log.close(); 124 | } 125 | 126 | 127 | int main(int argc, char** argv) { 128 | if (argc != 3) { 129 | std::cout << "Usage: float_fix rocket_output lspike_output" << std::endl; 130 | return -1; 131 | } 132 | DiffAndFix(std::string(argv[1]), std::string(argv[2])); 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /csrc/verilator.h: -------------------------------------------------------------------------------- 1 | #ifndef _ROCKET_VERILATOR_H 2 | #define _ROCKET_VERILATOR_H 3 | 4 | #include "verilated_vcd_c.h" 5 | #include 6 | #include 7 | 8 | extern bool verbose; 9 | extern bool done_reset; 10 | 11 | class VerilatedVcdFILE : public VerilatedVcdFile { 12 | public: 13 | VerilatedVcdFILE(FILE* file) : file(file) {} 14 | ~VerilatedVcdFILE() {} 15 | bool open(const string& name) override { 16 | // file should already be open 17 | return file != NULL; 18 | } 19 | void close() override { 20 | // file should be closed elsewhere 21 | } 22 | ssize_t write(const char* bufp, ssize_t len) override { 23 | return fwrite(bufp, 1, len, file); 24 | } 25 | private: 26 | FILE* file; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /jenkins/Makefile: -------------------------------------------------------------------------------- 1 | export TOP=$(PWD) 2 | export RISCV=$(TOP)/riscv 3 | export PATH=/opt/Xilinx/SDK/2018.1/bin:/opt/Xilinx/Vivado/2018.1/bin:/opt/Xilinx/DocNav:/usr/local/bin:/usr/bin:/bin:$(RISCV)/bin 4 | export FPGA_BOARD=nexys4_ddr 5 | export XILINX_VIVADO=/opt/Xilinx/Vivado/2018.1 6 | export JAVA_HOME=/usr/lib/jvm/java-8-oracle 7 | 8 | Checkout: 9 | git submodule update --init --recursive 10 | 11 | Build: $(RISCV)/bin/spike 12 | make -C fpga/board/nexys4_ddr bitstream 13 | 14 | Test: 15 | echo Test 16 | 17 | Deploy: 18 | echo Deploy 19 | rsync fpga/board/nexys4_ddr/lowrisc-chip-imp/lowrisc-chip-imp.runs/impl_1/chip_top.bit brexit:lowrisc-chip-refresh-v0.6/lowrisc-fpga/common/script 20 | 21 | Debug: 22 | echo Debug 23 | bash -i 24 | 25 | $(RISCV)/bin/spike: rocket-chip/riscv-tools/build.sh 26 | cd rocket-chip/riscv-tools; bash ./build.sh 27 | -------------------------------------------------------------------------------- /project/.gitignore: -------------------------------------------------------------------------------- 1 | *~ -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.12 2 | -------------------------------------------------------------------------------- /project/build.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | import sbt._ 4 | import Keys._ 5 | import complete._ 6 | import complete.DefaultParsers._ 7 | import xerial.sbt.Pack._ 8 | 9 | object BuildSettings extends Build { 10 | 11 | override lazy val settings = super.settings ++ Seq( 12 | organization := "berkeley", 13 | version := "1.2", 14 | scalaVersion := "2.11.7", 15 | parallelExecution in Global := false, 16 | traceLevel := 30, 17 | scalacOptions ++= Seq("-deprecation","-unchecked"), 18 | scalacOptions ++= Seq("-Xmax-classfile-name", "72"), 19 | libraryDependencies ++= Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value), 20 | addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full) 21 | ) 22 | 23 | lazy val chisel = project in file("chisel3") 24 | lazy val hardfloat = project.dependsOn(chisel) 25 | lazy val rocketchip = (project in file(".")).dependsOn(chisel, hardfloat) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven" 2 | 3 | addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.3") 4 | 5 | addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.1") 6 | 7 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") 8 | 9 | addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.8.0") 10 | 11 | addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.3.3") 12 | -------------------------------------------------------------------------------- /sbt-launch.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lowRISC/lowrisc-chip/091fa17733c36ceaeebf348f78e9b32a051efa26/sbt-launch.jar -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | /comlog 2 | /float_fix 3 | -------------------------------------------------------------------------------- /scripts/Makefile: -------------------------------------------------------------------------------- 1 | base_dir = $(abspath ..) 2 | 3 | CXXSRCS := comlog float_fix 4 | CXXFLAGS := $(CXXFLAGS) -std=c++11 -Wall 5 | 6 | OBJS := $(addsuffix .o,$(CXXSRCS)) 7 | PROGRAMS := $(CXXSRCS) 8 | 9 | all: $(PROGRAMS) 10 | 11 | %: %.o 12 | $(CXX) $< $(LDFLAGS) -o $@ 13 | 14 | %.o: $(base_dir)/csrc/%.cc 15 | $(CXX) $(CXXFLAGS) -c $< -o $@ 16 | 17 | clean: 18 | rm -f $(OBJS) $(PROGRAMS) 19 | -------------------------------------------------------------------------------- /scripts/authors: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | while read when who; do 4 | case "$who" in 5 | "Adam Izraelevitz") echo Berkeley ;; 6 | "Albert Magyar") echo Berkeley ;; 7 | "Albert Ou") if [ $when -ge 20151101 ]; then echo SiFive; else echo Berkeley; fi ;; 8 | "Amirali Sharifian") echo Unknown ;; 9 | "Andrew Waterman") if [ $when -ge 20150901 ]; then echo SiFive; else echo Berkeley; fi ;; 10 | "Ben Keller") echo Berkeley ;; 11 | "Christopher Celio") echo Berkeley ;; 12 | "Colin Schmidt") echo Berkeley ;; 13 | "Daiwei Li") echo Berkeley ;; 14 | "David Biancolin") echo Berkeley ;; 15 | "Donggyu") echo Berkeley ;; 16 | "Donggyu Kim") echo Berkeley ;; 17 | "ducky") echo Berkeley ;; 18 | "Eric Love") echo Berkeley ;; 19 | "Gage W Eads") echo Berkeley ;; 20 | "Henry Cook") if [ $when -ge 20160501 ]; then echo SiFive; else echo Berkeley; fi ;; 21 | "Howard Mao") if [ $when -ge 20160601 -a $when -le 20160819 ]; then echo SiFive; else echo Berkeley; fi ;; 22 | "Huy Vo") echo Berkeley ;; 23 | "Iori YONEJI") echo Unknown ;; 24 | "jackkoenig") echo Berkeley ;; 25 | "Jack Koenig") echo Berkeley ;; 26 | "Jacob Chang") echo SiFive ;; 27 | "Jim Lawson") echo Berkeley ;; 28 | "John Wright") echo Berkeley ;; 29 | "Ken McMillan") echo Microsoft;; 30 | "Matthew Naylor") if [ $when -le 20161127 ]; then echo Berkeley; else echo Cambridge; fi ;; 31 | "Megan Wachs") echo SiFive ;; 32 | "Miquel Moreto") echo Berkeley ;; 33 | "mwachs5") echo SiFive ;; 34 | "Palmer Dabbelt") echo Berkeley ;; 35 | "Quan Nguyen") echo Berkeley ;; 36 | "RainerWasserfuhr") echo Unknown ;; 37 | "Richard Xia") echo SiFive ;; 38 | "Rimas Avizienis") echo Berkeley ;; 39 | "roman3017") echo Unknown ;; 40 | "Sagar Karandikar") echo Berkeley ;; 41 | "Schuyler Eldridge") echo Unknown ;; 42 | "Scott Beamer") echo Berkeley ;; 43 | "Scott Johnson") echo SiFive ;; 44 | "SeungRyeol Lee") echo LGE ;; 45 | "Stephen Twigg") echo Berkeley ;; 46 | "Wei Song") echo Cambridge;; 47 | "Wesley W. Terpstra") echo SiFive ;; 48 | "Yunsup Lee") if [ $when -gt 20150901 ]; then echo SiFive; else echo Berkeley; fi ;; 49 | *) echo NoMatch; echo "Missing scripts/authors entry for $who" >&2; exit 1 ;; 50 | esac 51 | done 52 | -------------------------------------------------------------------------------- /scripts/check_cache_trace.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from collections import defaultdict 3 | 4 | # Checks a trace of cache transactions to make sure the data is correct 5 | # Note: this will only work if the L2 agent only receives cached traffic 6 | # (either caching Acquires or Releases). If there are any builtin 7 | # Put or PutBlock requests, they will not be reflected in the trace 8 | # and the data will appear to be incorrect. 9 | 10 | DATA_BEATS = 8 11 | 12 | def parse_prm(fname): 13 | mem_data_bits = 0 14 | cache_block_bytes = 0 15 | with open(fname) as f: 16 | for line in f: 17 | line = line.strip("() \t\n") 18 | parts = line.split(",") 19 | if parts[0] == "MEM_DATA_BITS": 20 | mem_data_bits = int(parts[1]) 21 | elif parts[1] == "CACHE_BLOCK_BYTES": 22 | cache_block_bytes = int(parts[1]) 23 | DATA_BEATS = (cache_block_bytes * 8) / mem_data_bits 24 | 25 | def data_block(): 26 | return [0] * DATA_BEATS 27 | 28 | blocks = defaultdict(data_block) 29 | 30 | def process_release(addr_block, addr_beat, data): 31 | blocks[addr_block][addr_beat] = data 32 | 33 | def process_get(addr_block, addr_beat, data): 34 | stored_data = blocks[addr_block][addr_beat] 35 | if stored_data != data: 36 | print("Error {:07x},{}: {:016x} != {:016x}".format( 37 | addr_block, addr_beat, stored_data, data)) 38 | 39 | def process_line(line): 40 | if not line: 41 | return 42 | pieces = line.split() 43 | if pieces[0] == "[release]": 44 | addr_block = int(pieces[1].split('=')[1], 16) 45 | addr_beat = int(pieces[2].split('=')[1]) 46 | data = int(pieces[3].split('=')[1], 16) 47 | process_release(addr_block, addr_beat, data) 48 | if pieces[0] == "[get]": 49 | addr_block = int(pieces[1].split('=')[1], 16) 50 | addr_beat = int(pieces[2].split('=')[1]) 51 | data = int(pieces[3].split('=')[1], 16) 52 | process_get(addr_block, addr_beat, data) 53 | 54 | def check_trace(fname): 55 | with open(fname) as f: 56 | for line in f: 57 | process_line(line.strip()) 58 | 59 | if __name__ == "__main__": 60 | if len(sys.argv) < 2: 61 | print("Usage: {} trace.out [params.prm]".format(sys.argv[0])) 62 | sys.exit(-1) 63 | if len(sys.argv) > 2: 64 | parse_prm(sys.argv[2]) 65 | check_trace(sys.argv[1]) 66 | -------------------------------------------------------------------------------- /scripts/check_comparator_trace.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import re 3 | 4 | N_BLOCKS = 4 5 | N_BEATS = 8 6 | N_BYTES = 8 7 | N_OPS = 142 8 | 9 | memory = [[list() for _ in range(0, N_BEATS)] for _ in range(0, N_BLOCKS)] 10 | addresses = {} 11 | 12 | def process_put_block(xid, addr_block, data): 13 | fullmask = (1 << (N_BYTES * 8)) - 1 14 | for i in range(0, N_BEATS): 15 | real_data = (data << i) + data 16 | memory[addr_block][i].append((xid, real_data & fullmask)) 17 | 18 | def expand_wmask(wmask): 19 | bitmask = 0 20 | bitmask_byte = 0xff 21 | 22 | for i in range(0, N_BYTES): 23 | if ((wmask >> i) & 1) == 1: 24 | bitmask |= bitmask_byte 25 | bitmask_byte <<= 8 26 | 27 | return bitmask 28 | 29 | def process_put(xid, addr_block, addr_beat, data, wmask): 30 | fullmask = (1 << (N_BYTES * 8)) - 1 31 | bitmask = expand_wmask(wmask) 32 | old_data = memory[addr_block][addr_beat][-1][1] 33 | new_data = ((bitmask & data) | (~bitmask & old_data)) & fullmask 34 | memory[addr_block][addr_beat].append((xid, new_data)) 35 | 36 | ACQ_RE = re.compile(r"\[acq\s*(\d+)\]: (.*)") 37 | PUT_BLOCK_RE = re.compile( 38 | r"PutBlock\(addr_block = ([0-9a-f]+), data = ([0-9a-f]+)\)") 39 | PUT_BEAT_RE = re.compile( 40 | (r"Put\(addr_block = ([0-9a-f]+), addr_beat = ([0-9a-f]+), " 41 | r"data = ([0-9a-f]+), wmask = ([0-9a-f]+)\)")) 42 | GET_BLOCK_RE = re.compile( 43 | r"GetBlock\(addr_block = ([0-9a-f]+)\)") 44 | GET_BEAT_RE = re.compile( 45 | (r"Get\(addr_block = ([0-9a-f]+), addr_beat = (\d+), " 46 | "addr_byte = \d+, op_size = \d+\)")) 47 | GNT_RE = re.compile( 48 | r"\[gnt\s*(\d+)\]: g_type = \d+, addr_beat = (\d+), data = ([0-9a-f]+)") 49 | 50 | def check_data(gnt_id, addr_beat, data): 51 | addr_block = addresses[gnt_id] 52 | last_data = None 53 | for (put_id, put_data) in memory[addr_block][addr_beat]: 54 | if put_id > gnt_id: 55 | break 56 | last_data = put_data 57 | if last_data != data: 58 | print("Data mismatch at {} for {:07x}, {} - got:{:016x} exp:{:016x}".format( 59 | gnt_id, addr_block, addr_beat, data, last_data)) 60 | 61 | def process_input(f): 62 | for line in f: 63 | m = ACQ_RE.match(line) 64 | if m: 65 | acq_id = int(m.groups()[0]) 66 | body = m.groups()[1] 67 | process_acquire(acq_id, body) 68 | m = GNT_RE.match(line) 69 | if m: 70 | gnt_id = int(m.groups()[0]) 71 | addr_beat = int(m.groups()[1]) 72 | data = int(m.groups()[2], 16) 73 | check_data(gnt_id, addr_beat, data) 74 | 75 | def process_acquire(acq_id, body): 76 | m = PUT_BLOCK_RE.match(body) 77 | if m: 78 | addr_block = int(m.groups()[0], 16) 79 | data = int(m.groups()[1], 16) 80 | process_put_block(acq_id, addr_block, data) 81 | return 82 | m = PUT_BEAT_RE.match(body) 83 | if m: 84 | addr_block = int(m.groups()[0], 16) 85 | addr_beat = int(m.groups()[1], 16) 86 | data = int(m.groups()[2], 16) 87 | wmask = int(m.groups()[3], 16) 88 | process_put(acq_id, addr_block, addr_beat, data, wmask) 89 | return 90 | m = GET_BLOCK_RE.match(body) 91 | if m: 92 | addresses[acq_id] = int(m.groups()[0], 16) 93 | return 94 | m = GET_BEAT_RE.match(body) 95 | if m: 96 | addresses[acq_id] = int(m.groups()[0], 16) 97 | 98 | def main(): 99 | if len(sys.argv) < 2: 100 | process_input(sys.stdin) 101 | else: 102 | with open(sys.argv[1]) as f: 103 | process_input(f) 104 | 105 | if __name__ == "__main__": 106 | main() 107 | -------------------------------------------------------------------------------- /scripts/copyright-file: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | d=$(dirname $0) 3 | for i in "$@"; do 4 | if [ $# -gt 1 ]; then echo "$i:"; fi 5 | git blame --date="format:%Y%m%d" -M -C -C -C "$i" | sed 's/[^(]*(\([^0-46-9]*\) \([0-9]*\).*/\2 \1/' | $d/authors | sort | uniq -c | sort -rn 6 | done 7 | -------------------------------------------------------------------------------- /scripts/debug_rom/Makefile: -------------------------------------------------------------------------------- 1 | # See LICENSE.SiFive for license details 2 | # Recursive make is bad, but in this case we're cross compiling which is a 3 | # pretty unusual use case. 4 | 5 | CC = $(RISCV)/bin/riscv64-unknown-elf-gcc 6 | OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy 7 | 8 | COMPILE = $(CC) -nostdlib -nostartfiles -I$(RISCV)/include/ -Tlink.ld 9 | 10 | ELFS = debug_rom 11 | DEPS = debug_rom.S link.ld 12 | 13 | all: $(patsubst %,%.h,$(ELFS)) 14 | 15 | publish: debug_rom.scala 16 | mv $< ../../src/main/scala/uncore/devices/debug/DebugRomContents.scala 17 | 18 | %.scala: %.raw 19 | xxd -i $^ | sed -e "s/^unsigned char debug_rom_raw\[\] = {/\/\/ This file was auto-generated by 'make publish' in debug\/ directory.\n\npackage uncore.devices\n\nobject DebugRomContents {\n\n def apply() : Array[Byte] = { Array (/" \ 20 | -e "s/};/ ).map(_.toByte) }\n\n}/" \ 21 | -e "s/^unsigned int debug_rom_raw_len.*//" > $@ 22 | 23 | 24 | %.raw: % 25 | $(OBJCOPY) -O binary --only-section .text $^ $@ 26 | 27 | debug_rom: $(DEPS) 28 | $(COMPILE) -o $@ $^ 29 | 30 | clean: 31 | rm -f $(ELFS) debug_rom*.raw debug_rom*.h 32 | -------------------------------------------------------------------------------- /scripts/debug_rom/debug_rom.S: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | #include "spike/encoding.h" 4 | 5 | // These are implementation-specific addresses in the Debug Module 6 | #define HALTED 0x100 7 | #define GOING 0x104 8 | #define RESUMING 0x108 9 | #define EXCEPTION 0x10C 10 | 11 | // Region of memory where each hart has 1 12 | // byte to read. 13 | #define FLAGS 0x400 14 | #define FLAG_GO 0 15 | #define FLAG_RESUME 1 16 | 17 | .option norvc 18 | .global entry 19 | .global exception 20 | 21 | // Entry location on ebreak, Halt, or Breakpoint 22 | // It is the same for all harts. They branch when 23 | // their GO or RESUME bit is set. 24 | 25 | entry: 26 | jal zero, _entry 27 | resume: 28 | jal zero, _resume 29 | exception: 30 | jal zero, _exception 31 | 32 | _entry: 33 | // This fence is required because the execution may have written something 34 | // into the Abstract Data or Program Buffer registers. 35 | fence 36 | csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID 37 | 38 | // We continue to let the hart know that we are halted in order that 39 | // a DM which was reset is still made aware that a hart is halted. 40 | // We keep checking both whether there is something the debugger wants 41 | // us to do, or whether we should resume. 42 | entry_loop: 43 | csrr s0, CSR_MHARTID 44 | sw s0, HALTED(zero) 45 | lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here. 46 | andi s0, s0, (1 << FLAG_GO) 47 | bnez s0, going 48 | csrr s0, CSR_MHARTID 49 | lbu s0, FLAGS(s0) // multiple harts can resume here 50 | andi s0, s0, (1 << FLAG_RESUME) 51 | bnez s0, resume 52 | jal zero, entry_loop 53 | 54 | _exception: 55 | sw zero, EXCEPTION(zero) // Let debug module know you got an exception. 56 | ebreak 57 | 58 | going: 59 | csrr s0, CSR_DSCRATCH // Restore s0 here 60 | sw zero, GOING(zero) // When debug module sees this write, the GO flag is reset. 61 | jalr zero, zero, %lo(whereto) // Rocket-Chip has a specific hack which is that jalr in 62 | // Debug Mode will flush the I-Cache. We need that so that the 63 | // remainder of the variable instructions will be what Debug Module 64 | // intends. 65 | _resume: 66 | csrr s0, CSR_MHARTID 67 | sw s0, RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset. 68 | csrr s0, CSR_DSCRATCH // Restore s0 69 | dret 70 | 71 | // END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT. 72 | 73 | .section .whereto 74 | whereto: 75 | nop 76 | // Variable "ROM" This is : jal x0 abstract, jal x0 program_buffer, 77 | // or jal x0 resume, as desired. 78 | // Debug Module state machine tracks what is 'desired'. 79 | // We don't need/want to use jalr here because all of the 80 | // Variable ROM contents are set by 81 | // Debug Module before setting the OK_GO byte. 82 | -------------------------------------------------------------------------------- /scripts/debug_rom/link.ld: -------------------------------------------------------------------------------- 1 | /* See LICENSE.SiFive for license details. */ 2 | OUTPUT_ARCH( "riscv" ) 3 | ENTRY( entry ) 4 | SECTIONS 5 | { 6 | .whereto 0x300 : 7 | { 8 | *(.whereto) 9 | } 10 | . = 0x800; 11 | .text : 12 | { 13 | *(.text) 14 | } 15 | _end = .; 16 | } 17 | -------------------------------------------------------------------------------- /scripts/modify-copyright: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | d=$(dirname "$0") 3 | threshold=10 4 | 5 | for i in $(git ls-tree -r HEAD . | grep '\.\(scala\|cc\|v\)' | cut -f2); do 6 | ("$d/copyright-file" "$i" | sort -rn | awk 'NR == 1 || $1 > '$threshold' { print }' | sed 's@[^A-Z]*@// See LICENSE.@;s@$@ for license details.@;$a\\'; \ 7 | grep -v "^// See LICENSE" $i | sed '/./,$!d') > $i.tmp 8 | mv $i.tmp $i 9 | done 10 | -------------------------------------------------------------------------------- /scripts/tracegen+check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This file was originally written by Matthew Naylor, University of 4 | # Cambridge. 5 | # 6 | # This software was partly developed by the University of Cambridge 7 | # Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 8 | # ("CTSRD"), as part of the DARPA CRASH research programme. 9 | # 10 | # This software was partly developed by the University of Cambridge 11 | # Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 12 | # ("MRC2"), as part of the DARPA MRC research programme. 13 | # 14 | # This software was partly developed by the University of Cambridge 15 | # Computer Laboratory as part of the Rigorous Engineering of 16 | # Mainstream Systems (REMS) project, funded by EPSRC grant 17 | # EP/K008528/1. 18 | 19 | # This script can be used to test the memory consistency of rocket 20 | # chip in simulation when compiled with the 'TraceGenConfig' 21 | # configuation. 22 | 23 | ############################################################################### 24 | 25 | # Parameters 26 | # ========== 27 | 28 | # Arguments are taken from environment variables where available. 29 | # Elsewhere, defaults values are chosen. 30 | 31 | START_SEED=${START_SEED-0} 32 | NUM_TESTS=${NUM_TESTS-100} 33 | EMU=${EMU-emulator-groundtest-TraceGenConfig} 34 | TRACE_GEN=${TRACE_GEN-tracegen.py} 35 | TO_AXE=${TO_AXE-toaxe.py} 36 | AXE=${AXE-axe} 37 | MODEL=${MODEL-WMO} 38 | LOG_DIR=${LOG_DIR-tracegen-log} 39 | TRACE_STATS=${TRACE_STATS-tracestats.py} 40 | 41 | ############################################################################### 42 | 43 | # Inferred parameters 44 | # =================== 45 | 46 | END_SEED=`expr \( $START_SEED + $NUM_TESTS \) - 1` 47 | LOG=$LOG_DIR 48 | PATH=$PATH:. 49 | 50 | # Sanity check 51 | # ============ 52 | 53 | if [ ! `command -v $EMU` ]; then 54 | echo Can\'t find emulator: \'$EMU\' 55 | exit -1 56 | fi 57 | 58 | if [ ! `command -v $TO_AXE` ]; then 59 | echo Please add \'toaxe.py\' to your PATH 60 | exit -1 61 | fi 62 | 63 | if [ ! `command -v $TRACE_GEN` ]; then 64 | echo Please add \'tracegen.py\' to your PATH 65 | exit -1 66 | fi 67 | 68 | if [ ! `command -v $AXE` ]; then 69 | echo Please add \'axe\' to your PATH 70 | exit -1 71 | fi 72 | 73 | if [ ! `command -v $TRACE_STATS` ]; then 74 | echo Please add \'tracestats.py\' to your PATH 75 | exit -1 76 | fi 77 | 78 | if [ "$MODEL" != SC -a \ 79 | "$MODEL" != TSO -a \ 80 | "$MODEL" != PSO -a \ 81 | "$MODEL" != WMO -a \ 82 | "$MODEL" != POW ]; then 83 | echo Unknown consistency model \'$MODEL\' 84 | exit -1 85 | fi 86 | 87 | # Setup log directory 88 | # =================== 89 | 90 | if [ ! -d $LOG ]; then 91 | echo Creating log directory: $LOG 92 | mkdir $LOG 93 | fi 94 | 95 | rm -f $LOG/errors.txt 96 | rm -f $LOG/stats.txt 97 | 98 | # Test loop 99 | # ========= 100 | 101 | echo Testing against $MODEL model: 102 | 103 | for (( I = $START_SEED; I <= $END_SEED; I++ )); do 104 | SPACE=`expr $I \% 10` 105 | if [ $SPACE -eq 0 ]; then 106 | echo -n " " 107 | fi 108 | 109 | NEWLINE=`expr $I \% 50` 110 | if [ $NEWLINE -eq 0 ]; then 111 | printf "\n%8i: " $I 112 | fi 113 | 114 | # Generate trace 115 | $TRACE_GEN $EMU $I > $LOG/trace.txt 116 | if [ ! $? -eq 0 ]; then 117 | echo -e "\n\nError: emulator returned non-zero exit code" 118 | echo See $LOG/trace.txt for details 119 | exit -1 120 | fi 121 | 122 | # Convert to axe format 123 | $TO_AXE $LOG/trace.txt $LOG/stats.txt 2>> $LOG/errors.txt > $LOG/trace.axe 124 | if [ ! $? -eq 0 ]; then 125 | echo -e "\n\nError during trace generation with seed $I" 126 | echo "See $LOG/errors.txt" 127 | exit -1 128 | else 129 | # Check trace 130 | OUTCOME=`$AXE check $MODEL $LOG/trace.axe 2>> $LOG/errors.txt` 131 | if [ "$OUTCOME" == "OK" ]; then 132 | echo -n . 133 | else 134 | if [ "$OUTCOME" == "NO" ]; then 135 | echo -e "\n\nFailed $MODEL with seed $I" 136 | echo "See $LOG/trace.txt and $LOG/trace.axe for counterexample" 137 | exit -1 138 | else 139 | echo -e "\n\nError during trace generation with seed $I" 140 | echo "See $LOG/errors.txt for details" 141 | exit -1 142 | fi 143 | fi 144 | fi 145 | done 146 | 147 | echo -e "\n\nOK, passed $NUM_TESTS tests" 148 | $TRACE_STATS $LOG/stats.txt 149 | -------------------------------------------------------------------------------- /scripts/tracegen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This file was originally written by Matthew Naylor, University of 4 | # Cambridge. 5 | # 6 | # This software was partly developed by the University of Cambridge 7 | # Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 8 | # ("CTSRD"), as part of the DARPA CRASH research programme. 9 | # 10 | # This software was partly developed by the University of Cambridge 11 | # Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 12 | # ("MRC2"), as part of the DARPA MRC research programme. 13 | # 14 | # This software was partly developed by the University of Cambridge 15 | # Computer Laboratory as part of the Rigorous Engineering of 16 | # Mainstream Systems (REMS) project, funded by EPSRC grant 17 | # EP/K008528/1. 18 | 19 | # ------- 20 | # Outline 21 | # ------- 22 | 23 | # Usage: 24 | # 25 | # tracegen.py EMULATOR SEED 26 | # 27 | # This script generates a trace using the given emulator (built 28 | # with CONFIG=TraceGenConfig). It waits until all cores have 29 | # completed trace generation before terminating the emulator. 30 | 31 | import sys 32 | import subprocess 33 | import re 34 | 35 | def main(): 36 | if len(sys.argv) != 3: 37 | sys.stderr.write("Usage: tracegen.py EMULATOR SEED\n") 38 | sys.exit(-1) 39 | 40 | p = subprocess.Popen([sys.argv[1], 41 | "+verbose", "-s" + sys.argv[2]], 42 | stderr=subprocess.PIPE, stdout=subprocess.PIPE) 43 | if p == None: 44 | sys.stderr.write("File not found: " + sys.argv[1] + "\n") 45 | sys.exit(-1) 46 | 47 | numFinished = 0 48 | while True: 49 | line = p.stderr.readline() 50 | if line[0:9] == "FINISHED ": 51 | total = int(line[9:-1]) 52 | numFinished = numFinished + 1 53 | if numFinished == total: 54 | break 55 | elif line[0:15] == "Completed after": 56 | break 57 | elif line[0:7] == "testing": 58 | continue 59 | else: 60 | print line, 61 | 62 | p.terminate() 63 | 64 | try: 65 | main() 66 | except KeyboardInterrupt: 67 | sys.exit(-1) 68 | -------------------------------------------------------------------------------- /scripts/tracestats.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This file was originally written by Matthew Naylor, University of 4 | # Cambridge. 5 | # 6 | # This software was partly developed by the University of Cambridge 7 | # Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 8 | # ("CTSRD"), as part of the DARPA CRASH research programme. 9 | # 10 | # This software was partly developed by the University of Cambridge 11 | # Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 12 | # ("MRC2"), as part of the DARPA MRC research programme. 13 | # 14 | # This software was partly developed by the University of Cambridge 15 | # Computer Laboratory as part of the Rigorous Engineering of 16 | # Mainstream Systems (REMS) project, funded by EPSRC grant 17 | # EP/K008528/1. 18 | 19 | # ------- 20 | # Outline 21 | # ------- 22 | 23 | # Usage: 24 | # 25 | # tracegen-stats.py STATS-FILE 26 | # 27 | # This script produces some statistics about the traces generated 28 | # using tracegen.py. 29 | 30 | import sys 31 | import subprocess 32 | import re 33 | 34 | def main(): 35 | if len(sys.argv) != 2: 36 | sys.stderr.write("Usage: tracegen-stats.py STATS-FILE\n") 37 | sys.exit(-1) 38 | 39 | f = open(sys.argv[1], 'r') 40 | if f == None: 41 | sys.stderr.write("File not found: " + sys.argv[1] + "\n") 42 | sys.exit(-1) 43 | 44 | lrscSuccessSum = 0.0 45 | lrscSuccessCount = 0 46 | loadExtRateSum = 0.0 47 | loadExtRateCount = 0 48 | for line in f: 49 | if line[0:18] == "LRSC_Success_Rate=": 50 | val = float(line[18:-1]) 51 | lrscSuccessSum = lrscSuccessSum + val 52 | lrscSuccessCount = lrscSuccessCount + 1 53 | 54 | if line[0:19] == "Load_External_Rate=": 55 | val = float(line[19:-1]) 56 | loadExtRateSum = loadExtRateSum + val 57 | loadExtRateCount = loadExtRateCount + 1 58 | 59 | if lrscSuccessCount > 0: 60 | lrscSuccessAvg = lrscSuccessSum / float(lrscSuccessCount) 61 | lrscSuccessRate = str(int(100.0*lrscSuccessAvg)) + "%" 62 | print "LR/SC success rate:", lrscSuccessRate 63 | else: 64 | print "LR/SC success rate: none performed" 65 | 66 | if loadExtRateCount > 0: 67 | loadExtRateAvg = loadExtRateSum / float(loadExtRateCount) 68 | loadExtRate = str(int(100.0*loadExtRateAvg)) + "%" 69 | print "Load-external rate:", loadExtRate 70 | else: 71 | print "Load-external rate: none performed" 72 | 73 | try: 74 | main() 75 | except KeyboardInterrupt: 76 | sys.exit(-1) 77 | -------------------------------------------------------------------------------- /scripts/vlsi_rom_gen: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # See LICENSE.SiFive for license details. 4 | 5 | from __future__ import division 6 | from __future__ import print_function 7 | from __future__ import unicode_literals 8 | 9 | import doctest 10 | import sys 11 | import warnings 12 | from collections import namedtuple 13 | 14 | verilog_template = """ 15 | module {name}( 16 | input clock, 17 | input oe, 18 | input me, 19 | input [{address_bits_minus_1}:0] address, 20 | output [{output_width_minus_1}:0] q 21 | ); 22 | reg [{output_width_minus_1}:0] out; 23 | reg [{output_width_minus_1}:0] rom [0:{depth_minus_1}]; 24 | 25 | 26 | // 1024 is the maximum length of $readmemh filename supported by Cadence Incisive 27 | reg [1024 * 8 - 1:0] path; 28 | 29 | integer i; 30 | initial begin 31 | `ifdef RANDOMIZE 32 | `ifdef RANDOMIZE_MEM_INIT 33 | for (i = 0; i < {depth}; i++) begin 34 | rom[i] = {{{num_random_blocks}{{$random}}}}; 35 | end 36 | `endif 37 | `endif 38 | if (!$value$plusargs("maskromhex=%s", path)) begin 39 | path = "{rom_hex_file}"; 40 | end 41 | $readmemh(path, rom); 42 | end 43 | 44 | 45 | always @(posedge clock) begin 46 | if (me) begin 47 | out <= rom[address]; 48 | end 49 | end 50 | 51 | assign q = oe ? out : {output_width}'bZ; 52 | 53 | endmodule 54 | """ 55 | 56 | 57 | def gen_rom(name, width, depth, rom_hex_file): 58 | variables = { 59 | 'name': name, 60 | 'address_bits_minus_1': (depth - 1).bit_length() - 1, 61 | 'depth': depth, 62 | 'depth_minus_1': depth - 1, 63 | 'output_width': width, 64 | 'output_width_minus_1': width - 1, 65 | # $random in verilog returns 32 bits; compute how many times to repeat 66 | # $random in order to fill the width 67 | 'num_random_blocks': (width - 1) // 32 + 1, 68 | 'rom_hex_file': rom_hex_file, 69 | } 70 | return verilog_template.format(**variables) 71 | 72 | 73 | def iterate_by_n(it, n): 74 | """Iterate over items in it, yielding n-tuples of successive items. 75 | 76 | >>> list(iterate_by_n([1, 2, 3, 4, 5, 6], n=2)) 77 | [(1, 2), (3, 4), (5, 6)] 78 | >>> list(iterate_by_n([1, 2, 3, 4, 5, 6], n=3)) 79 | [(1, 2, 3), (4, 5, 6)] 80 | >>> list(iterate_by_n([1, 2, 3, 4, 5, 6], n=4)) 81 | Traceback (most recent call last): 82 | ... 83 | ValueError: Iterable length not evenly divisible by 4 84 | """ 85 | it = iter(it) 86 | while True: 87 | batch = () 88 | for i in range(n): 89 | try: 90 | batch += (next(it),) 91 | except StopIteration: 92 | if batch: # If this is not the first iteration 93 | raise ValueError( 94 | 'Iterable length not evenly divisible by {}'.format(n) 95 | ) 96 | else: 97 | raise 98 | yield batch 99 | 100 | 101 | def try_cast_int(x): 102 | try: 103 | return int(x) 104 | except ValueError: 105 | return x 106 | 107 | 108 | ROMParameters = namedtuple('ROMParameters', ['name', 'depth', 'width']) 109 | default_rom_parameters = ROMParameters(name='', depth=0, width=0) 110 | 111 | 112 | def parse_line(line): 113 | kwargs = {key: try_cast_int(val) 114 | for key, val in iterate_by_n(line.split(), 2)} 115 | rom_parameters = default_rom_parameters._replace(**kwargs) 116 | return rom_parameters._asdict() 117 | 118 | 119 | def main(): 120 | if '--run-tests' in sys.argv: 121 | (failures, total) = doctest.testmod(verbose=True) 122 | sys.exit(1 if failures else 0) 123 | 124 | if len(sys.argv) < 2: 125 | sys.exit('Please give a .conf file as input') 126 | 127 | print('// This file created by ' + __file__) 128 | with open(sys.argv[1]) as fp: 129 | lines = fp.readlines() 130 | if len(lines) > 1: 131 | warnings.warn('vlsi_rom_gen detected multiple ROMs. ROM contents will be duplicated.') 132 | for line in lines: 133 | verilog = gen_rom(rom_hex_file=sys.argv[2], 134 | **parse_line(line)) 135 | print(verilog) 136 | 137 | if __name__ == '__main__': 138 | main() 139 | -------------------------------------------------------------------------------- /set_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # source this file 3 | echo "Setting up lowRISC/RISC-V and SoC Debug SoC environment..." 4 | echo "Make sure you source this script at the top of lowrisc-chip." 5 | echo 6 | 7 | # Variables for lowRISC/RISC-V 8 | if [ -z $TOP ] || [ ! -d $TOP ]; then 9 | echo "\$TOP is not defined or does not point to a directory. Set \$TOP to the top of lowrisc-chip which is the current directory." 10 | export TOP=$PWD 11 | fi 12 | 13 | if [ -z $RISCV ]; then 14 | echo "\$RISCV is not defined. Set \$TOP/riscv to the RISC-V toolchain installation target (\$RISCV)." 15 | export RISCV=$TOP/riscv 16 | fi 17 | 18 | export PATH=$PATH:$RISCV/bin 19 | 20 | # Variables for Open SoC Debug 21 | if [ -z $OSD_ROOT ]; then 22 | echo "\$OSD_ROOT is not defined." 23 | echo "Set \$TOP/tools to the Open SoC Debug installation target (\$OSD_ROOT)." 24 | export OSD_ROOT=$TOP/tools 25 | fi 26 | 27 | echo "Add opensocdebug to \$PYTHONPATH" 28 | export PYTHONPATH=$OSD_ROOT/lib/python2.7/site-packages:$PYTHONPATH 29 | 30 | if [ -z $LD_LIBRARY_PATH ]; then 31 | export LD_LIBRARY_PATH=$OSD_ROOT/lib 32 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/lib 33 | else 34 | export LD_LIBRARY_PATH=$OSD_ROOT/lib:$LD_LIBRARY_PATH 35 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/lib 36 | fi 37 | 38 | export PATH=$OSD_ROOT/bin:$PATH 39 | 40 | if [ -z $PKG_CONFIG_PATH ]; then 41 | export PKG_CONFIG_PATH=$OSD_ROOT/lib/pkgconfig 42 | else 43 | export PKG_CONFIG_PATH=$OSD_ROOT/lib/pkgconfig:$PKG_CONFIG_PATH 44 | fi 45 | 46 | # choose the FPGA board (Nexys4-DDR in default) 47 | if [ -z $FPGA_BOARD ]; then 48 | echo "\$FPGA_BOARD is not defined. Set the target FPGA board to nexys4_ddr." 49 | export FPGA_BOARD=nexys4_ddr 50 | fi 51 | 52 | echo "============================" 53 | echo " export TOP=$TOP" 54 | echo " export RISCV=$RISCV" 55 | echo " export OSD_ROOT=$OSD_ROOT" 56 | echo " export PYTHONPATH=$PYTHONPATH" 57 | echo " export PATH=$PATH" 58 | echo " export LD_LIBRARY_PATH=$LD_LIBRARY_PATH" 59 | echo " export PKG_CONFIG_PATH=$PKG_CONFIG_PATH" 60 | echo " export FPGA_BOARD=$FPGA_BOARD" 61 | echo "============================" 62 | -------------------------------------------------------------------------------- /src/main/verilog/SimJTAG_xilinx.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | module SimJTAG #( 4 | parameter TICK_DELAY = 50 5 | )( 6 | 7 | input clock, 8 | input reset, 9 | 10 | input enable, 11 | input init_done, 12 | 13 | output jtag_TCK, 14 | output jtag_TMS, 15 | output jtag_TDI, 16 | output jtag_TRSTn, 17 | 18 | input jtag_TDO_data, 19 | input jtag_TDO_driven, 20 | 21 | output [31:0] exit 22 | ); 23 | 24 | wire CAPTURE, DRCK, RESET, RUNTEST, SEL, SHIFT, TCK, TDI, TMS, UPDATE, TDO; 25 | 26 | /* This block is just used to feed the JTAG clock into the parts of Rocket that need it */ 27 | 28 | BSCANE2 #( 29 | .JTAG_CHAIN(2) // Value for USER command. 30 | ) 31 | BSCANE2_inst1 ( 32 | .CAPTURE(CAPTURE), // 1-bit output: CAPTURE output from TAP controller. 33 | .DRCK(DRCK), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 34 | // SHIFT are asserted. 35 | 36 | .RESET(RESET), // 1-bit output: Reset output for TAP controller. 37 | .RUNTEST(RUNTEST), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 38 | .SEL(SEL), // 1-bit output: USER instruction active output. 39 | .SHIFT(SHIFT), // 1-bit output: SHIFT output from TAP controller. 40 | .TCK(jtag_TCK), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 41 | .TDI(jtag_TDI), // 1-bit output: Test Data Input (TDI) output from TAP controller. 42 | .TMS(jtag_TMS), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 43 | .UPDATE(UPDATE), // 1-bit output: UPDATE output from TAP controller 44 | .TDO(jtag_TDO_data) // 1-bit input: Test Data Output (TDO) input for USER function. 45 | ); 46 | 47 | assign jtag_TRSTn = ~RESET; 48 | assign exit = 32'b0; 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /src/main/verilog/chip_top_dummy.sv: -------------------------------------------------------------------------------- 1 | module chip_top_dummy( // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257214.2] 2 | input clk_p, // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257215.4] 3 | input clk_n, // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257215.4] 4 | input rst_top, // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257216.4] 5 | output GPIO_LED_0_LS 6 | ); 7 | 8 | logic clock, clk_locked, clk_locked_wiz; 9 | 10 | TestHarness dut( // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257214.2] 11 | .clock(clock), // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257215.4] 12 | .reset(~clk_locked), // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257216.4] 13 | .io_success(GPIO_LED_0_LS) // @[:freechips.rocketchip.system.DefaultFPGAConfig.fir@257217.4] 14 | ); 15 | 16 | clk_wiz_dummy clk_gen 17 | ( 18 | // Clock in ports 19 | .clk_in1_p(clk_p), // input clk_in1_p 20 | .clk_in1_n(clk_n), // input clk_in1_n 21 | // Clock out ports 22 | .clk_out1(clock), // output clk_out1 23 | // Status and control signals 24 | .resetn(~rst_top), // input resetn 25 | .locked(clk_locked_wiz)); // output locked 26 | 27 | assign clk_locked = clk_locked_wiz & ~rst_top; 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /src/main/verilog/config.vh: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | //------------------------------------------------- 4 | // Define the features in simulatio/fpga/asic 5 | //------------------------------------------------- 6 | 7 | `ifndef CHIP_CONFIG_VH 8 | `define CHIP_CONFIG_VH 9 | 10 | // For some known cases 11 | `ifdef VERILATOR_SIM 12 | // when verilator is used for behavioural simulation 13 | `define SIMULATION 14 | `endif 15 | 16 | `ifdef VCS 17 | // when Synopsys VCS is used for behavioural simulation 18 | `define SIMULATION 19 | `endif 20 | 21 | `ifdef INCA 22 | // when Cadence NCSIM is used for behavioural simulation 23 | `define SIMULATION 24 | `endif 25 | 26 | `ifdef MODEL_TECH 27 | // when Mentor Graphic Modelsom is used for behavioural simulation 28 | `define SIMULATION 29 | `endif 30 | 31 | // The following should be indicated but can be directly enabled 32 | // SIMULATION : simulation 33 | // FPGA : FPGA implementation 34 | // ASIC : ASIC implementation 35 | 36 | // FPGA_FULL : simulation/implement very ip of FPGA 37 | 38 | //----------- Detailed configuration -------------// 39 | 40 | `define LOWRISC_IO_DAT_WIDTH 32 41 | 42 | `ifdef FPGA 43 | 44 | `ifdef FPGA_FULL 45 | `define ADD_PHY_DDR 46 | `endif 47 | 48 | `ifdef NEXYS4_VIDEO 49 | `define NEXYS4_COMMON 50 | `endif 51 | 52 | `ifdef NEXYS4 53 | `define NEXYS4_COMMON 54 | `endif 55 | 56 | //`define ADD_MINION_SD 57 | 58 | `endif // `ifdef FPGA 59 | 60 | `endif // `ifndef CHIP_CONFIG_VH 61 | 62 | -------------------------------------------------------------------------------- /src/main/verilog/consts.vh: -------------------------------------------------------------------------------- 1 | `ifndef LoRCCoreplex_HD 2 | `define LoRCCoreplex_HD 3 | `define ADD_BRAM 4 | `define ADD_ROCKET_INT 5 | `define ADD_HID 6 | `define BRAM_BASE (31'h40000000) 7 | `define BRAM_SIZE (21'h00100000) 8 | `define HID_BASE (31'h41000000) 9 | `define HID_SIZE (21'h00100000) 10 | `define MEM_ADDR_WIDTH (32'h00000020) 11 | `define MEM_BASE (64'h0000000080000000) 12 | `define MEM_DATA_WIDTH (32'h00000040) 13 | `define MEM_ID_WIDTH (32'h00000004) 14 | `define MEM_SIZE (64'h0000000010000000) 15 | `define MMIO_MASTER_ADDR_WIDTH (32'h0000001f) 16 | `define MMIO_MASTER_DATA_WIDTH (32'h00000040) 17 | `define MMIO_MASTER_ID_WIDTH (32'h00000004) 18 | `define MMIO_SLAVE_ADDR_WIDTH (32'h00000020) 19 | `define MMIO_SLAVE_DATA_WIDTH (32'h00000040) 20 | `define MMIO_SLAVE_ID_WIDTH (32'h00000008) 21 | `define ROCKET_INT_SIZE (32'h00000004) 22 | `endif 23 | -------------------------------------------------------------------------------- /src/main/verilog/dualmem.v: -------------------------------------------------------------------------------- 1 | 2 | module dualmem(clka, clkb, dina, dinb, addra, addrb, wea, web, douta, doutb, ena, enb); 3 | 4 | input wire clka, clkb; 5 | input [63:0] dina; 6 | input [63:0] dinb; 7 | input [10:0] addra; 8 | input [10:0] addrb; 9 | input [7:0] wea; 10 | input [7:0] web; 11 | input [0:0] ena, enb; 12 | output [63:0] douta; 13 | output [63:0] doutb; 14 | 15 | genvar r; 16 | 17 | `ifdef FPGA 18 | 19 | generate for (r = 0; r < 8; r=r+1) 20 | RAMB16_S9_S9 21 | RAMB16_S9_S9_inst 22 | ( 23 | .CLKA ( clka ), // Port A Clock 24 | .DOA ( douta[r*8 +: 8] ), // Port A 1-bit Data Output 25 | .DOPA ( ), 26 | .ADDRA ( addra ), // Port A 14-bit Address Input 27 | .DIA ( dina[r*8 +: 8] ), // Port A 1-bit Data Input 28 | .DIPA ( 1'b0 ), 29 | .ENA ( ena ), // Port A RAM Enable Input 30 | .SSRA ( 1'b0 ), // Port A Synchronous Set/Reset Input 31 | .WEA ( wea[r] ), // Port A Write Enable Input 32 | .CLKB ( clkb ), // Port B Clock 33 | .DOB ( doutb[r*8 +: 8] ), // Port B 1-bit Data Output 34 | .DOPB ( ), 35 | .ADDRB ( addrb ), // Port B 14-bit Address Input 36 | .DIB ( dinb[r*8 +: 8] ), // Port B 1-bit Data Input 37 | .DIPB ( 1'b0 ), 38 | .ENB ( enb ), // Port B RAM Enable Input 39 | .SSRB ( 1'b0 ), // Port B Synchronous Set/Reset Input 40 | .WEB ( web[r] ) // Port B Write Enable Input 41 | ); 42 | endgenerate 43 | 44 | `else // !`ifdef FPGA 45 | 46 | infer_dpram #(.RAM_SIZE(11), .BYTE_WIDTH(8)) ram1 // RAM_SIZE is in words 47 | ( 48 | .ram_clk_a(clka), 49 | .ram_en_a(ena), 50 | .ram_we_a(wea), 51 | .ram_addr_a(addra), 52 | .ram_wrdata_a(dina), 53 | .ram_rddata_a(douta), 54 | .ram_clk_b(clkb), 55 | .ram_en_b(enb), 56 | .ram_we_b(web), 57 | .ram_addr_b(addrb), 58 | .ram_wrdata_b(dinb), 59 | .ram_rddata_b(doutb) 60 | ); 61 | 62 | `endif 63 | 64 | endmodule // dualmem 65 | -------------------------------------------------------------------------------- /src/main/verilog/dualmem_32K_64.sv: -------------------------------------------------------------------------------- 1 | 2 | module dualmem_32K_64(clka, clkb, dina, dinb, addra, addrb, wea, web, douta, doutb, ena, enb); 3 | 4 | input wire clka, clkb; 5 | input [63:0] dina; 6 | input [63:0] dinb; 7 | input [8:0] addra; 8 | input [8:0] addrb; 9 | input [7:0] wea; 10 | input [7:0] web; 11 | input [0:0] ena, enb; 12 | output [63:0] douta; 13 | output [63:0] doutb; 14 | 15 | genvar r; 16 | 17 | `ifdef FPGA 18 | 19 | generate for (r = 0; r < 2; r=r+1) 20 | RAMB16_S36_S36 21 | RAMB16_S36_S36_inst 22 | ( 23 | .CLKA ( clka ), // Port A Clock 24 | .DOA ( douta[r*32 +: 32] ), // Port A 1-bit Data Output 25 | .DOPA ( ), 26 | .ADDRA ( addra ), // Port A 14-bit Address Input 27 | .DIA ( dina[r*32 +: 32] ), // Port A 1-bit Data Input 28 | .DIPA ( 4'b0 ), 29 | .ENA ( ena ), // Port A RAM Enable Input 30 | .SSRA ( 1'b0 ), // Port A Synchronous Set/Reset Input 31 | .WEA ( wea[r*4] ), // Port A Write Enable Input 32 | .CLKB ( clkb ), // Port B Clock 33 | .DOB ( doutb[r*32 +: 32] ), // Port B 1-bit Data Output 34 | .DOPB ( ), 35 | .ADDRB ( addrb ), // Port B 14-bit Address Input 36 | .DIB ( dinb[r*32 +: 32] ), // Port B 1-bit Data Input 37 | .DIPB ( 4'b0 ), 38 | .ENB ( enb ), // Port B RAM Enable Input 39 | .SSRB ( 1'b0 ), // Port B Synchronous Set/Reset Input 40 | .WEB ( web[r*4] ) // Port B Write Enable Input 41 | ); 42 | endgenerate 43 | 44 | `else // !`ifdef FPGA 45 | 46 | infer_dpram #(.RAM_SIZE(9), .BYTE_WIDTH(8)) ram1 // RAM_SIZE is in words 47 | ( 48 | .ram_clk_a(clka), 49 | .ram_en_a(ena), 50 | .ram_we_a(wea), 51 | .ram_addr_a(addra), 52 | .ram_wrdata_a(dina), 53 | .ram_rddata_a(douta), 54 | .ram_clk_b(clkb), 55 | .ram_en_b(enb), 56 | .ram_we_b(web), 57 | .ram_addr_b(addrb), 58 | .ram_wrdata_b(dinb), 59 | .ram_rddata_b(doutb) 60 | ); 61 | 62 | `endif 63 | 64 | endmodule // dualmem 65 | -------------------------------------------------------------------------------- /src/main/verilog/dualmem_widen.v: -------------------------------------------------------------------------------- 1 | 2 | module dualmem_widen(clka, clkb, dina, dinb, addra, addrb, wea, web, douta, doutb, ena, enb); 3 | 4 | input wire clka, clkb; 5 | input [15:0] dina; 6 | input [63:0] dinb; 7 | input [10:0] addra; 8 | input [8:0] addrb; 9 | input [1:0] wea; 10 | input [1:0] web; 11 | input [0:0] ena, enb; 12 | output [15:0] douta; 13 | output [63:0] doutb; 14 | 15 | genvar r; 16 | wire [47:0] dout; 17 | 18 | `ifdef FPGA 19 | 20 | generate for (r = 0; r < 2; r=r+1) 21 | RAMB16_S9_S36 22 | RAMB16_S9_S36_inst 23 | ( 24 | .CLKA ( clka ), // Port A Clock 25 | .DOA ( douta[r*8 +: 8] ), // Port A 1-bit Data Output 26 | .DOPA ( ), 27 | .ADDRA ( addra ), // Port A 14-bit Address Input 28 | .DIA ( dina[r*8 +: 8] ), // Port A 1-bit Data Input 29 | .DIPA ( 1'b0 ), 30 | .ENA ( ena ), // Port A RAM Enable Input 31 | .SSRA ( 1'b0 ), // Port A Synchronous Set/Reset Input 32 | .WEA ( wea[r] ), // Port A Write Enable Input 33 | .CLKB ( clkb ), // Port B Clock 34 | .DOB ( doutb[r*32 +: 32] ), // Port B 1-bit Data Output 35 | .DOPB ( ), 36 | .ADDRB ( addrb ), // Port B 14-bit Address Input 37 | .DIB ( dinb[r*32 +: 32] ), // Port B 1-bit Data Input 38 | .DIPB ( 4'b0 ), 39 | .ENB ( enb ), // Port B RAM Enable Input 40 | .SSRB ( 1'b0 ), // Port B Synchronous Set/Reset Input 41 | .WEB ( web[r] ) // Port B Write Enable Input 42 | ); 43 | endgenerate 44 | 45 | `else // !`ifdef FPGA 46 | 47 | // This bit is a placeholder 48 | 49 | infer_dpram #(.RAM_SIZE(11), .BYTE_WIDTH(8)) ram1 // RAM_SIZE is in words 50 | ( 51 | .ram_clk_a(clka), 52 | .ram_en_a(|ena), 53 | .ram_we_a({wea[1],wea[1],wea[1],wea[1],wea[0],wea[0],wea[0],wea[0]}), 54 | .ram_addr_a(addra), 55 | .ram_wrdata_a({dina,dina,dina,dina}), 56 | .ram_rddata_a({dout,douta}), 57 | .ram_clk_b(clkb), 58 | .ram_en_b(|enb), 59 | .ram_we_b({web[1],web[1],web[1],web[1],web[0],web[0],web[0],web[0]}), 60 | .ram_addr_b({2'b0,addrb}), 61 | .ram_wrdata_b(dinb), 62 | .ram_rddata_b(doutb) 63 | ); 64 | 65 | `endif 66 | 67 | endmodule // dualmem 68 | -------------------------------------------------------------------------------- /src/main/verilog/dualmem_widen8.v: -------------------------------------------------------------------------------- 1 | 2 | module dualmem_widen8(clka, clkb, dina, dinb, addra, addrb, wea, web, douta, doutb, ena, enb); 3 | 4 | input wire clka, clkb; 5 | input [15:0] dina; 6 | input [63:0] dinb; 7 | input [12:0] addra; 8 | input [10:0] addrb; 9 | input [1:0] wea; 10 | input [1:0] web; 11 | input [0:0] ena, enb; 12 | output [15:0] douta; 13 | output [63:0] doutb; 14 | 15 | genvar r; 16 | wire [63:0] dout0; 17 | wire [255:0] dout1; 18 | wire [7:0] we0, we1, en0, en1; 19 | wire [63:0] din0; 20 | wire [255:0] din1; 21 | 22 | reg [12:0] addra_dly; 23 | reg [10:0] addrb_dly; 24 | 25 | `ifdef FPGA 26 | 27 | assign douta = dout0 >> {addra_dly[12:11],4'b0000}; 28 | assign doutb = dout1 >> {addrb_dly[10:9],6'b000000}; 29 | assign we0 = wea << {addra[12:11],1'b0}; 30 | assign we1 = web << {addrb[10:9],1'b0}; 31 | assign en0 = {ena,ena} << {addra[12:11],1'b0}; 32 | assign en1 = {enb,enb} << {addrb[10:9],1'b0}; 33 | assign din0 = {dina,dina,dina,dina}; 34 | assign din1 = {dinb,dinb,dinb,dinb}; 35 | 36 | always @(posedge clka) 37 | begin 38 | addra_dly <= addra; 39 | addrb_dly <= addrb; 40 | end 41 | 42 | generate for (r = 0; r < 8; r=r+1) 43 | RAMB16_S9_S36 44 | RAMB16_S9_S36_inst 45 | ( 46 | .CLKA ( clka ), // Port A Clock 47 | .DOA ( dout0[r*8 +: 8] ), // Port A 1-bit Data Output 48 | .DOPA ( ), 49 | .ADDRA ( addra[10:0] ), // Port A 14-bit Address Input 50 | .DIA ( din0[r*8 +: 8] ), // Port A 1-bit Data Input 51 | .DIPA ( 1'b0 ), 52 | .ENA ( en0[r] ), // Port A RAM Enable Input 53 | .SSRA ( 1'b0 ), // Port A Synchronous Set/Reset Input 54 | .WEA ( we0[r] ), // Port A Write Enable Input 55 | .CLKB ( clkb ), // Port B Clock 56 | .DOB ( dout1[r*32 +: 32] ), // Port B 1-bit Data Output 57 | .DOPB ( ), 58 | .ADDRB ( addrb[8:0] ), // Port B 14-bit Address Input 59 | .DIB ( din1[r*32 +: 32] ), // Port B 1-bit Data Input 60 | .DIPB ( 4'b0 ), 61 | .ENB ( en1[r] ), // Port B RAM Enable Input 62 | .SSRB ( 1'b0 ), // Port B Synchronous Set/Reset Input 63 | .WEB ( we1[r] ) // Port B Write Enable Input 64 | ); 65 | endgenerate 66 | 67 | `else // !`ifdef FPGA 68 | 69 | // This bit is a placeholder 70 | 71 | infer_dpram #(.RAM_SIZE(11), .BYTE_WIDTH(8)) ram1 // RAM_SIZE is in words 72 | ( 73 | .ram_clk_a(clka), 74 | .ram_en_a(|ena), 75 | .ram_we_a({wea[1],wea[1],wea[1],wea[1],wea[0],wea[0],wea[0],wea[0]}), 76 | .ram_addr_a(addra), 77 | .ram_wrdata_a({dina,dina,dina,dina}), 78 | .ram_rddata_a({dout,douta}), 79 | .ram_clk_b(clkb), 80 | .ram_en_b(|enb), 81 | .ram_we_b({web[1],web[1],web[1],web[1],web[0],web[0],web[0],web[0]}), 82 | .ram_addr_b({2'b0,addrb}), 83 | .ram_wrdata_b(dinb), 84 | .ram_rddata_b(doutb) 85 | ); 86 | 87 | `endif 88 | 89 | endmodule // dualmem 90 | -------------------------------------------------------------------------------- /src/main/verilog/fpga_srams_edited.v: -------------------------------------------------------------------------------- 1 | 2 | module data_arrays_0_ext( 3 | input RW0_clk, 4 | input [8:0] RW0_addr, 5 | input RW0_en, 6 | input RW0_wmode, 7 | input [31:0] RW0_wmask, 8 | input [255:0] RW0_wdata, 9 | output [255:0] RW0_rdata 10 | ); 11 | 12 | /* name=data_arrays_0_ext, width=256, depth=512, mask_gran=8, mask_seg=32, ports=['mrw'] FPGA special case */ 13 | 14 | infer_bram #( 15 | .BRAM_SIZE(9), 16 | .BRAM_WIDTH(256), 17 | .IO_DAT_WIDTH(256)) 18 | my_block_ram ( 19 | .ram_clk(RW0_clk), // input wire clka 20 | .ram_en(RW0_en), // input wire ena 21 | .ram_we({RW0_wmask}), // input wire [31 : 0] wea 22 | .ram_addr(RW0_addr), // input wire [8: 0] addra 23 | .ram_wrdata(RW0_wdata), // input wire [255 : 0] dina 24 | .ram_rddata(RW0_rdata) // output wire [255 : 0] douta 25 | ); 26 | 27 | endmodule 28 | 29 | module tag_array_ext( 30 | input RW0_clk, 31 | input [5:0] RW0_addr, 32 | input RW0_en, 33 | input RW0_wmode, 34 | input [3:0] RW0_wmask, 35 | input [87:0] RW0_wdata, 36 | output [87:0] RW0_rdata 37 | ); 38 | 39 | 40 | /* name=tag_array_ext, width=88, depth=64, mask_gran=22, mask_seg=4, ports=['mrw'] normal case */ 41 | 42 | reg reg_RW0_ren; 43 | reg [5:0] reg_RW0_addr; 44 | reg [87:0] ram [63:0]; 45 | `ifdef RANDOMIZE_MEM_INIT 46 | integer initvar; 47 | initial begin 48 | #0.002 begin end 49 | for (initvar = 0; initvar < 64; initvar = initvar+1) 50 | ram[initvar] = {3 {$random}}; 51 | reg_RW0_addr = {1 {$random}}; 52 | end 53 | `endif 54 | integer i; 55 | always @(posedge RW0_clk) 56 | reg_RW0_ren <= RW0_en && !RW0_wmode; 57 | always @(posedge RW0_clk) 58 | if (RW0_en && !RW0_wmode) reg_RW0_addr <= RW0_addr; 59 | always @(posedge RW0_clk) 60 | if (RW0_en && RW0_wmode) begin 61 | if (RW0_wmask[0]) ram[RW0_addr][21:0] <= RW0_wdata[21:0]; 62 | if (RW0_wmask[1]) ram[RW0_addr][43:22] <= RW0_wdata[43:22]; 63 | if (RW0_wmask[2]) ram[RW0_addr][65:44] <= RW0_wdata[65:44]; 64 | if (RW0_wmask[3]) ram[RW0_addr][87:66] <= RW0_wdata[87:66]; 65 | end 66 | `ifdef RANDOMIZE_GARBAGE_ASSIGN 67 | reg [95:0] RW0_random; 68 | `ifdef RANDOMIZE_MEM_INIT 69 | initial begin 70 | #0.002 begin end 71 | RW0_random = {$random, $random, $random}; 72 | reg_RW0_ren = RW0_random[0]; 73 | end 74 | `endif 75 | always @(posedge RW0_clk) RW0_random <= {$random, $random, $random}; 76 | assign RW0_rdata = reg_RW0_ren ? ram[reg_RW0_addr] : RW0_random[87:0]; 77 | `else 78 | assign RW0_rdata = ram[reg_RW0_addr]; 79 | `endif 80 | 81 | endmodule 82 | 83 | module tag_array_0_ext( 84 | input RW0_clk, 85 | input [5:0] RW0_addr, 86 | input RW0_en, 87 | input RW0_wmode, 88 | input [3:0] RW0_wmask, 89 | input [83:0] RW0_wdata, 90 | output [83:0] RW0_rdata 91 | ); 92 | 93 | 94 | /* name=tag_array_0_ext, width=84, depth=64, mask_gran=21, mask_seg=4, ports=['mrw'] normal case */ 95 | 96 | reg reg_RW0_ren; 97 | reg [5:0] reg_RW0_addr; 98 | reg [83:0] ram [63:0]; 99 | `ifdef RANDOMIZE_MEM_INIT 100 | integer initvar; 101 | initial begin 102 | #0.002 begin end 103 | for (initvar = 0; initvar < 64; initvar = initvar+1) 104 | ram[initvar] = {3 {$random}}; 105 | reg_RW0_addr = {1 {$random}}; 106 | end 107 | `endif 108 | integer i; 109 | always @(posedge RW0_clk) 110 | reg_RW0_ren <= RW0_en && !RW0_wmode; 111 | always @(posedge RW0_clk) 112 | if (RW0_en && !RW0_wmode) reg_RW0_addr <= RW0_addr; 113 | always @(posedge RW0_clk) 114 | if (RW0_en && RW0_wmode) begin 115 | if (RW0_wmask[0]) ram[RW0_addr][20:0] <= RW0_wdata[20:0]; 116 | if (RW0_wmask[1]) ram[RW0_addr][41:21] <= RW0_wdata[41:21]; 117 | if (RW0_wmask[2]) ram[RW0_addr][62:42] <= RW0_wdata[62:42]; 118 | if (RW0_wmask[3]) ram[RW0_addr][83:63] <= RW0_wdata[83:63]; 119 | end 120 | `ifdef RANDOMIZE_GARBAGE_ASSIGN 121 | reg [95:0] RW0_random; 122 | `ifdef RANDOMIZE_MEM_INIT 123 | initial begin 124 | #0.002 begin end 125 | RW0_random = {$random, $random, $random}; 126 | reg_RW0_ren = RW0_random[0]; 127 | end 128 | `endif 129 | always @(posedge RW0_clk) RW0_random <= {$random, $random, $random}; 130 | assign RW0_rdata = reg_RW0_ren ? ram[reg_RW0_addr] : RW0_random[83:0]; 131 | `else 132 | assign RW0_rdata = ram[reg_RW0_addr]; 133 | `endif 134 | 135 | endmodule 136 | 137 | module data_arrays_0_0_ext( 138 | input RW0_clk, 139 | input [8:0] RW0_addr, 140 | input RW0_en, 141 | input RW0_wmode, 142 | input [3:0] RW0_wmask, 143 | input [127:0] RW0_wdata, 144 | output [127:0] RW0_rdata 145 | ); 146 | 147 | /* name=data_arrays_0_0_ext, width=128, depth=512, mask_gran=32, mask_seg=4, ports=['mrw'] FPGA special case */ 148 | 149 | infer_bram #( 150 | .BRAM_SIZE(9), 151 | .BRAM_WIDTH(128), 152 | .IO_DAT_WIDTH(128)) 153 | my_block_ram ( 154 | .ram_clk(RW0_clk), // input wire clka 155 | .ram_en(RW0_en), // input wire ena 156 | .ram_we({RW0_wmask[3],RW0_wmask[3],RW0_wmask[3],RW0_wmask[3],RW0_wmask[2],RW0_wmask[2],RW0_wmask[2],RW0_wmask[2],RW0_wmask[1],RW0_wmask[1],RW0_wmask[1],RW0_wmask[1],RW0_wmask[0],RW0_wmask[0],RW0_wmask[0],RW0_wmask[0]}), // input wire [15 : 0] wea 157 | .ram_addr(RW0_addr), // input wire [8: 0] addra 158 | .ram_wrdata(RW0_wdata), // input wire [255 : 0] dina 159 | .ram_rddata(RW0_rdata) // output wire [255 : 0] douta 160 | ); 161 | 162 | endmodule 163 | 164 | module mem_ext( 165 | input W0_clk, 166 | input [24:0] W0_addr, 167 | input W0_en, 168 | input [63:0] W0_data, 169 | input [7:0] W0_mask, 170 | input R0_clk, 171 | input [24:0] R0_addr, 172 | input R0_en, 173 | output reg [63:0] R0_data 174 | ); 175 | 176 | 177 | /* name=mem_ext, width=64, depth=33554432, mask_gran=8, mask_seg=8, ports=['mwrite', 'read'] normal case */ 178 | 179 | reg [63:0] ram [33554431:0]; 180 | integer i; 181 | always @(posedge R0_clk) 182 | if (R0_en) R0_data <= ram[R0_addr]; 183 | always @(posedge W0_clk) 184 | if (W0_en) begin 185 | if (W0_mask[0]) ram[W0_addr][7:0] <= W0_data[7:0]; 186 | if (W0_mask[1]) ram[W0_addr][15:8] <= W0_data[15:8]; 187 | if (W0_mask[2]) ram[W0_addr][23:16] <= W0_data[23:16]; 188 | if (W0_mask[3]) ram[W0_addr][31:24] <= W0_data[31:24]; 189 | if (W0_mask[4]) ram[W0_addr][39:32] <= W0_data[39:32]; 190 | if (W0_mask[5]) ram[W0_addr][47:40] <= W0_data[47:40]; 191 | if (W0_mask[6]) ram[W0_addr][55:48] <= W0_data[55:48]; 192 | if (W0_mask[7]) ram[W0_addr][63:56] <= W0_data[63:56]; 193 | end 194 | 195 | endmodule 196 | 197 | module mem_0_ext( 198 | input W0_clk, 199 | input [8:0] W0_addr, 200 | input W0_en, 201 | input [63:0] W0_data, 202 | input [7:0] W0_mask, 203 | input R0_clk, 204 | input [8:0] R0_addr, 205 | input R0_en, 206 | output reg [63:0] R0_data 207 | ); 208 | 209 | /* name=mem_0_ext, width=64, depth=512, mask_gran=8, mask_seg=8, ports=['mwrite', 'read'] normal case */ 210 | 211 | reg [63:0] ram [511:0]; 212 | integer i; 213 | always @(posedge R0_clk) 214 | if (R0_en) R0_data <= ram[R0_addr]; 215 | always @(posedge W0_clk) 216 | if (W0_en) begin 217 | if (W0_mask[0]) ram[W0_addr][7:0] <= W0_data[7:0]; 218 | if (W0_mask[1]) ram[W0_addr][15:8] <= W0_data[15:8]; 219 | if (W0_mask[2]) ram[W0_addr][23:16] <= W0_data[23:16]; 220 | if (W0_mask[3]) ram[W0_addr][31:24] <= W0_data[31:24]; 221 | if (W0_mask[4]) ram[W0_addr][39:32] <= W0_data[39:32]; 222 | if (W0_mask[5]) ram[W0_addr][47:40] <= W0_data[47:40]; 223 | if (W0_mask[6]) ram[W0_addr][55:48] <= W0_data[55:48]; 224 | if (W0_mask[7]) ram[W0_addr][63:56] <= W0_data[63:56]; 225 | end 226 | 227 | endmodule 228 | -------------------------------------------------------------------------------- /src/main/verilog/nasti_channel.sv: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | // Define the SV interfaces for NASTI channels 4 | 5 | interface nasti_channel 6 | #( 7 | N_PORT = 1, // number of nasti ports 8 | ID_WIDTH = 1, // id width 9 | ADDR_WIDTH = 8, // address width 10 | DATA_WIDTH = 8, // width of data 11 | USER_WIDTH = 1 // width of user field, must > 0, let synthesizer trim it if not in use 12 | ); 13 | 14 | initial assert(USER_WIDTH > 0) else $fatal(1, "[nasti interface] User field must have at least 1 bit!"); 15 | 16 | // write/read address 17 | logic [N_PORT-1:0][ID_WIDTH-1:0] aw_id, ar_id; 18 | logic [N_PORT-1:0][ADDR_WIDTH-1:0] aw_addr, ar_addr; 19 | logic [N_PORT-1:0][7:0] aw_len, ar_len; 20 | logic [N_PORT-1:0][2:0] aw_size, ar_size; 21 | logic [N_PORT-1:0][1:0] aw_burst, ar_burst; 22 | logic [N_PORT-1:0] aw_lock, ar_lock; 23 | logic [N_PORT-1:0][3:0] aw_cache, ar_cache; 24 | logic [N_PORT-1:0][2:0] aw_prot, ar_prot; 25 | logic [N_PORT-1:0][3:0] aw_qos, ar_qos; 26 | logic [N_PORT-1:0][3:0] aw_region, ar_region; 27 | logic [N_PORT-1:0][USER_WIDTH-1:0] aw_user, ar_user; 28 | logic [N_PORT-1:0] aw_valid, ar_valid; 29 | logic [N_PORT-1:0] aw_ready, ar_ready; 30 | 31 | // write/read data 32 | logic [N_PORT-1:0][DATA_WIDTH-1:0] w_data, r_data; 33 | logic [N_PORT-1:0][DATA_WIDTH/8-1:0] w_strb; 34 | logic [N_PORT-1:0] w_last, r_last; 35 | logic [N_PORT-1:0][USER_WIDTH-1:0] w_user; 36 | logic [N_PORT-1:0] w_valid; 37 | logic [N_PORT-1:0] w_ready; 38 | 39 | // write/read response 40 | logic [N_PORT-1:0][ID_WIDTH-1:0] b_id, r_id; 41 | logic [N_PORT-1:0][1:0] b_resp, r_resp; 42 | logic [N_PORT-1:0][USER_WIDTH-1:0] b_user, r_user; 43 | logic [N_PORT-1:0] b_valid, r_valid; 44 | logic [N_PORT-1:0] b_ready, r_ready; 45 | 46 | 47 | modport master ( 48 | // write/read address 49 | output aw_id, ar_id, 50 | output aw_addr, ar_addr, 51 | output aw_len, ar_len, 52 | output aw_size, ar_size, 53 | output aw_burst, ar_burst, 54 | output aw_lock, ar_lock, 55 | output aw_cache, ar_cache, 56 | output aw_prot, ar_prot, 57 | output aw_qos, ar_qos, 58 | output aw_region, ar_region, 59 | output aw_user, ar_user, 60 | output aw_valid, ar_valid, 61 | input aw_ready, ar_ready, 62 | // write data 63 | output w_data, 64 | output w_strb, 65 | output w_last, 66 | output w_user, 67 | output w_valid, 68 | input w_ready, 69 | // read data 70 | input r_data, 71 | input r_last, 72 | // write/read response 73 | input b_id, r_id, 74 | input b_resp, r_resp, 75 | input b_user, r_user, 76 | input b_valid, r_valid, 77 | output b_ready, r_ready 78 | ); 79 | 80 | modport slave ( 81 | // write/read address 82 | input aw_id, ar_id, 83 | input aw_addr, ar_addr, 84 | input aw_len, ar_len, 85 | input aw_size, ar_size, 86 | input aw_burst, ar_burst, 87 | input aw_lock, ar_lock, 88 | input aw_cache, ar_cache, 89 | input aw_prot, ar_prot, 90 | input aw_qos, ar_qos, 91 | input aw_region, ar_region, 92 | input aw_user, ar_user, 93 | input aw_valid, ar_valid, 94 | output aw_ready, ar_ready, 95 | // write data 96 | input w_data, 97 | input w_strb, 98 | input w_last, 99 | input w_user, 100 | input w_valid, 101 | output w_ready, 102 | // read data 103 | output r_data, 104 | output r_last, 105 | // write/read response 106 | output b_id, r_id, 107 | output b_resp, r_resp, 108 | output b_user, r_user, 109 | output b_valid, r_valid, 110 | input b_ready, r_ready 111 | ); 112 | 113 | endinterface // nasti_channel 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/main/verilog/ps2.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// ps2.v //// 4 | //// //// 5 | //// This file is part of the "ps2" project //// 6 | //// http://www.opencores.org/cores/ps2/ //// 7 | //// //// 8 | //// Author(s): //// 9 | //// - mihad@opencores.org //// 10 | //// - Miha Dolenc //// 11 | //// //// 12 | //// All additional information is avaliable in the README.txt //// 13 | //// file. //// 14 | //// //// 15 | //// //// 16 | ////////////////////////////////////////////////////////////////////// 17 | //// //// 18 | //// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// 19 | //// //// 20 | //// This source file may be used and distributed without //// 21 | //// restriction provided that this copyright statement is not //// 22 | //// removed from the file and that any derivative work contains //// 23 | //// the original copyright notice and the associated disclaimer. //// 24 | //// //// 25 | //// This source file is free software; you can redistribute it //// 26 | //// and/or modify it under the terms of the GNU Lesser General //// 27 | //// Public License as published by the Free Software Foundation; //// 28 | //// either version 2.1 of the License, or (at your option) any //// 29 | //// later version. //// 30 | //// //// 31 | //// This source is distributed in the hope that it will be //// 32 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 33 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 34 | //// PURPOSE. See the GNU Lesser General Public License for more //// 35 | //// details. //// 36 | //// //// 37 | //// You should have received a copy of the GNU Lesser General //// 38 | //// Public License along with this source; if not, download it //// 39 | //// from http://www.opencores.org/lgpl.shtml //// 40 | //// //// 41 | ////////////////////////////////////////////////////////////////////// 42 | 43 | module ps2(clk, rst, 44 | PS2_K_CLK_IO, PS2_K_DATA_IO, PS2_M_CLK_IO, PS2_M_DATA_IO, 45 | rx_scan_read, rx_released, rx_scan_ready, rx_scan_code, tx_error_no_keyboard_ack); 46 | 47 | input clk, rst; 48 | input rx_scan_read; 49 | 50 | inout PS2_K_CLK_IO; 51 | inout PS2_K_DATA_IO; 52 | inout PS2_M_CLK_IO; 53 | inout PS2_M_DATA_IO; 54 | 55 | output rx_scan_ready, rx_released, tx_error_no_keyboard_ack; 56 | output [7:0] rx_scan_code; 57 | 58 | wire ps2_k_clk_en_o_ ; 59 | wire ps2_k_data_en_o_ ; 60 | wire ps2_k_clk_i ; 61 | wire ps2_k_data_i ; 62 | 63 | wire rx_released; 64 | wire [7:0] rx_scan_code; 65 | wire rx_scan_read; 66 | wire rx_scan_ready; 67 | reg [7:0] tx_data; 68 | reg tx_write; 69 | wire tx_write_ack_o; 70 | wire tx_error_no_keyboard_ack; 71 | wire [15:0] divide_reg = 13000; 72 | 73 | io_buffer_generic IOBUF_k_clk ( 74 | .outg(ps2_k_clk_i), // Buffer output 75 | .inoutg(PS2_K_CLK_IO), // Buffer inout port (connect directly to top-level port) 76 | .ing(ps2_k_clk_en_o_), // Buffer input 77 | .ctrl(ps2_k_clk_en_o_) // 3-state enable input 78 | ); 79 | 80 | io_buffer_generic IOBUF_k_data ( 81 | .outg(ps2_k_data_i), // Buffer output 82 | .inoutg(PS2_K_DATA_IO), // Buffer inout port (connect directly to top-level port) 83 | .ing(ps2_k_data_en_o_), // Buffer input 84 | .ctrl(ps2_k_data_en_o_) // 3-state enable input 85 | ); 86 | 87 | ps2_keyboard key1( 88 | .clock_i(clk), 89 | .reset_i(rst), 90 | .ps2_clk_en_o_(ps2_k_clk_en_o_), 91 | .ps2_data_en_o_(ps2_k_data_en_o_), 92 | .ps2_clk_i(ps2_k_clk_i), 93 | .ps2_data_i(ps2_k_data_i), 94 | .rx_released(rx_released), 95 | .rx_scan_code(rx_scan_code), 96 | .rx_data_ready(rx_scan_ready), // rx_read_o 97 | .rx_read(rx_scan_read), // rx_read_ack_i 98 | .tx_data(tx_data), 99 | .tx_write(tx_write), 100 | .tx_write_ack_o(tx_write_ack_o), 101 | .tx_error_no_keyboard_ack(tx_error_no_keyboard_ack), 102 | .divide_reg_i(divide_reg) 103 | ); 104 | 105 | wire ps2_m_clk_en_o_ ; 106 | wire ps2_m_data_en_o_ ; 107 | wire ps2_m_clk_i ; 108 | wire ps2_m_data_i ; 109 | 110 | io_buffer_generic IOBUF_m_clk ( 111 | .outg(ps2_m_clk_i), // Buffer output 112 | .inoutg(PS2_M_CLK_IO), // Buffer inout port (connect directly to top-level port) 113 | .ing(ps2_m_clk_en_o_), // Buffer input 114 | .ctrl(ps2_m_clk_en_o_) // 3-state enable input 115 | ); 116 | 117 | io_buffer_generic IOBUF_m_data ( 118 | .outg(ps2_m_data_i), // Buffer output 119 | .inoutg(PS2_M_DATA_IO), // Buffer inout port (connect directly to top-level port) 120 | .ing(ps2_m_data_en_o_), // Buffer input 121 | .ctrl(ps2_m_data_en_o_) // 3-state enable input 122 | ); 123 | 124 | endmodule 125 | -------------------------------------------------------------------------------- /src/main/verilog/ps2_defines.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// ps2_defines.v //// 4 | //// //// 5 | //// This file is part of the "ps2" project //// 6 | //// http://www.opencores.org/cores/ps2/ //// 7 | //// //// 8 | //// Author(s): //// 9 | //// - mihad@opencores.org //// 10 | //// - Miha Dolenc //// 11 | //// //// 12 | //// All additional information is avaliable in the README.txt //// 13 | //// file. //// 14 | //// //// 15 | //// //// 16 | ////////////////////////////////////////////////////////////////////// 17 | //// //// 18 | //// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// 19 | //// //// 20 | //// This source file may be used and distributed without //// 21 | //// restriction provided that this copyright statement is not //// 22 | //// removed from the file and that any derivative work contains //// 23 | //// the original copyright notice and the associated disclaimer. //// 24 | //// //// 25 | //// This source file is free software; you can redistribute it //// 26 | //// and/or modify it under the terms of the GNU Lesser General //// 27 | //// Public License as published by the Free Software Foundation; //// 28 | //// either version 2.1 of the License, or (at your option) any //// 29 | //// later version. //// 30 | //// //// 31 | //// This source is distributed in the hope that it will be //// 32 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 33 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 34 | //// PURPOSE. See the GNU Lesser General Public License for more //// 35 | //// details. //// 36 | //// //// 37 | //// You should have received a copy of the GNU Lesser General //// 38 | //// Public License along with this source; if not, download it //// 39 | //// from http://www.opencores.org/lgpl.shtml //// 40 | //// //// 41 | ////////////////////////////////////////////////////////////////////// 42 | // 43 | // CVS Revision History 44 | // 45 | // $Log: not supported by cvs2svn $ 46 | // Revision 1.4 2003/07/01 12:34:03 mihad 47 | // Added an option to use constant values instead of RAM 48 | // in the translation table. 49 | // 50 | // Revision 1.3 2002/04/09 13:21:15 mihad 51 | // Added mouse interface and everything for its handling, cleaned up some unused code 52 | // 53 | // Revision 1.2 2002/02/18 16:33:08 mihad 54 | // Changed defines for simulation to work without xilinx primitives 55 | // 56 | // Revision 1.1.1.1 2002/02/18 16:16:56 mihad 57 | // Initial project import - working 58 | // 59 | // 60 | 61 | //`define PS2_RAMB4 62 | `define PS2_CONSTANTS_ROM 63 | 64 | `define PS2_TRANSLATION_TABLE_31_0 256'h5b03111e1f2c71665a02101d702a386559290f3e40424464583c3b3d3f4143ff 65 | `define PS2_TRANSLATION_TABLE_63_32 256'h5f0908162432726a5e071522233031695d061314212f39685c040512202d2e67 66 | `define PS2_TRANSLATION_TABLE_95_64 256'h76632b751b1c363a6e620d1a7428736d610c19272635346c600a0b181725336b 67 | `define PS2_TRANSLATION_TABLE_127_96 256'h544649374a514e574501484d4c5053526f7f7e474b7d4f7c7b0e7a7978775655 68 | `define PS2_TRANSLATION_TABLE_159_128 256'h9f9e9d9c9b9a999897969594939291908f8e8d8c8b8a89888786855441828180 69 | `define PS2_TRANSLATION_TABLE_191_160 256'hbfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0 70 | `define PS2_TRANSLATION_TABLE_223_192 256'hdfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0 71 | `define PS2_TRANSLATION_TABLE_255_224 256'hfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0 72 | 73 | `define PS2_TIMER_60USEC_VALUE_PP 12 // Number of sys_clks for 60usec. 74 | `define PS2_TIMER_60USEC_BITS_PP 4 // Number of bits needed for timer 75 | `define PS2_TIMER_5USEC_VALUE_PP 500 // Number of sys_clks for debounce 76 | `define PS2_TIMER_5USEC_BITS_PP 16 // Number of bits needed for timer 77 | 78 | //`define PS2_AUX 79 | -------------------------------------------------------------------------------- /src/main/verilog/rx_delay.v: -------------------------------------------------------------------------------- 1 | module rx_delay( 2 | input wire clk, 3 | input wire in, 4 | output reg maj 5 | ); 6 | 7 | reg [4:0] rx_dly; 8 | 9 | always @(posedge clk) 10 | begin 11 | maj <= (rx_dly[0] + rx_dly[1] + rx_dly[2] + rx_dly[3] + rx_dly[4]) > 2; 12 | rx_dly <= {rx_dly[4:0],in}; 13 | end // else: !if(!rstn) 14 | 15 | endmodule // rx_delay 16 | -------------------------------------------------------------------------------- /src/main/verilog/sd_clock_divider.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// WISHBONE SD Card Controller IP Core //// 4 | //// //// 5 | //// sd_clock_divider.v //// 6 | //// //// 7 | //// This file is part of the WISHBONE SD Card //// 8 | //// Controller IP Core project //// 9 | //// http://opencores.org/project,sd_card_controller //// 10 | //// //// 11 | //// Description //// 12 | //// Control of sd card clock rate //// 13 | //// //// 14 | //// Author(s): //// 15 | //// - Marek Czerski, ma.czerski@gmail.com //// 16 | //// //// 17 | ////////////////////////////////////////////////////////////////////// 18 | //// //// 19 | //// Copyright (C) 2013 Authors //// 20 | //// //// 21 | //// Based on original work by //// 22 | //// Adam Edvardsson (adam.edvardsson@orsoc.se) //// 23 | //// //// 24 | //// Copyright (C) 2009 Authors //// 25 | //// //// 26 | //// This source file may be used and distributed without //// 27 | //// restriction provided that this copyright statement is not //// 28 | //// removed from the file and that any derivative work contains //// 29 | //// the original copyright notice and the associated disclaimer. //// 30 | //// //// 31 | //// This source file is free software; you can redistribute it //// 32 | //// and/or modify it under the terms of the GNU Lesser General //// 33 | //// Public License as published by the Free Software Foundation; //// 34 | //// either version 2.1 of the License, or (at your option) any //// 35 | //// later version. //// 36 | //// //// 37 | //// This source is distributed in the hope that it will be //// 38 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 39 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 40 | //// PURPOSE. See the GNU Lesser General Public License for more //// 41 | //// details. //// 42 | //// //// 43 | //// You should have received a copy of the GNU Lesser General //// 44 | //// Public License along with this source; if not, download it //// 45 | //// from http://www.opencores.org/lgpl.shtml //// 46 | //// //// 47 | ////////////////////////////////////////////////////////////////////// 48 | 49 | module sd_clock_divider ( 50 | input CLK, 51 | input [7:0] DIVIDER, 52 | input RST, 53 | output SD_CLK 54 | ); 55 | 56 | reg [7:0] ClockDiv; 57 | reg SD_CLK_O; 58 | 59 | BUFG SD_CLK_buf_inst ( 60 | .O(SD_CLK), // 1-bit output: Clock output 61 | .I(SD_CLK_O) // 1-bit input: Clock input 62 | ); 63 | 64 | always @(posedge CLK or posedge RST) 65 | begin 66 | if (RST) begin 67 | ClockDiv <= 8'b0000_0000; 68 | SD_CLK_O <= 0; 69 | end 70 | else if (ClockDiv == DIVIDER) begin 71 | ClockDiv <= 0; 72 | SD_CLK_O <= ~SD_CLK_O; 73 | end else begin 74 | ClockDiv <= ClockDiv + 8'h1; 75 | SD_CLK_O <= SD_CLK_O; 76 | end 77 | end 78 | 79 | endmodule 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/main/verilog/sd_crc_16.v: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // CRC Generation Unit - Linear Feedback Shift Register implementation 3 | // (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL 4 | // ========================================================================== 5 | module sd_crc_16(BITVAL, ENABLE, BITSTRB, CLEAR, CRC); 6 | input BITVAL; // Next input bit 7 | input ENABLE; // Enable calculation 8 | input BITSTRB; // Current bit valid (Clock) 9 | input CLEAR; // Init CRC value 10 | output [15:0] CRC; // Current output CRC value 11 | 12 | reg [15:0] CRC; // We need output registers 13 | wire inv; 14 | 15 | assign inv = BITVAL ^ CRC[15]; // XOR required? 16 | 17 | always @(posedge BITSTRB or posedge CLEAR) begin 18 | if (CLEAR) begin 19 | CRC <= 0; // Init before calculation 20 | end 21 | else begin 22 | if (ENABLE == 1) begin 23 | CRC[15] <= CRC[14]; 24 | CRC[14] <= CRC[13]; 25 | CRC[13] <= CRC[12]; 26 | CRC[12] <= CRC[11] ^ inv; 27 | CRC[11] <= CRC[10]; 28 | CRC[10] <= CRC[9]; 29 | CRC[9] <= CRC[8]; 30 | CRC[8] <= CRC[7]; 31 | CRC[7] <= CRC[6]; 32 | CRC[6] <= CRC[5]; 33 | CRC[5] <= CRC[4] ^ inv; 34 | CRC[4] <= CRC[3]; 35 | CRC[3] <= CRC[2]; 36 | CRC[2] <= CRC[1]; 37 | CRC[1] <= CRC[0]; 38 | CRC[0] <= inv; 39 | end 40 | end 41 | end 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /src/main/verilog/sd_crc_7.v: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // CRC Generation Unit - Linear Feedback Shift Register implementation 3 | // (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL 4 | // ========================================================================== 5 | module sd_crc_7(BITVAL, ENABLE, BITSTRB, CLEAR, CRC); 6 | input BITVAL; // Next input bit 7 | input ENABLE; // Enable calculation 8 | input BITSTRB; // Current bit valid (Clock) 9 | input CLEAR; // Init CRC value 10 | output [6:0] CRC; // Current output CRC value 11 | 12 | reg [6:0] CRC; // We need output registers 13 | wire inv; 14 | 15 | assign inv = BITVAL ^ CRC[6]; // XOR required? 16 | 17 | always @(posedge BITSTRB or posedge CLEAR) begin 18 | if (CLEAR) begin 19 | CRC <= 0; // Init before calculation 20 | end 21 | else begin 22 | if (ENABLE == 1) begin 23 | CRC[6] <= CRC[5]; 24 | CRC[5] <= CRC[4]; 25 | CRC[4] <= CRC[3]; 26 | CRC[3] <= CRC[2] ^ inv; 27 | CRC[2] <= CRC[1]; 28 | CRC[1] <= CRC[0]; 29 | CRC[0] <= inv; 30 | end 31 | end 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /src/main/verilog/sd_defines.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// WISHBONE SD Card Controller IP Core //// 4 | //// //// 5 | //// sd_defines.h //// 6 | //// //// 7 | //// This file is part of the WISHBONE SD Card //// 8 | //// Controller IP Core project //// 9 | //// http://opencores.org/project,sd_card_controller //// 10 | //// //// 11 | //// Description //// 12 | //// Header file with common definitions //// 13 | //// //// 14 | //// Author(s): //// 15 | //// - Marek Czerski, ma.czerski@gmail.com //// 16 | //// //// 17 | ////////////////////////////////////////////////////////////////////// 18 | //// //// 19 | //// Copyright (C) 2013 Authors //// 20 | //// //// 21 | //// Based on original work by //// 22 | //// Adam Edvardsson (adam.edvardsson@orsoc.se) //// 23 | //// //// 24 | //// Copyright (C) 2009 Authors //// 25 | //// //// 26 | //// This source file may be used and distributed without //// 27 | //// restriction provided that this copyright statement is not //// 28 | //// removed from the file and that any derivative work contains //// 29 | //// the original copyright notice and the associated disclaimer. //// 30 | //// //// 31 | //// This source file is free software; you can redistribute it //// 32 | //// and/or modify it under the terms of the GNU Lesser General //// 33 | //// Public License as published by the Free Software Foundation; //// 34 | //// either version 2.1 of the License, or (at your option) any //// 35 | //// later version. //// 36 | //// //// 37 | //// This source is distributed in the hope that it will be //// 38 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 39 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 40 | //// PURPOSE. See the GNU Lesser General Public License for more //// 41 | //// details. //// 42 | //// //// 43 | //// You should have received a copy of the GNU Lesser General //// 44 | //// Public License along with this source; if not, download it //// 45 | //// from http://www.opencores.org/lgpl.shtml //// 46 | //// //// 47 | ////////////////////////////////////////////////////////////////////// 48 | 49 | //global defines 50 | `define BLKSIZE_W 12 51 | `define BLKCNT_W 16 52 | `define CMD_TIMEOUT_W 24 53 | `define DATA_TIMEOUT_W 24 54 | 55 | //cmd module interrupts 56 | `define INT_CMD_SIZE 5 57 | `define INT_CMD_CC 0 58 | `define INT_CMD_EI 1 59 | `define INT_CMD_CTE 2 60 | `define INT_CMD_CCRCE 3 61 | `define INT_CMD_CIE 4 62 | 63 | //data module interrupts 64 | `define INT_DATA_SIZE 5 65 | `define INT_DATA_CC 0 66 | `define INT_DATA_EI 1 67 | `define INT_DATA_CTE 2 68 | `define INT_DATA_CCRCE 3 69 | `define INT_DATA_CFE 4 70 | 71 | //command register defines 72 | `define CMD_REG_SIZE 14 73 | `define CMD_RESPONSE_CHECK 1:0 74 | `define CMD_BUSY_CHECK 2 75 | `define CMD_CRC_CHECK 3 76 | `define CMD_IDX_CHECK 4 77 | `define CMD_WITH_DATA 6:5 78 | `define CMD_INDEX 13:8 79 | 80 | //register addreses 81 | `define argument 8'h00 82 | `define command 8'h04 83 | `define resp0 8'h08 84 | `define resp1 8'h0c 85 | `define resp2 8'h10 86 | `define resp3 8'h14 87 | `define data_timeout 8'h18 88 | `define controller 8'h1c 89 | `define cmd_timeout 8'h20 90 | `define clock_d 8'h24 91 | `define reset 8'h28 92 | `define voltage 8'h2c 93 | `define capa 8'h30 94 | `define cmd_isr 8'h34 95 | `define cmd_iser 8'h38 96 | `define data_isr 8'h3c 97 | `define data_iser 8'h40 98 | `define blksize 8'h44 99 | `define blkcnt 8'h48 100 | `define dst_src_addr 8'h60 101 | 102 | //wb module defines 103 | `define RESET_BLOCK_SIZE 12'd511 104 | `define RESET_CLK_DIV 0 105 | `define SUPPLY_VOLTAGE_mV 3300 106 | -------------------------------------------------------------------------------- /src/main/verilog/sd_top.sv: -------------------------------------------------------------------------------- 1 | // 2 | // (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. 3 | // 4 | // This file contains confidential and proprietary information 5 | // of Xilinx, Inc. and is protected under U.S. and 6 | // international copyright and other intellectual property 7 | // laws. 8 | // 9 | // DISCLAIMER 10 | // This disclaimer is not a license and does not grant any 11 | // rights to the materials distributed herewith. Except as 12 | // otherwise provided in a valid license issued to you by 13 | // Xilinx, and to the maximum extent permitted by applicable 14 | // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 15 | // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 16 | // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 17 | // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 18 | // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 19 | // (2) Xilinx shall not be liable (whether in contract or tort, 20 | // including negligence, or under any other theory of 21 | // liability) for any loss or damage of any kind or nature 22 | // related to, arising under or in connection with these 23 | // materials, including for any direct, or any indirect, 24 | // special, incidental, or consequential loss or damage 25 | // (including loss of data, profits, goodwill, or any type of 26 | // loss or damage suffered as a result of any action brought 27 | // by a third party) even if such damage or loss was 28 | // reasonably foreseeable or Xilinx had been advised of the 29 | // possibility of the same. 30 | // 31 | // CRITICAL APPLICATIONS 32 | // Xilinx products are not designed or intended to be fail- 33 | // safe, or for use in any application requiring fail-safe 34 | // performance, such as life-support or safety devices or 35 | // systems, Class III medical devices, nuclear facilities, 36 | // applications related to the deployment of airbags, or any 37 | // other applications that could lead to death, personal 38 | // injury, or severe property or environmental damage 39 | // (individually and collectively, "Critical 40 | // Applications"). Customer assumes the sole risk and 41 | // liability of any use of Xilinx products in Critical 42 | // Applications, subject only to applicable laws and 43 | // regulations governing limitations on product liability. 44 | // 45 | // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 46 | // PART OF THIS FILE AT ALL TIMES. 47 | // 48 | 49 | // Copyright 2015 ETH Zurich and University of Bologna. 50 | // Copyright and related rights are licensed under the Solderpad Hardware 51 | // License, Version 0.51 (the "License"); you may not use this file except in 52 | // compliance with the License. You may obtain a copy of the License at 53 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 54 | // or agreed to in writing, software, hardware and materials distributed under 55 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 56 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 57 | // specific language governing permissions and limitations under the License. 58 | // See LICENSE for license details. 59 | 60 | `default_nettype none 61 | 62 | module sd_top( 63 | input wire sd_clk, 64 | input wire cmd_rst, 65 | input wire data_rst, 66 | input wire [2:0] setting_i, 67 | input wire start_i, 68 | input wire [31:0] arg_i, 69 | input wire [5:0] cmd_i, 70 | input wire [31:0] timeout_i, 71 | input wire [2:0] sd_data_start_i, 72 | input wire [1:0] sd_align_i, 73 | input wire [15:0] sd_blkcnt_i, 74 | input wire [11:0] sd_blksize_i, 75 | input wire [31:0] sd_data_i, 76 | input wire [3:0] sd_dat_to_host, 77 | input wire sd_cmd_to_host, 78 | //---------------Output ports--------------- 79 | output wire [31:0] response0_o, 80 | output wire [63:32] response1_o, 81 | output wire [95:64] response2_o, 82 | output wire [126:96] response3_o, 83 | output wire [31:0] wait_o, 84 | output wire [31:0] wait_data_o, 85 | output wire [31:4] status_o, 86 | output wire [31:0] packet0_o, 87 | output wire [15:0] packet1_o, 88 | output wire [6:0] crc_val_o, 89 | output wire [6:0] crc_actual_o, 90 | output wire finish_cmd_o, 91 | output wire finish_data_o, 92 | output wire crc_ok_o, 93 | output wire index_ok_o, 94 | output wire sd_rd_o, 95 | output wire sd_we_o, 96 | output wire [31:0] sd_data_o, 97 | output wire [15:0] transf_cnt_o, 98 | output wire [3:0] sd_dat_to_mem, 99 | output wire sd_cmd_to_mem, 100 | output wire sd_cmd_oe, 101 | output wire sd_dat_oe, 102 | output reg [9:0] sd_xfr_addr); 103 | 104 | reg sd_cmd_to_host_dly; 105 | reg [3:0] sd_dat_to_host_dly; 106 | 107 | wire start_data; 108 | wire data_crc_ok; 109 | wire sd_busy, sd_data_busy; 110 | 111 | assign status_o = {1'b0,crc_val_o[6:0], 112 | 1'b0,crc_actual_o[6:0], 113 | 5'b0,finish_data_o,sd_data_busy,finish_cmd_o, 114 | index_ok_o,crc_ok_o,data_crc_ok,sd_busy}; 115 | 116 | always @(negedge sd_clk) 117 | begin 118 | if (data_rst) 119 | sd_xfr_addr <= 0; 120 | else 121 | begin 122 | if (sd_rd_o|sd_we_o) 123 | sd_xfr_addr <= sd_xfr_addr + 1; 124 | end 125 | sd_cmd_to_host_dly <= sd_cmd_to_host; 126 | sd_dat_to_host_dly <= sd_dat_to_host; 127 | end 128 | 129 | sd_cmd_serial_host cmd_serial_host0( 130 | .sd_clk (sd_clk), 131 | .rst (cmd_rst), 132 | .setting_i (setting_i), 133 | .cmd_i ({cmd_i,arg_i}), 134 | .start_i (start_i), 135 | .timeout_i (timeout_i), 136 | .finish_o (finish_cmd_o), 137 | .response_o ({response3_o,response2_o,response1_o,response0_o,crc_actual_o}), 138 | .crc_ok_o (crc_ok_o), 139 | .crc_val_o (crc_val_o), 140 | .packet_o ({packet1_o,packet0_o}), 141 | .index_ok_o (index_ok_o), 142 | .wait_reg_o (wait_o), 143 | .start_data_o(start_data), 144 | .cmd_dat_i (sd_cmd_to_host_dly), 145 | .cmd_out_o (sd_cmd_to_mem), 146 | .cmd_oe_o (sd_cmd_oe) 147 | ); 148 | 149 | sd_data_serial_host data_serial_host0( 150 | .sd_clk (sd_clk), 151 | .rst (data_rst), 152 | .data_in (sd_data_i), 153 | .rd (sd_rd_o), 154 | .data_out (sd_data_o), 155 | .we (sd_we_o), 156 | .finish_o (finish_data_o), 157 | .DAT_oe_o (sd_dat_oe), 158 | .DAT_dat_o (sd_dat_to_mem), 159 | .DAT_dat_i (sd_dat_to_host_dly), 160 | .blksize (sd_blksize_i), 161 | .bus_4bit (sd_data_start_i[2]), 162 | .blkcnt (sd_blkcnt_i), 163 | .start (start_data ? sd_data_start_i[1:0] : 2'b00), 164 | .byte_alignment (sd_align_i), 165 | .timeout_i (timeout_i), 166 | .sd_data_busy (sd_data_busy), 167 | .busy (sd_busy), 168 | .wait_reg_o (wait_data_o), 169 | .crc_ok (data_crc_ok), 170 | .transf_cnt_o (transf_cnt_o) 171 | ); 172 | 173 | endmodule // chip_top 174 | `default_nettype wire 175 | -------------------------------------------------------------------------------- /src/main/verilog/spi_wrapper.sv: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | module spi_wrapper 4 | #( 5 | parameter ADDR_WIDTH = 8, 6 | parameter DATA_WIDTH = 8, 7 | parameter RESET_ADDR = 0 8 | ) 9 | ( 10 | input clk, rstn, 11 | nasti_channel.slave nasti, 12 | input io0_i, 13 | output io0_o, io0_t, 14 | input io1_i, 15 | output io1_o, io1_t, 16 | input sck_i, 17 | output sck_o, sck_t, 18 | input ss_i, 19 | output ss_o, ss_t, 20 | output ip2intc_irpt, 21 | output reg sd_reset 22 | ); 23 | 24 | // internal AXI signals 25 | logic [ADDR_WIDTH-1:0] aw_addr, ar_addr; 26 | logic aw_valid, ar_valid; 27 | logic aw_ready, ar_ready; 28 | logic [DATA_WIDTH-1:0] w_data, r_data; 29 | logic [DATA_WIDTH/8-1:0] w_strb; 30 | logic w_valid; 31 | logic w_ready; 32 | logic [1:0] b_resp, r_resp; 33 | logic b_valid, r_valid; 34 | logic b_ready, r_ready; 35 | 36 | 37 | // internal control signals 38 | logic write_addr_match, read_addr_match; 39 | logic read_sel, write_sel, write_enable; 40 | 41 | assign read_addr_match = nasti.ar_valid && (nasti.ar_addr & 8'hff) == RESET_ADDR; 42 | assign write_addr_match = nasti.aw_valid && (nasti.aw_addr & 8'hff) == RESET_ADDR; 43 | 44 | always_ff @(posedge clk or negedge rstn) 45 | if(!rstn) 46 | read_sel <= 1'b0; 47 | else if(read_addr_match) 48 | read_sel <= 1'b1; 49 | else if(nasti.r_valid && nasti.r_ready) 50 | read_sel <= 1'b0; 51 | 52 | always_ff @(posedge clk or negedge rstn) 53 | if(!rstn) 54 | write_sel <= 1'b0; 55 | else if(write_addr_match) 56 | write_sel <= 1'b1; 57 | else if(nasti.b_valid && nasti.b_ready) 58 | write_sel <= 1'b0; 59 | 60 | always_ff @(posedge clk or negedge rstn) 61 | if(!rstn) 62 | sd_reset <= 1'b1; 63 | else if(write_sel && nasti.w_valid && nasti.w_ready) 64 | sd_reset <= nasti.w_strb & 1'h1 ? nasti.w_data & 8'hff : sd_reset; 65 | 66 | assign ar_addr = nasti.ar_addr; 67 | assign ar_valid = nasti.ar_valid && !read_addr_match; 68 | assign nasti.ar_ready = ar_ready || read_addr_match; 69 | 70 | assign aw_addr = nasti.aw_addr; 71 | assign aw_valid = nasti.aw_valid && !write_addr_match; 72 | assign nasti.aw_ready = aw_ready || write_addr_match; 73 | 74 | assign w_data = nasti.w_data; 75 | assign w_strb = nasti.w_strb; 76 | assign w_valid = nasti.w_valid && !write_sel; 77 | assign nasti.w_ready = w_ready || write_sel; 78 | 79 | assign nasti.r_data = read_sel ? sd_reset : r_data; 80 | assign nasti.r_resp = read_sel ? 0 : r_resp; 81 | assign nasti.r_valid = r_valid || read_sel; 82 | assign r_ready = read_sel ? 0 : nasti.r_ready; 83 | 84 | assign nasti.b_resp = write_sel ? 0 : b_resp; 85 | assign nasti.b_valid = b_valid || write_sel; 86 | assign b_ready = write_sel ? 0 : nasti.b_ready; 87 | 88 | axi_quad_spi_0 spi_i 89 | ( 90 | .ext_spi_clk ( clk ), 91 | .s_axi_aclk ( clk ), 92 | .s_axi_aresetn ( rstn ), 93 | .s_axi_araddr ( ar_addr ), 94 | .s_axi_arready ( ar_ready ), 95 | .s_axi_arvalid ( ar_valid ), 96 | .s_axi_awaddr ( aw_addr ), 97 | .s_axi_awready ( aw_ready ), 98 | .s_axi_awvalid ( aw_valid ), 99 | .s_axi_bready ( b_ready ), 100 | .s_axi_bresp ( b_resp ), 101 | .s_axi_bvalid ( b_valid ), 102 | .s_axi_rdata ( r_data ), 103 | .s_axi_rready ( r_ready ), 104 | .s_axi_rresp ( r_resp ), 105 | .s_axi_rvalid ( r_valid ), 106 | .s_axi_wdata ( w_data ), 107 | .s_axi_wready ( w_ready ), 108 | .s_axi_wstrb ( w_strb ), 109 | .s_axi_wvalid ( w_valid ), 110 | .io0_i ( io0_i ), 111 | .io0_o ( io0_o ), 112 | .io0_t ( io0_t ), 113 | .io1_i ( io1_i ), 114 | .io1_o ( io1_o ), 115 | .io1_t ( io1_t ), 116 | .sck_i ( sck_i ), 117 | .sck_o ( sck_o ), 118 | .sck_t ( sck_t ), 119 | .ss_i ( ss_i ), 120 | .ss_o ( ss_o ), 121 | .ss_t ( ss_t ), 122 | .ip2intc_irpt ( ip2intc_irpt ) 123 | ); 124 | 125 | endmodule // spi_wrapper 126 | -------------------------------------------------------------------------------- /src/main/verilog/stubs.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module clock_buffer_generic(input wire ing, output wire outg); 4 | 5 | `ifdef FPGA 6 | 7 | BUFH buf1(.I(ing), .O(outg)); 8 | 9 | `else 10 | 11 | assign outg = ing; 12 | 13 | `endif 14 | 15 | endmodule // clock_buffer_generic 16 | 17 | module io_buffer_generic(inout wire inoutg, output wire outg, input wire ing, input wire ctrl); 18 | 19 | `ifdef FPGA 20 | 21 | IOBUF #( 22 | .DRIVE(12), // Specify the output drive strength 23 | .IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE" 24 | .IOSTANDARD("DEFAULT"), // Specify the I/O standard 25 | .SLEW("SLOW") // Specify the output slew rate 26 | ) IOBUF_inst ( 27 | .O(outg), // Buffer output 28 | .IO(inoutg), // Buffer inout port (connect directly to top-level port) 29 | .I(ing), // Buffer input 30 | .T(ctrl) // 3-state enable input, high=input, low=output 31 | ); 32 | 33 | `else 34 | 35 | assign outg = inoutg; 36 | assign inoutg = ctrl ? 1'bz : ing; 37 | 38 | `endif 39 | 40 | endmodule // io_buffer_generic 41 | 42 | module io_buffer_fast(inout wire inoutg, output wire outg, input wire ing, input wire ctrl); 43 | 44 | `ifdef FPGA 45 | 46 | IOBUF #( 47 | .DRIVE(24), // Specify the output drive strength 48 | .IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE" 49 | .IOSTANDARD("LVTTL"), // Specify the I/O standard 50 | .SLEW("FAST") // Specify the output slew rate 51 | ) IOBUF_inst ( 52 | .O(outg), // Buffer output 53 | .IO(inoutg), // Buffer inout port (connect directly to top-level port) 54 | .I(ing), // Buffer input 55 | .T(ctrl) // 3-state enable input, high=input, low=output 56 | ); 57 | 58 | `else 59 | 60 | assign outg = inoutg; 61 | assign inoutg = ctrl ? 1'bz : ing; 62 | 63 | `endif 64 | 65 | endmodule // io_buffer_fast 66 | 67 | module oddr_buffer_generic(output wire outg, input wire ing); 68 | 69 | `ifdef FPGA 70 | 71 | ODDR #( 72 | .DDR_CLK_EDGE("OPPOSITE_EDGE"), 73 | .INIT(1'b0), 74 | .IS_C_INVERTED(1'b0), 75 | .IS_D1_INVERTED(1'b0), 76 | .IS_D2_INVERTED(1'b0), 77 | .SRTYPE("SYNC")) 78 | refclk_inst 79 | (.C(ing), 80 | .CE(1'b1), 81 | .D1(1'b1), 82 | .D2(1'b0), 83 | .Q(outg), 84 | .R(1'b0), 85 | .S( )); 86 | 87 | `else 88 | 89 | assign outg = ing; 90 | 91 | `endif 92 | 93 | endmodule // oddr_buffer_generic 94 | 95 | module bscan_generic #( 96 | parameter integer JTAG_CHAIN = 1 97 | ) 98 | (output wire CAPTURE, DRCK, RESET, RUNTEST, SEL, SHIFT, TCK, TDI, TMS, UPDATE, input wire TDO); 99 | 100 | `ifdef FPGA 101 | 102 | BSCANE2 #( 103 | .JTAG_CHAIN(JTAG_CHAIN) // Value for USER command. 104 | ) 105 | BSCANE2_inst ( 106 | .CAPTURE(CAPTURE), // 1-bit output: CAPTURE output from TAP controller. 107 | .DRCK(DRCK), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 108 | // SHIFT are asserted. 109 | .RESET(RESET), // 1-bit output: Reset output for TAP controller. 110 | .RUNTEST(RUNTEST), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 111 | .SEL(SEL), // 1-bit output: USER instruction active output. 112 | .SHIFT(SHIFT), // 1-bit output: SHIFT output from TAP controller. 113 | .TCK(TCK), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 114 | .TDI(TDI), // 1-bit output: Test Data Input (TDI) output from TAP controller. 115 | .TMS(TMS), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 116 | .UPDATE(UPDATE), // 1-bit output: UPDATE output from TAP controller 117 | .TDO(TDO) // 1-bit input: Test Data Output (TDO) input for USER function. 118 | ); 119 | 120 | `else // !`ifdef FPGA 121 | 122 | assign {CAPTURE, DRCK, RESET, RUNTEST, SEL, SHIFT, TCK, TDI, TMS, UPDATE} = 'b0; 123 | 124 | `endif // `ifdef FPGA 125 | 126 | endmodule // bscan_generic 127 | -------------------------------------------------------------------------------- /src/test/cxx/common/dpi_host_behav.cpp: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifdef VERILATOR 4 | #include 5 | #endif 6 | 7 | #include "globals.h" 8 | #include "dpi_host_behav.h" 9 | #include 10 | #include 11 | 12 | void host_req (unsigned int id, unsigned long long data) { 13 | if(data & 1) { 14 | // test pass/fail 15 | if(data != 1) 16 | std::cerr << "Core " << id << " exit with error code " << (data >> 1) << std::endl; 17 | exit_code = (data >> 1); 18 | exit_delay = 1; 19 | } else { 20 | std::cerr << "Core " << id << " get unsolved tohost code " << std::hex << data << std::endl; 21 | exit_code = 1; 22 | exit_delay = 1; 23 | } 24 | } 25 | 26 | int check_exit() { 27 | if(exit_delay > 1) { 28 | exit_delay--; 29 | return -1; 30 | } else if(exit_delay == 1 || exit_code) { 31 | return exit_code; 32 | } else 33 | return -1; 34 | } 35 | -------------------------------------------------------------------------------- /src/test/cxx/common/dpi_host_behav.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef DPI_HOST_BEHAV_H 4 | #define DPI_HOST_BEHAV_H 5 | 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | // purely legacy code for ISA regression test 13 | extern void host_req (unsigned int id, unsigned long long data); 14 | extern int check_exit (); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/test/cxx/common/dpi_ram_behav.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef DPI_RAM_BEHAV_H 4 | #define DPI_RAM_BEHAV_H 5 | 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | extern svBit memory_write_req ( 14 | const svBitVecVal *id_16b, 15 | const svBitVecVal *addr_32b, 16 | const svBitVecVal *len_8b, 17 | const svBitVecVal *size_3b, 18 | const svBitVecVal *user_16b 19 | ); 20 | extern svBit memory_write_data ( 21 | const svBitVecVal *data_256, 22 | const svBitVecVal *strb_32, 23 | const svBit last 24 | ); 25 | extern svBit memory_write_resp ( 26 | svBitVecVal *id_16b, 27 | svBitVecVal *resp_2b, 28 | svBitVecVal *user_16b 29 | ); 30 | extern svBit memory_read_req ( 31 | const svBitVecVal *id_16b, 32 | const svBitVecVal *addr_32b, 33 | const svBitVecVal *len_8b, 34 | const svBitVecVal *size_3b, 35 | const svBitVecVal *user_16b 36 | ); 37 | extern svBit memory_read_resp ( 38 | svBitVecVal *id_16b, 39 | svBitVecVal *data_256b, 40 | svBitVecVal *resp_2b, 41 | svBit *last, 42 | svBitVecVal *user_16b 43 | ); 44 | extern svBit memory_model_init (); 45 | extern svBit memory_model_close (); 46 | extern svBit memory_model_step (); 47 | extern svBit memory_load_mem (const char* filename); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #include 54 | #include 55 | #include 56 | 57 | class Memory32 { // data width = 32-bit 58 | std::map mem; // memory storage 59 | const uint32_t addr_max; // the maximal address, 0 means all 32-bit 60 | 61 | public: 62 | Memory32(uint32_t addr_max) 63 | : addr_max(addr_max) {} 64 | 65 | Memory32() : addr_max(0) {} 66 | 67 | // initialize a memory location with a value 68 | void init(const uint32_t addr, const uint32_t& data) { 69 | mem[addr] = data; 70 | } 71 | 72 | // write a value 73 | bool write(const uint32_t addr, const uint32_t& data, const uint32_t& mask); 74 | // burst write 75 | void write_block(uint32_t addr, uint32_t size, const uint8_t* buf); 76 | // read a value 77 | bool read(const uint32_t addr, uint32_t &data); 78 | }; 79 | 80 | class MemoryOperation { 81 | public: 82 | bool rw; // write 1, read 0 83 | uint32_t tag; // transaction tag 84 | uint32_t addr; 85 | uint32_t data; 86 | uint32_t mask; // byte-mask 87 | 88 | // default constructor 89 | MemoryOperation() 90 | : rw(0), tag(0), addr(0), data(0), mask(0) {} 91 | 92 | // normal constructor 93 | MemoryOperation(const bool rw, const uint32_t tag, const uint32_t addr, 94 | const uint32_t data = 0, const uint32_t mask = 0xf) 95 | : rw(rw), tag(tag), addr(addr), data(data), mask(mask) {} 96 | 97 | // copy constructor 98 | MemoryOperation(const MemoryOperation& rhs) 99 | : rw(rhs.rw), tag(rhs.tag), addr(rhs.addr), data(rhs.data), mask(rhs.mask) {} 100 | 101 | // streamout (print) 102 | std::ostream& streamout(std::ostream& os) const; 103 | }; 104 | 105 | inline std::ostream& operator<< (std::ostream& os, const MemoryOperation& rhs) { 106 | return rhs.streamout(os); 107 | } 108 | 109 | class MemoryController { 110 | Memory32 mem; 111 | const unsigned int op_max; // maximal parallel operation FIFOs 112 | const unsigned int pending_max; // maximal number of pending operations 113 | std::list op_fifo; // parallel operation FIFOs 114 | std::map > resp_map; // the read response map 115 | std::map resp_len; // the len of each response 116 | std::list resp_que; 117 | 118 | public: 119 | MemoryController(const unsigned int op_max = 8, const unsigned int pending_max = 128) 120 | : op_max(op_max), pending_max(pending_max) {} 121 | 122 | void add_read_req(const uint32_t tag, const uint32_t addr); 123 | void record_read_size(const uint32_t tag, const unsigned int beat_size) { 124 | resp_len[tag] = beat_size; 125 | } 126 | void add_write_req(const uint32_t tag, const uint32_t addr, 127 | const uint32_t data, const uint32_t mask); 128 | // simulation step function 129 | void step(); 130 | // get an empty queue 131 | bool busy(); 132 | std::list* get_resp(uint32_t &tag); 133 | 134 | // load an initial memory 135 | void load_mem(const std::string& filename); 136 | }; 137 | 138 | // global memory controller 139 | extern MemoryController *memory_controller; 140 | 141 | // AXI controllers 142 | class AXIMemWriter { 143 | uint32_t tag; // tag to denote the requestor 144 | uint32_t addr; // the starting address of the write burst 145 | unsigned int len; // the length of burst (-1) 146 | unsigned int size; // the size of a beat 147 | uint32_t mask; // the maximal mask defined by the size field 148 | unsigned int fifo; // the chosen memory controller fifo 149 | bool valid; 150 | std::list resps; // response queue 151 | 152 | public: 153 | AXIMemWriter() 154 | : valid(false) {} 155 | 156 | bool write_addr_req(const uint32_t tag, const uint32_t addr, const unsigned int len, const unsigned int size); 157 | bool write_data_req(const uint32_t *data, const uint32_t mask, const bool last); 158 | 159 | bool writer_resp_req(uint32_t *tag, uint32_t *resp); 160 | }; 161 | 162 | extern AXIMemWriter* axi_mem_writer; 163 | 164 | class AXIMemReader { 165 | std::map tracker_len; // tracking burst length 166 | std::map tracker_size; // tracking beat size 167 | public: 168 | bool reader_addr_req(const uint32_t tag, const uint32_t addr, const unsigned int len, const unsigned int size); 169 | bool reader_data_req(uint32_t *tag, uint32_t *data, uint32_t *resp, bool *last, const unsigned int width); 170 | }; 171 | 172 | extern AXIMemReader *axi_mem_reader; 173 | 174 | #endif 175 | 176 | // emacs local variable 177 | 178 | // Local Variables: 179 | // mode: c++ 180 | // End: 181 | -------------------------------------------------------------------------------- /src/test/cxx/common/elf.h: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | #ifndef _ELF_H 4 | #define _ELF_H 5 | 6 | #include 7 | 8 | #define IS_ELF(hdr) \ 9 | ((hdr).e_ident[0] == 0x7f && (hdr).e_ident[1] == 'E' && \ 10 | (hdr).e_ident[2] == 'L' && (hdr).e_ident[3] == 'F') 11 | 12 | #define IS_ELF32(hdr) (IS_ELF(hdr) && (hdr).e_ident[4] == 1) 13 | #define IS_ELF64(hdr) (IS_ELF(hdr) && (hdr).e_ident[4] == 2) 14 | 15 | #if __riscv_xlen == 64 16 | # define Elf_Ehdr Elf64_Ehdr 17 | # define Elf_Phdr Elf64_Phdr 18 | #else 19 | # define Elf_Ehdr Elf32_Ehdr 20 | # define Elf_Phdr Elf32_Phdr 21 | #endif 22 | 23 | #define ET_EXEC 2 24 | #define ET_DYN 3 25 | 26 | #define EF_RISCV_RVC 1 27 | 28 | #define PT_LOAD 1 29 | 30 | #define AT_NULL 0 31 | #define AT_PHDR 3 32 | #define AT_PHENT 4 33 | #define AT_PHNUM 5 34 | #define AT_PAGESZ 6 35 | #define AT_ENTRY 9 36 | #define AT_SECURE 23 37 | #define AT_RANDOM 25 38 | 39 | #define PF_X 1 40 | #define PF_W 2 41 | #define PF_R 4 42 | 43 | #define SHT_NOBITS 8 44 | 45 | typedef struct { 46 | uint8_t e_ident[16]; 47 | uint16_t e_type; 48 | uint16_t e_machine; 49 | uint32_t e_version; 50 | uint32_t e_entry; 51 | uint32_t e_phoff; 52 | uint32_t e_shoff; 53 | uint32_t e_flags; 54 | uint16_t e_ehsize; 55 | uint16_t e_phentsize; 56 | uint16_t e_phnum; 57 | uint16_t e_shentsize; 58 | uint16_t e_shnum; 59 | uint16_t e_shstrndx; 60 | } Elf32_Ehdr; 61 | 62 | typedef struct { 63 | uint32_t sh_name; 64 | uint32_t sh_type; 65 | uint32_t sh_flags; 66 | uint32_t sh_addr; 67 | uint32_t sh_offset; 68 | uint32_t sh_size; 69 | uint32_t sh_link; 70 | uint32_t sh_info; 71 | uint32_t sh_addralign; 72 | uint32_t sh_entsize; 73 | } Elf32_Shdr; 74 | 75 | typedef struct 76 | { 77 | uint32_t p_type; 78 | uint32_t p_offset; 79 | uint32_t p_vaddr; 80 | uint32_t p_paddr; 81 | uint32_t p_filesz; 82 | uint32_t p_memsz; 83 | uint32_t p_flags; 84 | uint32_t p_align; 85 | } Elf32_Phdr; 86 | 87 | typedef struct 88 | { 89 | uint32_t st_name; 90 | uint32_t st_value; 91 | uint32_t st_size; 92 | uint8_t st_info; 93 | uint8_t st_other; 94 | uint16_t st_shndx; 95 | } Elf32_Sym; 96 | 97 | typedef struct { 98 | uint8_t e_ident[16]; 99 | uint16_t e_type; 100 | uint16_t e_machine; 101 | uint32_t e_version; 102 | uint64_t e_entry; 103 | uint64_t e_phoff; 104 | uint64_t e_shoff; 105 | uint32_t e_flags; 106 | uint16_t e_ehsize; 107 | uint16_t e_phentsize; 108 | uint16_t e_phnum; 109 | uint16_t e_shentsize; 110 | uint16_t e_shnum; 111 | uint16_t e_shstrndx; 112 | } Elf64_Ehdr; 113 | 114 | typedef struct { 115 | uint32_t sh_name; 116 | uint32_t sh_type; 117 | uint64_t sh_flags; 118 | uint64_t sh_addr; 119 | uint64_t sh_offset; 120 | uint64_t sh_size; 121 | uint32_t sh_link; 122 | uint32_t sh_info; 123 | uint64_t sh_addralign; 124 | uint64_t sh_entsize; 125 | } Elf64_Shdr; 126 | 127 | typedef struct { 128 | uint32_t p_type; 129 | uint32_t p_flags; 130 | uint64_t p_offset; 131 | uint64_t p_vaddr; 132 | uint64_t p_paddr; 133 | uint64_t p_filesz; 134 | uint64_t p_memsz; 135 | uint64_t p_align; 136 | } Elf64_Phdr; 137 | 138 | typedef struct { 139 | uint32_t st_name; 140 | uint8_t st_info; 141 | uint8_t st_other; 142 | uint16_t st_shndx; 143 | uint64_t st_value; 144 | uint64_t st_size; 145 | } Elf64_Sym; 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /src/test/cxx/common/globals.cpp: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include "globals.h" 4 | 5 | uint64_t main_time = 0; 6 | unsigned int exit_delay = 0; 7 | unsigned int exit_code = 0; 8 | -------------------------------------------------------------------------------- /src/test/cxx/common/globals.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef GLOBALS_H 4 | #define GLOBALS_H 5 | 6 | #include 7 | 8 | extern uint64_t main_time; 9 | extern unsigned int exit_delay; 10 | extern unsigned int exit_code; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/test/cxx/common/loadelf.cpp: -------------------------------------------------------------------------------- 1 | #include "elf.h" 2 | #include "loadelf.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | std::map elfLoader::operator() (const std::string& fn) { 12 | int fd = open(fn.c_str(), O_RDONLY); 13 | struct stat s; 14 | assert(fd != -1); 15 | assert(fstat(fd, &s) != -1); 16 | size_t size = s.st_size; 17 | 18 | char* buf = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 19 | assert(buf != MAP_FAILED); 20 | close(fd); 21 | 22 | assert(size >= sizeof(Elf64_Ehdr)); 23 | const Elf64_Ehdr* eh = (const Elf64_Ehdr*)buf; 24 | assert(IS_ELF64(*eh)); 25 | 26 | std::vector zeros; 27 | std::map symbols; 28 | 29 | Elf64_Phdr* ph = (Elf64_Phdr*)(buf + eh->e_phoff); 30 | assert(size >= eh->e_phoff + eh->e_phnum*sizeof(*ph)); 31 | for (unsigned i = 0; i < eh->e_phnum; i++) { 32 | if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { 33 | if (ph[i].p_filesz) { 34 | assert(size >= ph[i].p_offset + ph[i].p_filesz); 35 | write(ph[i].p_paddr, ph[i].p_filesz, (uint8_t*)buf + ph[i].p_offset); 36 | } 37 | if(ph[i].p_memsz - ph[i].p_filesz > 0) { 38 | zeros.resize(ph[i].p_memsz - ph[i].p_filesz); 39 | write(ph[i].p_paddr + ph[i].p_filesz, ph[i].p_memsz - ph[i].p_filesz, &zeros[0]); 40 | } 41 | } 42 | } 43 | Elf64_Shdr* sh = (Elf64_Shdr*)(buf + eh->e_shoff); 44 | assert(size >= eh->e_shoff + eh->e_shnum*sizeof(*sh)); 45 | assert(eh->e_shstrndx < eh->e_shnum); 46 | assert(size >= sh[eh->e_shstrndx].sh_offset + sh[eh->e_shstrndx].sh_size); 47 | char *shstrtab = buf + sh[eh->e_shstrndx].sh_offset; 48 | unsigned strtabidx = 0, symtabidx = 0; 49 | for (unsigned i = 0; i < eh->e_shnum; i++) { 50 | unsigned max_len = sh[eh->e_shstrndx].sh_size - sh[i].sh_name; 51 | assert(sh[i].sh_name < sh[eh->e_shstrndx].sh_size); 52 | assert(strnlen(shstrtab + sh[i].sh_name, max_len) < max_len); 53 | if (sh[i].sh_type & SHT_NOBITS) continue; 54 | assert(size >= sh[i].sh_offset + sh[i].sh_size); 55 | if (strcmp(shstrtab + sh[i].sh_name, ".strtab") == 0) 56 | strtabidx = i; 57 | if (strcmp(shstrtab + sh[i].sh_name, ".symtab") == 0) 58 | symtabidx = i; 59 | } 60 | if (strtabidx && symtabidx) { 61 | char* strtab = buf + sh[strtabidx].sh_offset; 62 | Elf64_Sym* sym = (Elf64_Sym*)(buf + sh[symtabidx].sh_offset); 63 | for (unsigned i = 0; i < sh[symtabidx].sh_size/sizeof(Elf64_Sym); i++) { 64 | unsigned max_len = sh[strtabidx].sh_size - sym[i].st_name; 65 | assert(sym[i].st_name < sh[strtabidx].sh_size); 66 | assert(strnlen(strtab + sym[i].st_name, max_len) < max_len); 67 | symbols[strtab + sym[i].st_name] = sym[i].st_value; 68 | } 69 | } 70 | 71 | munmap(buf, size); 72 | 73 | return symbols; 74 | } 75 | -------------------------------------------------------------------------------- /src/test/cxx/common/loadelf.hpp: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef LOADELF_CXX_HEADER 4 | #define LOADELF_CXX_HEADER 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | typedef std::function write_callback; 12 | 13 | class elfLoader { 14 | // write callback function void write(paddr, size, pbuffer) 15 | const write_callback write; 16 | 17 | public: 18 | elfLoader(write_callback func) : write(func) {} 19 | 20 | // load an elf file 21 | std::map operator() (const std::string&); 22 | }; 23 | 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/test/cxx/veri/veri_top.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include 4 | #ifdef TRACE_VCD 5 | #include 6 | #endif 7 | #include "Vchip_top.h" 8 | #include "globals.h" 9 | #include "dpi_ram_behav.h" 10 | #include 11 | #include 12 | #include 13 | 14 | //#include "GlipTcp.h" 15 | 16 | using std::string; 17 | using std::vector; 18 | 19 | Vchip_top *top; 20 | uint64_t max_time = 0; 21 | 22 | double sc_time_stamp() { return main_time; } 23 | 24 | int main(int argc, char** argv) { 25 | Verilated::commandArgs(argc, argv); 26 | 27 | // initialize memory model 28 | memory_model_init(); 29 | 30 | // handle arguements 31 | bool vcd_enable = false; 32 | string vcd_name = "verilated.vcd"; 33 | bool wait_debug = false; 34 | 35 | vector args(argv + 1, argv + argc); 36 | for(vector::iterator it = args.begin(); it != args.end(); ++it) { 37 | if(*it == "+vcd") 38 | vcd_enable = true; 39 | else if(it->find("+load=") == 0) { 40 | string filename = it->substr(strlen("+load=")); 41 | memory_controller->load_mem(filename); 42 | } 43 | else if(it->find("+max-cycles=") == 0) { 44 | max_time = 10 * strtoul(it->substr(strlen("+max-cycles=")).c_str(), NULL, 10); 45 | } 46 | else if(it->find("+vcd_name=") == 0) { 47 | vcd_name = it->substr(strlen("+vcd_name=")); 48 | } 49 | else if(it->find("+waitdebug") == 0) { 50 | wait_debug = true; 51 | } 52 | } 53 | 54 | top = new Vchip_top; 55 | top->rst_top = 1; 56 | 57 | // VCD dump 58 | #ifdef TRACE_VCD 59 | VerilatedVcdC* vcd = new VerilatedVcdC; 60 | if(vcd_enable) { 61 | Verilated::traceEverOn(true); 62 | top->trace(vcd, 99); 63 | vcd->open(vcd_name.c_str()); 64 | } 65 | #endif 66 | 67 | top->eval(); 68 | 69 | // GlipTcp &glip = GlipTcp::instance(); 70 | while(!Verilated::gotFinish() && (!exit_code || exit_delay > 1) && 71 | (max_time == 0 || main_time < max_time) && 72 | (exit_delay != 1) 73 | ) { 74 | // if (!glip.connected() && wait_debug) { 75 | // continue; 76 | // } 77 | if(main_time > 133) { 78 | top->rst_top = 0; 79 | } 80 | if((main_time % 10) == 0) { // 10ns clk 81 | top->clk_p = 1; 82 | top->clk_n = 0; 83 | } 84 | if((main_time % 10) == 5) { 85 | top->clk_p = 0; 86 | top->clk_n = 1; 87 | } 88 | 89 | top->eval(); 90 | if((main_time % 10) == 0) memory_controller->step(); 91 | #ifdef TRACE_VCD 92 | if(vcd_enable) vcd->dump(main_time); // do the dump 93 | #endif 94 | 95 | if(main_time < 140) 96 | main_time++; 97 | else 98 | main_time += 5; 99 | 100 | if((main_time % 10) == 0 && exit_delay > 1) 101 | exit_delay--; // postponed delay to allow VCD recording 102 | 103 | if((main_time % 10000000) == 0) 104 | std::cerr << "simulation has run for " << main_time/10 << " cycles..." << std::endl; 105 | } 106 | 107 | top->final(); 108 | #ifdef TRACE_VCD 109 | if(vcd_enable) vcd->close(); 110 | #endif 111 | 112 | delete top; 113 | memory_model_close(); 114 | 115 | if(max_time == 0 || main_time < max_time) 116 | return exit_code; 117 | else 118 | return -1; // timeout 119 | } 120 | -------------------------------------------------------------------------------- /src/test/verilog/host_behav.sv: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | module host_behav 4 | #( 5 | ID_WIDTH = 1, // id width 6 | USER_WIDTH = 1 // width of user field 7 | ) 8 | ( 9 | input logic clk, rstn, 10 | input logic req_valid, resp_ready, 11 | nasti_channel.slave nasti 12 | ); 13 | 14 | import "DPI-C" function void host_req ( input int unsigned id, input longint unsigned data); 15 | import "DPI-C" function int check_exit (); 16 | 17 | assign nasti.ar_ready = 0; 18 | assign nasti.r_valid = 0; 19 | 20 | logic aw_fire; 21 | logic [ID_WIDTH-1:0] b_id; 22 | logic [USER_WIDTH-1:0] b_user; 23 | 24 | always_ff @(posedge clk or negedge rstn) 25 | if(!rstn) 26 | aw_fire <= 0; 27 | else if(nasti.aw_valid && nasti.aw_ready) begin 28 | aw_fire <= 1; 29 | b_id <= nasti.aw_id; 30 | b_user <= nasti.aw_user; 31 | end else if(nasti.w_valid && nasti.w_ready) 32 | aw_fire <= 0; 33 | 34 | assign nasti.aw_ready = !aw_fire; 35 | assign nasti.w_ready = aw_fire; 36 | 37 | logic b_fire; 38 | always_ff @(posedge clk or negedge rstn) 39 | if(!rstn) 40 | b_fire <= 0; 41 | else if(nasti.b_valid && !nasti.b_ready) 42 | b_fire <= 1; 43 | else 44 | b_fire <= 0; 45 | 46 | assign nasti.b_valid = nasti.w_valid && nasti.w_ready || b_fire; 47 | 48 | assign nasti.b_id = b_id; 49 | assign nasti.b_resp = 0; 50 | assign nasti.b_user = b_user; 51 | 52 | logic [15:0] msg_id, msg_data; 53 | assign msg_id = nasti.w_data >> 16; 54 | assign msg_data = nasti.w_data; 55 | 56 | always @(posedge clk) 57 | if(nasti.w_valid && nasti.w_ready) 58 | host_req(msg_id, msg_data); 59 | 60 | endmodule // host_behav 61 | -------------------------------------------------------------------------------- /src/test/verilog/host_behav_dummy.sv: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | module host_behav 4 | #( 5 | ID_WIDTH = 1, // id width 6 | USER_WIDTH = 1 // width of user field 7 | ) 8 | ( 9 | input logic clk, rstn, 10 | input logic req_valid, resp_ready, 11 | nasti_channel.slave nasti 12 | ); 13 | 14 | import "DPI-C" function void host_req ( input int unsigned id, input longint unsigned data); 15 | import "DPI-C" function int check_exit (); 16 | 17 | assign nasti.ar_ready = 0; 18 | assign nasti.r_valid = 0; 19 | 20 | logic aw_fire; 21 | logic [ID_WIDTH-1:0] b_id; 22 | logic [USER_WIDTH-1:0] b_user; 23 | 24 | always_ff @(posedge clk or negedge rstn) 25 | if(!rstn) 26 | aw_fire <= 0; 27 | else if(nasti.aw_valid && nasti.aw_ready) begin 28 | aw_fire <= 1; 29 | b_id <= nasti.aw_id; 30 | b_user <= nasti.aw_user; 31 | end else if(nasti.w_valid && nasti.w_ready) 32 | aw_fire <= 0; 33 | 34 | assign nasti.aw_ready = !aw_fire; 35 | assign nasti.w_ready = aw_fire; 36 | 37 | logic b_fire; 38 | always_ff @(posedge clk or negedge rstn) 39 | if(!rstn) 40 | b_fire <= 0; 41 | else if(nasti.b_valid && !nasti.b_ready) 42 | b_fire <= 1; 43 | else 44 | b_fire <= 0; 45 | 46 | assign nasti.b_valid = nasti.w_valid && nasti.w_ready || b_fire; 47 | 48 | assign nasti.b_id = b_id; 49 | assign nasti.b_resp = 0; 50 | assign nasti.b_user = b_user; 51 | 52 | logic [15:0] msg_id, msg_data; 53 | assign msg_id = nasti.w_data >> 16; 54 | assign msg_data = nasti.w_data; 55 | 56 | always @(posedge clk) 57 | if(nasti.w_valid && nasti.w_ready) 58 | host_req(msg_id, msg_data); 59 | 60 | endmodule // host_behav 61 | -------------------------------------------------------------------------------- /src/test/verilog/nasti_ram_sim.sv: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | module nasti_ram_sim 4 | #( 5 | ID_WIDTH = 8, 6 | ADDR_WIDTH = 16, 7 | DATA_WIDTH = 128, 8 | USER_WIDTH = 1 9 | ) 10 | ( 11 | input clk, rstn, 12 | nasti_channel.slave nasti 13 | ); 14 | 15 | parameter base = 32'h80200000; 16 | 17 | integer i, fd, first, last; 18 | 19 | reg [7:0] mem[32'h0:32'h1000000]; 20 | 21 | // Read input arguments and initialize 22 | 23 | initial 24 | begin 25 | // JRRK hacks 26 | $readmemh("cnvmem.mem", mem); 27 | for (i = base; (i < base+32'h1000000) && (1'bx === ^mem[i-base]); i=i+8) 28 | ; 29 | first = i; 30 | for (i = base+32'h1000000; (i >= base) && (1'bx === ^mem[i-base]); i=i-8) 31 | ; 32 | last = (i+16); 33 | for (i = i+1; i < last; i=i+1) 34 | mem[i-base] = 0; 35 | $display("First = %X, Last = %X", first, last-1); 36 | for (i = first; i < last; i=i+1) 37 | if (1'bx === ^mem[i-base]) mem[i-base] = 0; 38 | #1 39 | for (i = first-base; i < last-base; i=i+8) 40 | begin 41 | SimAXIMem.AXI4RAM.mem.mem_ext.ram[(i+base-32'h80000000)/8] = 42 | {mem[i+7],mem[i+6],mem[i+5],mem[i+4],mem[i+3],mem[i+2],mem[i+1],mem[i+0]}; 43 | end 44 | end // initial begin 45 | 46 | function bit memory_load_mem (input string filename); 47 | 48 | begin 49 | end 50 | 51 | endfunction // memory_load_mem 52 | 53 | SimAXIMem SimAXIMem ( 54 | .clock(clk), 55 | .reset(~rstn), 56 | .io_axi4_0_ar_ready(nasti.ar_ready), 57 | .io_axi4_0_ar_valid(nasti.ar_valid), 58 | .io_axi4_0_ar_bits_id(nasti.ar_id), 59 | .io_axi4_0_ar_bits_addr(nasti.ar_addr), 60 | .io_axi4_0_ar_bits_len(nasti.ar_len), 61 | .io_axi4_0_ar_bits_size(nasti.ar_size), 62 | .io_axi4_0_ar_bits_burst(nasti.ar_burst), 63 | .io_axi4_0_r_ready(nasti.r_ready), 64 | .io_axi4_0_r_valid(nasti.r_valid), 65 | .io_axi4_0_r_bits_id(nasti.r_id), 66 | .io_axi4_0_r_bits_data(nasti.r_data), 67 | .io_axi4_0_r_bits_resp(nasti.r_resp), 68 | .io_axi4_0_r_bits_last(nasti.r_last), 69 | .io_axi4_0_aw_ready(nasti.aw_ready), 70 | .io_axi4_0_aw_valid(nasti.aw_valid), 71 | .io_axi4_0_aw_bits_id(nasti.aw_id), 72 | .io_axi4_0_aw_bits_addr(nasti.aw_addr), 73 | .io_axi4_0_aw_bits_len(nasti.aw_len), 74 | .io_axi4_0_aw_bits_size(nasti.aw_size), 75 | .io_axi4_0_aw_bits_burst(nasti.aw_burst), 76 | .io_axi4_0_w_ready(nasti.w_ready), 77 | .io_axi4_0_w_valid(nasti.w_valid), 78 | .io_axi4_0_w_bits_data(nasti.w_data), 79 | .io_axi4_0_w_bits_strb(nasti.w_strb), 80 | .io_axi4_0_w_bits_last(nasti.w_last), 81 | .io_axi4_0_b_ready(nasti.b_ready), 82 | .io_axi4_0_b_valid(nasti.b_valid), 83 | .io_axi4_0_b_bits_id(nasti.b_id), 84 | .io_axi4_0_b_bits_resp(nasti.b_resp) 85 | ); 86 | 87 | /* 88 | not used 89 | .s_axi_arlock ( nasti.ar_lock ), 90 | .s_axi_arcache ( nasti.ar_cache ), 91 | .s_axi_arprot ( nasti.ar_prot ), 92 | 93 | .s_axi_awlock ( nasti.aw_lock ), 94 | .s_axi_awcache ( nasti.aw_cache ), 95 | .s_axi_awprot ( nasti.aw_prot ), 96 | .s_axi_awready ( nasti.aw_ready ), 97 | */ 98 | 99 | endmodule // nasti_ram_behav 100 | -------------------------------------------------------------------------------- /unitest/.gitignore: -------------------------------------------------------------------------------- 1 | csrc 2 | DVEfiles 3 | generated-src 4 | libdpi.so 5 | opendatabase.log 6 | output 7 | stdout.log 8 | *-sim 9 | *-sim.daidir 10 | ucli.key 11 | vc_hdrs.h 12 | .nodeIdDynamicRanges 13 | -------------------------------------------------------------------------------- /unitest/vlsi_mem_gen: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # See LICENSE for license details. 4 | 5 | import sys 6 | import math 7 | 8 | use_latches = 0 9 | 10 | def parse_line(line): 11 | name = '' 12 | width = 0 13 | depth = 0 14 | ports = '' 15 | mask_gran = 1 16 | tokens = line.split() 17 | i = 0 18 | for i in xrange(0,len(tokens),2): 19 | s = tokens[i] 20 | if s == 'name': 21 | name = tokens[i+1] 22 | elif s == 'width': 23 | width = int(tokens[i+1]) 24 | elif s == 'depth': 25 | depth = int(tokens[i+1]) 26 | elif s == 'ports': 27 | ports = tokens[i+1].split(',') 28 | elif s == 'mask_gran': 29 | # currently used only for fpga, but here for .conf format compatability 30 | mask_gran = int(tokens[i+1]) 31 | else: 32 | sys.exit('%s: unknown argument %s' % (sys.argv[0], a)) 33 | return (name, width, depth, ports) 34 | 35 | def gen_mem(name, width, depth, ports): 36 | addr_width = max(math.ceil(math.log(depth)/math.log(2)),1) 37 | port_spec = ['input CLK', 'input RST', 'input init'] 38 | readports = [] 39 | writeports = [] 40 | latchports = [] 41 | rwports = [] 42 | decl = [] 43 | combinational = [] 44 | sequential = [] 45 | maskedports = {} 46 | for pid in range(len(ports)): 47 | ptype = ports[pid] 48 | if ptype[0:1] == 'm': 49 | ptype = ptype[1:] 50 | maskedports[pid] = pid 51 | 52 | if ptype == 'read': 53 | port_spec.append('input [%d:0] R%dA' % (addr_width-1, pid)) 54 | port_spec.append('input R%dE' % pid) 55 | port_spec.append('output [%d:0] R%dO' % (width-1, pid)) 56 | readports.append(pid) 57 | elif ptype == 'write': 58 | port_spec.append('input [%d:0] W%dA' % (addr_width-1, pid)) 59 | port_spec.append('input W%dE' % pid) 60 | port_spec.append('input [%d:0] W%dI' % (width-1, pid)) 61 | if pid in maskedports: 62 | port_spec.append('input [%d:0] W%dM' % (width-1, pid)) 63 | if not use_latches or pid in maskedports: 64 | writeports.append(pid) 65 | else: 66 | latchports.append(pid) 67 | elif ptype == 'rw': 68 | port_spec.append('input [%d:0] RW%dA' % (addr_width-1, pid)) 69 | port_spec.append('input RW%dE' % pid) 70 | port_spec.append('input RW%dW' % pid) 71 | if pid in maskedports: 72 | port_spec.append('input [%d:0] RW%dM' % (width-1, pid)) 73 | port_spec.append('input [%d:0] RW%dI' % (width-1, pid)) 74 | port_spec.append('output [%d:0] RW%dO' % (width-1, pid)) 75 | rwports.append(pid) 76 | else: 77 | sys.exit('%s: unknown port type %s' % (sys.argv[0], ptype)) 78 | 79 | nr = len(readports) 80 | nw = len(writeports) 81 | nrw = len(rwports) 82 | masked = len(maskedports)>0 83 | tup = (depth, width, nr, nw, nrw, masked) 84 | 85 | decl.append('reg [%d:0] ram [%d:0];' % (width-1, depth-1)) 86 | decl.append('`ifndef SYNTHESIS') 87 | decl.append(' integer initvar;') 88 | decl.append(' initial begin') 89 | decl.append(' #0.002;') 90 | decl.append(' for (initvar = 0; initvar < %d; initvar = initvar+1)' % depth) 91 | decl.append(' ram[initvar] = {%d {$random}};' % ((width-1)/32+1)) 92 | decl.append(' end') 93 | decl.append('`endif') 94 | 95 | for pid in readports: 96 | decl.append('reg [%d:0] reg_R%dA;' % (addr_width-1, pid)) 97 | sequential.append('if (R%dE) reg_R%dA <= R%dA;' % (pid, pid, pid)) 98 | combinational.append('assign R%dO = ram[reg_R%dA];' % (pid, pid)) 99 | 100 | for pid in rwports: 101 | decl.append('reg [%d:0] reg_RW%dA;' % (addr_width-1, pid)) 102 | sequential.append('if (RW%dE && !RW%dW) reg_RW%dA <= RW%dA;' % (pid, pid, pid, pid)) 103 | combinational.append('assign RW%dO = ram[reg_RW%dA];' % (pid, pid)) 104 | 105 | for pid in latchports: 106 | decl.append('reg [%d:0] latch_W%dA;' % (addr_width-1, pid)) 107 | decl.append('reg [%d:0] latch_W%dI;' % (width-1, pid)) 108 | decl.append('reg latch_W%dE;' % (pid)) 109 | combinational.append('always @(*) begin') 110 | combinational.append(' if (!CLK && W%dE) latch_W%dA <= W%dA;' % (pid, pid, pid)) 111 | combinational.append(' if (!CLK && W%dE) latch_W%dI <= W%dI;' % (pid, pid, pid)) 112 | combinational.append(' if (!CLK) latch_W%dE <= W%dE;' % (pid, pid)) 113 | combinational.append('end') 114 | combinational.append('always @(*)') 115 | combinational.append(' if (CLK && latch_W%dE)' % (pid)) 116 | combinational.append(' ram[latch_W%dA] <= latch_W%dI;' % (pid, pid)) 117 | 118 | decl.append("integer i;") 119 | sequential.append("for (i = 0; i < %d; i=i+1) begin" % width) 120 | for pid in writeports: 121 | mask = (' && W%dM[i]' % pid) if pid in maskedports else '' 122 | sequential.append(" if (W%dE%s) ram[W%dA][i] <= W%dI[i];" % (pid, mask, pid, pid)) 123 | for pid in rwports: 124 | mask = (' && RW%dM[i]' % pid) if pid in maskedports else '' 125 | sequential.append(" if (RW%dE && RW%dW%s) ram[RW%dA][i] <= RW%dI[i];" % (pid, pid, mask, pid, pid)) 126 | sequential.append("end") 127 | body = "\ 128 | %s\n\ 129 | always @(posedge CLK) begin\n\ 130 | %s\n\ 131 | end\n\ 132 | %s\n" % ('\n '.join(decl), '\n '.join(sequential), '\n '.join(combinational)) 133 | 134 | s = "module %s(\n\ 135 | %s\n\ 136 | );\n\ 137 | \n\ 138 | %s\ 139 | \n\ 140 | endmodule\n" % (name, ',\n '.join(port_spec), body) 141 | return s 142 | 143 | def main(): 144 | if len(sys.argv) < 2: 145 | sys.exit('Please give a .conf file as input') 146 | for line in open(sys.argv[1]): 147 | print gen_mem(*parse_line(line)) 148 | 149 | if __name__ == '__main__': 150 | main() 151 | -------------------------------------------------------------------------------- /vcs/.gitignore: -------------------------------------------------------------------------------- 1 | csrc 2 | DVEfiles 3 | generated-src 4 | libdpi.so 5 | opendatabase.log 6 | output 7 | stdout.log 8 | *-sim 9 | *-sim.daidir 10 | ucli.key 11 | vc_hdrs.h 12 | .nodeIdDynamicRanges 13 | -------------------------------------------------------------------------------- /vsim/.gitignore: -------------------------------------------------------------------------------- 1 | *.vcd 2 | *.vpd 3 | *.log 4 | *sim 5 | *sim-debug 6 | generated-src 7 | output 8 | verilator* 9 | DVEfiles 10 | .nodeIdDynamicRanges 11 | cnvmem.mem 12 | cnvmem.old 13 | tlbtest 14 | tlbtest.bin 15 | tlbtest.dis 16 | -------------------------------------------------------------------------------- /vsim/lowrisc.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | 3 | SECTIONS 4 | { 5 | . = 0x80000000; 6 | .text : 7 | { 8 | *(.text.entry) 9 | *(.text) 10 | } 11 | 12 | /* data segment */ 13 | .data : { *(.data) } 14 | 15 | .sdata : { 16 | __global_pointer$ = . + 0x800; 17 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) 18 | *(.srodata*) 19 | *(.sdata .sdata.* .gnu.linkonce.s.*) 20 | } 21 | 22 | /* bss segment */ 23 | .sbss : { 24 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 25 | *(.scommon) 26 | } 27 | .bss : { *(.bss) } 28 | 29 | __malloc_start = .; 30 | . = . + 512; 31 | 32 | /* End of uninitalized data segement */ 33 | _end = .; 34 | } 35 | -------------------------------------------------------------------------------- /vsim/tlbtest.sh: -------------------------------------------------------------------------------- 1 | riscv64-unknown-elf-gcc -g -nostdlib -T lowrisc.lds tlbtest.S -o tlbtest 2 | riscv64-unknown-elf-objdump -d tlbtest > tlbtest.dis 3 | riscv64-unknown-elf-objcopy -I elf64-little -O binary tlbtest tlbtest.bin 4 | riscv64-unknown-elf-objcopy -I binary -O verilog tlbtest.bin cnvmem.mem 5 | riscv64-unknown-elf-objcopy -I elf64-little -O verilog tlbtest cnvmem.old 6 | -------------------------------------------------------------------------------- /vsrc/AsyncResetReg.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | /** This black-boxes an Async Reset 4 | * Reg. 5 | * 6 | * Because Chisel doesn't support 7 | * parameterized black boxes, 8 | * we unfortunately have to 9 | * instantiate a number of these. 10 | * 11 | * We also have to hard-code the set/reset. 12 | * 13 | * Do not confuse an asynchronous 14 | * reset signal with an asynchronously 15 | * reset reg. You should still 16 | * properly synchronize your reset 17 | * deassertion. 18 | * 19 | * @param d Data input 20 | * @param q Data Output 21 | * @param clk Clock Input 22 | * @param rst Reset Input 23 | * @param en Write Enable Input 24 | * 25 | */ 26 | 27 | `default_nettype wire 28 | 29 | module AsyncResetReg ( 30 | input d, 31 | output reg q, 32 | input en, 33 | 34 | input clk, 35 | input rst); 36 | 37 | always @(posedge clk or posedge rst) begin 38 | 39 | if (rst) begin 40 | q <= 1'b0; 41 | end else if (en) begin 42 | q <= d; 43 | end 44 | end 45 | 46 | 47 | endmodule // AsyncResetReg 48 | 49 | -------------------------------------------------------------------------------- /vsrc/ClockDivider2.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | /** This black-boxes a Clock Divider by 2. 4 | * The output clock is phase-aligned to the input clock. 5 | * If you use this in synthesis, make sure your sdc 6 | * declares that you want it to do the same. 7 | * 8 | * Because Chisel does not support 9 | * blocking assignments, it is impossible 10 | * to create a deterministic divided clock. 11 | * 12 | * @param clk_out Divided Clock 13 | * @param clk_in Clock Input 14 | * 15 | */ 16 | 17 | module ClockDivider2 (output reg clk_out, input clk_in); 18 | 19 | initial clk_out = 1'b0; 20 | always @(posedge clk_in) begin 21 | clk_out = ~clk_out; // Must use =, NOT <= 22 | end 23 | 24 | endmodule // ClockDivider2 25 | -------------------------------------------------------------------------------- /vsrc/ClockDivider3.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | /** This black-boxes a Clock Divider by 3. 4 | * The output clock is phase-aligned to the input clock. 5 | * Do NOT use this in synthesis; the duty cycle is 2:1. 6 | * 7 | * Because Chisel does not support 8 | * blocking assignments, it is impossible 9 | * to create a deterministic divided clock. 10 | * 11 | * @param clk_out Divided Clock 12 | * @param clk_in Clock Input 13 | * 14 | */ 15 | 16 | module ClockDivider3 (output reg clk_out, input clk_in); 17 | 18 | reg delay; 19 | 20 | initial begin 21 | clk_out = 1'b0; 22 | delay = 1'b0; 23 | end 24 | 25 | always @(posedge clk_in) begin 26 | if (clk_out == 1'b0) begin 27 | clk_out = 1'b1; 28 | delay <= 1'b0; 29 | end else if (delay == 1'b1) begin 30 | clk_out = 1'b0; 31 | delay <= 1'b0; 32 | end else begin 33 | delay <= 1'b1; 34 | end 35 | end 36 | 37 | endmodule // ClockDivider3 38 | -------------------------------------------------------------------------------- /vsrc/JTAGDummy.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | module JTAGDummy( 4 | // LED and DIP switch 5 | output [7:0] o_led, 6 | input clk_p, 7 | input rst_top 8 | ); 9 | 10 | wire rxd; 11 | wire txd; 12 | wire rts; 13 | wire cts; 14 | wire flash_ss; 15 | wire [3:0] flash_io; 16 | wire spi_cs; 17 | wire spi_sclk; 18 | wire spi_mosi; 19 | wire spi_miso; 20 | // 4-bit full SD interface 21 | wire sd_sclk; 22 | wire sd_detect; 23 | wire [3:0] sd_dat; 24 | wire sd_cmd; 25 | wire sd_reset; 26 | 27 | // LED and DIP switch 28 | wire [7:0] o_led; 29 | wire [3:0] i_dip; 30 | 31 | // push button array 32 | wire GPIO_SW_C; 33 | wire GPIO_SW_W; 34 | wire GPIO_SW_E; 35 | wire GPIO_SW_N; 36 | wire GPIO_SW_S; 37 | 38 | //keyboard 39 | wire PS2_CLK; 40 | wire PS2_DATA; 41 | 42 | // display 43 | wire VGA_HS_O; 44 | wire VGA_VS_O; 45 | wire [3:0] VGA_RED_O; 46 | wire [3:0] VGA_BLUE_O; 47 | wire [3:0] VGA_GREEN_O; 48 | //! Ethernet MAC PHY interface signals 49 | wire [1:0] i_erxd; // RMII receive data 50 | wire i_erx_dv; // PHY data valid 51 | wire i_erx_er; // PHY coding error 52 | wire i_emdint; // PHY interrupt in active low 53 | wire o_erefclk; // RMII clock out 54 | wire [1:0] o_etxd; // RMII transmit data 55 | wire o_etx_en; // RMII transmit enable 56 | wire o_emdc; // MDIO clock 57 | wire io_emdio; // MDIO wire 58 | wire o_erstn; // PHY reset active low 59 | 60 | `ifdef verilator 61 | wire clk = clk_p; 62 | wire rst = ~rst_top; 63 | `else 64 | wire clk_locked; 65 | wire clk; 66 | wire rst = ~clk_locked; 67 | 68 | clk_wiz_2 clk_gen 69 | ( 70 | .clk_in1 ( clk_p ), // 100 MHz onboard 71 | .clk_out1 ( clk ), // 25 MHz 72 | .resetn ( rst_top ), 73 | .locked ( clk_locked ) 74 | ); 75 | `endif // !`ifdef verilator 76 | 77 | chip_top 78 | DUT 79 | ( 80 | .*, 81 | .clk_p ( clk ), 82 | .clk_n ( !clk ), 83 | .rst_top ( rst ) 84 | ); 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /vsrc/JtagTapController_artix.sv: -------------------------------------------------------------------------------- 1 | module JtagTapController( 2 | input clock, 3 | input reset, 4 | input io_jtag_TMS, 5 | input io_jtag_TDI, 6 | output io_jtag_TDO_data, 7 | output io_jtag_TDO_driven, 8 | input io_control_jtag_reset, 9 | output [4:0] io_output_instruction, 10 | output io_output_reset, 11 | output io_dataChainOut_shift, 12 | output io_dataChainOut_data, 13 | output io_dataChainOut_capture, 14 | output io_dataChainOut_update, 15 | input io_dataChainIn_data 16 | ); 17 | 18 | wire CAPTURE1; 19 | wire CAPTURE3; 20 | wire CAPTURE4; 21 | wire DRCK1; 22 | wire DRCK3; 23 | wire DRCK4; 24 | wire RESET1; 25 | wire RESET3; 26 | wire RESET4; 27 | wire RUNTEST1; 28 | wire RUNTEST3; 29 | wire RUNTEST4; 30 | wire SEL1; 31 | wire SEL3; 32 | wire SEL4; 33 | wire SHIFT1; 34 | wire SHIFT3; 35 | wire SHIFT4; 36 | wire TCK1; 37 | wire TCK3; 38 | wire TCK4; 39 | wire TDI1; 40 | wire TDI3; 41 | wire TDI4; 42 | wire TMS1; 43 | wire TMS3; 44 | wire TMS4; 45 | wire UPDATE1; 46 | wire UPDATE3; 47 | wire UPDATE4; 48 | 49 | // BSCANE2: Boundary-Scan User Instruction 50 | // Artix-7 51 | // Xilinx HDL Language Template, version 2015.4 52 | 53 | BSCANE2 #( 54 | .JTAG_CHAIN(1) // Value for USER command. 55 | ) 56 | BSCANE2_inst1 ( 57 | .CAPTURE(CAPTURE1), // 1-bit output: CAPTURE output from TAP controller. 58 | .DRCK(DRCK1), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 59 | // SHIFT are asserted. 60 | 61 | .RESET(RESET1), // 1-bit output: Reset output for TAP controller. 62 | .RUNTEST(RUNTEST1), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 63 | .SEL(SEL1), // 1-bit output: USER instruction active output. 64 | .SHIFT(SHIFT1), // 1-bit output: SHIFT output from TAP controller. 65 | .TCK(TCK1), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 66 | .TDI(TDI1), // 1-bit output: Test Data Input (TDI) output from TAP controller. 67 | .TMS(TMS1), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 68 | .UPDATE(UPDATE1), // 1-bit output: UPDATE output from TAP controller 69 | .TDO(io_dataChainIn_data) // 1-bit input: Test Data Output (TDO) input for USER function. 70 | ); 71 | 72 | 73 | // BSCANE2: Boundary-Scan User Instruction 74 | // Artix-7 75 | // Xilinx HDL Language Template, version 2015.4 76 | 77 | BSCANE2 #( 78 | .JTAG_CHAIN(3) // Value for USER command. 79 | ) 80 | BSCANE2_inst3 ( 81 | .CAPTURE(CAPTURE3), // 1-bit output: CAPTURE output from TAP controller. 82 | .DRCK(DRCK3), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 83 | // SHIFT are asserted. 84 | 85 | .RESET(RESET3), // 1-bit output: Reset output for TAP controller. 86 | .RUNTEST(RUNTEST3), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 87 | .SEL(SEL3), // 1-bit output: USER instruction active output. 88 | .SHIFT(SHIFT3), // 1-bit output: SHIFT output from TAP controller. 89 | .TCK(TCK3), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 90 | .TDI(TDI3), // 1-bit output: Test Data Input (TDI) output from TAP controller. 91 | .TMS(TMS3), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 92 | .UPDATE(UPDATE3), // 1-bit output: UPDATE output from TAP controller 93 | .TDO(io_dataChainIn_data) // 1-bit input: Test Data Output (TDO) input for USER function. 94 | ); 95 | 96 | 97 | // BSCANE2: Boundary-Scan User Instruction 98 | // Artix-7 99 | // Xilinx HDL Language Template, version 2015.4 100 | 101 | BSCANE2 #( 102 | .JTAG_CHAIN(4) // Value for USER command. 103 | ) 104 | BSCANE2_inst4 ( 105 | .CAPTURE(CAPTURE4), // 1-bit output: CAPTURE output from TAP controller. 106 | .DRCK(DRCK4), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 107 | // SHIFT are asserted. 108 | 109 | .RESET(RESET4), // 1-bit output: Reset output for TAP controller. 110 | .RUNTEST(RUNTEST4), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 111 | .SEL(SEL4), // 1-bit output: USER instruction active output. 112 | .SHIFT(SHIFT4), // 1-bit output: SHIFT output from TAP controller. 113 | .TCK(TCK4), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 114 | .TDI(TDI4), // 1-bit output: Test Data Input (TDI) output from TAP controller. 115 | .TMS(TMS4), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 116 | .UPDATE(UPDATE4), // 1-bit output: UPDATE output from TAP controller 117 | .TDO(io_dataChainIn_data) // 1-bit input: Test Data Output (TDO) input for USER function. 118 | ); 119 | 120 | assign io_dataChainOut_data = SHIFT1 ? TDI1 : SHIFT3 ? TDI3 : SHIFT4 ? TDI4 : 1'b0; 121 | assign io_jtag_TDO_driven = 1'b1; 122 | assign io_output_instruction = SEL1 ? 5'h1 : SEL3 ? 5'h10 : SEL4 ? 5'h11 : 5'b0; 123 | assign io_output_reset = RESET1|RESET3|RESET4; 124 | assign io_dataChainOut_shift = SHIFT1|SHIFT3|SHIFT4; 125 | assign io_jtag_TDO_data = io_dataChainOut_data; 126 | assign io_dataChainOut_capture = CAPTURE1|CAPTURE3|CAPTURE4; 127 | assign io_dataChainOut_update = UPDATE1|UPDATE3|UPDATE4; 128 | 129 | endmodule 130 | -------------------------------------------------------------------------------- /vsrc/JtagTapController_asic.sv: -------------------------------------------------------------------------------- 1 | module JtagTapController( 2 | input clock, 3 | input reset, 4 | input io_jtag_TMS, 5 | input io_jtag_TDI, 6 | output io_jtag_TDO_data, 7 | output io_jtag_TDO_driven, 8 | input io_control_jtag_reset, 9 | output [4:0] io_output_instruction, 10 | output io_output_reset, 11 | output io_dataChainOut_shift, 12 | output io_dataChainOut_data, 13 | output io_dataChainOut_capture, 14 | output io_dataChainOut_update, 15 | input io_dataChainIn_data 16 | ); 17 | wire _T_20; 18 | wire _T_22; 19 | wire _T_23; 20 | wire tdoReg_clock; 21 | wire tdoReg_io_next; 22 | wire tdoReg_io_enable; 23 | wire tdoReg_io_output; 24 | wire tdoeReg_clock; 25 | wire tdoeReg_io_next; 26 | wire tdoeReg_io_enable; 27 | wire tdoeReg_io_output; 28 | wire stateMachine_clock; 29 | wire stateMachine_io_tms; 30 | wire [3:0] stateMachine_io_currState; 31 | wire stateMachine_io_jtag_reset; 32 | wire irChain_clock; 33 | wire irChain_reset; 34 | wire irChain_io_chainIn_shift; 35 | wire irChain_io_chainIn_data; 36 | wire irChain_io_chainIn_capture; 37 | wire irChain_io_chainIn_update; 38 | wire irChain_io_chainOut_data; 39 | wire [4:0] irChain_io_capture_bits; 40 | wire [4:0] irChain_io_update_bits; 41 | wire _T_34; 42 | wire _T_36; 43 | wire _T_38; 44 | wire irReg_clock; 45 | wire [4:0] irReg_io_next; 46 | wire irReg_io_enable; 47 | wire [4:0] irReg_io_output; 48 | wire _T_52; 49 | wire _T_53; 50 | wire [4:0] _GEN_2; 51 | wire _T_58; 52 | wire _T_59; 53 | wire _GEN_4; 54 | wire _T_62; 55 | wire _T_64; 56 | wire _T_66; 57 | wire _T_68; 58 | wire _T_75; 59 | wire _T_76; 60 | wire _GEN_7; 61 | wire _T_81; 62 | wire _T_82; 63 | wire _GEN_9; 64 | NegativeEdgeLatch tdoReg ( 65 | .clock(tdoReg_clock), 66 | .io_next(tdoReg_io_next), 67 | .io_enable(tdoReg_io_enable), 68 | .io_output(tdoReg_io_output) 69 | ); 70 | NegativeEdgeLatch tdoeReg ( 71 | .clock(tdoeReg_clock), 72 | .io_next(tdoeReg_io_next), 73 | .io_enable(tdoeReg_io_enable), 74 | .io_output(tdoeReg_io_output) 75 | ); 76 | JtagStateMachine stateMachine ( 77 | .clock(stateMachine_clock), 78 | .io_tms(stateMachine_io_tms), 79 | .io_currState(stateMachine_io_currState), 80 | .io_jtag_reset(stateMachine_io_jtag_reset) 81 | ); 82 | CaptureUpdateChain_2 irChain ( 83 | .clock(irChain_clock), 84 | .reset(irChain_reset), 85 | .io_chainIn_shift(irChain_io_chainIn_shift), 86 | .io_chainIn_data(irChain_io_chainIn_data), 87 | .io_chainIn_capture(irChain_io_chainIn_capture), 88 | .io_chainIn_update(irChain_io_chainIn_update), 89 | .io_chainOut_data(irChain_io_chainOut_data), 90 | .io_capture_bits(irChain_io_capture_bits), 91 | .io_update_bits(irChain_io_update_bits) 92 | ); 93 | NegativeEdgeLatch_2 irReg ( 94 | .clock(irReg_clock), 95 | .io_next(irReg_io_next), 96 | .io_enable(irReg_io_enable), 97 | .io_output(irReg_io_output) 98 | ); 99 | assign io_jtag_TDO_data = tdoReg_io_output; 100 | assign io_jtag_TDO_driven = tdoeReg_io_output; 101 | assign io_output_instruction = irReg_io_output; 102 | assign io_output_reset = _T_62; 103 | assign io_dataChainOut_shift = _T_64; 104 | assign io_dataChainOut_data = io_jtag_TDI; 105 | assign io_dataChainOut_capture = _T_66; 106 | assign io_dataChainOut_update = _T_68; 107 | assign _T_20 = $unsigned(clock); 108 | assign _T_22 = _T_20 == 1'h0; 109 | assign _T_23 = $unsigned(_T_22); 110 | assign tdoReg_clock = _T_23; 111 | assign tdoReg_io_next = _GEN_7; 112 | assign tdoReg_io_enable = 1'h1; 113 | assign tdoeReg_clock = _T_23; 114 | assign tdoeReg_io_next = _GEN_9; 115 | assign tdoeReg_io_enable = 1'h1; 116 | assign stateMachine_clock = clock; 117 | assign stateMachine_io_tms = io_jtag_TMS; 118 | assign stateMachine_io_jtag_reset = io_control_jtag_reset; 119 | assign irChain_clock = clock; 120 | assign irChain_reset = reset; 121 | assign irChain_io_chainIn_shift = _T_34; 122 | assign irChain_io_chainIn_data = io_jtag_TDI; 123 | assign irChain_io_chainIn_capture = _T_36; 124 | assign irChain_io_chainIn_update = _T_38; 125 | assign irChain_io_capture_bits = 5'h1; 126 | assign _T_34 = stateMachine_io_currState == 4'ha; 127 | assign _T_36 = stateMachine_io_currState == 4'he; 128 | assign _T_38 = stateMachine_io_currState == 4'hd; 129 | assign irReg_clock = _T_23; 130 | assign irReg_io_next = _GEN_2; 131 | assign irReg_io_enable = _GEN_4; 132 | assign _T_52 = reset == 1'h0; 133 | assign _T_53 = _T_52 & _T_38; 134 | assign _GEN_2 = _T_53 ? irChain_io_update_bits : 5'h1; 135 | assign _T_58 = _T_38 == 1'h0; 136 | assign _T_59 = _T_52 & _T_58; 137 | assign _GEN_4 = _T_59 ? 1'h0 : 1'h1; 138 | assign _T_62 = stateMachine_io_currState == 4'hf; 139 | assign _T_64 = stateMachine_io_currState == 4'h2; 140 | assign _T_66 = stateMachine_io_currState == 4'h6; 141 | assign _T_68 = stateMachine_io_currState == 4'h5; 142 | assign _T_75 = _T_64 == 1'h0; 143 | assign _T_76 = _T_75 & _T_34; 144 | assign _GEN_7 = _T_76 ? irChain_io_chainOut_data : io_dataChainIn_data; 145 | assign _T_81 = _T_34 == 1'h0; 146 | assign _T_82 = _T_75 & _T_81; 147 | assign _GEN_9 = _T_82 ? 1'h0 : 1'h1; 148 | endmodule 149 | -------------------------------------------------------------------------------- /vsrc/SimDTM.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | import "DPI-C" function int debug_tick 4 | ( 5 | output bit debug_req_valid, 6 | input bit debug_req_ready, 7 | output int debug_req_bits_addr, 8 | output int debug_req_bits_op, 9 | output int debug_req_bits_data, 10 | 11 | input bit debug_resp_valid, 12 | output bit debug_resp_ready, 13 | input int debug_resp_bits_resp, 14 | input int debug_resp_bits_data 15 | ); 16 | 17 | module SimDTM( 18 | input clk, 19 | input reset, 20 | 21 | output debug_req_valid, 22 | input debug_req_ready, 23 | output [ 6:0] debug_req_bits_addr, 24 | output [ 1:0] debug_req_bits_op, 25 | output [31:0] debug_req_bits_data, 26 | 27 | input debug_resp_valid, 28 | output debug_resp_ready, 29 | input [ 1:0] debug_resp_bits_resp, 30 | input [31:0] debug_resp_bits_data, 31 | 32 | output [31:0] exit 33 | ); 34 | 35 | bit r_reset; 36 | 37 | wire #0.1 __debug_req_ready = debug_req_ready; 38 | wire #0.1 __debug_resp_valid = debug_resp_valid; 39 | wire [31:0] #0.1 __debug_resp_bits_resp = {30'b0, debug_resp_bits_resp}; 40 | wire [31:0] #0.1 __debug_resp_bits_data = debug_resp_bits_data; 41 | 42 | bit __debug_req_valid; 43 | int __debug_req_bits_addr; 44 | int __debug_req_bits_op; 45 | int __debug_req_bits_data; 46 | bit __debug_resp_ready; 47 | int __exit; 48 | 49 | assign #0.1 debug_req_valid = __debug_req_valid; 50 | assign #0.1 debug_req_bits_addr = __debug_req_bits_addr[6:0]; 51 | assign #0.1 debug_req_bits_op = __debug_req_bits_op[1:0]; 52 | assign #0.1 debug_req_bits_data = __debug_req_bits_data[31:0]; 53 | assign #0.1 debug_resp_ready = __debug_resp_ready; 54 | assign #0.1 exit = __exit; 55 | 56 | always @(posedge clk) 57 | begin 58 | r_reset <= reset; 59 | if (reset || r_reset) 60 | begin 61 | __debug_req_valid = 0; 62 | __debug_resp_ready = 0; 63 | __exit = 0; 64 | end 65 | else 66 | begin 67 | __exit = debug_tick( 68 | __debug_req_valid, 69 | __debug_req_ready, 70 | __debug_req_bits_addr, 71 | __debug_req_bits_op, 72 | __debug_req_bits_data, 73 | __debug_resp_valid, 74 | __debug_resp_ready, 75 | __debug_resp_bits_resp, 76 | __debug_resp_bits_data 77 | ); 78 | end 79 | end 80 | endmodule 81 | -------------------------------------------------------------------------------- /vsrc/SimDTM_JTAG.sv: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | module SimDTM( 4 | input clk, 5 | input reset, 6 | 7 | output debug_req_valid, 8 | input debug_req_ready, 9 | output [ 6:0] debug_req_bits_addr, 10 | output [ 1:0] debug_req_bits_op, 11 | output [31:0] debug_req_bits_data, 12 | 13 | input debug_resp_valid, 14 | output debug_resp_ready, 15 | input [ 1:0] debug_resp_bits_resp, 16 | input [31:0] debug_resp_bits_data, 17 | 18 | output [31:0] exit 19 | ); 20 | 21 | wire [10:0] io_jtag_mfr_id = 11'h2AA; 22 | 23 | wire CAPTURE2; 24 | wire DRCK2; 25 | wire RESET2; 26 | wire RUNTEST2; 27 | wire SEL2; 28 | wire SHIFT2; 29 | wire TCK2; 30 | wire TDI2; 31 | wire TMS2; 32 | wire UPDATE2; 33 | 34 | // BSCANE2: Boundary-Scan User Instruction 35 | // Artix-7 36 | // Xilinx HDL Language Template, version 2015.4 37 | 38 | BSCANE2 #( 39 | .JTAG_CHAIN(2) // Value for USER command. 40 | ) 41 | BSCANE2_inst1 ( 42 | .CAPTURE(CAPTURE2), // 1-bit output: CAPTURE output from TAP controller. 43 | .DRCK(DRCK2), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 44 | // SHIFT are asserted. 45 | 46 | .RESET(RESET2), // 1-bit output: Reset output for TAP controller. 47 | .RUNTEST(RUNTEST2), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 48 | .SEL(SEL2), // 1-bit output: USER instruction active output. 49 | .SHIFT(SHIFT2), // 1-bit output: SHIFT output from TAP controller. 50 | .TCK(TCK2), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 51 | .TDI(TDI2), // 1-bit output: Test Data Input (TDI) output from TAP controller. 52 | .TMS(TMS2), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 53 | .UPDATE(UPDATE2), // 1-bit output: UPDATE output from TAP controller 54 | .TDO(TDI2) // 1-bit input: Test Data Output (TDO) input for USER function. 55 | ); 56 | 57 | DebugTransportModuleJTAG dtm ( 58 | .clock(TCK2), 59 | .reset(RESET2), 60 | .io_dmi_req_ready(debug_req_ready), 61 | .io_dmi_req_valid(debug_req_valid), 62 | .io_dmi_req_bits_addr(debug_req_bits_addr), 63 | .io_dmi_req_bits_data(debug_req_bits_data), 64 | .io_dmi_req_bits_op(debug_req_bits_op), 65 | .io_dmi_resp_ready(debug_resp_ready), 66 | .io_dmi_resp_valid(debug_resp_valid), 67 | .io_dmi_resp_bits_data(debug_resp_bits_data), 68 | .io_dmi_resp_bits_resp(debug_resp_bits_resp), 69 | .io_jtag_TMS(), 70 | .io_jtag_TDI(), 71 | .io_jtag_TDO_data(), 72 | .io_jtag_TDO_driven(), 73 | .io_jtag_reset(RESET2), 74 | .io_jtag_mfr_id(io_jtag_mfr_id), 75 | .io_fsmReset() 76 | ); 77 | 78 | endmodule 79 | -------------------------------------------------------------------------------- /vsrc/TestDriver.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | `ifndef RESET_DELAY 4 | `define RESET_DELAY 777.7 5 | `endif 6 | 7 | module TestDriver; 8 | 9 | reg clock = 1'b0; 10 | reg reset = 1'b1; 11 | 12 | always #(`CLOCK_PERIOD/2.0) clock = ~clock; 13 | initial #(`RESET_DELAY) reset = 0; 14 | 15 | // Read input arguments and initialize 16 | reg verbose = 1'b0; 17 | wire printf_cond = verbose && !reset; 18 | reg [63:0] max_cycles = 0; 19 | reg [63:0] dump_start = 0; 20 | reg [63:0] trace_count = 0; 21 | reg [1023:0] vcdplusfile = 0; 22 | reg [1023:0] vcdfile = 0; 23 | int unsigned rand_value; 24 | initial 25 | begin 26 | void'($value$plusargs("max-cycles=%d", max_cycles)); 27 | void'($value$plusargs("dump-start=%d", dump_start)); 28 | verbose = $test$plusargs("verbose"); 29 | 30 | // do not delete the lines below. 31 | // $random function needs to be called with the seed once to affect all 32 | // the downstream $random functions within the Chisel-generated Verilog 33 | // code. 34 | // $urandom is seeded via cmdline (+ntb_random_seed in VCS) but that 35 | // doesn't seed $random. 36 | rand_value = $urandom; 37 | rand_value = $random(rand_value); 38 | if (verbose) begin 39 | `ifdef VCS 40 | $fdisplay(stderr, "testing $random %0x seed %d", rand_value, unsigned'($get_initial_random_seed)); 41 | `else 42 | $fdisplay(stderr, "testing $random %0x", rand_value); 43 | `endif 44 | end 45 | 46 | `ifdef DEBUG 47 | 48 | if ($value$plusargs("vcdplusfile=%s", vcdplusfile)) 49 | begin 50 | `ifdef VCS 51 | $vcdplusfile(vcdplusfile); 52 | `else 53 | $fdisplay(stderr, "Error: +vcdplusfile is VCS-only; use +vcdfile instead"); 54 | $fatal; 55 | `endif 56 | end 57 | 58 | if ($value$plusargs("vcdfile=%s", vcdfile)) 59 | begin 60 | $dumpfile(vcdfile); 61 | $dumpvars(0, testHarness); 62 | end 63 | `ifdef VCS 64 | `define VCDPLUSON $vcdpluson(0); $vcdplusmemon(0); 65 | `define VCDPLUSCLOSE $vcdplusclose; $dumpoff; 66 | `else 67 | `define VCDPLUSON $dumpon; 68 | `define VCDPLUSCLOSE $dumpoff; 69 | `endif 70 | `else 71 | // No +define+DEBUG 72 | `define VCDPLUSON 73 | `define VCDPLUSCLOSE 74 | 75 | if ($test$plusargs("vcdplusfile=") || $test$plusargs("vcdfile=")) 76 | begin 77 | $fdisplay(stderr, "Error: +vcdfile or +vcdplusfile requested but compile did not have +define+DEBUG enabled"); 78 | $fatal; 79 | end 80 | 81 | `endif 82 | end 83 | 84 | `ifdef TESTBENCH_IN_UVM 85 | // UVM library has its own way to manage end-of-simulation. 86 | // A UVM-based testbench will raise an objection, watch this signal until this goes 1, then drop the objection. 87 | reg finish_request = 1'b0; 88 | `endif 89 | reg [255:0] reason = ""; 90 | reg failure = 1'b0; 91 | wire success; 92 | integer stderr = 32'h80000002; 93 | always @(posedge clock) 94 | begin 95 | `ifdef GATE_LEVEL 96 | if (verbose) 97 | begin 98 | $fdisplay(stderr, "C: %10d", trace_count); 99 | end 100 | `endif 101 | if (trace_count == dump_start) 102 | begin 103 | `VCDPLUSON 104 | end 105 | 106 | trace_count = trace_count + 1; 107 | if (!reset) 108 | begin 109 | if (max_cycles > 0 && trace_count > max_cycles) 110 | begin 111 | reason = " (timeout)"; 112 | failure = 1'b1; 113 | end 114 | 115 | if (failure) 116 | begin 117 | $fdisplay(stderr, "*** FAILED ***%s after %d simulation cycles", reason, trace_count); 118 | `VCDPLUSCLOSE 119 | $fatal; 120 | end 121 | 122 | if (success) 123 | begin 124 | if (verbose) 125 | $fdisplay(stderr, "Completed after %d simulation cycles", trace_count); 126 | `VCDPLUSCLOSE 127 | `ifdef TESTBENCH_IN_UVM 128 | finish_request = 1; 129 | `else 130 | $finish; 131 | `endif 132 | end 133 | end 134 | end 135 | 136 | TestHarness testHarness( 137 | .clock(clock), 138 | .reset(reset), 139 | .io_success(success) 140 | ); 141 | 142 | endmodule 143 | -------------------------------------------------------------------------------- /vsrc/jtag_addr.v: -------------------------------------------------------------------------------- 1 | module jtag_addr(output reg [1:0] OP, output reg INC, output reg [31:0] ADDR, 2 | input wire CAPTURE, RESET, RUNTEST, SEL, SHIFT, TDI, TMS, UPDATE, TCK, 3 | output wire TDO); 4 | 5 | parameter wid = 35; 6 | 7 | reg [wid-1:0] SR; 8 | 9 | assign TDO = SR[0]; 10 | 11 | always @(posedge TCK) 12 | begin 13 | if (RESET) 14 | begin 15 | SR = 0; 16 | WR = 0; 17 | INC = 0; 18 | ADDR = 0; 19 | end 20 | else if (SEL) 21 | begin 22 | if (CAPTURE) 23 | begin 24 | SR = {INC,OP,ADDR}; 25 | end 26 | if (UPDATE) 27 | begin 28 | {INC,OP,ADDR} = SR; 29 | end 30 | if (SHIFT) 31 | begin 32 | SR = {TDI,SR[wid-1:1]}; 33 | end 34 | end 35 | end 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /vsrc/jtag_dummy.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `default_nettype none 3 | 4 | module jtag_dummy( 5 | output wire [1:0] OP, 6 | output wire [31:0] TO_MEM, 7 | output wire [31:0] ADDR, 8 | input wire [31:0] FROM_MEM, 9 | output wire TCK, 10 | output wire TCK2, 11 | output wire RESET, 12 | output wire RUNTEST); 13 | 14 | wire CAPTURE, DRCK, SEL, SHIFT, TDI, TDO, TMS, UPDATE, TCK_unbuf; 15 | wire CAPTURE2, DRCK2, RESET2, RUNTEST2, SEL2, SHIFT2, TDI2, TDO2, TMS2, UPDATE2; 16 | wire INC; 17 | wire [1:0] OP; 18 | wire [31:0] ADDR0; 19 | 20 | BUFH jtag_buf(.I(TCK_unbuf), .O(TCK)); 21 | 22 | // BSCANE2: Boundary-Scan User Instruction 23 | // Artix-7 24 | // Xilinx HDL Language Template, version 2017.1 25 | 26 | BSCANE2 #( 27 | .JTAG_CHAIN(1) // Value for USER command. 28 | ) 29 | BSCANE2_inst ( 30 | .CAPTURE(CAPTURE), // 1-bit output: CAPTURE output from TAP controller. 31 | .DRCK(DRCK), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 32 | // SHIFT are asserted. 33 | 34 | .RESET(RESET), // 1-bit output: Reset output for TAP controller. 35 | .RUNTEST(RUNTEST), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 36 | .SEL(SEL), // 1-bit output: USER instruction active output. 37 | .SHIFT(SHIFT), // 1-bit output: SHIFT output from TAP controller. 38 | .TCK(TCK_unbuf), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 39 | .TDI(TDI), // 1-bit output: Test Data Input (TDI) output from TAP controller. 40 | .TMS(TMS), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 41 | .UPDATE(UPDATE), // 1-bit output: UPDATE output from TAP controller 42 | .TDO(TDO) // 1-bit input: Test Data Output (TDO) input for USER function. 43 | ); 44 | 45 | BSCANE2 #( 46 | .JTAG_CHAIN(2) // Value for USER command. 47 | ) 48 | BSCANE2_inst2 ( 49 | .CAPTURE(CAPTURE2), // 1-bit output: CAPTURE output from TAP controller. 50 | .DRCK(DRCK2), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or 51 | // SHIFT are asserted. 52 | 53 | .RESET(RESET2), // 1-bit output: Reset output for TAP controller. 54 | .RUNTEST(RUNTEST2), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. 55 | .SEL(SEL2), // 1-bit output: USER instruction active output. 56 | .SHIFT(SHIFT2), // 1-bit output: SHIFT output from TAP controller. 57 | .TCK(TCK2), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. 58 | .TDI(TDI2), // 1-bit output: Test Data Input (TDI) output from TAP controller. 59 | .TMS(TMS2), // 1-bit output: Test Mode Select output. Fabric connection to TAP. 60 | .UPDATE(UPDATE2), // 1-bit output: UPDATE output from TAP controller 61 | .TDO(TDO2) // 1-bit input: Test Data Output (TDO) input for USER function. 62 | ); 63 | 64 | jtag_rom rom1( 65 | .WREN(WREN), 66 | .TO_MEM(TO_MEM), 67 | .ADDR(ADDR), 68 | .FROM_MEM(FROM_MEM), 69 | .INC(INC), 70 | .OP(OP), 71 | .OPIN(OPIN), 72 | .ADDR0(ADDR0), 73 | .TDO(TDO), 74 | .CAPTURE(CAPTURE), 75 | .RESET(RESET), 76 | .RUNTEST(RUNTEST), 77 | .SEL(SEL), 78 | .SHIFT(SHIFT), 79 | .TDI(TDI), 80 | .TMS(TMS), 81 | .UPDATE(UPDATE), 82 | .TCK(TCK) 83 | ); 84 | 85 | jtag_addr addr1( 86 | .DBG(DBG), 87 | .INC(INC), 88 | .OP(OP), 89 | .ADDR(ADDR0), 90 | .TDO(TDO2), 91 | .CAPTURE(CAPTURE2), 92 | .RESET(RESET2), 93 | .RUNTEST(RUNTEST2), 94 | .SEL(SEL2), 95 | .SHIFT(SHIFT2), 96 | .TDI(TDI2), 97 | .TMS(TMS2), 98 | .UPDATE(UPDATE2), 99 | .TCK(TCK) 100 | ); 101 | 102 | endmodule 103 | -------------------------------------------------------------------------------- /vsrc/jtag_rom.v: -------------------------------------------------------------------------------- 1 | module jtag_rom(input wire INC, input wire [1:0] OPIN, input wire [31:0] ADDR0, 2 | input wire CAPTURE, RESET, RUNTEST, SEL, SHIFT, TDI, TMS, UPDATE, TCK, 3 | output wire TDO, output reg [1:0] OP, output reg VALID, output reg [31:0] TO_MEM, output reg [31:0] ADDR, 4 | input wire [31:0] FROM_MEM ); 5 | 6 | parameter dataw = 32; 7 | 8 | reg [dataw-1:0] SR; 9 | 10 | reg INCEN; 11 | reg [7:0] CNT; 12 | 13 | assign TDO = SR[0]; 14 | 15 | always @(posedge TCK) 16 | begin 17 | if (RESET) 18 | begin 19 | CNT = 0; 20 | SR = 0; 21 | WREN = 0; 22 | TO_MEM = 0; 23 | ADDR = 0; 24 | INCEN = 1'b0; 25 | end 26 | else if (SEL) 27 | begin 28 | if (CAPTURE) 29 | begin 30 | CNT = 0; 31 | SR = ADDR0; 32 | OP = OPIN; 33 | INCEN = 1'b0; 34 | ADDR = ADDR0; 35 | end 36 | if (UPDATE) 37 | begin 38 | if (WR) 39 | TO_MEM = SR; 40 | WREN = WR; 41 | INCEN = 1'b0; 42 | CNT = 0; 43 | end 44 | if (SHIFT) 45 | begin 46 | ADDR = ADDR + {INCEN,2'b0}; 47 | INCEN = 1'b0; 48 | VALID = 1'b0; 49 | SR = {TDI,SR[dataw-1:1]}; 50 | CNT = CNT + 1; 51 | if (CNT == dataw) 52 | begin 53 | if (WR) 54 | TO_MEM = SR; 55 | else 56 | SR = FROM_MEM; 57 | VALID = 1'b1; 58 | INCEN = INC; 59 | CNT = 0; 60 | end 61 | end 62 | end 63 | end 64 | // End of BSCANE2_inst instantiation 65 | 66 | endmodule // unmatched end(function|task|module|primitive|interface|package|class|clocking) 67 | -------------------------------------------------------------------------------- /vsrc/jtag_vpi.tab: -------------------------------------------------------------------------------- 1 | $send_result_to_server call=send_result_to_server acc=rw:* 2 | $check_for_command call=check_for_command acc=rw:* 3 | -------------------------------------------------------------------------------- /vsrc/jtagsm_dummy.sv: -------------------------------------------------------------------------------- 1 | module JtagTapController( 2 | input clock, 3 | input reset, 4 | input io_jtag_TMS, 5 | input io_jtag_TDI, 6 | output io_jtag_TDO_data, 7 | output io_jtag_TDO_driven, 8 | input io_control_jtag_reset, 9 | output [4:0] io_output_instruction, 10 | output io_output_reset, 11 | output io_dataChainOut_shift, 12 | output io_dataChainOut_data, 13 | output io_dataChainOut_capture, 14 | output io_dataChainOut_update, 15 | input io_dataChainIn_data 16 | ); 17 | wire _T_20; 18 | wire _T_22; 19 | wire _T_23; 20 | wire tdoReg_clock; 21 | wire tdoReg_io_next; 22 | wire tdoReg_io_enable; 23 | wire tdoReg_io_output; 24 | wire tdoeReg_clock; 25 | wire tdoeReg_io_next; 26 | wire tdoeReg_io_enable; 27 | wire tdoeReg_io_output; 28 | wire stateMachine_clock; 29 | wire stateMachine_io_tms; 30 | wire [3:0] stateMachine_io_currState; 31 | wire stateMachine_io_jtag_reset; 32 | wire irChain_clock; 33 | wire irChain_reset; 34 | wire irChain_io_chainIn_shift; 35 | wire irChain_io_chainIn_data; 36 | wire irChain_io_chainIn_capture; 37 | wire irChain_io_chainIn_update; 38 | wire irChain_io_chainOut_data; 39 | wire [4:0] irChain_io_capture_bits; 40 | wire [4:0] irChain_io_update_bits; 41 | wire _T_34; 42 | wire _T_36; 43 | wire _T_38; 44 | wire irReg_clock; 45 | wire [4:0] irReg_io_next; 46 | wire irReg_io_enable; 47 | wire [4:0] irReg_io_output; 48 | wire _T_52; 49 | wire _T_53; 50 | wire [4:0] _GEN_2; 51 | wire _T_58; 52 | wire _T_59; 53 | wire _GEN_4; 54 | wire _T_62; 55 | wire _T_64; 56 | wire _T_66; 57 | wire _T_68; 58 | wire _T_75; 59 | wire _T_76; 60 | wire _GEN_7; 61 | wire _T_81; 62 | wire _T_82; 63 | wire _GEN_9; 64 | NegativeEdgeLatch tdoReg ( 65 | .clock(tdoReg_clock), 66 | .io_next(tdoReg_io_next), 67 | .io_enable(tdoReg_io_enable), 68 | .io_output(tdoReg_io_output) 69 | ); 70 | NegativeEdgeLatch tdoeReg ( 71 | .clock(tdoeReg_clock), 72 | .io_next(tdoeReg_io_next), 73 | .io_enable(tdoeReg_io_enable), 74 | .io_output(tdoeReg_io_output) 75 | ); 76 | JtagStateMachine stateMachine ( 77 | .clock(stateMachine_clock), 78 | .io_tms(stateMachine_io_tms), 79 | .io_currState(stateMachine_io_currState), 80 | .io_jtag_reset(stateMachine_io_jtag_reset) 81 | ); 82 | CaptureUpdateChain_2 irChain ( 83 | .clock(irChain_clock), 84 | .reset(irChain_reset), 85 | .io_chainIn_shift(irChain_io_chainIn_shift), 86 | .io_chainIn_data(irChain_io_chainIn_data), 87 | .io_chainIn_capture(irChain_io_chainIn_capture), 88 | .io_chainIn_update(irChain_io_chainIn_update), 89 | .io_chainOut_data(irChain_io_chainOut_data), 90 | .io_capture_bits(irChain_io_capture_bits), 91 | .io_update_bits(irChain_io_update_bits) 92 | ); 93 | NegativeEdgeLatch_2 irReg ( 94 | .clock(irReg_clock), 95 | .io_next(irReg_io_next), 96 | .io_enable(irReg_io_enable), 97 | .io_output(irReg_io_output) 98 | ); 99 | assign io_jtag_TDO_data = tdoReg_io_output; 100 | assign io_jtag_TDO_driven = tdoeReg_io_output; 101 | assign io_output_instruction = irReg_io_output; 102 | assign io_output_reset = _T_62; 103 | assign io_dataChainOut_shift = _T_64; 104 | assign io_dataChainOut_data = io_jtag_TDI; 105 | assign io_dataChainOut_capture = _T_66; 106 | assign io_dataChainOut_update = _T_68; 107 | assign _T_20 = $unsigned(clock); 108 | assign _T_22 = _T_20 == 1'h0; 109 | assign _T_23 = $unsigned(_T_22); 110 | assign tdoReg_clock = _T_23; 111 | assign tdoReg_io_next = _GEN_7; 112 | assign tdoReg_io_enable = 1'h1; 113 | assign tdoeReg_clock = _T_23; 114 | assign tdoeReg_io_next = _GEN_9; 115 | assign tdoeReg_io_enable = 1'h1; 116 | assign stateMachine_clock = clock; 117 | assign stateMachine_io_tms = io_jtag_TMS; 118 | assign stateMachine_io_jtag_reset = io_control_jtag_reset; 119 | assign irChain_clock = clock; 120 | assign irChain_reset = reset; 121 | assign irChain_io_chainIn_shift = _T_34; 122 | assign irChain_io_chainIn_data = io_jtag_TDI; 123 | assign irChain_io_chainIn_capture = _T_36; 124 | assign irChain_io_chainIn_update = _T_38; 125 | assign irChain_io_capture_bits = 5'h1; 126 | assign _T_34 = stateMachine_io_currState == 4'ha; 127 | assign _T_36 = stateMachine_io_currState == 4'he; 128 | assign _T_38 = stateMachine_io_currState == 4'hd; 129 | assign irReg_clock = _T_23; 130 | assign irReg_io_next = _GEN_2; 131 | assign irReg_io_enable = _GEN_4; 132 | assign _T_52 = reset == 1'h0; 133 | assign _T_53 = _T_52 & _T_38; 134 | assign _GEN_2 = _T_53 ? irChain_io_update_bits : 5'h1; 135 | assign _T_58 = _T_38 == 1'h0; 136 | assign _T_59 = _T_52 & _T_58; 137 | assign _GEN_4 = _T_59 ? 1'h0 : 1'h1; 138 | assign _T_62 = stateMachine_io_currState == 4'hf; 139 | assign _T_64 = stateMachine_io_currState == 4'h2; 140 | assign _T_66 = stateMachine_io_currState == 4'h6; 141 | assign _T_68 = stateMachine_io_currState == 4'h5; 142 | assign _T_75 = _T_64 == 1'h0; 143 | assign _T_76 = _T_75 & _T_34; 144 | assign _GEN_7 = _T_76 ? irChain_io_chainOut_data : io_dataChainIn_data; 145 | assign _T_81 = _T_34 == 1'h0; 146 | assign _T_82 = _T_75 & _T_81; 147 | assign _GEN_9 = _T_82 ? 1'h0 : 1'h1; 148 | endmodule 149 | -------------------------------------------------------------------------------- /vsrc/plusarg_reader.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | // No default parameter values are intended, nor does IEEE 1800-2012 require them (clause A.2.4 param_assignment), 4 | // but Incisive demands them. These default values should never be used. 5 | module plusarg_reader #(FORMAT="borked=%d", DEFAULT=0) ( 6 | output wire [31:0] out 7 | ); 8 | 9 | `ifdef SYNTHESIS 10 | assign out = DEFAULT; 11 | `else 12 | `ifdef verilator 13 | assign out = DEFAULT; 14 | `else 15 | reg [31:0] myplus; 16 | assign out = myplus; 17 | 18 | initial begin 19 | if (!$value$plusargs(FORMAT, myplus)) myplus = DEFAULT; 20 | end 21 | `endif 22 | `endif 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /vsrc/vsim_bscan_dummy.v: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) 1995/2010 Xilinx, Inc. 3 | // All Right Reserved. 4 | /////////////////////////////////////////////////////////////////////////////// 5 | // This version is a simulation stub. 6 | 7 | module BSCANE2 ( 8 | output CAPTURE, 9 | output DRCK, 10 | output RESET, 11 | output RUNTEST, 12 | output SEL, 13 | output SHIFT, 14 | output TCK, 15 | output TDI, 16 | output TMS, 17 | output UPDATE, 18 | 19 | input TDO 20 | ); 21 | 22 | parameter DISABLE_JTAG = "FALSE"; 23 | parameter integer JTAG_CHAIN = 1; 24 | 25 | pulldown (CAPTURE); 26 | pulldown (DRCK); 27 | pulldown (RESET); 28 | pulldown (RUNTEST); 29 | pulldown (SEL); 30 | pulldown (SHIFT); 31 | pulldown (TCK); 32 | pulldown (TDI); 33 | pulldown (TMS); 34 | pulldown (UPDATE); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /vsrc/vsim_glbl.v: -------------------------------------------------------------------------------- 1 | // $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $ 2 | `ifndef GLBL 3 | `define GLBL 4 | `timescale 1 ps / 1 ps 5 | 6 | module glbl ( // LED and DIP switch 7 | input tms_pad_i, // JTAG test mode select pad 8 | input tck_pad_i, // JTAG test clock pad 9 | input trstn_pad_i, // JTAG test reset pad 10 | input tdi_pad_i, // JTAG test data input pad 11 | output tdo_pad_o, // JTAG test data output pad 12 | output tdo_padoe_o, // Output enable for JTAG test data output pad 13 | output [5:0] latched_jtag_ir, 14 | output [7:0] o_led, 15 | input clk_p, 16 | input rst_top 17 | ); 18 | 19 | parameter ROC_WIDTH = 100000; 20 | parameter TOC_WIDTH = 0; 21 | 22 | // TAP states 23 | wire test_logic_reset_o; 24 | wire run_test_idle_o; 25 | wire shift_dr_o; 26 | wire pause_dr_o; 27 | wire update_dr_o; 28 | wire capture_dr_o; 29 | 30 | // Select signals for boundary scan or mbist 31 | wire extest_select_o; 32 | wire sample_preload_select_o; 33 | wire user1_select_o; 34 | wire user2_select_o; 35 | wire user3_select_o; 36 | wire user4_select_o; 37 | 38 | // TDO signal that is connected to TDI of sub-modules. 39 | wire tdi_o; 40 | 41 | // TDI signals from sub-modules 42 | wire debug_tdo_i; // from debug module 43 | wire bs_chain_tdo_i; // from Boundary Scan Chain 44 | wire user1_tdo_i; // from BSCANE2 Chain 45 | wire user2_tdo_i; // from BSCANE2 Chain 46 | wire user3_tdo_i; // from BSCANE2 Chain 47 | wire user4_tdo_i; // from BSCANE2 Chain 48 | 49 | //-------- STARTUP Globals -------------- 50 | wire GSR; 51 | wire GTS; 52 | wire GWE; 53 | wire PRLD; 54 | tri1 p_up_tmp; 55 | tri PLL_LOCKG = p_up_tmp; 56 | 57 | wire PROGB_GLBL; 58 | wire CCLKO_GLBL; 59 | wire FCSBO_GLBL; 60 | wire [3:0] DO_GLBL; 61 | wire [3:0] DI_GLBL; 62 | 63 | reg GSR_int; 64 | reg GTS_int; 65 | reg PRLD_int; 66 | 67 | //-------- JTAG Globals -------------- 68 | wire JTAG_TCK_GLBL = tck_pad_i; 69 | wire JTAG_TDI_GLBL = tdi_pad_i; 70 | wire JTAG_TMS_GLBL = tms_pad_i; 71 | wire JTAG_TRST_GLBL = !trstn_pad_i; 72 | 73 | wire JTAG_CAPTURE_GLBL = capture_dr_o; 74 | wire JTAG_RESET_GLBL = test_logic_reset_o; 75 | wire JTAG_SHIFT_GLBL = shift_dr_o; 76 | wire JTAG_UPDATE_GLBL = update_dr_o; 77 | wire JTAG_RUNTEST_GLBL = run_test_idle_o; 78 | 79 | wire JTAG_SEL1_GLBL = user1_select_o; 80 | wire JTAG_SEL2_GLBL = user2_select_o; 81 | wire JTAG_SEL3_GLBL = user3_select_o; 82 | wire JTAG_SEL4_GLBL = user4_select_o; 83 | 84 | wire JTAG_TDO_GLBL; 85 | assign tdo_pad_o = JTAG_TDO_GLBL; 86 | 87 | bit JTAG_USER_TDO1_GLBL; 88 | bit JTAG_USER_TDO2_GLBL; 89 | bit JTAG_USER_TDO3_GLBL; 90 | bit JTAG_USER_TDO4_GLBL; 91 | 92 | assign user1_tdo_i = JTAG_USER_TDO1_GLBL; 93 | assign user2_tdo_i = JTAG_USER_TDO2_GLBL; 94 | assign user3_tdo_i = JTAG_USER_TDO3_GLBL; 95 | assign user4_tdo_i = JTAG_USER_TDO4_GLBL; 96 | 97 | assign GSR = GSR_int; 98 | assign GTS = GTS_int; 99 | assign PRLD = PRLD_int; 100 | 101 | initial begin 102 | GSR_int = 1'b1; 103 | PRLD_int = 1'b1; 104 | GSR_int = 1'b0; 105 | PRLD_int = 1'b0; 106 | end 107 | 108 | initial begin 109 | GTS_int = 1'b1; 110 | GTS_int = 1'b0; 111 | end 112 | 113 | JTAGDummy dummy1( 114 | // LED and DIP switch 115 | .o_led(o_led), 116 | .clk_p(clk_p), 117 | .rst_top(rst_top) 118 | ); 119 | 120 | `ifdef TAP1 121 | tap_top tap1 ( 122 | // JTAG pads 123 | .tms_pad_i(tms_pad_i), 124 | .tck_pad_i(tck_pad_i), 125 | .trstn_pad_i(trstn_pad_i), 126 | .tdi_pad_i(tdi_pad_i), 127 | .tdo_pad_o(tdo_pad_o), 128 | .tdo_padoe_o(tdo_padoe_o), 129 | 130 | // TAP states 131 | .test_logic_reset_o(test_logic_reset_o), 132 | .run_test_idle_o(run_test_idle_o), 133 | .shift_dr_o(shift_dr_o), 134 | .pause_dr_o(pause_dr_o), 135 | .update_dr_o(update_dr_o), 136 | .capture_dr_o(capture_dr_o), 137 | 138 | // Select signals for boundary scan or mbist 139 | .extest_select_o(extest_select_o), 140 | .user1_select_o(user1_select_o), 141 | .user2_select_o(user2_select_o), 142 | .user3_select_o(user3_select_o), 143 | .user4_select_o(user4_select_o), 144 | .sample_preload_select_o(sample_preload_select_o), 145 | 146 | // TDO signal that is connected to TDI of sub-modules. 147 | .tdi_o(tdi_o), 148 | 149 | // TDI signals from sub-modules 150 | .user1_tdo_i(user1_tdo_i), // from BSCANE2 module 151 | .user2_tdo_i(user2_tdo_i), // from BSCANE2 module 152 | .user3_tdo_i(user3_tdo_i), // from BSCANE2 module 153 | .user4_tdo_i(user4_tdo_i), // from BSCANE2 module 154 | .bs_chain_tdo_i(bs_chain_tdo_i), // from Boundary Scan Chain 155 | 156 | .latched_jtag_ir(latched_jtag_ir) 157 | ); 158 | `endif 159 | 160 | endmodule 161 | `endif 162 | --------------------------------------------------------------------------------