├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── README.md ├── TODO ├── accelerators ├── DebugAccel │ ├── DebugAccel.bsv │ └── Makefrag ├── Makefile.accelerators └── StrLen │ ├── Makefrag │ └── StrLen.bsv ├── backends ├── connectal │ ├── Makefile │ ├── bsv │ │ ├── ProcConnectal.bsv │ │ └── SharedMemoryBridge.bsv │ ├── cpp │ │ ├── CircularBuffer.hpp │ │ ├── DeviceTree.cpp │ │ ├── DeviceTree.hpp │ │ ├── Devices.hpp │ │ ├── ElfLoader.cpp │ │ ├── ExternalMMIO.cpp │ │ ├── ExternalMMIO.hpp │ │ ├── HostInterface.cpp │ │ ├── HostInterface.hpp │ │ ├── NullTandemVerifier.hpp │ │ ├── Platform.cpp │ │ ├── Platform.hpp │ │ ├── PrintTrace.cpp │ │ ├── PrintTrace.hpp │ │ ├── ProcControl.cpp │ │ ├── ProcControl.hpp │ │ ├── SpikeTandemVerifier.cpp │ │ ├── SpikeTandemVerifier.hpp │ │ ├── TandemVerifier.hpp │ │ ├── UartBridge.cpp │ │ ├── UartBridge.hpp │ │ ├── Verification.cpp │ │ ├── Verification.hpp │ │ └── testproc.cpp │ └── pin_translation.json └── verilator │ ├── Makefile │ ├── bsv │ ├── ProcVerilator.bsv │ └── SimRam.bsv │ └── cpp │ └── verilator_top.cpp ├── codegen └── scripts │ └── meta-parse.py ├── procs ├── RV32IM_3stage │ ├── Core.bsv │ ├── CoreStates.bsv │ ├── ExecStage.bsv │ ├── FetchStage.bsv │ ├── Makefile │ ├── Proc.bsv │ ├── ProcConfig.bsv │ ├── WriteBackStage.bsv │ ├── genhex.sh │ ├── runtest.sh │ └── runtest64.sh ├── RV64G_multicycle │ ├── Core.bsv │ ├── Makefile │ ├── MemorySystem.bsv │ ├── Proc.bsv │ ├── ProcConfig.bsv │ ├── genhex.sh │ └── runtest.sh ├── riscy-lib │ ├── Abstraction.bsv │ ├── BRAMTightlyCoupledMemory.bsv │ ├── BasicMemorySystemBlocks.bsv │ ├── Bht.bsv │ ├── BootRom.bsv │ ├── BramIDMem.bsv │ ├── Btb.bsv │ ├── DCache.bsv │ ├── MainMemoryArbiter.bsv │ ├── MemoryMappedCSRs.bsv │ ├── Opcodes.bsv │ ├── Opcodes.defines │ ├── Prefetcher.bsv │ ├── ProcPins.bsv │ ├── RTC.bsv │ ├── RVAlu.bsv │ ├── RVAmo.bsv │ ├── RVControl.bsv │ ├── RVCsrFile.bsv │ ├── RVCsrFileMCU.bsv │ ├── RVDecode.bsv │ ├── RVExec.bsv │ ├── RVFpu.bsv │ ├── RVMemory.bsv │ ├── RVMulDiv.bsv │ ├── RVRegFile.bsv │ ├── RVSPI.bsv │ ├── RVTypes.bsv │ ├── RVUart.bsv │ ├── Ras.bsv │ ├── SPI.bsv │ ├── Scoreboard.bsv │ ├── TlbStorage.bsv │ ├── VerificationPacket.bsv │ └── VerificationPacketFilter.bsv └── scripts │ ├── isatest.sh │ └── stylecheck.py ├── setup.sh └── tools ├── build.sh └── elf2hex ├── ElfFile.cpp ├── ElfFile.hpp ├── Makefile └── elf2hex.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled toolchains 2 | /tools/RV* 3 | 4 | # generated directories and files 5 | verilator 6 | !/backends/verilator 7 | accelerator 8 | !/accelerator 9 | build 10 | out 11 | /tools/elf2hex/elf2hex 12 | *.exe 13 | generatedDesignInterfaceFile.json 14 | 15 | # hex files 16 | *.hex 17 | 18 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "buildcache"] 2 | path = buildcache 3 | url = https://github.com/cambridgehackers/buildcache.git 4 | [submodule "connectal"] 5 | path = connectal 6 | url = https://github.com/csail-csg/connectal.git 7 | [submodule "codegen/riscv-meta"] 8 | path = codegen/riscv-meta 9 | url = https://github.com/csail-csg/riscv-meta.git 10 | [submodule "recycle-bsv-lib"] 11 | path = recycle-bsv-lib 12 | url = https://github.com/csail-csg/recycle-bsv-lib.git 13 | [submodule "fpgamake"] 14 | path = fpgamake 15 | url = https://github.com/cambridgehackers/fpgamake.git 16 | [submodule "tools/riscv-gnu-toolchain"] 17 | path = tools/riscv-gnu-toolchain 18 | url = https://github.com/riscv/riscv-gnu-toolchain.git 19 | [submodule "tools/riscv-tests"] 20 | path = tools/riscv-tests 21 | url = https://github.com/csail-csg/riscv-tests.git 22 | [submodule "tools/riscv-isa-sim"] 23 | path = tools/riscv-isa-sim 24 | url = https://github.com/csail-csg/riscv-isa-sim.git 25 | [submodule "tools/riscv-fesvr"] 26 | path = tools/riscv-fesvr 27 | url = https://github.com/csail-csg/riscv-fesvr.git 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | cache: 3 | directories: 4 | env: 5 | global: 6 | # Bluespec 7 | - BLUESPECDIR=$PWD/Bluespec-2016.07.beta1/lib 8 | - PATH=$PATH:$PWD/Bluespec-2016.07.beta1/bin:$PWD/verilator/bin 9 | - LD_LIBRARY_PATH=$PWD/lib 10 | matrix: 11 | - TRAVIS_PROC=RV64G_multicycle TRAVIS_ISA_SIZE=64 12 | - TRAVIS_PROC=RV32IM_3stage TRAVIS_ISA_SIZE=32 13 | before_script: 14 | # get all submodules 15 | - git submodule update --init --recursive 16 | # build riscv-tools 17 | # - mkdir -p $RISCV 18 | # - export CXX=g++-4.8 CC=gcc-4.8 19 | # - cd tools 20 | # - travis_wait 45 ./build.sh 21 | # - cd .. 22 | # download pre-compiled tests 23 | # download and install bluespec 24 | - if [ -d Bluespec-2016.07.beta1 ] ; then echo bluespec cached; else curl http://buildbot.connectal.org/downloads/Bluespec-2016.07.beta1.tar.gz | tar -zxf - ; fi 25 | - mkdir -p lib 26 | - ln -s /usr/lib/x86_64-linux-gnu/libgmp.so.10 lib/libgmp.so.3 27 | # download and install verilator 28 | - curl -L http://www.veripool.org/ftp/verilator-3.888.tgz | tar -zxf - ; cd verilator-3.888/ ; ./configure --prefix=`dirname $PWD`/verilator ; make -j3 ; make install ; cd .. 29 | # download and install ply 30 | - curl http://www.dabeaz.com/ply/ply-3.9.tar.gz | tar -zxf - 31 | - ln -s ../ply-3.9/ply connectal/scripts 32 | - ls -l connectal/scripts/ply 33 | script: 34 | # download pre-compiled tests 35 | - cd tools ; curl http://csg.csail.mit.edu/riscy-e/data/RV${TRAVIS_ISA_SIZE}G.tar.gz | tar -zxf - ; cd .. 36 | - . setup.sh RV${TRAVIS_ISA_SIZE}G 37 | - cd $RISCY_HOME/procs/$TRAVIS_PROC && make verilator && ./runtest.sh 1 0 38 | sudo: no 39 | dist: trusty 40 | os: 41 | - linux 42 | addons: 43 | apt: 44 | sources: 45 | - ubuntu-toolchain-r-test 46 | packages: 47 | # riscv-tools 48 | - gcc-4.8 49 | - g++-4.8 50 | - gperf 51 | - autoconf 52 | - automake 53 | - autotools-dev 54 | - libmpc-dev 55 | - libmpfr-dev 56 | - libgmp-dev 57 | - gawk 58 | - build-essential 59 | - bison 60 | - flex 61 | - texinfo 62 | # connectal 63 | - python-dev 64 | - python-ply 65 | - libjsoncpp-dev 66 | # bsc 67 | - libgmp10 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Massachusetts Institute of Technology 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, copy, 7 | modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 18 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 19 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Riscy Processors - Open-Sourced RISC-V Processors 2 | ================================================= 3 | 4 | This repository contains a collection of open-sourced RISC-V processors written in Bluespec System Verilog (BSV). 5 | 6 | These processors can be built with a variety of backends to use the processors in different simulation frameworks or FPGA. 7 | Currently the supported backends are Connectal and Verilator. 8 | Connectal is a generic framework that supports a variety of FPGAs and simulation targets. 9 | 10 | ## Getting Started 11 | 12 | How to get started with this repository (tested in Ubuntu 14.04): 13 | 14 | 1. Get all the submodules. 15 | 16 | $ git submodule update --init --recursive 17 | 18 | 2. Get dependencies for building the RISC-V toolchain and building using connectal. 19 | 20 | $ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc python-ply 21 | 22 | 3. Build riscv-gnu-toolchain and riscv-tests. 23 | `build.sh` can be used to build custom toolchains by passing the desired RISC-V ISA string in all caps (eg: `./build.sh RV32IMC"). 24 | By default, `build.sh` builds the toolchain `tools/RV64G`. 25 | 26 | $ cd tools 27 | $ ./build.sh 28 | $ cd .. 29 | 30 | 4. Setup environment variables for the Riscy project. 31 | You should either use this script from the top-level directory of the Riscy repository, or you should change the variable `RISCY_HOME` in the script to be the path to the Riscy repository. 32 | 33 | $ source ./setup.sh 34 | 35 | 5. Get a newer version of Verilator. 36 | The version of Verilator in the Ubuntu package has a bug that prevents running our BSV designs. 37 | We use a PPA to provide a newer version of Verilator. 38 | 39 | $ sudo apt-add-repository -y ppa:jamey-hicks/connectal 40 | $ sudo apt-get update 41 | $ sudo apt-get install verilator 42 | 43 | 7. Build the multicycle processor using the connectal backend with its verilator target. 44 | 45 | $ cd procs/RV64G_multicycle 46 | $ make build.verilator 47 | 48 | 8. Simulate tests by running `./runtests.sh` and then select the `connectal (verilator)` backend and which tests to run 49 | 50 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | What do we need to do: 2 | 3 | * Clean up when statements. They are not used in an intuitive way, they are 4 | just used to add guards that depend on values from action value methods. 5 | * Don't use FIFOF if we don't need to 6 | * [bug] htifStall causes a problem with typing and printing at the same time 7 | * Perf counters: 8 | - Add perf counters in a clean way 9 | - Link performance counter txt file with android.exe so you don't have to 10 | copy over the txt file to the FPGA 11 | * Figure out if this notation can be legal: 12 | - let {addr: .phyPc, exception: .exMMU} = mmuResp.first; 13 | * Cleanup BSV source (lib, etc.) 14 | - Use Fence interface even if not necessary 15 | - Redo CSRF Interface 16 | - Rely on [riscv-opcodes] or [riscv-meta] more 17 | - Performance Counters 18 | * Improve Spike's HTIF for tandem verification 19 | - Console input doesn't stay synchronized. 20 | * [procs] Make stop interface method send a "stopped" verification packet 21 | -------------------------------------------------------------------------------- /accelerators/DebugAccel/DebugAccel.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import FIFO::*; 25 | import Vector::*; 26 | 27 | interface DebugAccelRequest; 28 | method Action printChar(Bit#(8) x); 29 | endinterface 30 | 31 | interface DebugAccelPins; 32 | method ActionValue#(Bit#(8)) charOut; 33 | endinterface 34 | 35 | interface DebugAccel; 36 | interface DebugAccelRequest debugAccelRequest; 37 | // interface DebugAccelPins debugAccelPins; 38 | endinterface 39 | 40 | module mkDebugAccel(DebugAccel); 41 | Reg#(Maybe#(Bit#(8))) lastChar <- mkReg(tagged Invalid); 42 | 43 | interface DebugAccelRequest debugAccelRequest; 44 | method Action printChar(Bit#(8) x); 45 | $fwrite(stderr, "%c", x); 46 | $fflush(stderr); 47 | lastChar <= tagged Valid x; 48 | endmethod 49 | endinterface 50 | 51 | // interface DebugAccelPins debugAccelPins; 52 | // method ActionValue#(Bit#(8)) charOut if (lastChar matches tagged Valid .c); 53 | // lastChar <= tagged Invalid; 54 | // return c; 55 | // endmethod 56 | // endinterface 57 | endmodule 58 | -------------------------------------------------------------------------------- /accelerators/DebugAccel/Makefrag: -------------------------------------------------------------------------------- 1 | ACCEL_BSVPATH += \ 2 | $(RISCY_HOME)/accelerators/DebugAccel \ 3 | 4 | ACCEL_BSVFILES += \ 5 | $(RISCY_HOME)/accelerators/DebugAccel/DebugAccel.bsv \ 6 | 7 | ACCEL_S2H_INTERFACES += \ 8 | DebugAccelRequest:DebugAccel.debugAccelRequest \ 9 | 10 | ACCEL_H2S_INTERFACES += \ 11 | 12 | #ACCEL_PINS_TYPES += \ 13 | # DebugAccelPins \ 14 | # 15 | #ACCEL_PINS_INTERFACES += \ 16 | # pins:DebugAccel.debugAccelPins \ 17 | 18 | -------------------------------------------------------------------------------- /accelerators/Makefile.accelerators: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, copy, 8 | # modify, merge, publish, distribute, sublicense, and/or sell copies 9 | # of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | ifndef RISCY_HOME 25 | $(error RISCY_HOME is not set) 26 | endif 27 | ifndef ACCELERATORS 28 | $(error ACCELERATORS is not set) 29 | endif 30 | 31 | CONNECTALDIR ?= $(RISCY_HOME)/connectal 32 | 33 | ifndef ACCEL_PROJECTDIR 34 | ifndef PROC 35 | $(error Either PROJECTDIR or PROC needs to be set) 36 | endif 37 | ACCEL_PROJECTDIR ?= $(RISCY_HOME)/procs/$(PROC)/accelerator 38 | endif 39 | 40 | include $(foreach f, $(ACCELERATORS), $(RISCY_HOME)/accelerators/$f/Makefrag) 41 | 42 | prebuild:: 43 | $(CONNECTALDIR)/scripts/topgen.py \ 44 | --project-dir $(ACCEL_PROJECTDIR)/generatedbsv \ 45 | --filename 'AccelTop.bsv' \ 46 | --topname mkAccelTop \ 47 | --ifcnames 'AccelIfcNames' \ 48 | $(foreach f, $(ACCEL_S2H_INTERFACES), --wrapper $f) \ 49 | $(foreach f, $(ACCEL_H2S_INTERFACES), --proxy $f) \ 50 | $(foreach f, $(ACCEL_PINS_TYPES), --pintype $f) \ 51 | $(foreach f, $(ACCEL_PINS_INTERFACES), --interface $f) 52 | $(CONNECTALDIR)/scripts/makefilegen.py \ 53 | -B$(BOARD) \ 54 | --project-dir $(ACCEL_PROJECTDIR) \ 55 | $(foreach f, $(ACCEL_S2H_INTERFACES), -interfaces $(word 1, $(subst /,, $(subst :, , $f)))) \ 56 | $(foreach f, $(ACCEL_H2S_INTERFACES), $(foreach g, $(subst $(comma), , $(word 2, $(subst :, , $f))), -interfaces $g)) \ 57 | $(foreach f, $(ACCEL_CPPFILES), --source $f) \ 58 | $(foreach f, $(ACCEL_BSVPATH), --bsvpath $f) \ 59 | $(CONNECTALFLAGS) \ 60 | $(ACCEL_BSVFILES) 61 | DTOP=$(ACCEL_PROJECTDIR) BSVPATH=$(RISCY_HOME)/procs $(CONNECTALDIR)/scripts/syntax.py $(ACCEL_BSVFILES) 62 | -make -C $(ACCEL_PROJECTDIR) 63 | 64 | -------------------------------------------------------------------------------- /accelerators/StrLen/Makefrag: -------------------------------------------------------------------------------- 1 | ACCEL_BSVPATH += \ 2 | $(RISCY_HOME)/accelerators/StrLen \ 3 | 4 | ACCEL_BSVFILES += \ 5 | $(RISCY_HOME)/accelerators/StrLen/StrLen.bsv \ 6 | 7 | ACCEL_S2H_INTERFACES += \ 8 | StrLenRequest:StrLen.strLenRequest \ 9 | 10 | ACCEL_H2S_INTERFACES += \ 11 | StrLen:StrLenIndication \ 12 | 13 | ACCEL_PINS_TYPES += \ 14 | StrLenPins \ 15 | 16 | ACCEL_PINS_INTERFACES += \ 17 | pins:StrLen.strLenPins \ 18 | 19 | CONNECTALFLAGS += -D CONFIG_STR_LEN_PINS 20 | 21 | -------------------------------------------------------------------------------- /accelerators/StrLen/StrLen.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import FIFO::*; 25 | import Vector::*; 26 | 27 | interface StrLenRequest; 28 | // x is the address of the c string 29 | method Action request(Bit#(64) x); 30 | endinterface 31 | 32 | interface StrLenIndication; 33 | // returns the length of the c string 34 | method Action response(Bit#(32) x); 35 | endinterface 36 | 37 | interface StrLenPins; 38 | method ActionValue#(Bit#(64)) readReq; 39 | method Action readData(Bit#(64) x); 40 | endinterface 41 | 42 | interface StrLenAccelerator; 43 | interface StrLenRequest strLenRequest; 44 | interface StrLenPins strLenPins; 45 | endinterface 46 | 47 | module mkStrLen#(StrLenIndication strLenIndication)(StrLenAccelerator); 48 | FIFO#(Bit#(64)) requestFIFO <- mkFIFO; 49 | FIFO#(Bit#(64)) responseFIFO <- mkFIFO; 50 | 51 | Reg#(Bool) running <- mkReg(False); 52 | Reg#(Bit#(64)) reqAddr <- mkReg(0); 53 | Reg#(Bit#(64)) respAddr <- mkReg(0); 54 | Reg#(Bit#(32)) count <- mkReg(0); 55 | 56 | rule strLenReqStep(running); 57 | // send a request 58 | let alignedReqAddr = reqAddr & ~'h07; 59 | requestFIFO.enq(alignedReqAddr); 60 | // and increment 61 | reqAddr <= alignedReqAddr + 8; 62 | endrule 63 | rule strLenRespStep(running); 64 | // get a response 65 | let data = responseFIFO.first; 66 | responseFIFO.deq; 67 | 68 | Vector#(8, Bit#(8)) bytes = unpack(data); 69 | let alignment = respAddr & 'h07; 70 | function Bool eqZero(Bit#(8) x); 71 | return x == 0; 72 | endfunction 73 | Vector#(8, Bool) zeroBytes = map( eqZero, bytes ); 74 | // Vector#(8, Bool) zeroBytes = map( \== (0), bytes ); 75 | Vector#(8, Bool) bytesInRange = unpack('1 << alignment[2:0]); 76 | function Bool boolAnd(Bool x, Bool y); 77 | return x && y; 78 | endfunction 79 | Bit#(8) zeroBytesToCount = pack(zipWith( boolAnd, zeroBytes, bytesInRange)); 80 | // Bit#(8) zeroBytesToCount = pack(zipWith( \&& , zeroBytes, bytesInRange)); 81 | Integer newBytes = (case (zeroBytesToCount) matches 82 | 8'b00000000: 8; 83 | 8'b10000000: 7; 84 | 8'b?1000000: 6; 85 | 8'b??100000: 5; 86 | 8'b???10000: 4; 87 | 8'b????1000: 3; 88 | 8'b?????100: 2; 89 | 8'b??????10: 1; 90 | 8'b???????1: 0; 91 | endcase); 92 | let newCount = count + fromInteger(newBytes) - truncate(alignment); 93 | count <= newCount; 94 | respAddr <= (respAddr & ~'h07) + 8; 95 | if (newBytes != 8) begin 96 | running <= False; 97 | strLenIndication.response(newCount); 98 | end 99 | endrule 100 | rule strLenRespDrain(!running); 101 | respAddr <= (respAddr & ~'h07) + 8; 102 | responseFIFO.deq; 103 | endrule 104 | 105 | interface StrLenRequest strLenRequest; 106 | method Action request(Bit#(64) x) if (!running && (reqAddr == respAddr)); 107 | respAddr <= x; 108 | reqAddr <= x; 109 | running <= True; 110 | count <= 0; 111 | endmethod 112 | endinterface 113 | 114 | interface StrLenPins strLenPins; 115 | method ActionValue#(Bit#(64)) readReq; 116 | requestFIFO.deq; 117 | return requestFIFO.first; 118 | endmethod 119 | method Action readData(Bit#(64) x); 120 | responseFIFO.enq(x); 121 | endmethod 122 | endinterface 123 | endmodule 124 | -------------------------------------------------------------------------------- /backends/connectal/cpp/CircularBuffer.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef CIRCULAR_BUFFER_HPP 25 | #define CIRCULAR_BUFFER_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | class CircularBuffer { 34 | public: 35 | CircularBuffer(size_t maxSizeIn) : maxSize(maxSizeIn), entriesToPrint(0), ostreamForPrinting(NULL), data(), firstEntry(true) {} 36 | 37 | void addLine(std::string stringIn) { 38 | // compute timeDiff and update prevTime 39 | time_t timeDiff; 40 | time_t currTime; 41 | time(&currTime); 42 | if (!firstEntry) { 43 | timeDiff = currTime - prevTime; 44 | } else { 45 | timeDiff = 0; 46 | firstEntry = false; 47 | } 48 | prevTime = currTime; 49 | 50 | // Add a line to the string when a significant amount of time has 51 | // elapsed. 52 | std::ostringstream buffer; 53 | if (timeDiff > timeThreshold) { 54 | buffer << "[" << std::dec << timeDiff << " seconds elapsed]" << std::endl; 55 | } 56 | buffer << stringIn; 57 | 58 | // Either print the string or add it to a buffer 59 | if (entriesToPrint > 0) { 60 | (*ostreamForPrinting) << buffer.str() << std::endl; 61 | entriesToPrint--; 62 | } else { 63 | data.push_back(buffer.str()); 64 | if (data.size() > maxSize) { 65 | data.pop_front(); 66 | } 67 | } 68 | } 69 | 70 | void printToOStream(std::ostream * o, size_t extraEntriesToPrint) { 71 | // compute timeDiff and update prevTime (if firstEntry == false) 72 | time_t currTime; 73 | time_t timeDiff; 74 | time(&currTime); 75 | if (!firstEntry) { 76 | timeDiff = currTime - prevTime; 77 | prevTime = currTime; 78 | } else { 79 | timeDiff = 0; 80 | } 81 | // if this is the first entry, nothing will be done 82 | 83 | // dump the current circular buffer 84 | while (data.size() > 0) { 85 | (*o) << data.front() << std::endl; 86 | data.pop_front(); 87 | } 88 | if (timeDiff > timeThreshold) { 89 | (*o) << "[" << std::dec << timeDiff << " seconds elapsed]" << std::endl; 90 | } 91 | 92 | // if extraEntriesToPrint > 0, then future lines will be printed 93 | // as they are added 94 | ostreamForPrinting = o; 95 | entriesToPrint = extraEntriesToPrint; 96 | } 97 | 98 | private: 99 | size_t maxSize; 100 | size_t entriesToPrint; 101 | std::ostream *ostreamForPrinting; 102 | std::list data; 103 | bool firstEntry; 104 | time_t prevTime; 105 | 106 | const time_t timeThreshold = 3; 107 | }; 108 | #endif 109 | -------------------------------------------------------------------------------- /backends/connectal/cpp/DeviceTree.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | #include 26 | #include "fesvr/htif.h" 27 | #include "spike/devicetree.h" 28 | #include "DeviceTree.hpp" 29 | 30 | // This function makes a device tree that matches spike 31 | 32 | // temporary define 33 | #define NCSR 4096 34 | 35 | std::vector makeDeviceTree(size_t memSz, unsigned int numProcs, std::string isa) { 36 | char buf[32]; 37 | size_t max_devtree_size = numProcs * 4096; // sloppy upper bound 38 | size_t cpu_size = NCSR * 64 / 8; // this assumes RV64 39 | reg_t cpu_addr = memSz + max_devtree_size; 40 | 41 | device_tree dt; 42 | dt.begin_node(""); 43 | dt.add_prop("#address-cells", 2); 44 | dt.add_prop("#size-cells", 2); 45 | dt.add_prop("model", "Spike"); 46 | dt.begin_node("memory@0"); 47 | dt.add_prop("device_type", "memory"); 48 | dt.add_reg({0, memSz}); 49 | dt.end_node(); 50 | dt.begin_node("cpus"); 51 | dt.add_prop("#address-cells", 2); 52 | dt.add_prop("#size-cells", 2); 53 | for (size_t i = 0; i < numProcs; i++) { 54 | sprintf(buf, "cpu@%" PRIx64, cpu_addr); 55 | dt.begin_node(buf); 56 | dt.add_prop("device_type", "cpu"); 57 | dt.add_prop("compatible", "riscv"); 58 | dt.add_prop("isa", isa); 59 | dt.add_reg({cpu_addr}); 60 | dt.end_node(); 61 | 62 | // bus.add_device(cpu_addr, procs[i]); 63 | cpu_addr += cpu_size; 64 | } 65 | dt.end_node(); 66 | dt.end_node(); 67 | 68 | return dt.finalize(); 69 | } 70 | -------------------------------------------------------------------------------- /backends/connectal/cpp/DeviceTree.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef DEVICE_TREE_HPP 25 | #define DEVICE_TREE_HPP 26 | 27 | #include 28 | #include 29 | 30 | // This function makes a device tree that matches spike 31 | std::vector makeDeviceTree(size_t memSz, unsigned int numProcs, std::string isa); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /backends/connectal/cpp/Devices.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVICES_HPP 2 | #define DEVICES_HPP 3 | 4 | #include 5 | 6 | #include "spike/devices.h" 7 | 8 | class emulated_uart_t : public abstract_device_t { 9 | public: 10 | bool load(reg_t addr, size_t len, uint8_t* bytes) { 11 | return false; 12 | } 13 | bool store(reg_t addr, size_t len, const uint8_t* bytes) { 14 | // if (addr == 0x40000020) { 15 | if (addr == 0x20) { 16 | std::cout << (char) bytes[0]; 17 | return true; 18 | } 19 | return false; 20 | } 21 | }; 22 | 23 | class exit_code_reg_t : public abstract_device_t { 24 | public: 25 | exit_code_reg_t() { 26 | sem_init(&writeSem, 0, 0); 27 | } 28 | ~exit_code_reg_t() { 29 | sem_destroy(&writeSem); 30 | } 31 | bool load(reg_t addr, size_t len, uint8_t* bytes) { 32 | return false; 33 | } 34 | bool store(reg_t addr, size_t len, const uint8_t* bytes) { 35 | if (addr == 0x00) { 36 | // cap len at 8 otherwise memcpy will overflow uint64_t 37 | if (len > 8) { 38 | len = 8; 39 | } 40 | exit_code = 0; 41 | memcpy((void *) &exit_code, (const void*) bytes, len); 42 | sem_post(&writeSem); 43 | return true; 44 | } else { 45 | return false; 46 | } 47 | } 48 | uint64_t wait_for_exit_code() { 49 | sem_wait(&writeSem); 50 | return exit_code; 51 | } 52 | private: 53 | sem_t writeSem; 54 | uint64_t exit_code; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /backends/connectal/cpp/ElfLoader.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "Platform.hpp" 30 | 31 | template 32 | bool Platform::load_elf_specific(char* buf, size_t buf_sz) { 33 | // 64-bit ELF 34 | Elf_Ehdr *ehdr = (Elf_Ehdr*) buf; 35 | Elf_Phdr *phdr = (Elf_Phdr*) (buf + ehdr->e_phoff); 36 | if (buf_sz < ehdr->e_phoff + ehdr->e_phnum * sizeof(Elf_Phdr)) { 37 | std::cerr << "ERROR: load_elf: file too small for expected number of program header tables" << std::endl; 38 | return false; 39 | } 40 | // loop through program header tables 41 | for (int i = 0 ; i < ehdr->e_phnum ; i++) { 42 | if ((phdr[i].p_type == PT_LOAD) && (phdr[i].p_memsz > 0)) { 43 | if (phdr[i].p_memsz < phdr[i].p_filesz) { 44 | std::cerr << "ERROR: load_elf: file size is larger than memory size" << std::endl; 45 | return false; 46 | } 47 | if (phdr[i].p_filesz > 0) { 48 | if (phdr[i].p_offset + phdr[i].p_filesz > buf_sz) { 49 | std::cerr << "ERROR: load_elf: file section overflow" << std::endl; 50 | return false; 51 | } 52 | // start of file section: buf + phdr[i].p_offset 53 | // end of file section: buf + phdr[i].p_offset + phdr[i].p_filesz 54 | // start of memory: phdr[i].p_paddr 55 | this->write_chunk( phdr[i].p_paddr, phdr[i].p_filesz, buf + phdr[i].p_offset ); 56 | } 57 | if (phdr[i].p_memsz > phdr[i].p_filesz) { 58 | // copy 0's to fill up remaining memory 59 | size_t zeros_sz = phdr[i].p_memsz - phdr[i].p_filesz; 60 | char* zeros = new char[zeros_sz]; 61 | memset( (void *) zeros, 0, zeros_sz ); 62 | this->write_chunk( phdr[i].p_paddr + phdr[i].p_filesz, phdr[i].p_memsz - phdr[i].p_filesz, zeros ); 63 | delete[] zeros; 64 | } 65 | } 66 | } 67 | return true; 68 | } 69 | 70 | bool Platform::load_elf(const char* elf_filename) { 71 | std::ifstream elffile; 72 | elffile.open(elf_filename, std::ios::in | std::ios::binary); 73 | 74 | if (!elffile.is_open()) { 75 | std::cerr << "ERROR: load_elf: failed opening file \"" << elf_filename << "\"" << std::endl; 76 | return false; 77 | } 78 | 79 | elffile.seekg(0, elffile.end); 80 | size_t buf_sz = elffile.tellg(); 81 | elffile.seekg(0, elffile.beg); 82 | 83 | // Read the entire file. If it doesn't fit in host memory, it won't fit in the risc-v processor 84 | char* buf = new char[buf_sz]; 85 | elffile.read(buf, buf_sz); 86 | 87 | if (!elffile) { 88 | std::cerr << "ERROR: load_elf: failed reading elf header" << std::endl; 89 | return false; 90 | } 91 | 92 | if (buf_sz < sizeof(Elf32_Ehdr)) { 93 | std::cerr << "ERROR: load_elf: file too small to be a valid elf file" << std::endl; 94 | return false; 95 | } 96 | 97 | // make sure the header matches elf32 or elf64 98 | Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buf; 99 | unsigned char* e_ident = ehdr->e_ident; 100 | if (e_ident[EI_MAG0] != ELFMAG0 101 | || e_ident[EI_MAG1] != ELFMAG1 102 | || e_ident[EI_MAG2] != ELFMAG2 103 | || e_ident[EI_MAG3] != ELFMAG3) { 104 | std::cerr << "ERROR: load_elf: file is not an elf file" << std::endl; 105 | return false; 106 | } 107 | 108 | if (e_ident[EI_CLASS] == ELFCLASS32) { 109 | // 32-bit ELF 110 | return this->load_elf_specific(buf, buf_sz); 111 | } else if (e_ident[EI_CLASS] == ELFCLASS64) { 112 | // 64-bit ELF 113 | return this->load_elf_specific(buf, buf_sz); 114 | } else { 115 | std::cerr << "ERROR: load_elf: file is neither 32-bit nor 64-bit" << std::endl; 116 | return false; 117 | } 118 | } 119 | 120 | -------------------------------------------------------------------------------- /backends/connectal/cpp/ExternalMMIO.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | #include "ExternalMMIO.hpp" 26 | 27 | ExternalMMIO::ExternalMMIO(unsigned int requestId, unsigned int responseId) : ExternalMMIORequestWrapper(requestId) { 28 | externalMMIOResponse = new ExternalMMIOResponseProxy(responseId); 29 | pthread_mutex_init(&mutex, 0); 30 | } 31 | 32 | void ExternalMMIO::addDevice(const uint64_t addr, abstract_device_t* device) { 33 | bus.add_device((reg_t) addr, device); 34 | } 35 | 36 | void ExternalMMIO::triggerInterrupt() { 37 | externalMMIOResponse->triggerExternalInterrupt(); 38 | } 39 | 40 | void ExternalMMIO::request(const int write, const uint64_t addr, const uint64_t data) { 41 | // get mutex 42 | pthread_mutex_lock(&mutex); 43 | // forward request to device 44 | uint64_t respData = 0; 45 | bool success = false; 46 | if (write == 0) { 47 | #ifdef CONFIG_RV64 48 | success = bus.load((reg_t) addr, 8, (uint8_t*) &respData); 49 | #else 50 | success = bus.load((reg_t) addr, 4, (uint8_t*) &respData); 51 | #endif 52 | } else { 53 | #ifdef CONFIG_RV64 54 | success = bus.store((reg_t) addr, 8, (uint8_t*) &data); 55 | #else 56 | success = bus.store((reg_t) addr, 4, (uint8_t*) &data); 57 | #endif 58 | } 59 | if (!success) { 60 | if (write == 0) { 61 | std::cerr << "[ERROR] MMIO read failed, addr = 0x" << std::hex << addr << std::endl; 62 | } else { 63 | std::cerr << "[ERROR] MMIO write failed, addr = 0x" << std::hex << addr << ", data = 0x" << std::hex << data << std::endl; 64 | } 65 | } 66 | // forward response to processor 67 | externalMMIOResponse->response(write, respData); 68 | // release mutex 69 | pthread_mutex_unlock(&mutex); 70 | } 71 | -------------------------------------------------------------------------------- /backends/connectal/cpp/ExternalMMIO.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef EXTERNAL_MMIO_HPP 25 | #define EXTERNAL_MMIO_HPP 26 | 27 | #include 28 | #include "ExternalMMIORequest.h" 29 | #include "ExternalMMIOResponse.h" 30 | #include "GeneratedTypes.h" 31 | #include "spike/devices.h" 32 | 33 | class ExternalMMIO : public ExternalMMIORequestWrapper { 34 | public: 35 | ExternalMMIO(unsigned int requestId, unsigned int responseId); 36 | ~ExternalMMIO(); 37 | 38 | void addDevice(const uint64_t addr, abstract_device_t* device); 39 | void triggerInterrupt(); 40 | 41 | private: 42 | void request(const int write, const uint64_t addr, const uint64_t data); 43 | 44 | ExternalMMIOResponseProxy *externalMMIOResponse; 45 | bus_t bus; 46 | pthread_mutex_t mutex; 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /backends/connectal/cpp/HostInterface.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "HostInterface.hpp" 25 | 26 | HostInterface::HostInterface(unsigned int indicationId, unsigned int requestId) : HostInterfaceIndicationWrapper(indicationId) { 27 | hostInterfaceRequest = new HostInterfaceRequestProxy(requestId); 28 | pthread_mutex_init(&mutex, 0); 29 | } 30 | 31 | HostInterface::~HostInterface() { 32 | pthread_mutex_lock(&mutex); 33 | pthread_mutex_destroy(&mutex); 34 | delete hostInterfaceRequest; 35 | } 36 | 37 | void HostInterface::toHost(const uint64_t v) { 38 | // enqueue v to the toHostMessages queue 39 | // fprintf(stderr, "%s:%d HostInterface::toHost(%d) starting\n", __FILE__, __LINE__, (int) v); 40 | pthread_mutex_lock(&mutex); 41 | toHostMessages.push(v); 42 | pthread_mutex_unlock(&mutex); 43 | // fprintf(stderr, "%s:%d HostInterface::toHost(%d) finishing\n", __FILE__, __LINE__, (int) v); 44 | } 45 | 46 | bool HostInterface::getToHostMessage(uint64_t *msg) { 47 | // try to dequeue a message from the toHostMessages queue 48 | // fprintf(stderr, "%s:%d HostInterface::getToHostMessage starting\n", __FILE__, __LINE__); 49 | bool foundMsg = false; 50 | pthread_mutex_lock(&mutex); 51 | if (!toHostMessages.empty()) { 52 | foundMsg = true; 53 | *msg = toHostMessages.front(); 54 | toHostMessages.pop(); 55 | } else { 56 | // default tohost value is 0 57 | *msg = 0; 58 | } 59 | pthread_mutex_unlock(&mutex); 60 | /* 61 | if (foundMsg) { 62 | fprintf(stderr, "%s:%d HostInterface::getToHostMessage finished, msg = %d\n", __FILE__, __LINE__, (int) *msg); 63 | } else { 64 | fprintf(stderr, "%s:%d HostInterface::getToHostMessage finished, no msg found\n", __FILE__, __LINE__); 65 | } 66 | */ 67 | return foundMsg; 68 | } 69 | 70 | void HostInterface::putFromHostMessage(uint64_t msg) { 71 | // fprintf(stderr, "%s:%d HostInterface::gromHostMessage(%d)\n", __FILE__, __LINE__, (int) msg); 72 | hostInterfaceRequest->fromHost(msg); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /backends/connectal/cpp/HostInterface.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef HOST_INTERFACE_HPP 25 | #define HOST_INTERFACE_HPP 26 | 27 | #include 28 | #include 29 | #include "HostInterfaceIndication.h" 30 | #include "HostInterfaceRequest.h" 31 | #include "GeneratedTypes.h" 32 | 33 | class HostInterface : public HostInterfaceIndicationWrapper { 34 | public: 35 | HostInterface(unsigned int indicationId, unsigned int requestId); 36 | ~HostInterface(); 37 | 38 | // called by HostInterfaceIndication thread 39 | void toHost(const uint64_t v); 40 | 41 | // called by the main thread to access tohost/fromhost 42 | bool getToHostMessage(uint64_t *msg); 43 | void putFromHostMessage(uint64_t msg); 44 | 45 | private: 46 | // only used by main thread 47 | HostInterfaceRequestProxy *hostInterfaceRequest; 48 | 49 | // used by both threads 50 | std::queue toHostMessages; 51 | pthread_mutex_t mutex; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /backends/connectal/cpp/NullTandemVerifier.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef NULL_TANDEM_VERIFIER_HPP 25 | #define NULL_TANDEM_VERIFIER_HPP 26 | 27 | #include 28 | #include 29 | #include "CircularBuffer.hpp" 30 | #include "TandemVerifier.hpp" 31 | 32 | class NullTandemVerifier : public TandemVerifier { 33 | public: 34 | NullTandemVerifier() : TandemVerifier(), outBuffer(40) { 35 | packets = 0; 36 | } 37 | ~NullTandemVerifier() { 38 | } 39 | bool checkVerificationPacket(VerificationPacket p) { 40 | packets++; 41 | lastPc = p.pc; 42 | std::ostringstream buffer; 43 | buffer << "0x" << std::hex << p.pc; 44 | outBuffer.addLine(buffer.str()); 45 | return true; 46 | } 47 | void printStatus() { 48 | fprintf(stderr, "NullTandemVerifier::printStatus() - %llu packets seen. Last pc = 0x%llx\n", (long long unsigned) packets, (long long int) lastPc); 49 | outBuffer.printToOStream(&std::cerr, 0); 50 | } 51 | private: 52 | std::string verificationPacketToString(VerificationPacket p); 53 | CircularBuffer outBuffer; 54 | uint64_t packets; 55 | uint64_t lastPc; 56 | }; 57 | 58 | #endif // TANDEM_VERIFIER_HPP 59 | -------------------------------------------------------------------------------- /backends/connectal/cpp/Platform.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef PLATFORM_HPP 25 | #define PLATFORM_HPP 26 | 27 | #include "DmaBuffer.h" 28 | #include "PlatformIndication.h" 29 | #include "PlatformRequest.h" 30 | #include "GeneratedTypes.h" 31 | 32 | class Platform : PlatformIndicationWrapper { 33 | public: 34 | Platform(unsigned int indicationId, unsigned int requestId, size_t ramBaseAddrIn, size_t ramSzIn); 35 | virtual ~Platform() {} 36 | 37 | virtual void init(); 38 | 39 | bool load_elf(const char* elf_filename); 40 | 41 | // Functions to access the RISC-V's memory 42 | // These either access the memory through shared memory or through 43 | // the external memory interface. 44 | virtual void read_chunk(uint64_t taddr, size_t len, void* dst); 45 | virtual void write_chunk(uint64_t taddr, size_t len, const void* src); 46 | 47 | private: 48 | // Access the RISC-V's memory through the external memory interface 49 | uint64_t memRead(uint64_t addr); 50 | void memWrite(uint64_t addr, uint64_t data); 51 | void read_chunk_extIfc(uint64_t taddr, size_t len, void* dst); 52 | void write_chunk_extIfc(uint64_t taddr, size_t len, const void* src); 53 | 54 | // Read from shared memory 55 | void read_chunk_sharedMem(uint64_t taddr, size_t len, void* dst); 56 | void write_chunk_sharedMem(uint64_t taddr, size_t len, const void* src); 57 | 58 | // called by connectal thread 59 | void memResponse(const int write, const uint64_t data); 60 | 61 | template 62 | bool load_elf_specific(char* buf, size_t buf_sz); 63 | 64 | bool verbose; 65 | 66 | size_t ramBaseAddr; 67 | size_t ramSz; 68 | DmaBuffer ram; 69 | 70 | uint64_t* ramBuffer; 71 | 72 | PlatformRequestProxy *platformRequest; 73 | 74 | // used by both threads 75 | sem_t responseSem; 76 | uint64_t responseData; 77 | }; 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /backends/connectal/cpp/PrintTrace.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef PRINT_TRACE_HPP 25 | #define PRINT_TRACE_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | #include "spike/sim.h" 31 | #include "spike/disasm.h" 32 | #include "CircularBuffer.hpp" 33 | #include "TandemVerifier.hpp" 34 | 35 | class PrintTrace : public TandemVerifier { 36 | public: 37 | PrintTrace(); 38 | ~PrintTrace(); 39 | 40 | // called by VerificationIndication 41 | bool checkVerificationPacket(VerificationPacket p); 42 | 43 | // called by main thread (probably?) 44 | void printStatus(); 45 | 46 | private: 47 | std::string verificationPacketToString(VerificationPacket p); 48 | 49 | disassembler_t *disassembler; 50 | pthread_mutex_t mutex; 51 | 52 | // number of packets seen 53 | unsigned int packets; 54 | 55 | CircularBuffer outBuffer; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /backends/connectal/cpp/ProcControl.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "ProcControl.hpp" 25 | 26 | ProcControl::ProcControl(unsigned int indicationId, unsigned int requestId) : 27 | ProcControlIndicationWrapper(indicationId), 28 | verificationPacketsToIgnore(0), 29 | sendSynchronizationPackets(false) { 30 | procControlRequest = new ProcControlRequestProxy(requestId); 31 | sem_init(&resetSem, 0, 0); 32 | } 33 | 34 | ProcControl::~ProcControl() { 35 | sem_destroy(&resetSem); 36 | delete procControlRequest; 37 | } 38 | 39 | // TODO: only configure the processor in one place 40 | void ProcControl::reset() { 41 | // request for the processor to reset 42 | procControlRequest->reset(); 43 | // wait for reset to finish 44 | sem_wait(&resetSem); 45 | } 46 | 47 | // configure and start 48 | void ProcControl::start(const uint64_t startPc) { 49 | procControlRequest->start(startPc, verificationPacketsToIgnore, (int) sendSynchronizationPackets); 50 | } 51 | 52 | void ProcControl::stop() { 53 | procControlRequest->stop(); 54 | } 55 | 56 | void ProcControl::configureVerificationPackets(const uint64_t verificationPacketsToIgnoreIn, const bool sendSynchronizationPacketsIn) { 57 | verificationPacketsToIgnore = verificationPacketsToIgnoreIn; 58 | sendSynchronizationPackets = sendSynchronizationPacketsIn; 59 | } 60 | 61 | void ProcControl::resetDone() { 62 | // signal that reset is done 63 | sem_post(&resetSem); 64 | } 65 | -------------------------------------------------------------------------------- /backends/connectal/cpp/ProcControl.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef PROC_CONTROL_HPP 25 | #define PROC_CONTROL_HPP 26 | 27 | #include 28 | #include "ProcControlIndication.h" 29 | #include "ProcControlRequest.h" 30 | #include "GeneratedTypes.h" 31 | 32 | class ProcControl : public ProcControlIndicationWrapper { 33 | public: 34 | ProcControl(unsigned int indicationId, unsigned int requestId); 35 | ~ProcControl(); 36 | 37 | // these are called by the main thread 38 | void reset(); 39 | void start(const uint64_t startPc); 40 | void stop(); 41 | void configure(const uint32_t sharedMemRefPointer, const uint64_t externalMMIOBaseAddr); 42 | 43 | // this sets the verification packet settings for the next time start 44 | // is called 45 | void configureVerificationPackets(const uint64_t verificationPacketsToIgnoreIn, const bool sendSynchronizationPacketsIn); 46 | 47 | // called by ProcControlIndication thread 48 | void resetDone(); 49 | 50 | private: 51 | // only used by main thread 52 | ProcControlRequestProxy *procControlRequest; 53 | uint64_t verificationPacketsToIgnore; 54 | bool sendSynchronizationPackets; 55 | 56 | // used by both threads 57 | sem_t resetSem; 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /backends/connectal/cpp/SpikeTandemVerifier.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef SPIKE_TANDEM_VERIFIER_HPP 25 | #define SPIKE_TANDEM_VERIFIER_HPP 26 | 27 | #include 28 | #include 29 | #include 30 | #include "spike/sim.h" 31 | #include "spike/disasm.h" 32 | #include "CircularBuffer.hpp" 33 | #include "TandemVerifier.hpp" 34 | 35 | class SpikeTandemVerifier : public TandemVerifier { 36 | public: 37 | SpikeTandemVerifier(std::vector htifArgsIn, size_t memSzIn); 38 | ~SpikeTandemVerifier(); 39 | 40 | // called by VerificationIndication 41 | bool checkVerificationPacket(VerificationPacket p); 42 | bool shouldAbort(); 43 | 44 | // called by main thread (probably?) 45 | void printStatus(); 46 | 47 | private: 48 | void initSim(); 49 | void synchronize(VerificationPacket p); 50 | VerificationPacket synchronizedSimStep(VerificationPacket p); 51 | bool comparePackets(VerificationPacket procP, VerificationPacket spikeP); 52 | std::string verificationPacketToString(VerificationPacket p); 53 | 54 | std::vector htifArgs; 55 | size_t memSz; 56 | sim_t *sim; 57 | disassembler_t *disassembler; 58 | pthread_mutex_t mutex; 59 | 60 | // number of packets seen 61 | unsigned int packets; 62 | // number of instructions retired 63 | unsigned int instructions; 64 | // if too many errors have been seen 65 | bool abort; 66 | 67 | CircularBuffer outBuffer; 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /backends/connectal/cpp/TandemVerifier.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef TANDEM_VERIFIER_HPP 25 | #define TANDEM_VERIFIER_HPP 26 | 27 | #include "GeneratedTypes.h" 28 | 29 | class TandemVerifier { 30 | public: 31 | TandemVerifier() : errors(0) {} 32 | virtual ~TandemVerifier() {} 33 | virtual bool checkVerificationPacket(VerificationPacket p) { return true; } 34 | virtual void printStatus() {} 35 | virtual unsigned int getNumErrors() { return errors; } 36 | virtual bool shouldAbort() { return false; } 37 | protected: 38 | // number of errors seen 39 | unsigned int errors; 40 | }; 41 | 42 | #endif // TANDEM_VERIFIER_HPP 43 | -------------------------------------------------------------------------------- /backends/connectal/cpp/UartBridge.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "UartBridge.hpp" 25 | 26 | UartBridge::UartBridge(unsigned int indicationId, unsigned int requestId) : 27 | UartBridgeIndicationWrapper(indicationId) { 28 | uartBridgeRequest = new UartBridgeRequestProxy(requestId); 29 | sem_init(&responseSem, 0, 0); 30 | } 31 | 32 | UartBridge::~UartBridge() { 33 | sem_destroy(&responseSem); 34 | delete uartBridgeRequest; 35 | } 36 | 37 | void UartBridge::put(const uint8_t character) { 38 | uartBridgeRequest->put(character); 39 | } 40 | 41 | void UartBridge::setDivisor(const uint16_t divisor) { 42 | uartBridgeRequest->setDivisor(divisor); 43 | sem_wait(&responseSem); 44 | } 45 | 46 | void UartBridge::get(const uint8_t character) { 47 | responseData = (uint32_t) character; 48 | printf("%c", character); 49 | fflush(stdout); 50 | } 51 | 52 | void UartBridge::setDivisorDone() { 53 | sem_post(&responseSem); 54 | } 55 | -------------------------------------------------------------------------------- /backends/connectal/cpp/UartBridge.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef UART_BRIDGE_HPP 25 | #define UART_BRIDGE_HPP 26 | 27 | #include 28 | #include "UartBridgeIndication.h" 29 | #include "UartBridgeRequest.h" 30 | #include "GeneratedTypes.h" 31 | 32 | class UartBridge : public UartBridgeIndicationWrapper { 33 | public: 34 | UartBridge(unsigned int indicationId, unsigned int requestId); 35 | ~UartBridge(); 36 | 37 | // these are called by the main thread 38 | void put(const uint8_t character); 39 | void setDivisor(const uint16_t divisor); 40 | void get(const uint8_t character); 41 | void setDivisorDone(); 42 | 43 | private: 44 | sem_t responseSem; 45 | uint32_t responseData; 46 | 47 | UartBridgeRequestProxy *uartBridgeRequest; 48 | }; 49 | #endif 50 | -------------------------------------------------------------------------------- /backends/connectal/cpp/Verification.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "Verification.hpp" 25 | #include "SpikeTandemVerifier.hpp" 26 | 27 | Verification::Verification(unsigned int id, TandemVerifier *tandemVerifierIn) 28 | : VerificationIndicationWrapper(id), tandemVerifier(tandemVerifierIn) { 29 | } 30 | 31 | Verification::~Verification() { 32 | if (tandemVerifier != NULL) { 33 | delete tandemVerifier; 34 | } 35 | } 36 | 37 | void Verification::getVerificationPacket(VerificationPacket p) { 38 | if (tandemVerifier != NULL) { 39 | tandemVerifier->checkVerificationPacket(p); 40 | } 41 | } 42 | 43 | void Verification::printStatus() { 44 | if (tandemVerifier != NULL) { 45 | fprintf(stderr, "Verification::printStatus():\n"); 46 | tandemVerifier->printStatus(); 47 | } else { 48 | fprintf(stderr, "Verification::printStatus(): tandemVerifier == NULL\n"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /backends/connectal/cpp/Verification.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef VERIFICATION_HPP 25 | #define VERIFICATION_HPP 26 | 27 | #include "VerificationIndication.h" 28 | #include "TandemVerifier.hpp" 29 | #include "GeneratedTypes.h" 30 | 31 | class Verification : public VerificationIndicationWrapper { 32 | public: 33 | Verification(unsigned int id, TandemVerifier *tandemVerifierIn); 34 | virtual ~Verification(); 35 | 36 | // these are called by the main thread 37 | // XXX: none for now 38 | 39 | // called by ProcControlIndication thread 40 | void getVerificationPacket(VerificationPacket p); 41 | void printStatus(); 42 | 43 | private: 44 | TandemVerifier *tandemVerifier; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /backends/connectal/pin_translation.json: -------------------------------------------------------------------------------- 1 | { 2 | "uart_SOUT": { 3 | "uart": "d_out" 4 | }, 5 | "uart_SIN": { 6 | "uart": "d_in" 7 | }, 8 | "spi_sclk": { 9 | "PIO_DIRECTION": "OUTPUT", 10 | "sdio": "clk" 11 | }, 12 | "spi_mosi": { 13 | "PIO_DIRECTION": "OUTPUT", 14 | "sdio": "cmd" 15 | }, 16 | "spi_miso": { 17 | "PIO_DIRECTION": "INPUT", 18 | "sdio": "dat0" 19 | }, 20 | "spi_ncs": { 21 | "PIO_DIRECTION": "OUTPUT", 22 | "sdio": "cd_dat3" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backends/verilator/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, copy, 8 | # modify, merge, publish, distribute, sublicense, and/or sell copies 9 | # of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | # PROC should be defined in another makefile 25 | ifndef PROC 26 | $(error PROC is not set) 27 | endif 28 | 29 | ifndef RISCY_HOME 30 | $(error RISCY_HOME is not set) 31 | endif 32 | 33 | VERILATOR_EXE=$(PROC).exe 34 | 35 | TOP_MODULE=mkProcVerilator 36 | TOP_BSV_FILE=$(RISCY_HOME)/backends/verilator/bsv/ProcVerilator.bsv 37 | 38 | # Build Directories 39 | BUILD_DIR=build 40 | BSC_DIR=$(BUILD_DIR)/bsc 41 | VERILOG_DIR=$(BUILD_DIR)/verilog 42 | VERILATOR_DIR=$(BUILD_DIR)/verilator 43 | 44 | 45 | 46 | BSV_PATH = $(RISCY_HOME)/procs/riscy-lib:$(RISCY_HOME)/procs/$(PROC):$(RISCY_HOME)/backends/verilator/bsv:$(RISCY_HOME)/recycle-bsv-lib/src/bsv:+ 47 | BSC_DEFINES += -D CONFIG_IDMEM_INIT_HEX_FILE=\"idmem.hex\" 48 | BSC_DEFINES += -D CONFIG_RAM_INIT_HEX_FILE=\"ram.hex\" 49 | BSC_FLAGS = -aggressive-conditions -keep-fires $(BSC_DEFINES) -p $(BSV_PATH) -bdir $(BSC_DIR) -fdir $(BSC_DIR) -info-dir $(BSC_DIR) -simdir $(BSC_DIR) -vdir $(VERILOG_DIR) 50 | 51 | VERILOG_PATH = -y $(BLUESPECDIR)/Verilog -y $(VERILOG_DIR) 52 | VERILATOR_FLAGS = -Mdir $(VERILATOR_DIR) -CFLAGS -O2 $(VERILOG_PATH) -Wno-fatal --trace 53 | VERILATOR_CPP = $(RISCY_HOME)/backends/verilator/cpp/verilator_top.cpp 54 | 55 | .PHONY: verilator verilog clean 56 | 57 | verilator: $(VERILATOR_EXE) 58 | 59 | verilog: $(TOP_BSV_FILE) $(this) 60 | mkdir -p $(BSC_DIR) 61 | mkdir -p $(VERILOG_DIR) 62 | bsc $(BSC_FLAGS) -u -verilog -g $(TOP_MODULE) $(TOP_BSV_FILE) 63 | 64 | $(VERILATOR_EXE): verilog 65 | mkdir -p $(VERILATOR_DIR) 66 | verilator --cc $(VERILATOR_FLAGS) -o $(VERILATOR_EXE) $(VERILOG_DIR)/$(TOP_MODULE).v --exe $(VERILATOR_CPP) 67 | make -C $(VERILATOR_DIR) -f V$(TOP_MODULE).mk 68 | cp $(VERILATOR_DIR)/$(VERILATOR_EXE) . 69 | 70 | clean: 71 | rm -rf $(BSC_DIR) $(VERILOG_DIR) $(VERILATOR_DIR) 72 | rmdir --ignore-fail-on-non-empty $(BUILD_DIR) 73 | rm -rf $(VERILATOR_EXE) 74 | -------------------------------------------------------------------------------- /backends/verilator/bsv/ProcVerilator.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | // ProcVerilator.bsv 27 | // This is a wrapper to translate the generic Proc interface to an interface 28 | // that is accepted by verilator. 29 | 30 | import RS232::*; 31 | 32 | import MemUtil::*; 33 | 34 | // This assumes a Proc.bsv file that contains the mkProc definition 35 | import Abstraction::*; 36 | import BuildVector::*; 37 | import ClientServer::*; 38 | import Clocks::*; 39 | import Connectable::*; 40 | import FIFO::*; 41 | import GetPut::*; 42 | import Port::*; 43 | import Proc::*; 44 | import Vector::*; 45 | import VerificationPacket::*; 46 | import VerificationPacketFilter::*; 47 | import ProcPins::*; 48 | import RVTypes::*; 49 | 50 | import SimRam::*; 51 | 52 | interface ProcVerilator; 53 | // Processor Control 54 | method Action start(); 55 | method Action stop(); 56 | method Action stallPipeline(Bool stall); 57 | 58 | // Verification 59 | method Maybe#(VerificationPacket) currVerificationPacket; 60 | 61 | // TODO: re-enable this port 62 | // interface UncachedMemClientPort mmio; 63 | interface CoarseMemServerPort#(XLEN, TLog#(TDiv#(XLEN,8))) extmem; 64 | // Interrupts 65 | method Action triggerExternalInterrupt; 66 | 67 | method Action sendUartChar(Bit#(8) x); 68 | method ActionValue#(Bit#(8)) receiveUartChar; 69 | endinterface 70 | 71 | module mkProcVerilator(ProcVerilator); 72 | CoarseMemServerPort#(XLEN, TLog#(TDiv#(MainMemoryWidth,8))) simRam <- mkSimRam(`CONFIG_RAM_INIT_HEX_FILE); 73 | Proc#(MainMemoryWidth) proc <- mkProc; 74 | 75 | // connect the processor to the simRam 76 | mkConnection(proc.ram, simRam); 77 | 78 | // some of our processors write to a certain location when finished executing: 79 | rule checkForFinish if ((proc.mmio.request.first.addr == 'h6000_0000) && (proc.mmio.request.first.write)); 80 | if (proc.mmio.request.first.data == 0) begin 81 | $display("PASSED"); 82 | end else begin 83 | $display("FAILED %0d", proc.mmio.request.first.data); 84 | end 85 | $finish; 86 | endrule 87 | 88 | `ifdef CONFIG_SPI 89 | rule tieOff; 90 | proc.pins.spi.miso(0); 91 | endrule 92 | `endif 93 | 94 | `ifdef CONFIG_RS232 95 | Reg#(Bit#(16)) uartDivisor <- mkReg(17); 96 | UART#(16) simUart <- mkUART(8, NONE, STOP_1, uartDivisor); 97 | let uartSimToFPGABridge <- mkConnection(toPut(proc.pins.uart.sin), toGet(simUart.rs232.sout)); 98 | let uartFPGAToSimBridge <- mkConnection(toPut(simUart.rs232.sin), toGet(proc.pins.uart.sout)); 99 | 100 | rule displayMsg; 101 | let x <- simUart.tx.get(); 102 | $write("%c", x); 103 | endrule 104 | `endif 105 | 106 | // Processor Control 107 | method Action start; 108 | proc.start; 109 | endmethod 110 | method Action stop(); 111 | proc.stop; 112 | endmethod 113 | method Action stallPipeline(Bool stall); 114 | proc.stallPipeline(stall); 115 | endmethod 116 | 117 | // Verification 118 | method Maybe#(VerificationPacket) currVerificationPacket; 119 | return proc.currVerificationPacket; 120 | endmethod 121 | 122 | // Uncached Connections 123 | // interface UncachedMemClientPort mmio = proc.mmio; 124 | // External Connections 125 | interface GenericMemServerPort extmem = proc.extmem; 126 | // Interrupts 127 | method Action triggerExternalInterrupt = proc.triggerExternalInterrupt; 128 | 129 | `ifdef CONFIG_RS232 130 | method Action sendUartChar(Bit#(8) x); 131 | simUart.rx.put(x); 132 | endmethod 133 | method ActionValue#(Bit#(8)) receiveUartChar; 134 | let x <- simUart.tx.get; 135 | return x; 136 | endmethod 137 | `else 138 | method Action sendUartChar(Bit#(8) x) if (False); 139 | noAction; 140 | endmethod 141 | method ActionValue#(Bit#(8)) receiveUartChar if (False); 142 | return ?; 143 | endmethod 144 | `endif 145 | endmodule 146 | -------------------------------------------------------------------------------- /backends/verilator/bsv/SimRam.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import BRAM::*; 27 | import Vector::*; 28 | 29 | import MemUtil::*; 30 | import Port::*; 31 | import ShiftRegister::*; 32 | 33 | import Abstraction::*; 34 | import RVTypes::*; 35 | 36 | /// This module creates a GenericMemServerPort from a BRAM that is initialized 37 | /// by a hex file 38 | module mkSimRam#(String hex_file_name)(CoarseMemServerPort#(addrSz, logNumBytes)) 39 | provisos (NumAlias#(TExp#(TSub#(logNumBytes, 2)), numWords), 40 | Mul#(4, numWords, TExp#(logNumBytes)), 41 | Add#(a__, 16, addrSz)); 42 | BRAM_Configure bram_config = defaultValue; 43 | bram_config.loadFormat = tagged Hex hex_file_name; 44 | 45 | BRAM1Port#(Bit#(16), Bit#(32)) bram <- mkBRAM1Server(bram_config); 46 | 47 | ShiftRegister#(numWords, 32) dataShiftRegister <- mkShiftRegister; 48 | 49 | Reg#(Bit#(addrSz)) currAddr <- mkReg(0); 50 | Reg#(Maybe#(Bool)) pendingReqIsStore <- mkReg(tagged Invalid); 51 | Reg#(Bit#(TLog#(TAdd#(numWords, 1)))) wordsLeft <- mkReg(0); 52 | 53 | rule handleStoreReq(pendingReqIsStore matches tagged Valid .isStore &&& (isStore && (wordsLeft != 0))); 54 | let word = dataShiftRegister.serial.response.first; 55 | dataShiftRegister.serial.response.deq; 56 | bram.portA.request.put(BRAMRequest { 57 | write: True, 58 | responseOnWrite: False, 59 | address: truncate(currAddr >> 2), 60 | datain: word}); 61 | currAddr <= currAddr + 4; 62 | wordsLeft <= wordsLeft - 1; 63 | endrule 64 | 65 | rule handleLoadReq(pendingReqIsStore matches tagged Valid .isStore &&& (!isStore && (wordsLeft != 0))); 66 | bram.portA.request.put(BRAMRequest { 67 | write: False, 68 | responseOnWrite: False, 69 | address: truncate(currAddr >> 2), 70 | datain: 0}); 71 | currAddr <= currAddr + 4; 72 | wordsLeft <= wordsLeft - 1; 73 | endrule 74 | 75 | rule handleResp(pendingReqIsStore matches tagged Valid .isStore &&& !isStore); 76 | let x <- bram.portA.response.get(); 77 | dataShiftRegister.serial.request.enq(x); 78 | endrule 79 | 80 | interface InputPort request; 81 | method Action enq(CoarseMemReq#(addrSz, logNumBytes) req) if (!isValid(pendingReqIsStore)); 82 | if (req.write) begin 83 | Vector#(numWords, Bit#(32)) data_vec = unpack(req.data); 84 | dataShiftRegister.parallel.request.enq(data_vec); 85 | end 86 | pendingReqIsStore <= tagged Valid req.write; 87 | let addr_mask = ~fromInteger((valueOf(numWords) * 4) - 1); 88 | currAddr <= req.addr & addr_mask; 89 | wordsLeft <= fromInteger(valueOf(numWords)); 90 | endmethod 91 | method Bool canEnq; 92 | return !isValid(pendingReqIsStore); 93 | endmethod 94 | endinterface 95 | interface OutputPort response; 96 | method CoarseMemResp#(logNumBytes) first if (pendingReqIsStore matches tagged Valid .isStore &&& ((isStore || dataShiftRegister.parallel.response.canDeq) && (wordsLeft == 0))); 97 | if (!isStore) begin 98 | let data_vec = dataShiftRegister.parallel.response.first; 99 | return CoarseMemResp { 100 | write: False, 101 | data: pack(data_vec) }; 102 | end else begin 103 | return CoarseMemResp { 104 | write: True, 105 | data: 0 }; 106 | end 107 | endmethod 108 | method Action deq if (pendingReqIsStore matches tagged Valid .isStore &&& ((isStore || dataShiftRegister.parallel.response.canDeq) && (wordsLeft == 0))); 109 | if (!isStore) begin 110 | dataShiftRegister.parallel.response.deq; 111 | end 112 | pendingReqIsStore <= tagged Invalid; 113 | endmethod 114 | method Bool canDeq; 115 | if (pendingReqIsStore matches tagged Valid .isStore) begin 116 | return (isStore || dataShiftRegister.parallel.response.canDeq); 117 | end else begin 118 | return False; 119 | end 120 | endmethod 121 | endinterface 122 | endmodule 123 | -------------------------------------------------------------------------------- /backends/verilator/cpp/verilator_top.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include "verilated_vcd_c.h" 5 | 6 | #include "VmkProcVerilator.h" 7 | 8 | // #define DO_TRACE 9 | 10 | 11 | VmkProcVerilator* top = NULL; 12 | VerilatedVcdC* tfp = NULL; 13 | uint64_t main_time = 0; 14 | 15 | void tick() { 16 | top->CLK = 0; 17 | top->eval(); 18 | #ifdef DO_TRACE 19 | tfp->dump(main_time); 20 | #endif 21 | top->CLK = 1; 22 | top->eval(); 23 | #ifdef DO_TRACE 24 | tfp->dump(main_time); 25 | #endif 26 | main_time++; 27 | } 28 | void tick(int n) { 29 | for(int i = 0; i < n; i++) { 30 | tick(); 31 | } 32 | } 33 | 34 | void methodCall( uint8_t& rdy, uint8_t& en ) { 35 | // set en to 0 36 | en = 0; 37 | // wait until rdy is 1 38 | while (rdy == 0) { 39 | tick(); 40 | } 41 | // set en to 1 for one cycle 42 | en = 1; 43 | tick(); 44 | // set en to 0 45 | en = 0; 46 | } 47 | 48 | uint8_t getBit( uint32_t* base, uint32_t bit ) { 49 | while (bit >= 32) { 50 | base++; 51 | bit -= 32; 52 | } 53 | return ((*base) >> bit) & 1; 54 | } 55 | uint64_t getBits( uint32_t* base, uint32_t high, uint32_t low ) { 56 | uint64_t ret = 0; 57 | for (int i = high ; i >= (int) low ; i--) { 58 | ret = (ret << 1) | (uint64_t) getBit(base, i); 59 | } 60 | return ret; 61 | } 62 | 63 | int main(int argc, char* argv[]) { 64 | Verilated::commandArgs(argc, argv); 65 | #ifdef DO_TRACE 66 | Verilated::traceEverOn(true); 67 | #else 68 | Verilated::traceEverOn(false); 69 | #endif 70 | 71 | top = new VmkProcVerilator(); 72 | 73 | #ifdef DO_TRACE 74 | VerilatedVcdC* tfp = new VerilatedVcdC(); 75 | top->trace(tfp, 99); 76 | tfp->open("trace.vcd"); 77 | #endif 78 | 79 | top->RST_N = 0; 80 | tick(5); 81 | top->RST_N = 1; 82 | tick(5); 83 | 84 | std::cout << "Starting processor..." << std::endl; 85 | methodCall(top->RDY_start, top->EN_start); 86 | std::cout << "Processor started!" << std::endl; 87 | 88 | while (!Verilated::gotFinish()) { 89 | tick(); 90 | // get PC from verification packet: 91 | // if (top->RDY_currVerificationPacket == 1) { 92 | // if (getBit(top->currVerificationPacket, 301) == 1) { 93 | // uint64_t pc = getBits(top->currVerificationPacket, 236, 173); 94 | // } 95 | // } 96 | } 97 | 98 | top->final(); 99 | #ifdef DO_TRACE 100 | tfp->close(); 101 | #endif 102 | 103 | delete top; 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/Core.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import CoreStates::*; 27 | import FetchStage::*; 28 | import ExecStage::*; 29 | import WriteBackStage::*; 30 | 31 | import ClientServer::*; 32 | import GetPut::*; 33 | import Connectable::*; 34 | import DefaultValue::*; 35 | import FIFO::*; 36 | import GetPut::*; 37 | 38 | import Ehr::*; 39 | import MemUtil::*; 40 | import Port::*; 41 | 42 | import Abstraction::*; 43 | import RegUtil::*; 44 | import RVRegFile::*; 45 | `ifdef CONFIG_U 46 | import RVCsrFile::*; 47 | `else 48 | import RVCsrFileMCU::*; 49 | `endif 50 | import RVTypes::*; 51 | import VerificationPacket::*; 52 | 53 | import RVMemory::*; 54 | `ifdef CONFIG_M 55 | import RVMulDiv::*; 56 | `endif 57 | 58 | interface Core#(numeric type xlen); 59 | method Action start(Bit#(xlen) startPc); 60 | method Action stop; 61 | method Action stallPipeline(Bool stall); 62 | method Maybe#(VerificationPacket) currVerificationPacket; 63 | endinterface 64 | 65 | module mkThreeStageCore#( 66 | ReadOnlyMemServerPort#(xlen, 2) ifetch, 67 | AtomicMemServerPort#(xlen, TLog#(TDiv#(xlen,8))) dmem, 68 | Bool ipi, 69 | Bool timerInterrupt, 70 | Bit#(64) timer, 71 | Bool externalInterrupt, 72 | Bit#(xlen) hartID 73 | )(Core#(xlen)) provisos (NumAlias#(xlen, 32)); 74 | 75 | Reg#(Bool) stallReg <- mkReg(False); 76 | 77 | RVRegFile#(xlen) rf <- mkRVRegFileBypass(False); // make this true if you add an FPU 78 | 79 | // TODO: make this depend on a bool 80 | // If user mode is supported, use the full CSR File 81 | RVCsrFile#(xlen) csrf <- 82 | `ifdef CONFIG_U 83 | mkRVCsrFile(hartID, timer, timerInterrupt, ipi, externalInterrupt); 84 | `else 85 | mkRVCsrFileMCU(hartID, timer, timerInterrupt, ipi, externalInterrupt); 86 | `endif 87 | 88 | // TODO: make this depend on a bool 89 | `ifdef CONFIG_M 90 | MulDivExec#(xlen) mulDiv <- mkBoothRoughMulDivExec; 91 | `endif 92 | 93 | Ehr#(4, Maybe#(FetchState#(xlen))) fetchStateEhr <- mkEhr(tagged Invalid); 94 | Ehr#(4, Maybe#(ExecuteState#(xlen))) executeStateEhr <- mkEhr(tagged Invalid); 95 | Ehr#(4, Maybe#(WriteBackState#(xlen))) writeBackStateEhr <- mkEhr(tagged Invalid); 96 | 97 | Ehr#(2, Maybe#(VerificationPacket)) verificationPacketEhr <- mkEhr(tagged Invalid); 98 | 99 | let fetchRegs = FetchRegs{ 100 | fs: fetchStateEhr[2], 101 | es: executeStateEhr[2], 102 | ifetchreq: ifetch.request}; 103 | FetchStage f <- mkFetchStage(fetchRegs); 104 | 105 | let execRegs = ExecRegs{ 106 | fs: fetchStateEhr[1], 107 | es: executeStateEhr[1], 108 | ws: writeBackStateEhr[1], 109 | ifetchres: ifetch.response, 110 | dmemreq: dmem.request, 111 | `ifdef CONFIG_M 112 | mulDiv: mulDiv, 113 | `endif 114 | csrf: csrf, 115 | rf: rf}; 116 | ExecStage e <- mkExecStage(execRegs); 117 | 118 | let writeBackRegs = WriteBackRegs{ 119 | fs: fetchStateEhr[0], 120 | es: executeStateEhr[0], 121 | ws: writeBackStateEhr[0], 122 | dmemres: dmem.response, 123 | `ifdef CONFIG_M 124 | mulDiv: mulDiv, 125 | `endif 126 | csrf: csrf, 127 | rf: rf, 128 | verificationPackets: verificationPacketEhr[1]}; 129 | WriteBackStage w <- mkWriteBackStage(writeBackRegs, stallReg); 130 | 131 | rule clearVerificationPacketEhr; 132 | verificationPacketEhr[0] <= tagged Invalid; 133 | endrule 134 | 135 | method Action start(Bit#(xlen) startPc); 136 | fetchStateEhr[3] <= tagged Valid FetchState { pc: startPc }; 137 | executeStateEhr[3] <= tagged Invalid; 138 | writeBackStateEhr[3] <= tagged Invalid; 139 | stallReg <= False; 140 | endmethod 141 | method Action stop; 142 | fetchStateEhr[3] <= tagged Invalid; 143 | executeStateEhr[3] <= tagged Invalid; 144 | writeBackStateEhr[3] <= tagged Invalid; 145 | endmethod 146 | 147 | method Action stallPipeline(Bool stall); 148 | stallReg <= stall; 149 | endmethod 150 | 151 | method Maybe#(VerificationPacket) currVerificationPacket; 152 | return stallReg ? tagged Invalid : verificationPacketEhr[0]; 153 | endmethod 154 | endmodule 155 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/CoreStates.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import RVTypes::*; 25 | 26 | typedef struct { 27 | Bit#(xlen) pc; 28 | } FetchState#(numeric type xlen) deriving (Bits, Eq, FShow); 29 | 30 | typedef struct { 31 | Bool poisoned; 32 | Bit#(xlen) pc; 33 | } ExecuteState#(numeric type xlen) deriving (Bits, Eq, FShow); 34 | 35 | typedef struct { 36 | Bit#(xlen) pc; 37 | Maybe#(TrapCause) trap; 38 | RVDecodedInst dInst; 39 | Bit#(xlen) addr; 40 | Bit#(xlen) data; 41 | } WriteBackState#(numeric type xlen) deriving (Bits, Eq, FShow); 42 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/FetchStage.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import GetPut::*; 25 | 26 | import Port::*; 27 | import MemUtil::*; 28 | 29 | import RVTypes::*; 30 | import CoreStates::*; 31 | 32 | interface FetchStage; 33 | endinterface 34 | 35 | typedef struct { 36 | Reg#(Maybe#(FetchState#(xlen))) fs; 37 | Reg#(Maybe#(ExecuteState#(xlen))) es; 38 | InputPort#(ReadOnlyMemReq#(xlen, 2)) ifetchreq; 39 | } FetchRegs#(numeric type xlen); 40 | 41 | module mkFetchStage#(FetchRegs#(xlen) fr)(FetchStage); 42 | let ifetchreq = fr.ifetchreq; 43 | 44 | rule doFetch(fr.fs matches tagged Valid .fetchState 45 | &&& fr.es == tagged Invalid); 46 | // get and clear the fetch state 47 | let pc = fetchState.pc; 48 | fr.fs <= tagged Invalid; 49 | 50 | // request instruction 51 | ifetchreq.enq(ReadOnlyMemReq{ addr: pc }); 52 | 53 | // pass to execute state 54 | fr.es <= tagged Valid ExecuteState{ poisoned: False, pc: pc }; 55 | endrule 56 | endmodule 57 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, copy, 8 | # modify, merge, publish, distribute, sublicense, and/or sell copies 9 | # of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | PROC=RV32IM_3stage 25 | 26 | CONNECTALFLAGS += -D CONFIG_RV32 27 | # Use a 32-bit data bus for shared memory in connectal 28 | CONNECTALFLAGS += -D DataBusWidth=32 29 | 30 | # This processor can be configured as an RV64 processor by uncommenting these 31 | # two lines below and commenting out the two lines above. 32 | # CONNECTALFLAGS += -D CONFIG_RV64 33 | # CONNECTALFLAGS += -D DataBusWidth=64 34 | 35 | CONNECTALFLAGS += -D CONFIG_M 36 | CONNECTALFLAGS += -D CONFIG_S 37 | CONNECTALFLAGS += -D CONFIG_U 38 | CONNECTALFLAGS += -D CONFIG_PLATFORM_MCU 39 | CONNECTALFLAGS += -D CONFIG_RS232 40 | CONNECTALFLAGS += -D CONFIG_SPI 41 | 42 | # This is for printing to textfiles 43 | # CONNECTALFLAGS += -D CONFIG_TEXTFILE_DEBUG 44 | 45 | # Suppress "duplicate folder" and "unfolding over ... steps" warnings 46 | # CONNECTALFLAGS += --bscflags=" -suppress-warnings S0073:G0024 " 47 | 48 | # Attempt to optimize the generated Verilog. In a small test with part of the 49 | # decoder, this increased the post-synthesis area by 10% so we don't use these 50 | # flags by default. 51 | # CONNECTALFLAGS += --bscflags=" -opt-undetermined-vals -unspecified-to X " 52 | 53 | ifdef RISCY_HOME 54 | ifeq ($(MAKECMDGOALS),verilator) 55 | include $(RISCY_HOME)/backends/verilator/Makefile 56 | else ifeq ($(MAKECMDGOALS),verilog) 57 | include $(RISCY_HOME)/backends/verilator/Makefile 58 | else 59 | # connectal backend 60 | include $(RISCY_HOME)/backends/connectal/Makefile 61 | endif 62 | else 63 | $(error RISCY_HOME is undefined) 64 | endif 65 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/Proc.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import BuildVector::*; 27 | import DefaultValue::*; 28 | import ClientServer::*; 29 | import Clocks::*; 30 | import Connectable::*; 31 | import FIFO::*; 32 | import GetPut::*; 33 | import Vector::*; 34 | 35 | import ClientServerUtil::*; 36 | import FIFOG::*; 37 | import GenericAtomicMem::*; 38 | import PolymorphicMem::*; 39 | import Port::*; 40 | import MemUtil::*; 41 | import ServerUtil::*; 42 | 43 | import Abstraction::*; 44 | // import BasicMemorySystemBlocks::*; 45 | // import BramIDMem::*; 46 | import Core::*; 47 | import ProcPins::*; 48 | import RTC::*; 49 | import RVUart::*; 50 | import SPI::*; 51 | import RVSPI::*; 52 | import RVTypes::*; 53 | import VerificationPacket::*; 54 | import VerificationPacketFilter::*; 55 | 56 | // This is used by ProcConnectal 57 | typedef DataSz MainMemoryWidth; 58 | 59 | // Multiple devices in mkProc can't be clock gated, so the mkProc module 60 | // should not have the gate_all_clocks attribute. 61 | (* synthesize *) 62 | module mkProc(Proc#(DataSz)); 63 | // Address map (some portions hard-coded in memory system 64 | // 0x0000_0000 - 0x2000_0000 : tightly coupled memory (not all used) 65 | // 0x2000_0000 - 0x2FFF_FFFF : rtc 66 | // 0x3000_0000 - 0x3FFF_FFFF : uart 67 | // 0x4000_0000 - 0xFFFF_FFFF : mmio 68 | 69 | let clock <- exposeCurrentClock(); 70 | 71 | `ifdef CONFIG_RV32 72 | RTC#(1, ByteEnMemServerPort#(32,2)) rtc <- mkRTC_RV32; 73 | `else 74 | RTC#(1, ByteEnMemServerPort#(64,3)) rtc <- mkRTC_RV64; 75 | `endif 76 | 77 | // 9600 baud: divisor = 26042 78 | // 115200 baud: divisor = 134 79 | RVUart#(ByteEnMemServerPort#(32,2)) uart_module <- mkRVUart_RV32(17); 80 | 81 | RVSPI#(ByteEnMemServerPort#(32,2)) spi_module <- mkRVSPI(); 82 | 83 | Bool timer_interrupt = rtc.timerInterrupt[0]; 84 | Bit#(64) timer_value = rtc.timerValue; 85 | 86 | Wire#(Bool) extInterruptWire <- mkDWire(False); 87 | 88 | `ifdef CONFIG_IDMEM_INIT_HEX_FILE 89 | let sram <- mkPolymorphicBRAMLoad(64*1024/4, tagged Hex `CONFIG_IDMEM_INIT_HEX_FILE); 90 | `else 91 | let sram <- mkPolymorphicBRAM(64*1024/4); 92 | `endif 93 | 94 | // MMIO server for devices outside of the processor 95 | FIFOG#(CoarseMemReq#(32,2)) uncachedReqFIFO <- mkFIFOG; 96 | FIFOG#(CoarseMemResp#(2)) uncachedRespFIFO <- mkFIFOG; 97 | let mmio_server = toServerPort(uncachedReqFIFO, uncachedRespFIFO); 98 | let mmio_client = toClientPort(uncachedReqFIFO, uncachedRespFIFO); 99 | 100 | // numClients = 3 101 | // addrSz = 32 102 | // logNumBytes = 2 103 | MixedAtomicMemBus#(3, 32, 2) memBus <- mkMixedAtomicMemBus(vec( 104 | mixedMemBusItemFromAddrRange( 'h0000_0000, 'h1FFF_FFFF, tagged ByteEn sram ), 105 | mixedMemBusItemFromAddrRange( 'h2000_0000, 'h2FFF_FFFF, tagged ByteEn rtc.memifc ), 106 | mixedMemBusItemFromAddrRange( 'h3000_0000, 'h3000_FFFF, tagged ByteEn uart_module.memifc ), 107 | mixedMemBusItemFromAddrRange( 'h3001_0000, 'h3001_FFFF, tagged ByteEn spi_module.memifc ), 108 | mixedMemBusItemFromAddrRange( 'h4000_0000, 'h7FFF_FFFF, tagged Coarse mmio_server ), 109 | mixedMemBusItemFromAddrRange( 'h8000_0000, 'hFFFF_FFFF, tagged Coarse mmio_server ))); 110 | 111 | ReadOnlyMemServerPort#(32, 2) imem = simplifyMemServerPort(memBus.clients[0]); 112 | 113 | Core#(32) core <- mkThreeStageCore( 114 | imem, 115 | memBus.clients[1], 116 | False, // inter-process interrupt 117 | timer_interrupt, // timer interrupt 118 | timer_value, // timer value 119 | extInterruptWire, // external interrupt 120 | 0); // hart ID 121 | 122 | // Processor Control 123 | method Action start(); 124 | core.start(0); 125 | endmethod 126 | method Action stop(); 127 | core.stop; 128 | endmethod 129 | 130 | // Verification 131 | method Maybe#(VerificationPacket) currVerificationPacket; 132 | return core.currVerificationPacket; 133 | endmethod 134 | 135 | // Main Memory Connection 136 | interface CoarseMemClientPort ram = nullClientPort; 137 | 138 | interface CoarseMemServerPort mmio = mmio_client; 139 | 140 | interface CoarseMemServerPort extmem = simplifyMemServerPort(memBus.clients[2]); 141 | 142 | // Interrupts 143 | method Action triggerExternalInterrupt; 144 | extInterruptWire <= True; 145 | endmethod 146 | 147 | method Action stallPipeline(Bool stall); 148 | core.stallPipeline(stall); 149 | endmethod 150 | 151 | interface ProcPins pins; 152 | // no other pins connected at the moment 153 | `ifdef CONFIG_RS232 154 | interface RS232 uart = uart_module.uart_pins; 155 | `endif 156 | `ifdef CONFIG_SPI 157 | interface SPIMasterPins spi = spi_module.spi_pins; 158 | `endif 159 | interface Clock deleteme_unused_clock = clock; 160 | endinterface 161 | endmodule 162 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/ProcConfig.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | /* 25 | * This file is the configuration file for Riscy processors. This file defines 26 | * macros that are used during the BSV compilation process to select what 27 | * processor to build. 28 | * 29 | * This ProcConfig.bsv is for connectal-based designs. When a connectal flag 30 | * is added to the makefile like so: 31 | * CONNECTALFLAGS += -D FOO=5 32 | * The flag FOO is defined to be 5 throughout the build process (Makefile, 33 | * BSV, C++, and TCL). The makefile for each connectal-based processor has 34 | * defined macros to give information about the processor to build. 35 | * 36 | * If you want to make a non-connectal-based design, then you will implement 37 | * your own ProcConfig.bsv where you define only the BSV macros you want in 38 | * your design. 39 | */ 40 | 41 | // ConnectalProjectConfig.bsv is generated by connectal during compilation. 42 | // This file includes BSV defines for any macros defined in CONNECTALFLAGS. 43 | // This file may define the following macros: 44 | // CONFIG_RV64 - 64-bit RISC-V ISA 45 | // CONFIG_RV32 - 32-bit RISC-V ISA 46 | // CONFIG_S - Supervisor Mode 47 | // CONFIG_U - User Mode 48 | // CONFIG_M - "M" ISA Extension - Multiplication and Division 49 | // CONFIG_A - "A" ISA Extension - Atomic Memory Operations 50 | // CONFIG_F - "F" ISA Extension - Single-Precision Floating Point 51 | // CONFIG_D - "D" ISA Extension - Double-Precision Floating Point 52 | // To see which macros are defined in this project, and to make modifications, 53 | // see the project's Makefile 54 | `ifdef CONNECTAL 55 | `include "ConnectalProjectConfig.bsv" 56 | `else 57 | `define CONFIG_RV32 58 | `define CONFIG_M 59 | `define CONFIG_S 60 | `define CONFIG_U 61 | `define CONFIG_PLATFORM_MCU 62 | `define CONFIG_RS232 63 | `define CONFIG_SPI 64 | `endif 65 | 66 | 67 | 68 | // Debugging infrastructure 69 | `define VERIFICATION_PACKETS 70 | 71 | // Workarounds 72 | 73 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/genhex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2017 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | print_usage() 26 | { 27 | echo "Usage: $0 []" 28 | echo "" 29 | echo "This script generates the necessary hex file from the provided ELF file." 30 | echo "If no elf file is provided, then this script uses the test rv64ui-p-add" 31 | echo "as a default program." 32 | echo "" 33 | echo "Note: This script requires RISCY_HOME to be defined" 34 | } 35 | 36 | if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then 37 | print_usage 38 | exit 0 39 | fi 40 | 41 | if [ ! -d $RISCY_HOME/tools/elf2hex ] ; then 42 | echo "[ERROR] Can't find folder \$RISCY_HOME/tools/elf2hex, check if RISCY_HOME is defined" 43 | exit 1 44 | fi 45 | 46 | if [ ! -f $RISCY_HOME/tools/elf2hex/elf2hex ] ; then 47 | echo "[INFO] Compiling elf2hex binary" 48 | make -C $RISCY_HOME/tools/elf2hex 49 | if [ ! -f $RISCY_HOME/tools/elf2hex/elf2hex ] ; then 50 | echo "[ERROR] Compilation failed" 51 | exit 1 52 | fi 53 | fi 54 | 55 | if [ $# -eq 0 ] ; then 56 | ELF_FILE=$RISCY_TOOLS/riscv32-unknown-elf/share/riscv-tests/isa/rv32ui-mcu-add 57 | else 58 | ELF_FILE=$1 59 | fi 60 | 61 | if [ ! -f $ELF_FILE ] ; then 62 | echo "[ERROR] Can't find elf file $ELF_FILE" 63 | exit 1 64 | fi 65 | 66 | # Make ram.hex for this processor 67 | $RISCY_HOME/tools/elf2hex/elf2hex $ELF_FILE 0x00000000 64K idmem.hex 68 | $RISCY_HOME/tools/elf2hex/elf2hex $ELF_FILE 0x80000000 256K ram.hex 69 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/runtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, 2017 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | SKIP_TESTS="rv32mi-mcu-dirty rv32mi-mcu-scall" 26 | 27 | print_usage () 28 | { 29 | echo "Usage: $0 [ []]" 30 | echo "" 31 | echo "This script runs a selection of riscv-tests on the current processor." 32 | echo "backend-id and test-id are the values from the menus that appear when" 33 | echo "no command line arguments are provided." 34 | } 35 | 36 | run_connectal () 37 | { 38 | hexfile=$1 39 | basehexfile=$(basename "$hexfile") 40 | 41 | # run the processor 42 | ./verilator/bin/ubuntu.exe --just-trace $hexfile &> out/${basehexfile}.out 43 | } 44 | 45 | run_verilator () 46 | { 47 | hexfile=$1 48 | basehexfile=$(basename "$hexfile") 49 | 50 | # generate hex file 51 | ./genhex.sh $hexfile 52 | 53 | # and run the processor 54 | ./RV32IM_3stage.exe &> out/${basehexfile}.out 55 | } 56 | 57 | if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then 58 | print_usage 59 | exit 0 60 | fi 61 | 62 | # make sure test directory exists 63 | if [ ! -d $RISCY_TOOLS ] ; then 64 | echo "[ERROR] Can't find directory RISCY_TOOLS=\"${RISCY_TOOLS}\"" 65 | exit 1 66 | elif [ -d $RISCY_TOOLS/riscv32-unknown-elf/share/riscv-tests/isa ] ; then 67 | TEST_DIR=$RISCY_TOOLS/riscv32-unknown-elf/share/riscv-tests/isa 68 | elif [ -d $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa ] ; then 69 | TEST_DIR=$RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa 70 | else 71 | echo "[ERROR] Can't find test directory in \"${RISCY_TOOLS}\"" 72 | exit 1 73 | fi 74 | 75 | if [ "$#" -gt 0 ] ; then 76 | BACKEND=$1 77 | else 78 | echo "Please select a backend:" 79 | echo "0) connectal (verilator)" 80 | echo "1) verilator" 81 | read BACKEND 82 | fi 83 | 84 | # Validate backend choice 85 | case "$BACKEND" in 86 | 0) ;; 87 | 1) ;; 88 | *) echo "[ERROR] Invalid Backend Code" 89 | exit 1 90 | ;; 91 | esac 92 | 93 | if [ "$#" -gt 1 ] ; then 94 | TESTS=$2 95 | else 96 | echo "Please select a set of tests:" 97 | echo "0) full test suite" 98 | echo "" 99 | echo " sanity checks:" 100 | echo "1) rv32ui-mcu-add" 101 | echo "" 102 | echo " im tests:" 103 | echo "2) rv32ui-mcu-*" 104 | echo "3) rv32um-mcu-*" 105 | echo "" 106 | echo " privilege tests:" 107 | echo "4) rv32mi-mcu-*" 108 | echo "5) rv32si-mcu-*" 109 | read TESTS 110 | fi 111 | 112 | case "$TESTS" in 113 | 0) files=`find $TEST_DIR/rv32ui-mcu-* -type f ! -name "*.*"` 114 | files="$files "`find $TEST_DIR/rv32um-mcu-* -type f ! -name "*.*"` 115 | files="$files "`find $TEST_DIR/rv32mi-mcu-* -type f ! -name "*.*"` 116 | files="$files "`find $TEST_DIR/rv32si-mcu-* -type f ! -name "*.*"` 117 | ;; 118 | 1) files=$TEST_DIR/rv32ui-mcu-add 119 | ;; 120 | 2) files=`find $TEST_DIR/rv32ui-mcu-* -type f ! -name "*.*"` 121 | ;; 122 | 3) files=`find $TEST_DIR/rv32um-mcu-* -type f ! -name "*.*"` 123 | ;; 124 | 4) files=`find $TEST_DIR/rv32mi-mcu-* -type f ! -name "*.*"` 125 | ;; 126 | 5) files=`find $TEST_DIR/rv32si-mcu-* -type f ! -name "*.*"` 127 | ;; 128 | *) echo "[ERROR] Invalid Test Code" 129 | exit 1 130 | ;; 131 | esac 132 | 133 | rm -rf out/ 134 | mkdir -p out 135 | 136 | EXIT_CODE=0 137 | 138 | for hexfile in $files ; do 139 | basehexfile=$(basename "$hexfile") 140 | 141 | # skip some tests 142 | SKIP=0 143 | for skippedtest in $SKIP_TESTS ; do 144 | if [ "$basehexfile" == "$skippedtest" ] ; then 145 | echo "$basehexfile SKIPPED" 146 | SKIP=1 147 | fi 148 | done 149 | if [ $SKIP -eq 1 ] ; then 150 | continue 151 | fi 152 | 153 | # run processor 154 | case "$BACKEND" in 155 | 0) run_connectal $hexfile 156 | ;; 157 | 1) run_verilator $hexfile 158 | ;; 159 | *) echo "[ERROR] Invalid Backend Code" 160 | exit 1 161 | ;; 162 | esac 163 | 164 | # check results 165 | grep PASSED out/${basehexfile}.out > /dev/null 166 | if [ $? -ne 0 ] ; then 167 | errorcode=`grep FAILED out/${basehexfile}.out` 168 | if [ $? -ne 0 ] ; then 169 | # neither PASSED nor FAILED were found in the output 170 | echo "$basehexfile ERROR (neither pass nor fail)" 171 | else 172 | # This will print FAILED from the error code 173 | echo "$basehexfile $errorcode" 174 | EXIT_CODE=1 175 | fi 176 | else 177 | echo "$basehexfile OK" 178 | fi 179 | done 180 | 181 | rm -f SOCK.* 182 | 183 | exit $EXIT_CODE 184 | -------------------------------------------------------------------------------- /procs/RV32IM_3stage/runtest64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, 2017 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | SKIP_TESTS="rv32mi-mcu-dirty rv32mi-mcu-scall" 26 | 27 | print_usage () 28 | { 29 | echo "Usage: $0 [ []]" 30 | echo "" 31 | echo "This script runs a selection of riscv-tests on the current processor." 32 | echo "backend-id and test-id are the values from the menus that appear when" 33 | echo "no command line arguments are provided." 34 | } 35 | 36 | run_connectal () 37 | { 38 | hexfile=$1 39 | basehexfile=$(basename "$hexfile") 40 | 41 | # run the processor 42 | ./verilator/bin/ubuntu.exe --just-trace $hexfile &> out/${basehexfile}.out 43 | } 44 | 45 | run_verilator () 46 | { 47 | hexfile=$1 48 | basehexfile=$(basename "$hexfile") 49 | 50 | # generate hex file 51 | ./genhex.sh $hexfile 52 | 53 | # and run the processor 54 | ./RV32IM_3stage.exe &> out/${basehexfile}.out 55 | } 56 | 57 | if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then 58 | print_usage 59 | exit 0 60 | fi 61 | 62 | # make sure test directory exists 63 | if [ ! -d $RISCY_TOOLS ] ; then 64 | echo "[ERROR] Can't find directory RISCY_TOOLS=\"${RISCY_TOOLS}\"" 65 | exit 1 66 | elif [ -d $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa ] ; then 67 | TEST_DIR=$RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa 68 | else 69 | echo "[ERROR] Can't find test directory in \"${RISCY_TOOLS}\"" 70 | exit 1 71 | fi 72 | 73 | if [ "$#" -gt 0 ] ; then 74 | BACKEND=$1 75 | else 76 | echo "Please select a backend:" 77 | echo "0) connectal (verilator)" 78 | echo "1) verilator" 79 | read BACKEND 80 | fi 81 | 82 | # Validate backend choice 83 | case "$BACKEND" in 84 | 0) ;; 85 | 1) ;; 86 | *) echo "[ERROR] Invalid Backend Code" 87 | exit 1 88 | ;; 89 | esac 90 | 91 | if [ "$#" -gt 1 ] ; then 92 | TESTS=$2 93 | else 94 | echo "Please select a set of tests:" 95 | echo "0) full test suite" 96 | echo "" 97 | echo " sanity checks:" 98 | echo "1) rv64ui-mcu-add" 99 | echo "" 100 | echo " im tests:" 101 | echo "2) rv64ui-mcu-*" 102 | echo "3) rv64um-mcu-*" 103 | echo "" 104 | echo " privilege tests:" 105 | echo "4) rv64mi-mcu-*" 106 | echo "5) rv64si-mcu-*" 107 | read TESTS 108 | fi 109 | 110 | case "$TESTS" in 111 | 0) files=`find $TEST_DIR/rv64ui-mcu-* -type f ! -name "*.*"` 112 | files="$files "`find $TEST_DIR/rv64um-mcu-* -type f ! -name "*.*"` 113 | files="$files "`find $TEST_DIR/rv64mi-mcu-* -type f ! -name "*.*"` 114 | files="$files "`find $TEST_DIR/rv64si-mcu-* -type f ! -name "*.*"` 115 | ;; 116 | 1) files=$TEST_DIR/rv64ui-mcu-add 117 | ;; 118 | 2) files=`find $TEST_DIR/rv64ui-mcu-* -type f ! -name "*.*"` 119 | ;; 120 | 3) files=`find $TEST_DIR/rv64um-mcu-* -type f ! -name "*.*"` 121 | ;; 122 | 4) files=`find $TEST_DIR/rv64mi-mcu-* -type f ! -name "*.*"` 123 | ;; 124 | 5) files=`find $TEST_DIR/rv64si-mcu-* -type f ! -name "*.*"` 125 | ;; 126 | *) echo "[ERROR] Invalid Test Code" 127 | exit 1 128 | ;; 129 | esac 130 | 131 | rm -rf out/ 132 | mkdir -p out 133 | 134 | EXIT_CODE=0 135 | 136 | for hexfile in $files ; do 137 | basehexfile=$(basename "$hexfile") 138 | 139 | # skip some tests 140 | SKIP=0 141 | for skippedtest in $SKIP_TESTS ; do 142 | if [ "$basehexfile" == "$skippedtest" ] ; then 143 | echo "$basehexfile SKIPPED" 144 | SKIP=1 145 | fi 146 | done 147 | if [ $SKIP -eq 1 ] ; then 148 | continue 149 | fi 150 | 151 | # run processor 152 | case "$BACKEND" in 153 | 0) run_connectal $hexfile 154 | ;; 155 | 1) run_verilator $hexfile 156 | ;; 157 | *) echo "[ERROR] Invalid Backend Code" 158 | exit 1 159 | ;; 160 | esac 161 | 162 | # check results 163 | grep PASSED out/${basehexfile}.out > /dev/null 164 | if [ $? -ne 0 ] ; then 165 | errorcode=`grep FAILED out/${basehexfile}.out` 166 | if [ $? -ne 0 ] ; then 167 | # neither PASSED nor FAILED were found in the output 168 | echo "$basehexfile ERROR (neither pass nor fail)" 169 | else 170 | # This will print FAILED from the error code 171 | echo "$basehexfile $errorcode" 172 | EXIT_CODE=1 173 | fi 174 | else 175 | echo "$basehexfile OK" 176 | fi 177 | done 178 | 179 | rm -f SOCK.* 180 | 181 | exit $EXIT_CODE 182 | -------------------------------------------------------------------------------- /procs/RV64G_multicycle/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, copy, 8 | # modify, merge, publish, distribute, sublicense, and/or sell copies 9 | # of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | PROC=RV64G_multicycle 25 | ACCELERATORS=StrLen DebugAccel 26 | 27 | CONNECTALFLAGS += -D CONFIG_RV64 28 | CONNECTALFLAGS += -D CONFIG_S 29 | CONNECTALFLAGS += -D CONFIG_U 30 | CONNECTALFLAGS += -D CONFIG_M 31 | CONNECTALFLAGS += -D CONFIG_A 32 | CONNECTALFLAGS += -D CONFIG_F 33 | CONNECTALFLAGS += -D CONFIG_D 34 | 35 | # Suppress "duplicate folder" and "unfolding over ... steps" warnings 36 | # CONNECTALFLAGS += --bscflags=" -suppress-warnings S0073:G0024 " 37 | 38 | # Attempt to optimize the generated Verilog. In a small test with part of the 39 | # decoder, this increased the post-synthesis area by 10% so we don't use these 40 | # flags by default. 41 | # CONNECTALFLAGS += --bscflags=" -opt-undetermined-vals -unspecified-to X " 42 | 43 | ifdef RISCY_HOME 44 | ifeq ($(MAKECMDGOALS),verilator) 45 | include $(RISCY_HOME)/backends/verilator/Makefile 46 | else ifeq ($(MAKECMDGOALS),verilog) 47 | include $(RISCY_HOME)/backends/verilator/Makefile 48 | else 49 | # connectal backend 50 | include $(RISCY_HOME)/backends/connectal/Makefile 51 | endif 52 | else 53 | $(error RISCY_HOME is undefined) 54 | endif 55 | -------------------------------------------------------------------------------- /procs/RV64G_multicycle/ProcConfig.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | /* 25 | * This file is the configuration file for Riscy processors. This file defines 26 | * macros that are used during the BSV compilation process to select what 27 | * processor to build. 28 | * 29 | * This ProcConfig.bsv is for connectal-based designs. When a connectal flag 30 | * is added to the makefile like so: 31 | * CONNECTALFLAGS += -D FOO=5 32 | * The flag FOO is defined to be 5 throughout the build process (Makefile, 33 | * BSV, C++, and TCL). The makefile for each connectal-based processor has 34 | * defined macros to give information about the processor to build. 35 | * 36 | * If you want to make a non-connectal-based design, then you will implement 37 | * your own ProcConfig.bsv where you define only the BSV macros you want in 38 | * your design. 39 | */ 40 | 41 | // ConnectalProjectConfig.bsv is generated by connectal during compilation. 42 | // This file includes BSV defines for any macros defined in CONNECTALFLAGS. 43 | // This file may define the following macros: 44 | // CONFIG_RV64 - 64-bit RISC-V ISA 45 | // CONFIG_RV32 - 32-bit RISC-V ISA 46 | // CONFIG_S - Supervisor Mode 47 | // CONFIG_U - User Mode 48 | // CONFIG_M - "M" ISA Extension - Multiplication and Division 49 | // CONFIG_A - "A" ISA Extension - Atomic Memory Operations 50 | // CONFIG_F - "F" ISA Extension - Single-Precision Floating Point 51 | // CONFIG_D - "D" ISA Extension - Double-Precision Floating Point 52 | // To see which macros are defined in this project, and to make modifications, 53 | // see the project's Makefile 54 | `ifdef CONNECTAL 55 | `include "ConnectalProjectConfig.bsv" 56 | `else 57 | `define CONFIG_RV64 58 | `define CONFIG_S 59 | `define CONFIG_U 60 | `define CONFIG_M 61 | `define CONFIG_A 62 | `define CONFIG_F 63 | `define CONFIG_D 64 | `endif 65 | 66 | // BSV-only macros: These macros are only used within the BSV-project, so they 67 | // are defined here instead of in CONNECTALFLAGS 68 | `define REUSE_FMA 69 | // `define NO_FDIV 70 | // `define NO_FSQRT 71 | // `define USE_DUMMY_FPU 72 | 73 | // Debugging infrastructure 74 | `define VERIFICATION_PACKETS 75 | 76 | // Workarounds 77 | 78 | -------------------------------------------------------------------------------- /procs/RV64G_multicycle/genhex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2017 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | print_usage() 26 | { 27 | echo "Usage: $0 []" 28 | echo "" 29 | echo "This script generates the necessary hex file from the provided ELF file." 30 | echo "If no elf file is provided, then this script uses the test rv64ui-p-add" 31 | echo "as a default program." 32 | echo "" 33 | echo "Note: This script requires RISCY_HOME to be defined" 34 | } 35 | 36 | if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then 37 | print_usage 38 | exit 0 39 | fi 40 | 41 | if [ ! -d $RISCY_HOME/tools/elf2hex ] ; then 42 | echo "[ERROR] Can't find folder \$RISCY_HOME/tools/elf2hex, check if RISCY_HOME is defined" 43 | exit 1 44 | fi 45 | 46 | if [ ! -f $RISCY_HOME/tools/elf2hex/elf2hex ] ; then 47 | echo "[INFO] Compiling elf2hex binary" 48 | make -C $RISCY_HOME/tools/elf2hex 49 | if [ ! -f $RISCY_HOME/tools/elf2hex/elf2hex ] ; then 50 | echo "[ERROR] Compilation failed" 51 | exit 1 52 | fi 53 | fi 54 | 55 | if [ $# -eq 0 ] ; then 56 | ELF_FILE=$RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add 57 | else 58 | ELF_FILE=$1 59 | fi 60 | 61 | if [ ! -f $ELF_FILE ] ; then 62 | echo "[ERROR] Can't find elf file $ELF_FILE" 63 | exit 1 64 | fi 65 | 66 | # Make ram.hex for this processor 67 | $RISCY_HOME/tools/elf2hex/elf2hex $ELF_FILE 0x80000000 256K ram.hex 68 | -------------------------------------------------------------------------------- /procs/riscy-lib/Abstraction.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import ClientServer::*; 25 | import Connectable::*; 26 | import DefaultValue::*; 27 | import GetPut::*; 28 | import Vector::*; 29 | 30 | import MemUtil::*; 31 | import Port::*; 32 | 33 | import ProcPins::*; 34 | import RVTypes::*; 35 | import VerificationPacket::*; 36 | 37 | ///////////////////////////////////////////// 38 | // Types for the three module abstraction: // 39 | ///////////////////////////////////////////// 40 | 41 | typedef struct { 42 | VMInfo#(xlen) vmI; // only if MMU is in front-end 43 | CsrState state; // Bit#(2) prv; 44 | // Bit#(3) frm; 45 | // Bool f_enabled; 46 | // Bool x_enabled; 47 | } FrontEndCsrs#(numeric type xlen) deriving (Bits, Eq, FShow); 48 | instance DefaultValue#(CsrState); 49 | function CsrState defaultValue = CsrState {prv: prvM, frm: 0, f_enabled: False, x_enabled: False}; 50 | endinstance 51 | instance DefaultValue#(FrontEndCsrs#(xlen)); 52 | function FrontEndCsrs#(xlen) defaultValue = FrontEndCsrs {vmI: defaultValue, state: defaultValue}; 53 | endinstance 54 | 55 | typedef Bit#(addrSz) RVIMMUReq#(numeric type addrSz); // maybe add prv 56 | typedef struct { 57 | Bit#(xlen) addr; 58 | Maybe#(ExceptionCause) exception; 59 | } RVIMMUResp#(numeric type xlen) deriving (Bits, Eq, FShow); 60 | 61 | typedef struct { 62 | Bit#(xlen) addr; 63 | RVMemSize size; // for address misaligned 64 | RVMemOp op; // really just load or store (amo counts as store) 65 | } RVDMMUReq#(numeric type xlen) deriving (Bits, Eq, FShow); 66 | typedef RVIMMUResp#(addrSz) RVDMMUResp#(numeric type addrSz); 67 | 68 | // typedef struct { 69 | // RVMemAmoOp op; 70 | // RVMemSize size; 71 | // Bool isUnsigned; 72 | // PAddr addr; 73 | // Data data; 74 | // // Bool aq; // XXX: I don't think these are necessary 75 | // // Bool rl; // XXX: I don't think these are necessary 76 | // } RVDMemReq deriving (Bits, Eq, FShow); 77 | // typedef Data RVDMemResp; 78 | 79 | typedef Fence FenceReq; 80 | typedef void FenceResp; 81 | 82 | interface Proc#(numeric type mainMemoryWidth); 83 | // Processor Control 84 | method Action start(); 85 | method Action stop(); 86 | 87 | // Verification 88 | method Maybe#(VerificationPacket) currVerificationPacket; 89 | 90 | // Cached Connections 91 | interface CoarseMemClientPort#(XLEN, TLog#(TDiv#(mainMemoryWidth,8))) ram; 92 | // Uncached Connections 93 | interface CoarseMemClientPort#(XLEN, TLog#(TDiv#(XLEN,8))) mmio; 94 | // External Connections 95 | interface CoarseMemServerPort#(XLEN, TLog#(TDiv#(XLEN,8))) extmem; 96 | // Interrupts 97 | method Action triggerExternalInterrupt; 98 | 99 | method Action stallPipeline(Bool stall); 100 | 101 | // Pins 102 | (* prefix = "" *) 103 | interface ProcPins pins; 104 | endinterface 105 | -------------------------------------------------------------------------------- /procs/riscy-lib/Bht.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import RVTypes::*; 25 | import RegFile::*; 26 | import Vector::*; 27 | 28 | interface DirPred; 29 | method Bool dirPred(Addr pc); 30 | method Action update(Addr pc, Bool taken); 31 | endinterface 32 | 33 | // Local BHT Typedefs 34 | typedef 64 BhtEntries; 35 | typedef Bit#(TLog#(BhtEntries)) BhtIndex; 36 | 37 | (* synthesize, gate_all_clocks *) 38 | module mkBht(DirPred); 39 | // Read and Write ordering doesn't matter since this is a predictor 40 | // mkRegFileWCF is the RegFile version of mkConfigReg 41 | RegFile#(BhtIndex, Bit#(2)) hist <- mkRegFileWCF(0,fromInteger(valueOf(BhtEntries)-1)); 42 | 43 | function BhtIndex getIndex(Addr pc); 44 | return truncate(pc >> 2); 45 | endfunction 46 | 47 | method Bool dirPred(Addr pc); 48 | let index = getIndex(pc); 49 | return unpack(hist.sub(index)[1]); 50 | endmethod 51 | 52 | method Action update(Addr pc, Bool taken); 53 | let index = getIndex(pc); 54 | let current_hist = hist.sub(index); 55 | Bit#(2) next_hist; 56 | if(taken) begin 57 | next_hist = (current_hist == 2'b11) ? 2'b11 : current_hist + 1; 58 | end else begin 59 | next_hist = (current_hist == 2'b00) ? 2'b00 : current_hist - 1; 60 | end 61 | hist.upd(index, next_hist); 62 | endmethod 63 | endmodule 64 | 65 | -------------------------------------------------------------------------------- /procs/riscy-lib/BootRom.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import BRAM::*; 25 | import BuildVector::*; 26 | import Vector::*; 27 | 28 | import ConcatReg::*; 29 | import Ehr::*; 30 | import MemUtil::*; 31 | import PolymorphicMem::*; 32 | import Port::*; 33 | import RegUtil::*; 34 | 35 | import Abstraction::*; 36 | import RVExec::*; 37 | import RVTypes::*; 38 | 39 | typedef struct { 40 | Addr bootrom_addr; 41 | Addr start_addr; 42 | Addr config_string_addr; 43 | } BootRomConfig deriving (Eq); 44 | 45 | module mkBasicBootRom32#(BootRomConfig cfg)(ReadOnlyMemServerPort#(addrSz, 2)) 46 | provisos (MkPolymorphicMemFromRegs#(ReadOnlyMemReq#(addrSz, 2), ReadOnlyMemResp#(2), 4, 32)); 47 | Vector#(4, Reg#(Bit#(32))) rom = 48 | vec( 49 | readOnlyReg('h297 + truncate(cfg.start_addr - cfg.bootrom_addr)), 50 | readOnlyReg(32'h00028067), 51 | readOnlyReg(32'h00000000), 52 | readOnlyReg(truncate(cfg.config_string_addr)) 53 | ); 54 | let memIfc <- mkPolymorphicMemFromRegs(rom); 55 | return memIfc; 56 | endmodule 57 | 58 | module mkBasicBootRom64#(BootRomConfig cfg)(ReadOnlyMemServerPort#(addrSz, 3)) 59 | provisos (MkPolymorphicMemFromRegs#(ReadOnlyMemReq#(addrSz, 3), ReadOnlyMemResp#(3), 2, 64)); 60 | Vector#(2, Reg#(Bit#(64))) rom = 61 | vec( 62 | concatReg2(readOnlyReg(32'h00028067), readOnlyReg('h297 + truncate(cfg.start_addr - cfg.bootrom_addr))), 63 | concatReg2(readOnlyReg(truncate(cfg.config_string_addr)), readOnlyReg(32'h00000000)) 64 | ); 65 | let memIfc <- mkPolymorphicMemFromRegs(rom); 66 | return memIfc; 67 | endmodule 68 | 69 | -------------------------------------------------------------------------------- /procs/riscy-lib/Btb.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import ConfigReg::*; 25 | import RegFile::*; 26 | import RVTypes::*; 27 | import Vector::*; 28 | 29 | interface NextAddrPred; 30 | method Addr predPc(Addr pc); 31 | method Action update(Addr pc, Addr nextPc, Bool taken); 32 | endinterface 33 | 34 | // Local BTB Typedefs 35 | typedef 16 BtbEntries; 36 | typedef Bit#(TLog#(BtbEntries)) BtbIndex; 37 | typedef Bit#(TSub#(TSub#(AddrSz, TLog#(BtbEntries)), 2)) BtbTag; 38 | 39 | (* synthesize, gate_all_clocks *) 40 | module mkBtb(NextAddrPred); 41 | // Read and Write ordering doesn't matter since this is a predictor 42 | // mkRegFileWCF is the RegFile version of mkConfigReg 43 | RegFile#(BtbIndex, Addr) next_addrs <- mkRegFileWCF(0,fromInteger(valueOf(BtbEntries)-1)); 44 | RegFile#(BtbIndex, BtbTag) tags <- mkRegFileWCF(0,fromInteger(valueOf(BtbEntries)-1)); 45 | Vector#(BtbEntries, Reg#(Bool)) valid <- replicateM(mkConfigReg(False)); 46 | 47 | function BtbIndex getIndex(Addr pc) = truncate(pc >> 2); 48 | function BtbTag getTag(Addr pc) = truncateLSB(pc); 49 | 50 | method Addr predPc(Addr pc); 51 | BtbIndex index = getIndex(pc); 52 | BtbTag tag = getTag(pc); 53 | if(valid[index] && tag == tags.sub(index)) 54 | return next_addrs.sub(index); 55 | else 56 | return (pc + 4); 57 | endmethod 58 | 59 | method Action update(Addr pc, Addr nextPc, Bool taken); 60 | let index = getIndex(pc); 61 | let tag = getTag(pc); 62 | if(taken) begin 63 | valid[index] <= True; 64 | tags.upd(index, tag); 65 | next_addrs.upd(index, nextPc); 66 | end else if( tags.sub(index) == tag ) begin 67 | // current instruction has target in btb, so clear it 68 | valid[index] <= False; 69 | end 70 | endmethod 71 | endmodule 72 | 73 | -------------------------------------------------------------------------------- /procs/riscy-lib/MemoryMappedCSRs.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import ClientServer::*; 27 | import GetPut::*; 28 | import Vector::*; 29 | 30 | import CompareProvisos::*; 31 | import Ehr::*; 32 | import MemUtil::*; 33 | import Port::*; 34 | 35 | import Abstraction::*; 36 | import RVTypes::*; 37 | 38 | interface MemoryMappedCSRs#(numeric type xlen, numeric type cores); 39 | // memory-mapped interface 40 | // 0x0000 = timer 41 | // 0x0008 = timecmp0 42 | // 0x0010 = timecmp1 43 | // ... 44 | // 0x1000 = ipi0 45 | // 0x2000 = ipi1 46 | // ... 47 | interface CoarseMemServerPort#(xlen, TLog#(TDiv#(xlen,8))) memifc; 48 | method Bit#(64) timerValue; 49 | method Vector#(cores, Bool) timerInterrupt; 50 | method Vector#(cores, Bool) ipi; 51 | endinterface 52 | 53 | module mkMemoryMappedCSRs64#(PAddr baseaddr)(MemoryMappedCSRs#(64, cores)) provisos (LT#(cores, 16)); 54 | // this doesn't work for 16 or more cores since it assumes a 16 bit address space 55 | Reg#(Maybe#(CoarseMemResp#(3))) resp <- mkReg(tagged Invalid); 56 | 57 | Reg#(Bit#(10)) subTimer <- mkReg(0); 58 | Reg#(Bit#(64)) timer <- mkReg(0); 59 | Ehr#(2, Maybe#(Bit#(64))) newTimeEhr <- mkEhr(tagged Invalid); 60 | Vector#(cores, Reg#(Bit#(64))) timeCmp <- replicateM(mkReg('1)); 61 | Vector#(cores, Reg#(Bool)) ipiReg <- replicateM(mkReg(False)); 62 | 63 | rule incrementTimer; 64 | if (newTimeEhr[1] matches tagged Valid .validNewTime) begin 65 | subTimer <= 0; 66 | timer <= validNewTime; 67 | end else begin 68 | Bool overflow = subTimer == 999; 69 | subTimer <= overflow ? 0 : subTimer + 1; 70 | timer <= overflow ? timer + 1 : timer; 71 | end 72 | newTimeEhr[1] <= tagged Invalid; 73 | endrule 74 | 75 | interface CoarseMemServerPort memifc; 76 | interface InputPort request; 77 | method Action enq(CoarseMemReq#(64, 3) req) if (!isValid(resp)); 78 | CoarseMemResp#(3) newResp = CoarseMemResp{write: req.write, data: 0}; 79 | Bit#(16) addr = truncate(req.addr - baseaddr); 80 | if (addr < 16'h1000) begin 81 | // RTC registers 82 | let index = addr >> 3; 83 | if (index <= fromInteger(valueof(cores))) begin 84 | if (index == 0) begin 85 | if (req.write) begin 86 | newTimeEhr[0] <= tagged Valid req.data; 87 | end else begin 88 | newResp.data = timer; 89 | end 90 | end else begin 91 | if (req.write) begin 92 | timeCmp[index] <= req.data; 93 | end else begin 94 | newResp.data = timeCmp[index]; 95 | end 96 | end 97 | end else begin 98 | $fdisplay(stderr, "[ERROR] MemoryMappedCSRs: unexpected mem request: ", fshow(req)); 99 | end 100 | end else begin 101 | // IPI registers 102 | if ((addr & 16'h0FF8) == 0) begin 103 | let index = addr >> 12; 104 | if (index < fromInteger(valueof(cores))) begin 105 | if (req.write) begin 106 | ipiReg[index] <= unpack(req.data[0]); 107 | end else begin 108 | newResp.data = zeroExtend(pack(ipiReg[index])); 109 | end 110 | end else begin 111 | $fdisplay(stderr, "[ERROR] MemoryMappedCSRs: unexpected mem request: ", fshow(req)); 112 | end 113 | end else begin 114 | $fdisplay(stderr, "[ERROR] MemoryMappedCSRs: unexpected mem request: ", fshow(req)); 115 | end 116 | end 117 | resp <= tagged Valid newResp; 118 | endmethod 119 | method Bool canEnq; 120 | return !isValid(resp); 121 | endmethod 122 | endinterface 123 | interface OutputPort response; 124 | method CoarseMemResp#(3) first if (resp matches tagged Valid .validResp); 125 | return validResp; 126 | endmethod 127 | method Action deq if (resp matches tagged Valid .validResp); 128 | resp <= tagged Invalid; 129 | endmethod 130 | method Bool canDeq; 131 | return isValid(resp); 132 | endmethod 133 | endinterface 134 | endinterface 135 | method Bit#(64) timerValue = timer; 136 | method Vector#(cores, Bool) timerInterrupt = zipWith( \>= , replicate(timer), readVReg(timeCmp)); 137 | method Vector#(cores, Bool) ipi = readVReg(ipiReg); 138 | endmodule 139 | -------------------------------------------------------------------------------- /procs/riscy-lib/ProcPins.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import RS232::*; 27 | import SPI::*; 28 | 29 | export SPIMasterPins(..); 30 | export RS232(..); 31 | export ProcPins(..); 32 | 33 | interface ProcPins; 34 | `ifdef CONFIG_RS232 35 | interface RS232 uart; 36 | `endif 37 | `ifdef CONFIG_SPI 38 | interface SPIMasterPins spi; 39 | `endif 40 | // This is to avoid BSV errors 41 | interface Clock deleteme_unused_clock; 42 | endinterface 43 | -------------------------------------------------------------------------------- /procs/riscy-lib/RTC.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import BuildVector::*; 27 | import ClientServer::*; 28 | import ConfigReg::*; 29 | import GetPut::*; 30 | import Vector::*; 31 | 32 | import Ehr::*; 33 | import PolymorphicMem::*; 34 | import Port::*; 35 | 36 | import Abstraction::*; 37 | 38 | interface RTC#(numeric type cores, type memIfcT); 39 | // memory-mapped interface 40 | // 0x0000 = timer 41 | // 0x0008 = timecmp0 42 | // 0x0010 = timecmp1 43 | // ... 44 | interface memIfcT memifc; 45 | method Bit#(64) timerValue; 46 | method Vector#(cores, Bool) timerInterrupt; 47 | endinterface 48 | 49 | // This is only supported on RV32 systems 50 | // Only supports full-word memory accesses 51 | module mkRTC_RV32(RTC#(1, ServerPort#(reqT, respT))) provisos (MkPolymorphicMemFromRegs#(reqT, respT, 4, 32)); 52 | // memory mapped registers 53 | // make the time registers config registers to avoid complicated 54 | // scheduling constraints between the memory system and the CSRF 55 | Reg#(Bit#(32)) timeRegLo <- mkConfigReg(0); 56 | Reg#(Bit#(32)) timeRegHi <- mkConfigReg(0); 57 | Reg#(Bit#(32)) timeCmpLo <- mkConfigReg(0); 58 | Reg#(Bit#(32)) timeCmpHi <- mkConfigReg(0); 59 | 60 | Bool timerInterruptEn = {timeRegHi, timeRegLo} >= {timeCmpHi, timeCmpLo}; 61 | 62 | Vector#(4, Reg#(Bit#(32))) memoryMappedRegisters = vec( 63 | asReg(timeRegLo), // 0x00 64 | asReg(timeRegHi), // 0x04 65 | asReg(timeCmpLo), // 0x08 66 | asReg(timeCmpHi)); // 0x0C 67 | ServerPort#(reqT, respT) memoryMappedIfc <- mkPolymorphicMemFromRegs(memoryMappedRegisters); 68 | 69 | rule incrementTimer; 70 | Bit#(64) timeValue = {timeRegHi, timeRegLo}; 71 | Bit#(64) newTimeValue = timeValue + 1; 72 | timeRegLo <= newTimeValue[31:0]; 73 | timeRegHi <= newTimeValue[63:32]; 74 | endrule 75 | 76 | interface ServerPort memifc = memoryMappedIfc; 77 | method Bit#(64) timerValue = {timeRegHi, timeRegLo}; 78 | method Vector#(1, Bool) timerInterrupt = vec(timerInterruptEn); 79 | endmodule 80 | 81 | // This is only supported on RV64 systems 82 | // Only supports full-word memory accesses 83 | // Also, this doesn't support polymorphic mem yet 84 | module mkRTC_RV64(RTC#(1, ServerPort#(reqT, respT))) provisos (MkPolymorphicMemFromRegs#(reqT, respT, 2, 64)); 85 | // memory mapped registers 86 | // make the time registers config registers to avoid complicated 87 | // scheduling constraints between the memory system and the CSRF 88 | Reg#(Bit#(64)) timeReg <- mkConfigReg(0); 89 | Reg#(Bit#(64)) timeCmp <- mkConfigReg(0); 90 | 91 | Bool timerInterruptEn = timeReg >= timeCmp; 92 | 93 | Vector#(2, Reg#(Bit#(64))) memoryMappedRegisters = vec( 94 | asReg(timeReg), // 0x00 95 | asReg(timeCmp)); // 0x08 96 | ServerPort#(reqT, respT) memoryMappedIfc <- mkPolymorphicMemFromRegs(memoryMappedRegisters); 97 | 98 | rule incrementTimer; 99 | timeReg <= timeReg + 1; 100 | endrule 101 | 102 | interface ServerPort memifc = memoryMappedIfc; 103 | method Bit#(64) timerValue = timeReg; 104 | method Vector#(1, Bool) timerInterrupt = vec(timerInterruptEn); 105 | endmodule 106 | -------------------------------------------------------------------------------- /procs/riscy-lib/RVAlu.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | import RVTypes::*; 27 | 28 | typeclass ExecAluInst#(numeric type xlen); 29 | function Bit#(xlen) execAluInst(AluInst aluInst, Bit#(xlen) rVal1, Bit#(xlen) rVal2, Maybe#(Bit#(xlen)) imm, Bit#(xlen) pc); 30 | endtypeclass 31 | 32 | instance ExecAluInst#(32); 33 | function Bit#(32) execAluInst(AluInst aluInst, Bit#(32) rVal1, Bit#(32) rVal2, Maybe#(Bit#(32)) imm, Bit#(32) pc); 34 | Bit#(32) aluVal1 = (case (aluInst.op) 35 | Auipc: pc; 36 | Lui: 0; 37 | default: rVal1; 38 | endcase); 39 | Bit#(32) aluVal2 = (case (imm) matches 40 | tagged Valid .validImm: validImm; 41 | default: rVal2; 42 | endcase); 43 | 44 | Bit#(32) data = alu32(aluInst.op, aluVal1, aluVal2); 45 | 46 | return data; 47 | endfunction 48 | endinstance 49 | 50 | instance ExecAluInst#(64); 51 | function Bit#(64) execAluInst(AluInst aluInst, Bit#(64) rVal1, Bit#(64) rVal2, Maybe#(Bit#(64)) imm, Bit#(64) pc); 52 | Bit#(64) aluVal1 = (case (aluInst.op) 53 | Auipc: pc; 54 | Lui: 0; 55 | default: rVal1; 56 | endcase); 57 | Bit#(64) aluVal2 = (case (imm) matches 58 | tagged Valid .validImm: validImm; 59 | default: rVal2; 60 | endcase); 61 | 62 | Bit#(64) data = alu64(aluInst.op, aluInst.w, aluVal1, aluVal2); 63 | 64 | return data; 65 | endfunction 66 | endinstance 67 | 68 | // RV64 ALU -- no need to use Data or other similar types because this has the 69 | // "w" field only seen in 64-bit RISC-V, but it doesn't have the necessary 70 | // inputs for 128-bit RISC-V 71 | (* noinline *) 72 | function Bit#(64) alu64(AluFunc func, Bool w, Bit#(64) a, Bit#(64) b); 73 | // setup inputs 74 | if (w) begin 75 | a = (func == Sra) ? signExtend(a[31:0]) : zeroExtend(a[31:0]); 76 | b = zeroExtend(b[31:0]); 77 | end 78 | Bit#(6) shamt = truncate(b); 79 | if (w) begin 80 | shamt = {1'b0, shamt[4:0]}; 81 | end 82 | 83 | Bit#(64) res = (case(func) 84 | Add: (a + b); 85 | Sub: (a - b); 86 | And: (a & b); 87 | Or: (a | b); 88 | Xor: (a ^ b); 89 | Slt: zeroExtend( pack( signedLT(a, b) ) ); 90 | Sltu: zeroExtend( pack( a < b ) ); 91 | Sll: (a << shamt); 92 | Srl: (a >> shamt); 93 | Sra: signedShiftRight(a, shamt); 94 | Auipc: (a + b); 95 | Lui: (a + b); 96 | default: 0; 97 | endcase); 98 | 99 | if (w) begin 100 | res = signExtend(res[31:0]); 101 | end 102 | 103 | return res; 104 | endfunction 105 | 106 | // RV32 ALU -- no need to use Data or other similar types because this doesn't 107 | // have the support necessary for larger ISAs 108 | (* noinline *) 109 | function Bit#(32) alu32(AluFunc func, Bit#(32) a, Bit#(32) b); 110 | // setup inputs 111 | Bit#(5) shamt = truncate(b); 112 | 113 | Bit#(32) res = (case(func) 114 | Add: (a + b); 115 | Sub: (a - b); 116 | And: (a & b); 117 | Or: (a | b); 118 | Xor: (a ^ b); 119 | Slt: zeroExtend( pack( signedLT(a, b) ) ); 120 | Sltu: zeroExtend( pack( a < b ) ); 121 | Sll: (a << shamt); 122 | Srl: (a >> shamt); 123 | Sra: signedShiftRight(a, shamt); 124 | Auipc: (a + b); 125 | Lui: (a + b); 126 | default: 0; 127 | endcase); 128 | 129 | return res; 130 | endfunction 131 | 132 | -------------------------------------------------------------------------------- /procs/riscy-lib/RVControl.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import RVTypes::*; 25 | 26 | function Bit#(xlen) execControl(BrFunc brFunc, Bit#(xlen) rVal1, Bit#(xlen) rVal2, Maybe#(Bit#(xlen)) imm, Bit#(xlen) pc); 27 | // XXX: This should only be used with a valid imm 28 | Bool taken = aluBr(brFunc, rVal1, rVal2); 29 | Bit#(xlen) targetPc = brAddrCalc(brFunc, pc, rVal1, fromMaybe(?, imm)); 30 | return taken ? targetPc : (pc + 4); 31 | endfunction 32 | 33 | function Bool aluBr(BrFunc brFunc, Bit#(xlen) a, Bit#(xlen) b); 34 | Bool eq = (a == b); 35 | Bool lt = signedLT(a,b); 36 | Bool ltu = (a < b); 37 | Bool brTaken = (case(brFunc) 38 | Eq: eq; 39 | Neq: (!eq); 40 | Lt: lt; 41 | Ltu: ltu; 42 | Ge: (!lt); 43 | Geu: (!ltu); 44 | Jal: True; 45 | Jalr: True; 46 | default: True; 47 | endcase); 48 | return brTaken; 49 | endfunction 50 | 51 | function Bit#(xlen) brAddrCalc(BrFunc brFunc, Bit#(xlen) pc, Bit#(xlen) val, Bit#(xlen) imm); 52 | Bit#(xlen) in1 = (brFunc == Jalr) ? val : pc; 53 | Bit#(xlen) addOut = in1 + imm; 54 | // if JALR, zero LSB 55 | Bit#(xlen) targetAddr = (brFunc == Jalr) ? (addOut & (~1)) : addOut; 56 | return targetAddr; 57 | 58 | // XXX: Old implementation 59 | // Addr targetAddr = (case (brFunc) 60 | // Jal: (pc + imm); 61 | // Jalr: {(val + imm)[valueOf(AddrSz)-1:1], 1'b0}; 62 | // default: (pc + imm); 63 | // endcase); 64 | // return targetAddr; 65 | endfunction 66 | 67 | -------------------------------------------------------------------------------- /procs/riscy-lib/RVMemory.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import RVTypes::*; 25 | 26 | function Bit#(xlen) addrCalc(Bit#(xlen) rVal1, Maybe#(Bit#(xlen)) imm); 27 | return rVal1 + fromMaybe(0, imm); 28 | endfunction 29 | 30 | //function Data gatherLoad(Addr addr, ByteEn byteEn, Bool unsignedLd, Data data); 31 | // function extend = unsignedLd ? zeroExtend : signExtend; 32 | // Bit#(IndxShamt) offset = truncate(addr); 33 | // 34 | // if(byteEn[7]) begin 35 | // return extend(data); 36 | // end else if(byteEn[3]) begin 37 | // Vector#(2, Bit#(32)) dataVec = unpack(data); 38 | // return extend(dataVec[offset[2]]); 39 | // end else if(byteEn[1]) begin 40 | // Vector#(4, Bit#(16)) dataVec = unpack(data); 41 | // return extend(dataVec[offset[2:1]]); 42 | // end else begin 43 | // Vector#(8, Bit#(8)) dataVec = unpack(data); 44 | // return extend(dataVec[offset]); 45 | // end 46 | //endfunction 47 | // 48 | //function Tuple2#(ByteEn, Data) scatterStore(Addr addr, ByteEn byteEn, Data data); 49 | // Bit#(IndxShamt) offset = truncate(addr); 50 | // if(byteEn[7]) begin 51 | // return tuple2(byteEn, data); 52 | // end else if(byteEn[3]) begin 53 | // return tuple2(unpack(pack(byteEn) << (offset)), data << {(offset), 3'b0}); 54 | // end else if(byteEn[1]) begin 55 | // return tuple2(unpack(pack(byteEn) << (offset)), data << {(offset), 3'b0}); 56 | // end else begin 57 | // return tuple2(unpack(pack(byteEn) << (offset)), data << {(offset), 3'b0}); 58 | // end 59 | //endfunction 60 | 61 | -------------------------------------------------------------------------------- /procs/riscy-lib/RVSPI.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | // This is a wrapper for SPI.bsv to provide a memory-mapped interface for 25 | // integration with the Riscy processors. 26 | 27 | import BuildVector::*; 28 | import ClientServer::*; 29 | import Vector::*; 30 | import GetPut::*; 31 | import Vector::*; 32 | 33 | import ConcatReg::*; 34 | import Ehr::*; 35 | import PolymorphicMem::*; 36 | import Port::*; 37 | import RegUtil::*; 38 | 39 | import Abstraction::*; 40 | import SPI::*; 41 | 42 | interface RVSPI#(type memIfcT); 43 | // Memory mapped interface 44 | interface memIfcT memifc; 45 | 46 | // Pins 47 | (* prefix = "" *) 48 | interface SPIMasterPins spi_pins; 49 | endinterface 50 | 51 | module mkRVSPI(RVSPI#(ServerPort#(reqT, respT))) provisos (MkPolymorphicMemFromRegs#(reqT, respT, 4, 32)); 52 | // Layout of memory interface 53 | // Address Name Description 54 | // 0x0000 txData Transmit data register 55 | // 0x0004 rxData Receive data register 56 | // 0x0008 enable Chip select enable register 57 | // bit 0 - set to enable SD card 58 | // 0x000C div Sclk divider 59 | 60 | SPIMaster spi <- mkSPIMaster; 61 | 62 | Reg#(Maybe#(Bit#(8))) txDataReg <- mkReg(tagged Invalid); 63 | Reg#(Maybe#(Bit#(8))) rxDataReg <- mkReg(tagged Invalid); 64 | Reg#(Bit#(32)) enableReg = 65 | (interface Reg; 66 | method Action _write(Bit#(32) x); 67 | spi.setNcs(~x[0]); 68 | endmethod 69 | method Bit#(32) _read; 70 | return {0, pack(spi.isChipSelectEnabled())}; 71 | endmethod 72 | endinterface); 73 | Reg#(Bit#(32)) divReg = 74 | (interface Reg; 75 | method Action _write(Bit#(32) x); 76 | spi.setSclkDiv(truncate(x)); 77 | endmethod 78 | method Bit#(32) _read; 79 | return 0; 80 | endmethod 81 | endinterface); 82 | 83 | Vector#(4, Reg#(Bit#(32))) memoryMappedRegisters = vec( 84 | concatReg3(readOnlyReg(pack(isValid(txDataReg))), readOnlyReg(0), fromMaybeReg(0, txDataReg)), 85 | concatReg3(readOnlyReg(pack(isValid(rxDataReg))), readOnlyReg(0), fromMaybeReg(0, rxDataReg)), 86 | enableReg, 87 | divReg); 88 | 89 | ServerPort#(reqT, respT) memoryMappedIfc <- mkPolymorphicMemFromRegs(memoryMappedRegisters); 90 | 91 | rule doTxData (txDataReg matches tagged Valid .x); 92 | spi.put(x); 93 | txDataReg <= tagged Invalid; 94 | endrule 95 | 96 | rule doRxData (rxDataReg matches tagged Invalid .x); 97 | let data <- spi.get; 98 | rxDataReg <= tagged Valid data; 99 | endrule 100 | 101 | interface ServerPort memifc = memoryMappedIfc; 102 | 103 | interface SPIMasterPins spi_pins = spi.pins; 104 | endmodule 105 | -------------------------------------------------------------------------------- /procs/riscy-lib/RVUart.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import BuildVector::*; 25 | import ClientServer::*; 26 | import GetPut::*; 27 | import RS232::*; 28 | import Vector::*; 29 | 30 | import ConcatReg::*; 31 | import Ehr::*; 32 | import PolymorphicMem::*; 33 | import Port::*; 34 | import RegUtil::*; 35 | 36 | import Abstraction::*; 37 | 38 | interface RVUart#(type memIfcT); 39 | // Internal connections 40 | interface memIfcT memifc; 41 | 42 | // external connections for rx/tx (to be connected to a UART 43 | (* prefix = "" *) 44 | interface RS232 uart_pins; 45 | method Bit#(16) divisor; 46 | method Bool interrupt; 47 | endinterface 48 | 49 | module mkRVUart_RV32#(Bit#(16) divisor)(RVUart#(ServerPort#(reqT, respT))) provisos (MkPolymorphicMemFromRegs#(reqT, respT, 5, 32)); 50 | Bool verbose = False; 51 | 52 | // memory mapped registers 53 | Reg#(Maybe#(Bit#(8))) txDataReg <- mkReg(tagged Invalid); 54 | Reg#(Maybe#(Bit#(8))) rxDataReg <- mkReg(tagged Invalid); 55 | Reg#(Bit#(32)) txCtrlReg <- mkReg(0); 56 | Reg#(Bit#(32)) rxCtrlReg <- mkReg(0); 57 | Reg#(Bit#(16)) divReg <- mkReg(divisor); 58 | 59 | Vector#(5, Reg#(Bit#(32))) memoryMappedRegisters = 60 | vec( 61 | concatReg3(readOnlyReg(pack(isValid(txDataReg))), readOnlyReg(0), fromMaybeReg(0, txDataReg)), 62 | concatReg3(readOnlyReg(pack(isValid(rxDataReg))), readOnlyReg(0), fromMaybeReg(0, rxDataReg)), 63 | txCtrlReg, 64 | rxCtrlReg, 65 | zeroExtendReg(divReg) 66 | ); 67 | ServerPort#(reqT, respT) memoryMappedIfc <- mkPolymorphicMemFromRegs(memoryMappedRegisters); 68 | 69 | UART#(16) uart <- mkUART(8, NONE, STOP_1, divReg); 70 | 71 | rule doTxData (txDataReg matches tagged Valid .x); 72 | // There is an implicit guard on the Fifo for uart.put 73 | uart.rx.put(x); 74 | txDataReg <= tagged Invalid; 75 | endrule 76 | 77 | rule doRxData (rxDataReg matches tagged Invalid .x); 78 | // There is an implicit guard on the Fifo for uart.get 79 | let data <- uart.tx.get; 80 | rxDataReg <= Valid(data); 81 | endrule 82 | 83 | interface ServerPort memifc = memoryMappedIfc; 84 | 85 | interface RS232 uart_pins = uart.rs232; 86 | method Bit#(16) divisor = divReg; 87 | method Bool interrupt = isValid(rxDataReg); 88 | endmodule 89 | -------------------------------------------------------------------------------- /procs/riscy-lib/Ras.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import RegFile::*; 25 | import RVTypes::*; 26 | import Vector::*; 27 | 28 | interface ReturnAddrStack; 29 | method Action pushAddress(Addr a); 30 | method ActionValue#(Addr) popAddress(); 31 | endinterface 32 | 33 | // Local RAS Typedefs 34 | typedef 8 RasEntries; 35 | typedef Bit#(TLog#(RasEntries)) RasIndex; 36 | 37 | (* synthesize, gate_all_clocks *) 38 | module mkRas( ReturnAddrStack ); 39 | Vector#(RasEntries, Reg#(Addr)) stack <- replicateM(mkReg(0)); 40 | 41 | // head points past valid data 42 | // to gracefully overflow, head is allowed to overflow to 0 and overwrite the oldest data 43 | Reg#(RasIndex) head <- mkReg(0); 44 | 45 | RasIndex max_head = fromInteger(valueOf(RasEntries)-1); 46 | 47 | method Action pushAddress(Addr a); 48 | stack[head] <= a; 49 | head <= (head == max_head) ? 0 : head + 1; 50 | endmethod 51 | 52 | method ActionValue#(Addr) popAddress(); 53 | let new_head = (head == 0) ? max_head : head - 1; 54 | head <= new_head; 55 | return stack[new_head]; 56 | endmethod 57 | endmodule 58 | -------------------------------------------------------------------------------- /procs/riscy-lib/SPI.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | // For information about SPI, check wikipedia: 25 | // https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus 26 | 27 | (* always_ready, always_enabled *) 28 | interface SPIMasterPins; 29 | // serial clock 30 | (* prefix = "", result = "sclk" *) 31 | method Bit#(1) sclk; 32 | // master-out slave-in 33 | (* prefix = "", result = "mosi" *) 34 | method Bit#(1) mosi; 35 | // master-in slave-out 36 | (* prefix = "" *) 37 | method Action miso((* port = "miso" *)Bit#(1) x); 38 | // active-low chip select 39 | (* prefix = "", result = "ncs" *) 40 | method Bit#(1) ncs; 41 | endinterface 42 | 43 | interface SPIMaster; 44 | // configuration 45 | method Action setSclkDiv(Bit#(16) d); 46 | method Action setNcs(Bit#(1) new_ncs); 47 | method Action setCpol(Bit#(1) new_cpol); // idle value of clock 48 | method Action setCpha(Bit#(1) new_cpha); // which clock transition captures data 49 | // cpha = 0 => odd transitions (1st, 3rd, etc.) 50 | // cpha = 1 => even transitions (2nd, 4th, etc.) 51 | // status 52 | method Bool isChipSelectEnabled(); 53 | // data 54 | method Action put(Bit#(8) x); 55 | method ActionValue#(Bit#(8)) get(); 56 | // pins 57 | (* prefix = "" *) 58 | interface SPIMasterPins pins; 59 | endinterface 60 | 61 | module mkSPIMaster(SPIMaster); 62 | let clock <- exposeCurrentClock(); 63 | // registers for the interface pins 64 | Reg#(Bit#(1)) sclkReg <- mkReg(0); 65 | Reg#(Bit#(16)) sclkDiv <- mkReg(1); 66 | Wire#(Bit#(1)) misoWire <- mkDWire(0); 67 | Reg#(Bit#(1)) misoReg <- mkReg(0); 68 | Reg#(Bit#(1)) ncsReg <- mkReg(1); 69 | // MSB gets shifted out 70 | Reg#(Bit#(8)) shiftReg <- mkReg(0); 71 | 72 | // SPI configuration 73 | Reg#(Bit#(1)) cpol <- mkReg(0); 74 | Reg#(Bit#(1)) cpha <- mkReg(0); 75 | 76 | // 17 ticks per SPI cycle, between each tick is a clock transition 77 | Reg#(Bool) running <- mkReg(False); 78 | Reg#(Bool) resultReady <- mkReg(False); 79 | Reg#(Bit#(5)) tickCount <- mkReg(0); 80 | // sclkReg determines how many mini ticks make up a tick 81 | Reg#(Bit#(16)) miniTickCount <- mkReg(0); 82 | 83 | (* fire_when_enabled, no_implicit_conditions *) 84 | rule run(running); 85 | let nextMiniTickCount = miniTickCount + 1; 86 | if ((nextMiniTickCount == sclkDiv) || sclkDiv == 0) begin 87 | miniTickCount <= 0; 88 | if (tickCount == 16) begin 89 | // done 90 | running <= False; 91 | resultReady <= True; 92 | tickCount <= 0; 93 | end else begin 94 | // tick clock 95 | sclkReg <= ~sclkReg; 96 | // increment tickCount 97 | tickCount <= tickCount + 1; 98 | // either capture input or shift output 99 | if (tickCount[0] == cpha) begin 100 | // capture input 101 | misoReg <= misoWire; 102 | end else begin 103 | // shift output 104 | if (tickCount == 0) begin 105 | // but never on the first tick 106 | end else begin 107 | shiftReg <= {shiftReg[6:0], misoReg}; 108 | end 109 | end 110 | end 111 | end else begin 112 | miniTickCount <= nextMiniTickCount; 113 | end 114 | endrule 115 | 116 | method Action setSclkDiv(Bit#(16) d); 117 | sclkDiv <= d; 118 | endmethod 119 | method Action setNcs(Bit#(1) new_ncs); 120 | ncsReg <= new_ncs; 121 | endmethod 122 | method Action setCpol(Bit#(1) new_cpol); 123 | cpol <= new_cpol; 124 | endmethod 125 | method Action setCpha(Bit#(1) new_cpha); 126 | cpha <= new_cpha; 127 | endmethod 128 | 129 | method Bool isChipSelectEnabled(); 130 | return ncsReg == 0; 131 | endmethod 132 | 133 | method Action put(Bit#(8) x) if (!running); 134 | resultReady <= False; 135 | running <= True; 136 | tickCount <= 0; 137 | miniTickCount <= 0; 138 | shiftReg <= x; 139 | endmethod 140 | method ActionValue#(Bit#(8)) get() if (resultReady); 141 | resultReady <= False; 142 | return shiftReg; 143 | endmethod 144 | 145 | interface SPIMasterPins pins; 146 | method Bit#(1) sclk; 147 | return sclkReg; 148 | endmethod 149 | method Bit#(1) mosi; 150 | return running ? shiftReg[7] : 1; 151 | endmethod 152 | method Action miso(Bit#(1) x); 153 | misoWire <= x; 154 | endmethod 155 | method Bit#(1) ncs; 156 | return ncsReg; 157 | endmethod 158 | endinterface 159 | endmodule 160 | 161 | -------------------------------------------------------------------------------- /procs/riscy-lib/Scoreboard.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import SearchFIFO::*; 25 | import RVTypes::*; 26 | 27 | interface Scoreboard#(numeric type size); 28 | method Action insert(Maybe#(FullRegIndex) fullRegIndex); 29 | method Action remove; 30 | method Bool search1(Maybe#(FullRegIndex) fullRegIndex); 31 | method Bool search2(Maybe#(FullRegIndex) fullRegIndex); 32 | method Bool search3(Maybe#(FullRegIndex) fullRegIndex); 33 | method Bool notEmpty; 34 | method Action clear; 35 | endinterface 36 | 37 | module mkScoreboard(Scoreboard#(size)); 38 | function Bool isFound(Maybe#(FullRegIndex) x, Maybe#(FullRegIndex) y); 39 | return isValid(x) && isValid(y) && x == y; 40 | endfunction 41 | 42 | SearchFIFO#(size, Maybe#(FullRegIndex), Maybe#(FullRegIndex)) f <- mkSearchFIFO(isFound); 43 | 44 | method insert = f.enq; 45 | method remove = f.deq; 46 | method search1 = f.search; 47 | method search2 = f.search; 48 | method search3 = f.search; 49 | method notEmpty = f.notEmpty; 50 | method clear = f.clear; 51 | endmodule 52 | 53 | // scoreboard for bypassing 54 | module mkBypassingScoreboard(Scoreboard#(size)); 55 | function Bool isFound(Maybe#(FullRegIndex) x, Maybe#(FullRegIndex) y); 56 | return isValid(x) && isValid(y) && x == y; 57 | endfunction 58 | 59 | SearchFIFO#(size, Maybe#(FullRegIndex), Maybe#(FullRegIndex)) f <- mkPipelineSearchFIFO(isFound); 60 | 61 | method insert = f.enq; 62 | method remove = f.deq; 63 | method search1 = f.search; 64 | method search2 = f.search; 65 | method search3 = f.search; 66 | method notEmpty = f.notEmpty; 67 | method clear = f.clear; 68 | endmodule 69 | 70 | -------------------------------------------------------------------------------- /procs/riscy-lib/VerificationPacket.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | 26 | typedef struct { 27 | Bit#(64) skippedPackets; 28 | Bit#(64) pc; 29 | Bit#(32) instruction; 30 | Bit#(64) data; 31 | Bit#(64) addr; 32 | Bit#(7) dst; 33 | Bool exception; 34 | Bool interrupt; 35 | Bit#(4) cause; 36 | } VerificationPacket deriving (Bits); 37 | -------------------------------------------------------------------------------- /procs/riscy-lib/VerificationPacketFilter.bsv: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2016, 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | `include "ProcConfig.bsv" 25 | import RVTypes::*; 26 | import VerificationPacket::*; 27 | import FIFO::*; 28 | import FIFOLevel::*; 29 | 30 | interface VerificationPacketFilter; 31 | method Action init(Bit#(64) verificationPacketsToIgnore, Bool sendSynchronizationPackets); 32 | method ActionValue#(VerificationPacket) getPacket; 33 | method Bool nearFull; // full or one away from full 34 | method Bool nearEmpty; // 0 or 1 elements 35 | endinterface 36 | 37 | module mkVerificationPacketFilter#(function ActionValue#(VerificationPacket) packetIn)(VerificationPacketFilter); 38 | Reg#(Bit#(64)) ignoreCounter <- mkReg(0); 39 | Reg#(Bit#(64)) skippedCounter <- mkReg(0); 40 | Reg#(Bool) sendSynchronization <- mkReg(False); 41 | FIFOLevelIfc#(VerificationPacket, 4) packets <- mkFIFOLevel; 42 | 43 | `ifdef CONFIG_TEXTFILE_DEBUG 44 | Reg#(Bit#(64)) packet_count <- mkReg(1); 45 | Reg#(Bit#(64)) time_init <- mkReg('1); 46 | Reg#(Bool) tracefile_init <- mkReg(False); 47 | Reg#(File) tracefile <- mkReg(tagged InvalidFile); 48 | rule openFile(!tracefile_init); 49 | let file <- $fopen("trace.txt", "w"); 50 | tracefile <= file; 51 | tracefile_init <= True; 52 | endrule 53 | `endif 54 | 55 | rule getPackets; 56 | let packet <- packetIn; 57 | 58 | `ifdef CONFIG_TEXTFILE_DEBUG 59 | if (tracefile != tagged InvalidFile) begin 60 | let t <- $time; 61 | packet_count <= packet_count + 1; 62 | t = t >> 1; 63 | if (time_init == '1) begin 64 | time_init <= t - 1; 65 | t = 1; 66 | end else begin 67 | t = t - time_init; 68 | end 69 | $fwrite(tracefile, "%0d - %0d - pc: %08x, addr: %08x, data: %08x", t, packet_count, packet.pc, packet.addr, packet.data); 70 | if (packet.interrupt) begin 71 | $fwrite(tracefile, " - interrupt: %0d", packet.cause); 72 | end else if (packet.exception) begin 73 | $fwrite(tracefile, " - exception: %0d", packet.cause); 74 | end 75 | $fwrite(tracefile, "\n"); 76 | end 77 | `endif 78 | 79 | // update skippedPackets field 80 | packet.skippedPackets = skippedCounter; 81 | 82 | // detect if the packet is for synchronization - a packet is a 83 | // synchronization packet if it is a timer or host interrupt, or if it 84 | // reads a non-deterministic CSR 85 | Bool isSynchronizationPacket = False; 86 | if (packet.interrupt) begin 87 | if (packet.cause == 3) begin 88 | // machine inter-processor interrupt 89 | isSynchronizationPacket = True; 90 | end else if (packet.cause == 7) begin 91 | // machine timer interrupt 92 | isSynchronizationPacket = True; 93 | end 94 | end 95 | 96 | if ((packet.instruction[6:0] == 7'b1110011) && (packet.instruction[14:12] != 0)) begin 97 | CSR csr = unpack(packet.instruction[31:20]); 98 | case (csr) 99 | CSRmtime, CSRstime, CSRtime, CSRcycle, CSRinstret, CSRmip: 100 | isSynchronizationPacket = True; 101 | endcase 102 | end 103 | 104 | // figure out if packet should be sent or not 105 | if (ignoreCounter == 0) begin 106 | // send and clear skippedCounter 107 | packets.enq(packet); 108 | skippedCounter <= 0; 109 | end else begin 110 | if (ignoreCounter != '1) begin 111 | // decrement ignoreCounter 112 | ignoreCounter <= ignoreCounter - 1; 113 | end 114 | if (isSynchronizationPacket && sendSynchronization) begin 115 | // send and clear skippedCounter 116 | packets.enq(packet); 117 | skippedCounter <= 0; 118 | end else begin 119 | // don't send; increment skippedCounter 120 | skippedCounter <= skippedCounter + 1; 121 | end 122 | end 123 | endrule 124 | 125 | method Action init(Bit#(64) verificationPacketsToIgnore, Bool sendSynchronizationPackets); 126 | ignoreCounter <= verificationPacketsToIgnore; 127 | sendSynchronization <= sendSynchronizationPackets; 128 | skippedCounter <= 0; 129 | endmethod 130 | method ActionValue#(VerificationPacket) getPacket; 131 | packets.deq; 132 | return packets.first; 133 | endmethod 134 | method Bool nearFull; 135 | return packets.isGreaterThan(2); 136 | endmethod 137 | method Bool nearEmpty; 138 | return packets.isLessThan(2); 139 | endmethod 140 | endmodule 141 | -------------------------------------------------------------------------------- /procs/scripts/isatest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | if [ "$#" -eq 0 ] ; then 26 | echo "ERROR: RUN_EXE should be passed as a command line argument" 27 | exit 1 28 | else 29 | RUN_EXE=$1 30 | fi 31 | 32 | rm -rf out/ 33 | mkdir -p out 34 | 35 | # All the assembly files 36 | files=`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-* -type f ! -name "*.*"` 37 | files="$files "`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64um-p-* -type f ! -name "*.*"` 38 | files="$files "`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64ua-p-* -type f ! -name "*.*"` 39 | files="$files "`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64uf-p-* -type f ! -name "*.*"` 40 | files="$files "`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64ud-p-* -type f ! -name "*.*"` 41 | files="$files "`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64mi-p-* -type f ! -name "*.*"` 42 | files="$files "`find $RISCY_TOOLS/riscv64-unknown-elf/share/riscv-tests/isa/rv64si-p-* -type f ! -name "*.*"` 43 | 44 | for hexfile in $files ; do 45 | basehexfile=$(basename "$hexfile") 46 | $RUN_EXE $hexfile &> out/${basehexfile}.out 47 | # check return value 48 | errorcode=$? 49 | if [ $errorcode -ne 0 ] ; then 50 | grep ERROR out/${basehexfile}.out > /dev/null 51 | if [ $? -eq 0 ] ; then 52 | echo "$basehexfile FAILED $errorcode" # with divergence 53 | else 54 | echo "$basehexfile FAILED $errorcode (without divergence)" 55 | fi 56 | # exit 1 57 | else 58 | grep ERROR out/${basehexfile}.out > /dev/null 59 | if [ $? -eq 0 ] ; then 60 | echo "$basehexfile PASSED (with divergence)" 61 | else 62 | echo "$basehexfile OK" 63 | fi 64 | fi 65 | done 66 | rm SOCK.* 67 | -------------------------------------------------------------------------------- /procs/scripts/stylecheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (c) 2016 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import sys 26 | import os 27 | 28 | def print_usage(): 29 | print("%s bsvfile" % sys.argv[0]) 30 | print(" checks the style for the provided file") 31 | print("%s bsvdirectory" % sys.argv[0]) 32 | print(" checks the style for all bsv files in the directory") 33 | 34 | def get_bsv_files(foldername): 35 | bsvfiles = [] 36 | contents = list(map(lambda f : foldername + '/' + f, os.listdir(foldername))) 37 | for f in contents: 38 | if os.path.isdir(f): 39 | bsvfiles = bsvfiles + get_bsv_files(f) 40 | elif os.path.isfile(f): 41 | if f.endswith('.bsv'): 42 | bsvfiles = bsvfiles + [f] 43 | return bsvfiles 44 | 45 | def check_file(filename): 46 | error = False 47 | newline_error = False 48 | with open(filename, 'r') as f: 49 | linenum = 0 50 | for line in f: 51 | linenum = linenum + 1 52 | # Rule 0 - lines end with '\n' 53 | if not newline_error: 54 | if ('\r\n' in f.newlines) or ('\r' in f.newlines): 55 | print("[%s:%d] [rule 0 - only unix newlines]" % (os.path.basename(filename), linenum)) 56 | error = True 57 | newline_error = True 58 | # strip newline characters if it exists 59 | if len(line) > 1: 60 | if line[-1] == '\n': 61 | line = line[:-1] 62 | # Rule 1 - no tab characters 63 | if '\t' in line: 64 | error = True 65 | print("[%s:%d] [rule 1 - no tab characters] %s" % (os.path.basename(filename), linenum, line.replace('\t','--->'))) 66 | # Rule 2 - no XXX, TODO, or FIXME messages 67 | upperline = line.upper() 68 | if ('XXX' in upperline) or ('TODO' in upperline) or ('FIXME' in upperline): 69 | error = True 70 | print("[%s:%d] [rule 2 - no XXX, TODO, or FIXME] %s" % (os.path.basename(filename), linenum, line)) 71 | # Rule 3 - lines don't end wtih whitespace 72 | if len(line) > 1: 73 | if line[-1].isspace(): 74 | print("[%s:%d] [rule 3 - no whitespace at end of line] %s" % (os.path.basename(filename), linenum, line)) 75 | error = True 76 | # Rule 4 - lines aren't longer than 80 characters 77 | if len(line) > 80: 78 | print("[%s:%d] [rule 4 - line too long] %s" % (os.path.basename(filename), linenum, line)) 79 | error = True 80 | return error 81 | 82 | if __name__ == "__main__": 83 | if len(sys.argv) <= 1: 84 | print_usage() 85 | sys.exit(1) 86 | 87 | for arg in sys.argv[1:]: 88 | files = [] 89 | if os.path.isdir(arg): 90 | files = get_bsv_files(arg) 91 | elif os.path.isfile(arg): 92 | files = [arg] 93 | else: 94 | print("[ERROR] Can't find " + arg) 95 | sys.exit(1) 96 | 97 | for f in files: 98 | check_file(f) 99 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, 2017 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | # This script takes an optional argument for toolchains built for specific 26 | # subsets of the RISC-V ISA. 27 | 28 | # Points to root folder of repository 29 | export RISCY_HOME=$PWD 30 | 31 | [ "$0" == "$BASH_SOURCE" ] && echo "[WARNING] This scipt needs to be sourced to correctly setup the environment variables" 32 | 33 | if [ ! -d $RISCY_HOME/tools ] ; then 34 | echo "[ERROR] Can't find folder $RISCY_HOME/tools" 35 | echo "" 36 | echo "Either this script needs to be run at the top level of the Riscy" 37 | echo "repo, or you need to set RISCY_HOME to be the path to the Riscy" 38 | echo "repo inside this script" 39 | return 1 40 | fi 41 | 42 | if [ $# -eq 0 ] ; then 43 | TOOLCHAIN=RV64G 44 | else 45 | TOOLCHAIN=$1 46 | fi 47 | 48 | # TOOLCHAIN should be an ISA string like RV32IM 49 | 50 | if echo "$TOOLCHAIN" | grep -vqE "^RV(32|64)" ; then 51 | # error 52 | echo "[ERROR] This script expects a RISC-V ISA string in all caps as the" 53 | echo "command line argument (example: RV64IMAFDC)" 54 | return 1 55 | fi 56 | 57 | if [ ! -d $RISCY_HOME/tools/$TOOLCHAIN ] ; then 58 | if [ "$TOOLCHAIN" == "RV64G" ] ; then 59 | BUILD_COMMAND="./build.sh" 60 | else 61 | BUILD_COMMAND="./build.sh $TOOLCHAIN" 62 | fi 63 | 64 | echo "[WARNING] $RISCY_HOME/tools/$TOOLCHAIN does not exist" 65 | echo "" 66 | echo "To use this toolchain you need to build it first by going to the tools folder and running $BUILD_COMMAND" 67 | # echo "" 68 | # read -p "Would you like to start building the toolchain now? [N/y] " RESP 69 | # case $RESP in 70 | # [Yy]*) pushd $RISCY_HOME/tools ; $BUILD_COMMAND ; popd ;; 71 | # esac 72 | fi 73 | 74 | # Points to toolchain 75 | export RISCY_TOOLS=$RISCY_HOME/tools/$TOOLCHAIN 76 | # Adding to path and ld library path 77 | export PATH=$RISCY_TOOLS/bin:$PATH 78 | if [ "$LD_LIBRARY_PATH" == "" ] ; then 79 | export LD_LIBRARY_PATH=$RISCY_TOOLS/lib 80 | else 81 | export LD_LIBRARY_PATH=$RISCY_TOOLS/lib:$LD_LIBRARY_PATH 82 | fi 83 | -------------------------------------------------------------------------------- /tools/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2017 Massachusetts Institute of Technology 4 | 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, copy, 9 | # modify, merge, publish, distribute, sublicense, and/or sell copies 10 | # of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | # Abort on error 26 | set -e 27 | 28 | if [ $# -eq 1 ] ; then 29 | ISA=$1 30 | else 31 | # default ISA is RV64G 32 | ISA=RV64G 33 | fi 34 | 35 | if echo "$ISA" | grep -qE "^RV32" ; then 36 | XLEN=32 37 | elif echo "$ISA" | grep -qE "^RV64" ; then 38 | XLEN=64 39 | else 40 | echo "[ERROR] This script expects a RISC-V ISA string in all caps as an input" 41 | echo "example: $0 RV64IMAFDC" 42 | return 1 43 | fi 44 | 45 | case $ISA in 46 | "RV64G") WITH_ARCH=" " ;; 47 | "RV64GC") WITH_ARCH=" --with-arch=RV64IMAFDC " ;; 48 | "RV32G") WITH_ARCH=" --with-xlen=32 " ;; 49 | "RV32GC") WITH_ARCH=" --with-arch=RV32IMAFDC " ;; 50 | "RV64IMAFD") WITH_ARCH=" " ;; 51 | "RV32IMAFD") WITH_ARCH=" --with-xlen=32 " ;; 52 | *) WITH_ARCH=" --with-arch=$ISA " ;; 53 | esac 54 | 55 | echo "Building $ISA toolchain..." 56 | 57 | STARTINGDIR=$PWD 58 | export RISCV=$PWD/$ISA 59 | export PATH=$RISCV/bin:$PATH 60 | OUTPUT_PATH=$RISCV/build-log 61 | 62 | mkdir -p $RISCV 63 | mkdir -p $OUTPUT_PATH 64 | 65 | # Build riscv-gnu-toolchain 66 | OUTPUT_FILE=$OUTPUT_PATH/riscv-gnu-toolchain.log 67 | echo "Building riscv-gnu-toolchain... (writing output to $OUTPUT_FILE)" 68 | cd $RISCV 69 | mkdir build-gnu-toolchain 70 | cd build-gnu-toolchain 71 | ../../riscv-gnu-toolchain/configure --prefix=$RISCV $WITH_ARCH &> $OUTPUT_FILE 72 | make &>> $OUTPUT_FILE 73 | 74 | # Rebuild newlib with -mcmodel=medany 75 | OUTPUT_FILE=$OUTPUT_PATH/newlib.log 76 | echo "Rebuilding newlib... (writing output to $OUTPUT_FILE)" 77 | cd build-gcc-newlib/riscv$XLEN-unknown-elf/newlib 78 | sed 's/^CFLAGS = /CFLAGS = -mcmodel=medany /' Makefile > Makefile.sed 79 | mv Makefile.sed Makefile 80 | make clean &> $OUTPUT_FILE 81 | make &>> $OUTPUT_FILE 82 | make install &>> $OUTPUT_FILE 83 | 84 | # Build riscv-tests 85 | OUTPUT_FILE=$OUTPUT_PATH/riscv-tests.log 86 | echo "Building riscv-tests... (writing output to $OUTPUT_FILE)" 87 | cd $RISCV 88 | mkdir build-tests 89 | cd build-tests 90 | ../../riscv-tests/configure --prefix=$RISCV/riscv$XLEN-unknown-elf --with-xlen=$XLEN &> $OUTPUT_FILE 91 | # This may fail since some riscv-tests require ISA extensions 92 | # Also there is an issue with building 32-bit executables when gcc is 93 | # configured with --with-arch= 94 | set +e 95 | make &>> $OUTPUT_FILE 96 | if [ $? -eq 0 ] ; then 97 | make install &>> $OUTPUT_FILE 98 | RISCV_TEST_FAILED=0 99 | else 100 | RISCV_TEST_FAILED=1 101 | fi 102 | set -e 103 | 104 | # Build riscv-fesvr 105 | OUTPUT_FILE=$OUTPUT_PATH/riscv-fesvr.log 106 | echo "Building riscv-fesvr... (writing output to $OUTPUT_FILE)" 107 | cd $RISCV 108 | mkdir build-fesvr 109 | cd build-fesvr 110 | ../../riscv-fesvr/configure --prefix=$RISCV &> $OUTPUT_FILE 111 | make &>> $OUTPUT_FILE 112 | make install &>> $OUTPUT_FILE 113 | 114 | # Build riscv-isa-sim 115 | OUTPUT_FILE=$OUTPUT_PATH/riscv-isa-sim.log 116 | echo "Building riscv-isa-sim... (writing output to $OUTPUT_FILE)" 117 | cd $RISCV 118 | mkdir build-isa-sim 119 | cd build-isa-sim 120 | ../../riscv-isa-sim/configure --prefix=$RISCV --with-fesvr=$RISCV &> $OUTPUT_FILE 121 | make &>> $OUTPUT_FILE 122 | make install &>> $OUTPUT_FILE 123 | 124 | cd $STARTINGDIR 125 | 126 | if [ $RISCV_TEST_FAILED -eq 1 ] ; then 127 | echo "" 128 | echo "[WARNING] $ISA toolchain compiled successfully, but riscv-tests compilation failed." 129 | echo "If you need riscv-tests, try compiling them with a RV64G toolchain using ./build.sh" 130 | else 131 | echo "" 132 | echo "$ISA toolchain and riscv-tests compiled successfully." 133 | fi 134 | -------------------------------------------------------------------------------- /tools/elf2hex/ElfFile.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "ElfFile.hpp" 30 | 31 | ElfFile::ElfFile() { 32 | elf_size = 0; 33 | elf_data = nullptr; 34 | elf_bit_width = 0; 35 | } 36 | 37 | bool ElfFile::open(char* filename) { 38 | // load filename into elf_data and set elf_size 39 | std::ifstream elf_file; 40 | elf_file.open(filename, std::ios::in | std::ios::binary); 41 | 42 | if (!elf_file.is_open()) { 43 | std::cerr << "ERROR: ElfFile::open(): failed opening file \"" << filename << "\"" << std::endl; 44 | return false; 45 | } 46 | 47 | elf_file.seekg(0, elf_file.end); 48 | elf_size = elf_file.tellg(); 49 | elf_file.seekg(0, elf_file.beg); 50 | 51 | elf_data = new char[elf_size]; 52 | elf_file.read(elf_data, elf_size); 53 | 54 | if (!elf_file) { 55 | std::cerr << "ERROR: ElfFile::open(): failed reading elf file" << std::endl; 56 | elf_size = 0; 57 | delete[] elf_data; 58 | elf_data = nullptr; 59 | return false; 60 | } 61 | 62 | if (elf_size < sizeof(Elf32_Ehdr)) { 63 | std::cerr << "ERROR: ElfFile::open(): file too small to be a valid elf file" << std::endl; 64 | elf_size = 0; 65 | delete[] elf_data; 66 | elf_data = nullptr; 67 | return false; 68 | } 69 | 70 | // make sure the header matches elf32 or elf64 71 | Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elf_data; 72 | unsigned char* e_ident = ehdr->e_ident; 73 | if (e_ident[EI_MAG0] != ELFMAG0 74 | || e_ident[EI_MAG1] != ELFMAG1 75 | || e_ident[EI_MAG2] != ELFMAG2 76 | || e_ident[EI_MAG3] != ELFMAG3) { 77 | std::cerr << "ERROR: ElfFile::open(): file is not an elf file" << std::endl; 78 | elf_size = 0; 79 | delete[] elf_data; 80 | elf_data = nullptr; 81 | return false; 82 | } 83 | 84 | bool success = false; 85 | if (e_ident[EI_CLASS] == ELFCLASS32) { 86 | // 32-bit ELF 87 | elf_bit_width = 32; 88 | success = finishLoad(); 89 | } else if (e_ident[EI_CLASS] == ELFCLASS64) { 90 | // 64-bit ELF 91 | elf_bit_width = 64; 92 | success = finishLoad(); 93 | } else { 94 | std::cerr << "ERROR: ElfFile::open(): file is neither 32-bit nor 64-bit" << std::endl; 95 | elf_size = 0; 96 | delete[] elf_data; 97 | elf_data = nullptr; 98 | return false; 99 | } 100 | 101 | if (success) { 102 | return true; 103 | } else { 104 | std::cerr << "ERROR: ElfFile::open(): finishLoad() failed" << std::endl; 105 | elf_size = 0; 106 | delete[] elf_data; 107 | elf_data = nullptr; 108 | return false; 109 | } 110 | } 111 | 112 | const std::vector& ElfFile::getSections() { 113 | return sections; 114 | } 115 | 116 | template 117 | bool ElfFile::finishLoad() { 118 | // This uses templated types to support 32-bit and 64-bit elfs 119 | Elf_Ehdr *ehdr = (Elf_Ehdr*) elf_data; 120 | Elf_Phdr *phdr = (Elf_Phdr*) (elf_data + ehdr->e_phoff); 121 | if (elf_size < ehdr->e_phoff + ehdr->e_phnum * sizeof(Elf_Phdr)) { 122 | std::cerr << "ERROR: ElfFile::finishLoad(): file too small for expected number of program header tables" << std::endl; 123 | return false; 124 | } 125 | // loop through program header tables 126 | for (int i = 0 ; i < ehdr->e_phnum ; i++) { 127 | // only look at non-zero length PT_LOAD sections 128 | if ((phdr[i].p_type == PT_LOAD) && (phdr[i].p_memsz > 0)) { 129 | if (phdr[i].p_memsz < phdr[i].p_filesz) { 130 | std::cerr << "ERROR: ElfFile::finishLoad(): file size is larger than memory size" << std::endl; 131 | return false; 132 | } 133 | if (phdr[i].p_filesz > 0) { 134 | if (phdr[i].p_offset + phdr[i].p_filesz > elf_size) { 135 | std::cerr << "ERROR: ElfFile::finishLoad(): file section overflow" << std::endl; 136 | return false; 137 | } 138 | } 139 | Section curr_section; 140 | curr_section.base = phdr[i].p_paddr; // maybe p_vaddr? 141 | curr_section.section_size = phdr[i].p_memsz; 142 | curr_section.data_size = phdr[i].p_filesz; 143 | curr_section.data = elf_data + phdr[i].p_offset; 144 | sections.push_back(curr_section); 145 | } 146 | } 147 | return true; 148 | } 149 | 150 | -------------------------------------------------------------------------------- /tools/elf2hex/ElfFile.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | 26 | #include 27 | 28 | class ElfFile { 29 | public: 30 | struct Section { 31 | unsigned long long base; 32 | unsigned long long section_size; 33 | unsigned long long data_size; 34 | char* data; 35 | }; 36 | 37 | ElfFile(); 38 | bool open(char* filename); 39 | const std::vector
& getSections(); 40 | 41 | private: 42 | template 43 | bool finishLoad(); 44 | 45 | char* elf_data; 46 | size_t elf_size; 47 | int elf_bit_width; // 32 or 64 48 | 49 | std::vector
sections; 50 | }; 51 | 52 | -------------------------------------------------------------------------------- /tools/elf2hex/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2017 Massachusetts Institute of Technology 3 | 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, copy, 8 | # modify, merge, publish, distribute, sublicense, and/or sell copies 9 | # of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | elf2hex: elf2hex.cpp ElfFile.cpp 25 | g++ -O --std=c++11 $^ -o $@ 26 | 27 | clean: 28 | rm -rf elf2hex 29 | -------------------------------------------------------------------------------- /tools/elf2hex/elf2hex.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2017 Massachusetts Institute of Technology 3 | // 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, copy, 8 | // modify, merge, publish, distribute, sublicense, and/or sell copies 9 | // of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be 13 | // included in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "ElfFile.hpp" 33 | 34 | void printUsage(const char* program_name) { 35 | std::cerr << "Usage: " << program_name << " " << std::endl; 36 | std::cerr << "This program converts a specified address range from an ELF file into a hex file" << std::endl; 37 | std::cerr << " elf-file input ELF file to convert to a hex file" << std::endl; 38 | std::cerr << " base-address base address of output hex file" << std::endl; 39 | std::cerr << " This value is interpreted as decimal by default, but it can also be" << std::endl; 40 | std::cerr << " interpreted as octal with a '0' prefix or hex with a '0x' or '0X' prefix" << std::endl; 41 | std::cerr << " length intended length of output hex file" << std::endl; 42 | std::cerr << " This value can use a K, M, or G suffix" << std::endl; 43 | std::cerr << " output-hex filename for output hex file" << std::endl; 44 | } 45 | 46 | int main(int argc, char* argv[]) { 47 | if (argc != 5) { 48 | std::cerr << "ERROR: Incorrect command line arguments" << std::endl; 49 | printUsage(argv[0]); 50 | exit(1); 51 | } 52 | 53 | char *elf_filename = argv[1]; 54 | char *base_address_string = argv[2]; 55 | char *length_string = argv[3]; 56 | char *hex_filename = argv[4]; 57 | 58 | // parse base address 59 | char *endptr = 0; 60 | unsigned long long base_address = strtoull(base_address_string, &endptr, 0); 61 | if (strcmp(endptr, "") != 0) { 62 | // conversion failure 63 | std::cerr << "ERROR: base-address expected to be a number" << std::endl; 64 | printUsage(argv[0]); 65 | exit(1); 66 | } 67 | 68 | // parse length 69 | unsigned long long length = strtoull(length_string, &endptr, 0); 70 | if (strcmp(endptr, "K") == 0) { 71 | length *= 1024; 72 | } else if (strcmp(endptr, "M") == 0) { 73 | length *= 1024 * 1024; 74 | } else if (strcmp(endptr, "G") == 0) { 75 | length *= 1024 * 1024 * 1024; 76 | } else if (strcmp(endptr, "") != 0) { 77 | // conversion failure 78 | std::cerr << "ERROR: length expected to be a number with an optional prefix K, M, or G" << std::endl; 79 | printUsage(argv[0]); 80 | exit(1); 81 | } 82 | 83 | // Command line arguments are parsed and ready to go 84 | 85 | ElfFile elf_file; 86 | if (!elf_file.open(elf_filename)) { 87 | std::cerr << "ERROR: failed opening ELF file" << std::endl; 88 | exit(1); 89 | } 90 | 91 | std::vector sections = elf_file.getSections(); 92 | 93 | // write output_buff to hex_filename in hex file format 94 | std::ofstream hex_file; 95 | hex_file.open(hex_filename, std::ios_base::out); 96 | if (!hex_file) { 97 | std::cerr << "ERROR: unable to open \"" << hex_filename << "\" for writing" << std::endl; 98 | exit(1); 99 | } 100 | 101 | uint64_t prev_hex_addr = 0; 102 | uint64_t curr_hex_addr = 0; 103 | uint64_t section_offset = 0; 104 | for (int i = 0 ; i < sections.size() ; i++) { 105 | if (base_address + length < sections[i].base) { 106 | // This section starts after the last address in the hex file. 107 | continue; 108 | } 109 | if (sections[i].base < base_address) { 110 | // This section starts at a lower address than the hex file base 111 | // address. Compute section_offset to correspond to base_address. 112 | section_offset = base_address - sections[i].base; 113 | curr_hex_addr = 0; 114 | } else { 115 | curr_hex_addr = sections[i].base - base_address; 116 | section_offset = 0; 117 | } 118 | 119 | // assumes 32-bit width for output hex file 120 | hex_file << "@" << std::hex << std::setw(0) << (curr_hex_addr >> 2) << std::endl; 121 | while ((sections[i].base + section_offset < base_address + length) && (section_offset < sections[i].data_size)) { 122 | // write stuff 123 | uint32_t *hex_data = (uint32_t*) §ions[i].data[section_offset]; 124 | hex_file << std::hex << std::setw(0) << *hex_data << std::endl; 125 | section_offset += 4; 126 | } 127 | while ((sections[i].base + section_offset < base_address + length) && (section_offset < sections[i].section_size)) { 128 | // write zeros 129 | hex_file << std::hex << std::setw(0) << 0 << std::endl; 130 | section_offset += 4; 131 | } 132 | } 133 | 134 | hex_file << "@" << std::hex << std::setw(0) << (length >> 2) << std::endl; 135 | 136 | hex_file.close(); 137 | 138 | return 0; 139 | } 140 | --------------------------------------------------------------------------------