├── .gitignore ├── LICENSE ├── README.md ├── bin └── logisim-evolution.jar ├── chisel ├── .mill-version ├── Makefile ├── TestBench.sv ├── build.sc ├── env.sh └── src │ └── main │ └── scala │ ├── Main.scala │ ├── core │ ├── Consts.scala │ ├── ControlPath.scala │ ├── Core.scala │ ├── DataPath.scala │ ├── Instructions.scala │ └── Tile.scala │ ├── fpga │ └── Arty100TTop.scala │ └── peripheral │ └── UART.scala ├── docs ├── cover.jpg └── result.jpg ├── logisim └── RV32I_single_cycle_cpu.circ └── verilog ├── lib ├── ram_artix7.v ├── ram_simple.v ├── register.v └── rom.v ├── rtl ├── alu.v ├── consts.vh ├── core.v ├── ctrlpath.v ├── datapath.v ├── gpio.v ├── regfile.v ├── tile.v └── top.v ├── sim ├── tb_alu.sv ├── tb_core.sv └── tb_tile.sv └── software ├── firmware.S └── firmware.mem /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ### Vivado ### 3 | *.cache/ 4 | *.gen/ 5 | *.hw/ 6 | *.ip_user_files/ 7 | *.runs/ 8 | *.sim/ 9 | *.srcs/ 10 | vivado*.jou 11 | vivado*.log 12 | 13 | ### VSCode ### 14 | .vscode/ 15 | 16 | ### Scala/Chisel ### 17 | .metals/ 18 | .scala-build/ 19 | csrc/ 20 | out/ 21 | build/ 22 | 23 | ### VCS Simulation ### 24 | novas_dump.log 25 | out.fsdb 26 | simv.daidir/ 27 | simv 28 | ucli.key 29 | verdi_config_file -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 -T.K.- 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies 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 included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RISC-V Single Cycle CPU 2 | 3 | ![Cover Image](docs/cover.jpg) 4 | 5 | --- 6 | 7 | ![Result Image](docs/result.jpg) 8 | 9 | 10 | ## Notes 11 | 12 | - Single page version can achieve ~300 Hz clock rate on a i7-6700K computer. 13 | 14 | ## Terms and Conditions 15 | 16 | The software [Logisim-evoluion](https://github.com/logisim-evolution/logisim-evolution) is released under the terms of the [GNU GENERAL PUBLIC LICENSE (GPL)](https://github.com/logisim-evolution/logisim-evolution/blob/master/LICENSE.md). For your convenience, the jar file is included in this repository in accordance with the redistribution guideline of the GPL-3.0 license agreement. 17 | 18 | This project is under MIT License. 19 | -------------------------------------------------------------------------------- /bin/logisim-evolution.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T-K-233/RISC-V-Single-Cycle-CPU/ca807fe88ca54eea48e50cf75a2ba3835de6d028/bin/logisim-evolution.jar -------------------------------------------------------------------------------- /chisel/.mill-version: -------------------------------------------------------------------------------- 1 | 0.11.5 2 | -------------------------------------------------------------------------------- /chisel/Makefile: -------------------------------------------------------------------------------- 1 | VCS = vcs -full64 2 | 3 | OUTPUT = ./simv 4 | 5 | 6 | # $(VCS) top.v -o $(OUTPUT) -debug_access+all -kdb -lca -sverilog 7 | 8 | # -debug_access+all enables dumping to fsdb format 9 | 10 | build: 11 | mill BA30XSystem 12 | 13 | sim: 14 | $(VCS) $(wildcard *.sv) -o $(OUTPUT) -debug_access+all -kdb -lca -sverilog 15 | $(OUTPUT) 16 | 17 | clean: 18 | rm -rf csrc simv* ucli.key vc_hdrs.h DVEfiles Top.sv 19 | -------------------------------------------------------------------------------- /chisel/TestBench.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | module TestBench (); 4 | parameter CLOCK_FREQ = 100_000_000; 5 | parameter CLOCK_PERIOD = 1_000_000_000 / CLOCK_FREQ; 6 | 7 | // setup clock and reset 8 | reg clk, rst; 9 | initial clk = 'b0; 10 | always #(CLOCK_PERIOD/2) clk = ~clk; 11 | 12 | 13 | 14 | Tile dut ( 15 | .clock(clk), 16 | .reset(rst), 17 | .io_led() 18 | ); 19 | 20 | reg clock; 21 | 22 | 23 | initial begin 24 | 25 | // set up logging 26 | // $dumpfile("out.vcd"); 27 | // $dumpvars(0, top); 28 | $fsdbDumpfile("out.fsdb"); 29 | $fsdbDumpvars("+all"); 30 | 31 | 32 | #0; 33 | rst = 1; 34 | $display("[TEST]\tRESET pulled HIGH."); 35 | repeat(2) @(posedge clk); 36 | 37 | @(negedge clk); 38 | rst = 0; 39 | $display("[TEST]\tRESET pulled LOW."); 40 | @(posedge clk); 41 | 42 | repeat(100) @(posedge clk); 43 | 44 | $display("[TEST]\tDONE."); 45 | 46 | $finish; 47 | end 48 | 49 | endmodule -------------------------------------------------------------------------------- /chisel/build.sc: -------------------------------------------------------------------------------- 1 | // import Mill dependency 2 | import mill._ 3 | import mill.define.Sources 4 | import mill.modules.Util 5 | import mill.scalalib.TestModule.ScalaTest 6 | import scalalib._ 7 | // support BSP 8 | import mill.bsp._ 9 | 10 | object BA30XSystem extends SbtModule { m => 11 | override def millSourcePath = os.pwd 12 | override def scalaVersion = "2.13.12" 13 | override def scalacOptions = Seq( 14 | "-language:reflectiveCalls", 15 | "-deprecation", 16 | "-feature", 17 | "-Xcheckinit", 18 | ) 19 | override def ivyDeps = Agg( 20 | ivy"org.chipsalliance::chisel:6.2.0", 21 | ) 22 | override def scalacPluginIvyDeps = Agg( 23 | ivy"org.chipsalliance:::chisel-plugin:6.2.0", 24 | ) 25 | object test extends SbtModuleTests with TestModule.ScalaTest { 26 | override def ivyDeps = m.ivyDeps() ++ Agg( 27 | ivy"org.scalatest::scalatest::3.2.16", 28 | ivy"edu.berkeley.cs::chiseltest::6.0.0" 29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /chisel/env.sh: -------------------------------------------------------------------------------- 1 | source /ecad/tools/vlsi.bashrc 2 | -------------------------------------------------------------------------------- /chisel/src/main/scala/Main.scala: -------------------------------------------------------------------------------- 1 | package bad 2 | 3 | import chisel3._ 4 | import chisel3.util.Decoupled 5 | import circt.stage.ChiselStage 6 | 7 | object Main extends App { 8 | // generate verilog and save as file 9 | // ChiselStage.emitSystemVerilogFile(new Arty100TTop()) 10 | ChiselStage.emitSystemVerilogFile(new Tile()) 11 | } 12 | -------------------------------------------------------------------------------- /chisel/src/main/scala/core/Consts.scala: -------------------------------------------------------------------------------- 1 | package bad 2 | 3 | 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | -------------------------------------------------------------------------------- /chisel/src/main/scala/core/ControlPath.scala: -------------------------------------------------------------------------------- 1 | package bad 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | -------------------------------------------------------------------------------- /chisel/src/main/scala/core/Core.scala: -------------------------------------------------------------------------------- 1 | 2 | package bad 3 | 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | class Core extends Module { 8 | val io = IO(new Bundle { 9 | val imem_addr = Output(UInt(32.W)) 10 | }) 11 | 12 | // val control_path = Module(new ControlPath()) 13 | val data_path = Module(new DataPath()) 14 | 15 | io.imem_addr := data_path.io.imem_addr 16 | 17 | } -------------------------------------------------------------------------------- /chisel/src/main/scala/core/DataPath.scala: -------------------------------------------------------------------------------- 1 | package bad 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | class DataPath extends Module { 7 | val io = IO(new Bundle { 8 | val imem_addr = Output(UInt(32.W)) 9 | }) 10 | 11 | val pc = RegInit(0.U(32.W)) 12 | 13 | val pc_4 = Wire(UInt(32.W)) 14 | 15 | pc_4 := pc + 4.U 16 | 17 | pc := pc_4 18 | 19 | io.imem_addr := pc 20 | } -------------------------------------------------------------------------------- /chisel/src/main/scala/core/Instructions.scala: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | package bad 4 | 5 | import chisel3._ 6 | import chisel3.util._ 7 | 8 | /* Automatically generated by parse-opcodes */ 9 | object Instructions { 10 | def BEQ = BitPat("b?????????????????000?????1100011") 11 | def BNE = BitPat("b?????????????????001?????1100011") 12 | def BLT = BitPat("b?????????????????100?????1100011") 13 | def BGE = BitPat("b?????????????????101?????1100011") 14 | def BLTU = BitPat("b?????????????????110?????1100011") 15 | def BGEU = BitPat("b?????????????????111?????1100011") 16 | def JALR = BitPat("b?????????????????000?????1100111") 17 | def JAL = BitPat("b?????????????????????????1101111") 18 | def LUI = BitPat("b?????????????????????????0110111") 19 | def AUIPC = BitPat("b?????????????????????????0010111") 20 | def ADDI = BitPat("b?????????????????000?????0010011") 21 | //def SLLI = BitPat("b000000???????????001?????0010011") 22 | def SLTI = BitPat("b?????????????????010?????0010011") 23 | def SLTIU = BitPat("b?????????????????011?????0010011") 24 | def XORI = BitPat("b?????????????????100?????0010011") 25 | //def SRLI = BitPat("b000000???????????101?????0010011") 26 | //def SRAI = BitPat("b010000???????????101?????0010011") 27 | def ORI = BitPat("b?????????????????110?????0010011") 28 | def ANDI = BitPat("b?????????????????111?????0010011") 29 | def ADD = BitPat("b0000000??????????000?????0110011") 30 | def SUB = BitPat("b0100000??????????000?????0110011") 31 | def SLL = BitPat("b0000000??????????001?????0110011") 32 | def SLT = BitPat("b0000000??????????010?????0110011") 33 | def SLTU = BitPat("b0000000??????????011?????0110011") 34 | def XOR = BitPat("b0000000??????????100?????0110011") 35 | def SRL = BitPat("b0000000??????????101?????0110011") 36 | def SRA = BitPat("b0100000??????????101?????0110011") 37 | def OR = BitPat("b0000000??????????110?????0110011") 38 | def AND = BitPat("b0000000??????????111?????0110011") 39 | def ADDIW = BitPat("b?????????????????000?????0011011") 40 | def SLLIW = BitPat("b0000000??????????001?????0011011") 41 | def SRLIW = BitPat("b0000000??????????101?????0011011") 42 | def SRAIW = BitPat("b0100000??????????101?????0011011") 43 | def ADDW = BitPat("b0000000??????????000?????0111011") 44 | def SUBW = BitPat("b0100000??????????000?????0111011") 45 | def SLLW = BitPat("b0000000??????????001?????0111011") 46 | def SRLW = BitPat("b0000000??????????101?????0111011") 47 | def SRAW = BitPat("b0100000??????????101?????0111011") 48 | def LB = BitPat("b?????????????????000?????0000011") 49 | def LH = BitPat("b?????????????????001?????0000011") 50 | def LW = BitPat("b?????????????????010?????0000011") 51 | def LD = BitPat("b?????????????????011?????0000011") 52 | def LBU = BitPat("b?????????????????100?????0000011") 53 | def LHU = BitPat("b?????????????????101?????0000011") 54 | def LWU = BitPat("b?????????????????110?????0000011") 55 | def SB = BitPat("b?????????????????000?????0100011") 56 | def SH = BitPat("b?????????????????001?????0100011") 57 | def SW = BitPat("b?????????????????010?????0100011") 58 | def SD = BitPat("b?????????????????011?????0100011") 59 | def FENCE = BitPat("b?????????????????000?????0001111") 60 | def FENCE_I = BitPat("b?????????????????001?????0001111") 61 | def MUL = BitPat("b0000001??????????000?????0110011") 62 | def MULH = BitPat("b0000001??????????001?????0110011") 63 | def MULHSU = BitPat("b0000001??????????010?????0110011") 64 | def MULHU = BitPat("b0000001??????????011?????0110011") 65 | def DIV = BitPat("b0000001??????????100?????0110011") 66 | def DIVU = BitPat("b0000001??????????101?????0110011") 67 | def REM = BitPat("b0000001??????????110?????0110011") 68 | def REMU = BitPat("b0000001??????????111?????0110011") 69 | def MULW = BitPat("b0000001??????????000?????0111011") 70 | def DIVW = BitPat("b0000001??????????100?????0111011") 71 | def DIVUW = BitPat("b0000001??????????101?????0111011") 72 | def REMW = BitPat("b0000001??????????110?????0111011") 73 | def REMUW = BitPat("b0000001??????????111?????0111011") 74 | def LR_W = BitPat("b00010??00000?????010?????0101111") 75 | def SC_W = BitPat("b00011????????????010?????0101111") 76 | def LR_D = BitPat("b00010??00000?????011?????0101111") 77 | def SC_D = BitPat("b00011????????????011?????0101111") 78 | def ECALL = BitPat("b00000000000000000000000001110011") 79 | def EBREAK = BitPat("b00000000000100000000000001110011") 80 | def URET = BitPat("b00000000001000000000000001110011") 81 | def MRET = BitPat("b00110000001000000000000001110011") 82 | def DRET = BitPat("b01111011001000000000000001110011") 83 | def SFENCE_VMA = BitPat("b0001001??????????000000001110011") 84 | def WFI = BitPat("b00010000010100000000000001110011") 85 | def CSRRW = BitPat("b?????????????????001?????1110011") 86 | def CSRRS = BitPat("b?????????????????010?????1110011") 87 | def CSRRC = BitPat("b?????????????????011?????1110011") 88 | def CSRRWI = BitPat("b?????????????????101?????1110011") 89 | def CSRRSI = BitPat("b?????????????????110?????1110011") 90 | def CSRRCI = BitPat("b?????????????????111?????1110011") 91 | def CUSTOM0 = BitPat("b?????????????????000?????0001011") 92 | def CUSTOM0_RS1 = BitPat("b?????????????????010?????0001011") 93 | def CUSTOM0_RS1_RS2 = BitPat("b?????????????????011?????0001011") 94 | def CUSTOM0_RD = BitPat("b?????????????????100?????0001011") 95 | def CUSTOM0_RD_RS1 = BitPat("b?????????????????110?????0001011") 96 | def CUSTOM0_RD_RS1_RS2 = BitPat("b?????????????????111?????0001011") 97 | def CUSTOM1 = BitPat("b?????????????????000?????0101011") 98 | def CUSTOM1_RS1 = BitPat("b?????????????????010?????0101011") 99 | def CUSTOM1_RS1_RS2 = BitPat("b?????????????????011?????0101011") 100 | def CUSTOM1_RD = BitPat("b?????????????????100?????0101011") 101 | def CUSTOM1_RD_RS1 = BitPat("b?????????????????110?????0101011") 102 | def CUSTOM1_RD_RS1_RS2 = BitPat("b?????????????????111?????0101011") 103 | def CUSTOM2 = BitPat("b?????????????????000?????1011011") 104 | def CUSTOM2_RS1 = BitPat("b?????????????????010?????1011011") 105 | def CUSTOM2_RS1_RS2 = BitPat("b?????????????????011?????1011011") 106 | def CUSTOM2_RD = BitPat("b?????????????????100?????1011011") 107 | def CUSTOM2_RD_RS1 = BitPat("b?????????????????110?????1011011") 108 | def CUSTOM2_RD_RS1_RS2 = BitPat("b?????????????????111?????1011011") 109 | def CUSTOM3 = BitPat("b?????????????????000?????1111011") 110 | def CUSTOM3_RS1 = BitPat("b?????????????????010?????1111011") 111 | def CUSTOM3_RS1_RS2 = BitPat("b?????????????????011?????1111011") 112 | def CUSTOM3_RD = BitPat("b?????????????????100?????1111011") 113 | def CUSTOM3_RD_RS1 = BitPat("b?????????????????110?????1111011") 114 | def CUSTOM3_RD_RS1_RS2 = BitPat("b?????????????????111?????1111011") 115 | def SLLI_RV32 = BitPat("b0000000??????????001?????0010011") 116 | def SRLI_RV32 = BitPat("b0000000??????????101?????0010011") 117 | def SRAI_RV32 = BitPat("b0100000??????????101?????0010011") 118 | def RDCYCLE = BitPat("b11000000000000000010?????1110011") 119 | def RDTIME = BitPat("b11000000000100000010?????1110011") 120 | def RDINSTRET = BitPat("b11000000001000000010?????1110011") 121 | def RDCYCLEH = BitPat("b11001000000000000010?????1110011") 122 | def RDTIMEH = BitPat("b11001000000100000010?????1110011") 123 | def RDINSTRETH = BitPat("b11001000001000000010?????1110011") 124 | 125 | /* Custom complex instructions */ 126 | def MOVN = BitPat("b?????????????????????????1110111") 127 | /* TODO: Add your custom instruction encoding here */ 128 | } 129 | object Causes { 130 | val misaligned_fetch = 0x0 131 | val fetch_access = 0x1 132 | val illegal_instruction = 0x2 133 | val breakpoint = 0x3 134 | val misaligned_load = 0x4 135 | val load_access = 0x5 136 | val misaligned_store = 0x6 137 | val store_access = 0x7 138 | val user_ecall = 0x8 139 | val machine_ecall = 0xb 140 | val all = { 141 | val res = collection.mutable.ArrayBuffer[Int]() 142 | res += misaligned_fetch 143 | res += fetch_access 144 | res += illegal_instruction 145 | res += breakpoint 146 | res += misaligned_load 147 | res += load_access 148 | res += misaligned_store 149 | res += store_access 150 | res += user_ecall 151 | res += machine_ecall 152 | res.toArray 153 | } 154 | } 155 | object CSRs { 156 | val cycle = 0xc00 157 | val instret = 0xc02 158 | val hpmcounter3 = 0xc03 159 | val hpmcounter4 = 0xc04 160 | val hpmcounter5 = 0xc05 161 | val hpmcounter6 = 0xc06 162 | val hpmcounter7 = 0xc07 163 | val hpmcounter8 = 0xc08 164 | val hpmcounter9 = 0xc09 165 | val hpmcounter10 = 0xc0a 166 | val hpmcounter11 = 0xc0b 167 | val hpmcounter12 = 0xc0c 168 | val hpmcounter13 = 0xc0d 169 | val hpmcounter14 = 0xc0e 170 | val hpmcounter15 = 0xc0f 171 | val hpmcounter16 = 0xc10 172 | val hpmcounter17 = 0xc11 173 | val hpmcounter18 = 0xc12 174 | val hpmcounter19 = 0xc13 175 | val hpmcounter20 = 0xc14 176 | val hpmcounter21 = 0xc15 177 | val hpmcounter22 = 0xc16 178 | val hpmcounter23 = 0xc17 179 | val hpmcounter24 = 0xc18 180 | val hpmcounter25 = 0xc19 181 | val hpmcounter26 = 0xc1a 182 | val hpmcounter27 = 0xc1b 183 | val hpmcounter28 = 0xc1c 184 | val hpmcounter29 = 0xc1d 185 | val hpmcounter30 = 0xc1e 186 | val hpmcounter31 = 0xc1f 187 | val mstatus = 0x300 188 | val misa = 0x301 189 | val medeleg = 0x302 190 | val mideleg = 0x303 191 | val mie = 0x304 192 | val mtvec = 0x305 193 | val mscratch = 0x340 194 | val mcounteren = 0x306 195 | val mepc = 0x341 196 | val mcause = 0x342 197 | val mtval = 0x343 198 | val mip = 0x344 199 | val tselect = 0x7a0 200 | val tdata1 = 0x7a1 201 | val tdata2 = 0x7a2 202 | val tdata3 = 0x7a3 203 | val dcsr = 0x7b0 204 | val dpc = 0x7b1 205 | val dscratch = 0x7b2 206 | val mcycle = 0xb00 207 | val minstret = 0xb02 208 | val mhpmcounter3 = 0xb03 209 | val mhpmcounter4 = 0xb04 210 | val mhpmcounter5 = 0xb05 211 | val mhpmcounter6 = 0xb06 212 | val mhpmcounter7 = 0xb07 213 | val mhpmcounter8 = 0xb08 214 | val mhpmcounter9 = 0xb09 215 | val mhpmcounter10 = 0xb0a 216 | val mhpmcounter11 = 0xb0b 217 | val mhpmcounter12 = 0xb0c 218 | val mhpmcounter13 = 0xb0d 219 | val mhpmcounter14 = 0xb0e 220 | val mhpmcounter15 = 0xb0f 221 | val mhpmcounter16 = 0xb10 222 | val mhpmcounter17 = 0xb11 223 | val mhpmcounter18 = 0xb12 224 | val mhpmcounter19 = 0xb13 225 | val mhpmcounter20 = 0xb14 226 | val mhpmcounter21 = 0xb15 227 | val mhpmcounter22 = 0xb16 228 | val mhpmcounter23 = 0xb17 229 | val mhpmcounter24 = 0xb18 230 | val mhpmcounter25 = 0xb19 231 | val mhpmcounter26 = 0xb1a 232 | val mhpmcounter27 = 0xb1b 233 | val mhpmcounter28 = 0xb1c 234 | val mhpmcounter29 = 0xb1d 235 | val mhpmcounter30 = 0xb1e 236 | val mhpmcounter31 = 0xb1f 237 | val mucounteren = 0x320 238 | val mhpmevent3 = 0x323 239 | val mhpmevent4 = 0x324 240 | val mhpmevent5 = 0x325 241 | val mhpmevent6 = 0x326 242 | val mhpmevent7 = 0x327 243 | val mhpmevent8 = 0x328 244 | val mhpmevent9 = 0x329 245 | val mhpmevent10 = 0x32a 246 | val mhpmevent11 = 0x32b 247 | val mhpmevent12 = 0x32c 248 | val mhpmevent13 = 0x32d 249 | val mhpmevent14 = 0x32e 250 | val mhpmevent15 = 0x32f 251 | val mhpmevent16 = 0x330 252 | val mhpmevent17 = 0x331 253 | val mhpmevent18 = 0x332 254 | val mhpmevent19 = 0x333 255 | val mhpmevent20 = 0x334 256 | val mhpmevent21 = 0x335 257 | val mhpmevent22 = 0x336 258 | val mhpmevent23 = 0x337 259 | val mhpmevent24 = 0x338 260 | val mhpmevent25 = 0x339 261 | val mhpmevent26 = 0x33a 262 | val mhpmevent27 = 0x33b 263 | val mhpmevent28 = 0x33c 264 | val mhpmevent29 = 0x33d 265 | val mhpmevent30 = 0x33e 266 | val mhpmevent31 = 0x33f 267 | val mvendorid = 0xf11 268 | val marchid = 0xf12 269 | val mimpid = 0xf13 270 | val mhartid = 0xf14 271 | val cycleh = 0xc80 272 | val instreth = 0xc82 273 | val hpmcounter3h = 0xc83 274 | val hpmcounter4h = 0xc84 275 | val hpmcounter5h = 0xc85 276 | val hpmcounter6h = 0xc86 277 | val hpmcounter7h = 0xc87 278 | val hpmcounter8h = 0xc88 279 | val hpmcounter9h = 0xc89 280 | val hpmcounter10h = 0xc8a 281 | val hpmcounter11h = 0xc8b 282 | val hpmcounter12h = 0xc8c 283 | val hpmcounter13h = 0xc8d 284 | val hpmcounter14h = 0xc8e 285 | val hpmcounter15h = 0xc8f 286 | val hpmcounter16h = 0xc90 287 | val hpmcounter17h = 0xc91 288 | val hpmcounter18h = 0xc92 289 | val hpmcounter19h = 0xc93 290 | val hpmcounter20h = 0xc94 291 | val hpmcounter21h = 0xc95 292 | val hpmcounter22h = 0xc96 293 | val hpmcounter23h = 0xc97 294 | val hpmcounter24h = 0xc98 295 | val hpmcounter25h = 0xc99 296 | val hpmcounter26h = 0xc9a 297 | val hpmcounter27h = 0xc9b 298 | val hpmcounter28h = 0xc9c 299 | val hpmcounter29h = 0xc9d 300 | val hpmcounter30h = 0xc9e 301 | val hpmcounter31h = 0xc9f 302 | val mcycleh = 0xb80 303 | val minstreth = 0xb82 304 | val mhpmcounter3h = 0xb83 305 | val mhpmcounter4h = 0xb84 306 | val mhpmcounter5h = 0xb85 307 | val mhpmcounter6h = 0xb86 308 | val mhpmcounter7h = 0xb87 309 | val mhpmcounter8h = 0xb88 310 | val mhpmcounter9h = 0xb89 311 | val mhpmcounter10h = 0xb8a 312 | val mhpmcounter11h = 0xb8b 313 | val mhpmcounter12h = 0xb8c 314 | val mhpmcounter13h = 0xb8d 315 | val mhpmcounter14h = 0xb8e 316 | val mhpmcounter15h = 0xb8f 317 | val mhpmcounter16h = 0xb90 318 | val mhpmcounter17h = 0xb91 319 | val mhpmcounter18h = 0xb92 320 | val mhpmcounter19h = 0xb93 321 | val mhpmcounter20h = 0xb94 322 | val mhpmcounter21h = 0xb95 323 | val mhpmcounter22h = 0xb96 324 | val mhpmcounter23h = 0xb97 325 | val mhpmcounter24h = 0xb98 326 | val mhpmcounter25h = 0xb99 327 | val mhpmcounter26h = 0xb9a 328 | val mhpmcounter27h = 0xb9b 329 | val mhpmcounter28h = 0xb9c 330 | val mhpmcounter29h = 0xb9d 331 | val mhpmcounter30h = 0xb9e 332 | val mhpmcounter31h = 0xb9f 333 | val all = { 334 | val res = collection.mutable.ArrayBuffer[Int]() 335 | res += cycle 336 | res += instret 337 | res += hpmcounter3 338 | res += hpmcounter4 339 | res += hpmcounter5 340 | res += hpmcounter6 341 | res += hpmcounter7 342 | res += hpmcounter8 343 | res += hpmcounter9 344 | res += hpmcounter10 345 | res += hpmcounter11 346 | res += hpmcounter12 347 | res += hpmcounter13 348 | res += hpmcounter14 349 | res += hpmcounter15 350 | res += hpmcounter16 351 | res += hpmcounter17 352 | res += hpmcounter18 353 | res += hpmcounter19 354 | res += hpmcounter20 355 | res += hpmcounter21 356 | res += hpmcounter22 357 | res += hpmcounter23 358 | res += hpmcounter24 359 | res += hpmcounter25 360 | res += hpmcounter26 361 | res += hpmcounter27 362 | res += hpmcounter28 363 | res += hpmcounter29 364 | res += hpmcounter30 365 | res += hpmcounter31 366 | res += mstatus 367 | res += misa 368 | res += medeleg 369 | res += mideleg 370 | res += mie 371 | res += mtvec 372 | res += mscratch 373 | res += mepc 374 | res += mcause 375 | res += mtval 376 | res += mip 377 | res += tselect 378 | res += tdata1 379 | res += tdata2 380 | res += tdata3 381 | res += dcsr 382 | res += dpc 383 | res += dscratch 384 | res += mcycle 385 | res += minstret 386 | res += mhpmcounter3 387 | res += mhpmcounter4 388 | res += mhpmcounter5 389 | res += mhpmcounter6 390 | res += mhpmcounter7 391 | res += mhpmcounter8 392 | res += mhpmcounter9 393 | res += mhpmcounter10 394 | res += mhpmcounter11 395 | res += mhpmcounter12 396 | res += mhpmcounter13 397 | res += mhpmcounter14 398 | res += mhpmcounter15 399 | res += mhpmcounter16 400 | res += mhpmcounter17 401 | res += mhpmcounter18 402 | res += mhpmcounter19 403 | res += mhpmcounter20 404 | res += mhpmcounter21 405 | res += mhpmcounter22 406 | res += mhpmcounter23 407 | res += mhpmcounter24 408 | res += mhpmcounter25 409 | res += mhpmcounter26 410 | res += mhpmcounter27 411 | res += mhpmcounter28 412 | res += mhpmcounter29 413 | res += mhpmcounter30 414 | res += mhpmcounter31 415 | res += mucounteren 416 | res += mhpmevent3 417 | res += mhpmevent4 418 | res += mhpmevent5 419 | res += mhpmevent6 420 | res += mhpmevent7 421 | res += mhpmevent8 422 | res += mhpmevent9 423 | res += mhpmevent10 424 | res += mhpmevent11 425 | res += mhpmevent12 426 | res += mhpmevent13 427 | res += mhpmevent14 428 | res += mhpmevent15 429 | res += mhpmevent16 430 | res += mhpmevent17 431 | res += mhpmevent18 432 | res += mhpmevent19 433 | res += mhpmevent20 434 | res += mhpmevent21 435 | res += mhpmevent22 436 | res += mhpmevent23 437 | res += mhpmevent24 438 | res += mhpmevent25 439 | res += mhpmevent26 440 | res += mhpmevent27 441 | res += mhpmevent28 442 | res += mhpmevent29 443 | res += mhpmevent30 444 | res += mhpmevent31 445 | res += mvendorid 446 | res += marchid 447 | res += mimpid 448 | res += mhartid 449 | res.toArray 450 | } 451 | val all32 = { 452 | val res = collection.mutable.ArrayBuffer(all:_*) 453 | res += cycleh 454 | res += instreth 455 | res += hpmcounter3h 456 | res += hpmcounter4h 457 | res += hpmcounter5h 458 | res += hpmcounter6h 459 | res += hpmcounter7h 460 | res += hpmcounter8h 461 | res += hpmcounter9h 462 | res += hpmcounter10h 463 | res += hpmcounter11h 464 | res += hpmcounter12h 465 | res += hpmcounter13h 466 | res += hpmcounter14h 467 | res += hpmcounter15h 468 | res += hpmcounter16h 469 | res += hpmcounter17h 470 | res += hpmcounter18h 471 | res += hpmcounter19h 472 | res += hpmcounter20h 473 | res += hpmcounter21h 474 | res += hpmcounter22h 475 | res += hpmcounter23h 476 | res += hpmcounter24h 477 | res += hpmcounter25h 478 | res += hpmcounter26h 479 | res += hpmcounter27h 480 | res += hpmcounter28h 481 | res += hpmcounter29h 482 | res += hpmcounter30h 483 | res += hpmcounter31h 484 | res += mcycleh 485 | res += minstreth 486 | res += mhpmcounter3h 487 | res += mhpmcounter4h 488 | res += mhpmcounter5h 489 | res += mhpmcounter6h 490 | res += mhpmcounter7h 491 | res += mhpmcounter8h 492 | res += mhpmcounter9h 493 | res += mhpmcounter10h 494 | res += mhpmcounter11h 495 | res += mhpmcounter12h 496 | res += mhpmcounter13h 497 | res += mhpmcounter14h 498 | res += mhpmcounter15h 499 | res += mhpmcounter16h 500 | res += mhpmcounter17h 501 | res += mhpmcounter18h 502 | res += mhpmcounter19h 503 | res += mhpmcounter20h 504 | res += mhpmcounter21h 505 | res += mhpmcounter22h 506 | res += mhpmcounter23h 507 | res += mhpmcounter24h 508 | res += mhpmcounter25h 509 | res += mhpmcounter26h 510 | res += mhpmcounter27h 511 | res += mhpmcounter28h 512 | res += mhpmcounter29h 513 | res += mhpmcounter30h 514 | res += mhpmcounter31h 515 | res.toArray 516 | } 517 | } 518 | 519 | 520 | // TODO: use the riscv-dis binary instead. Requires change to Makefile (and the installation of riscv-dis). 521 | // Using Chisel is not very efficient to get a disassemble string. :( 522 | //object Disassemble 523 | //{ 524 | // def apply(insn: UInt, is_mini: Boolean = false) = { 525 | // val name :: fmt :: Nil = ListLookup(insn, default, table) 526 | // if (is_mini) 527 | // sprintf("%s", name) 528 | // else 529 | // sprintf("%s %s", name, operands(insn, fmt)) 530 | // } 531 | // 532 | // 533 | // private def operands(insn: Bits, fmt: Bits): Bits = { 534 | // val x = Vec(Str("zero"), Str(" ra"), Str(" sp"), Str(" gp"), 535 | // Str(" tp"), Str(" t0"), Str(" t1"), Str(" t2"), 536 | // Str(" s0"), Str(" s1"), Str(" a0"), Str(" a1"), 537 | // Str(" a2"), Str(" a3"), Str(" a4"), Str(" a5"), 538 | // Str(" a6"), Str(" a7"), Str(" s2"), Str(" s3"), 539 | // Str(" s4"), Str(" s5"), Str(" s6"), Str(" s7"), 540 | // Str(" s8"), Str(" s9"), Str(" s10"), Str(" s11"), 541 | // Str(" t3"), Str(" t4"), Str(" t5"), Str(" t6")) 542 | // val f = Vec(Str(" ft0"), Str(" ft1"), Str(" ft2"), Str(" ft3"), 543 | // Str(" ft4"), Str(" ft5"), Str(" ft6"), Str(" ft7"), 544 | // Str(" fs0"), Str(" fs1"), Str(" fa0"), Str(" fa1"), 545 | // Str(" fa2"), Str(" fa3"), Str(" fa4"), Str(" fa5"), 546 | // Str(" fa6"), Str(" fa7"), Str(" fs2"), Str(" fs3"), 547 | // Str(" fs4"), Str(" fs5"), Str(" fs6"), Str(" fs7"), 548 | // Str(" fs8"), Str(" fs9"), Str("fs10"), Str("fs11"), 549 | // Str(" ft8"), Str(" ft9"), Str("ft10"), Str("ft11")) 550 | // val p = Vec(Str(" cr0"), Str(" cr1"), Str(" cr2"), Str(" cr3"), 551 | // Str(" cr4"), Str(" cr5"), Str(" cr6"), Str(" cr7"), 552 | // Str(" cr8"), Str(" cr9"), Str("cr10"), Str("cr11"), 553 | // Str("cr12"), Str("cr13"), Str("cr14"), Str("cr15"), 554 | // Str("cr16"), Str("cr17"), Str("cr18"), Str("cr19"), 555 | // Str("cr20"), Str("cr21"), Str("cr22"), Str("cr23"), 556 | // Str("cr24"), Str("cr25"), Str("cr26"), Str("cr27"), 557 | // Str("cr28"), Str("cr29"), Str("cr30"), Str("cr31")) 558 | // 559 | // 560 | // def hex(x: SInt, plus: Char = ' ') = 561 | // Cat(Mux(x < SInt(0), Str("-0x"), Str(plus + "0x")), Str(x.abs, 16)) 562 | // 563 | // val comma = Str(',') 564 | // val lparen = Str('(') 565 | // val rparen = Str(')') 566 | // 567 | // val rd = insn(11,7) 568 | // val rs1 = insn(19,15) 569 | // val rs2 = insn(24,20) 570 | // val immv = insn(31,20).toSInt 571 | // val smmv = Cat(insn(31, 25), insn(11,7)).toSInt 572 | // val bmmv = Cat(insn(31), insn(7), insn(30,25), insn(11,8)).toSInt 573 | // val jmmv = Cat(insn(31,7), insn(19,12), insn(20), insn(30,21)).toSInt 574 | // 575 | // val imm = hex(immv) 576 | // val bmm = hex(bmmv << UInt(1)) 577 | // val jmm = hex(jmmv << UInt(1)) 578 | // val smm = hex(smmv) 579 | // val umm = Cat(Str("0x"), Str(insn(31,12).toUInt, 16)) 580 | // 581 | // val laddr = Cat(Str(immv), lparen, x(rs1), rparen) 582 | // val saddr = Cat(Str(bmmv), lparen, x(rs1), rparen) 583 | // 584 | // val r0 = x(rd) 585 | // val r1 = Cat(r0, comma, x(rs1)) 586 | // val r2 = Cat(r1, comma, x(rs2)) 587 | // val f1 = Cat(f(rd), comma, f(rs1)) 588 | // val f2 = Cat(f1, comma, f(rs2)) 589 | // val fx = Cat(f(rd), comma, x(rs1)) 590 | // val xf1 = Cat(x(rd), comma, f(rs1)) 591 | // val xf2 = Cat(xf1, comma, f(rs2)) 592 | // val z = Str(' ') 593 | // val i = Cat(r1, comma, imm) 594 | // val b = Cat(x(rs1), comma, x(rs2), comma, bmm) 595 | // val j = jmm 596 | // val l = Cat(x(rd), comma, umm) 597 | // val ld = Cat(x(rd), comma, laddr) 598 | // val st = Cat(x(rs2), comma, saddr) 599 | // val fld = Cat(f(rd), comma, laddr) 600 | // val fst = Cat(f(rs2), comma, saddr) 601 | // val amo = r2 602 | // val r2_p = Cat(r0, comma, p(rs1), comma, x(rs2)) 603 | // 604 | // val opts = Seq(r0, r1, r2, f1, f2, UInt(0), fx, xf1, xf2, z, i, b, j, l, ld, st, 605 | // fld, fst, amo, r2_p) 606 | // val maxLen = opts.map(_.getWidth).reduce(_ max _) 607 | // val padded = opts.map(x => x.toUInt << UInt(maxLen - x.getWidth)) 608 | // Vec(padded)(fmt.toUInt) 609 | // } 610 | // 611 | // private def FMT_R0 = Bits(0, 5) 612 | // private def FMT_R1 = Bits(1, 5) 613 | // private def FMT_R2 = Bits(2, 5) 614 | // private def FMT_F1 = Bits(3, 5) 615 | // private def FMT_F2 = Bits(4, 5) 616 | // private def FMT_F3 = Bits(5, 5) 617 | // private def FMT_FX = Bits(6, 5) 618 | // private def FMT_XF1 = Bits(7, 5) 619 | // private def FMT_XF2 = Bits(8, 5) 620 | // private def FMT_0 = Bits(9, 5) 621 | // private def FMT_I = Bits(10, 5) 622 | // private def FMT_B = Bits(11, 5) 623 | // private def FMT_J = Bits(12, 5) 624 | // private def FMT_L = Bits(13, 5) 625 | // private def FMT_LD = Bits(14, 5) 626 | // private def FMT_ST = Bits(15, 5) 627 | // private def FMT_FLD = Bits(16, 5) 628 | // private def FMT_FST = Bits(17, 5) 629 | // private def FMT_AMO = Bits(18, 5) 630 | // private def FMT_R2_P= Bits(19, 5) 631 | // 632 | // private def default = List(Str("unknown "), FMT_0) 633 | // 634 | // import Instructions._ 635 | // private def table = Array( 636 | //// NOP-> List(Str("nop "), FMT_0), 637 | // Bits(0x4033,32)-> // machine generated bubble 638 | // List(Str(" - "), FMT_0), 639 | // 640 | // BNE-> List(Str("bne "), FMT_B), 641 | // BEQ-> List(Str("beq "), FMT_B), 642 | // BLT-> List(Str("blt "), FMT_B), 643 | // BLTU-> List(Str("bltu "), FMT_B), 644 | // BGE-> List(Str("bge "), FMT_B), 645 | // BGEU-> List(Str("bgeu "), FMT_B), 646 | // 647 | // JAL-> List(Str("jal "), FMT_J), 648 | // JALR-> List(Str("jalr "), FMT_LD), 649 | // AUIPC-> List(Str("auipc "), FMT_L), 650 | // 651 | // LB-> List(Str("lb "), FMT_LD), 652 | // LH-> List(Str("lh "), FMT_LD), 653 | // LW-> List(Str("lw "), FMT_LD), 654 | // LD-> List(Str("ld "), FMT_LD), 655 | // LBU-> List(Str("lbu "), FMT_LD), 656 | // LHU-> List(Str("lhu "), FMT_LD), 657 | // LWU-> List(Str("lwu "), FMT_LD), 658 | // SB-> List(Str("sb "), FMT_ST), 659 | // SH-> List(Str("sh "), FMT_ST), 660 | // SW-> List(Str("sw "), FMT_ST), 661 | // SD-> List(Str("sd "), FMT_ST), 662 | // 663 | // AMOADD_W-> List(Str("amoadd.w "), FMT_AMO), 664 | // AMOSWAP_W-> List(Str("amoswap.w "), FMT_AMO), 665 | // AMOAND_W-> List(Str("amoand.w "), FMT_AMO), 666 | // AMOOR_W-> List(Str("amoor.w "), FMT_AMO), 667 | // AMOMIN_W-> List(Str("amomin.w "), FMT_AMO), 668 | // AMOMINU_W-> List(Str("amominu.w "), FMT_AMO), 669 | // AMOMAX_W-> List(Str("amomax.w "), FMT_AMO), 670 | // AMOMAXU_W-> List(Str("amomaxu.w "), FMT_AMO), 671 | // AMOADD_D-> List(Str("amoadd.d "), FMT_AMO), 672 | // AMOSWAP_D-> List(Str("amoswap.d "), FMT_AMO), 673 | // AMOAND_D-> List(Str("amoand.d "), FMT_AMO), 674 | // AMOOR_D-> List(Str("amoor.d "), FMT_AMO), 675 | // AMOMIN_D-> List(Str("amomin.d "), FMT_AMO), 676 | // AMOMINU_D-> List(Str("amominu.d "), FMT_AMO), 677 | // AMOMAX_D-> List(Str("amomax.d "), FMT_AMO), 678 | // AMOMAXU_D-> List(Str("amomaxu.d "), FMT_AMO), 679 | // 680 | // LR_W-> List(Str("lr.w "), FMT_AMO), 681 | // LR_D-> List(Str("lr.d "), FMT_AMO), 682 | // SC_W-> List(Str("sc.w "), FMT_AMO), 683 | // SC_D-> List(Str("sc.d "), FMT_AMO), 684 | // 685 | // LUI-> List(Str("lui "), FMT_L), 686 | // ADDI-> List(Str("addi "), FMT_I), 687 | // SLTI -> List(Str("slti "), FMT_I), 688 | // SLTIU-> List(Str("sltiu "), FMT_I), 689 | // ANDI-> List(Str("andi "), FMT_I), 690 | // ORI-> List(Str("ori "), FMT_I), 691 | // XORI-> List(Str("xori "), FMT_I), 692 | // SLLI-> List(Str("slli "), FMT_I), 693 | // SRLI-> List(Str("srli "), FMT_I), 694 | // SRAI-> List(Str("srai "), FMT_I), 695 | // ADD-> List(Str("add "), FMT_R2), 696 | // SUB-> List(Str("sub "), FMT_R2), 697 | // SLT-> List(Str("slt "), FMT_R2), 698 | // SLTU-> List(Str("sltu "), FMT_R2), 699 | // AND-> List(Str("and "), FMT_R2), 700 | // OR-> List(Str("or "), FMT_R2), 701 | // XOR-> List(Str("xor "), FMT_R2), 702 | // SLL-> List(Str("sll "), FMT_R2), 703 | // SRL-> List(Str("srl "), FMT_R2), 704 | // SRA-> List(Str("sra "), FMT_R2), 705 | // 706 | // ADDIW-> List(Str("addiw "), FMT_I), 707 | // SLLIW-> List(Str("slliw "), FMT_I), 708 | // SRLIW-> List(Str("srliw "), FMT_I), 709 | // SRAIW-> List(Str("sraiw "), FMT_I), 710 | // ADDW-> List(Str("addw "), FMT_R2), 711 | // SUBW-> List(Str("subw "), FMT_R2), 712 | // SLLW-> List(Str("sllw "), FMT_R2), 713 | // SRLW-> List(Str("srlw "), FMT_R2), 714 | // SRAW-> List(Str("sraw "), FMT_R2), 715 | // 716 | // MUL-> List(Str("mul "), FMT_R2), 717 | // MULH-> List(Str("mulh "), FMT_R2), 718 | // MULHU-> List(Str("mulhu "), FMT_R2), 719 | // MULHSU-> List(Str("mulhsu "), FMT_R2), 720 | // MULW-> List(Str("mulw "), FMT_R2), 721 | // 722 | // DIV-> List(Str("div "), FMT_R2), 723 | // DIVU-> List(Str("divu "), FMT_R2), 724 | // REM-> List(Str("rem "), FMT_R2), 725 | // REMU-> List(Str("remu "), FMT_R2), 726 | // DIVW-> List(Str("divw "), FMT_R2), 727 | // DIVUW-> List(Str("divuw "), FMT_R2), 728 | // REMW-> List(Str("remw "), FMT_R2), 729 | // REMUW-> List(Str("remuw "), FMT_R2), 730 | // 731 | // SCALL-> List(Str("scall "), FMT_0), 732 | // CSRRW-> List(Str("csrrw "), FMT_I), 733 | // CSRRS-> List(Str("csrrs "), FMT_I), 734 | // CSRRC-> List(Str("csrrc "), FMT_I), 735 | // CSRRWI-> List(Str("csrrwi "), FMT_I), 736 | // CSRRSI-> List(Str("csrrsi "), FMT_I), 737 | // CSRRCI-> List(Str("csrrci "), FMT_I), 738 | // SRET-> List(Str("sret "), FMT_0), 739 | // FENCE-> List(Str("fence "), FMT_0), 740 | // FENCE_I-> List(Str("fence.i "), FMT_0) 741 | ///* 742 | // FCVT_S_D-> List(Str("fcvt.s.d "), FMT_F1), 743 | // FCVT_D_S-> List(Str("fcvt.d.s "), FMT_F1), 744 | // FSGNJ_S-> List(Str("fsgnj.s "), FMT_F2), 745 | // FSGNJ_D-> List(Str("fsgnj.d "), FMT_F2), 746 | // FSGNJX_S-> List(Str("fsgnx.s "), FMT_F2), 747 | // FSGNJX_D-> List(Str("fsgnx.d "), FMT_F2), 748 | // FSGNJN_S-> List(Str("fsgnjn.s "), FMT_F2), 749 | // FSGNJN_D-> List(Str("fsgnjn.d "), FMT_F2), 750 | // FMIN_S-> List(Str("fmin.s "), FMT_F2), 751 | // FMIN_D-> List(Str("fmin.d "), FMT_F2), 752 | // FMAX_S-> List(Str("fmax.s "), FMT_F2), 753 | // FMAX_D-> List(Str("fmax.d "), FMT_F2), 754 | // FADD_S-> List(Str("fadd.s "), FMT_F2), 755 | // FADD_D-> List(Str("fadd.d "), FMT_F2), 756 | // FSUB_S-> List(Str("fsub.s "), FMT_F2), 757 | // FSUB_D-> List(Str("fsub.d "), FMT_F2), 758 | // FMUL_S-> List(Str("fmul.s "), FMT_F2), 759 | // FMUL_D-> List(Str("fmul.d "), FMT_F2), 760 | // FMADD_S-> List(Str("fmadd.s "), FMT_F3), 761 | // FMADD_D-> List(Str("fmadd.d "), FMT_F3), 762 | // FMSUB_S-> List(Str("fmsub.s "), FMT_F3), 763 | // FMSUB_D-> List(Str("fmsub.d "), FMT_F3), 764 | // FNMADD_S-> List(Str("fnmadd.s "), FMT_F3), 765 | // FNMADD_D-> List(Str("fnmadd.d "), FMT_F3), 766 | // FNMSUB_S-> List(Str("fnmsub.s "), FMT_F3), 767 | // FNMSUB_D-> List(Str("fnmsub.d "), FMT_F3), 768 | // FCVT_W_S-> List(Str("fcvt.w.s "), FMT_XF1), 769 | // FCVT_W_D-> List(Str("fcvt.w.d "), FMT_XF1), 770 | // FCVT_WU_S-> List(Str("fcvt.wu.s "), FMT_XF1), 771 | // FCVT_WU_D-> List(Str("fcvt.wu.d "), FMT_XF1), 772 | // FCVT_L_S-> List(Str("fcvt.l.s "), FMT_XF1), 773 | // FCVT_L_D-> List(Str("fcvt.l.d "), FMT_XF1), 774 | // FCVT_LU_S-> List(Str("fcvt.lu.s "), FMT_XF1), 775 | // FCVT_LU_D-> List(Str("fcvt.lu.d "), FMT_XF1), 776 | // FEQ_S-> List(Str("feq.s "), FMT_XF2), 777 | // FEQ_D-> List(Str("feq.d "), FMT_XF2), 778 | // FLT_S-> List(Str("flt.s "), FMT_XF2), 779 | // FLT_D-> List(Str("flt.d "), FMT_XF2), 780 | // FLE_S-> List(Str("fle.s "), FMT_XF2), 781 | // FLE_D-> List(Str("fle.d "), FMT_XF2), 782 | // FCVT_S_W-> List(Str("fcvt.s.w "), FMT_FX), 783 | // FCVT_D_W-> List(Str("fcvt.d.w "), FMT_FX), 784 | // FCVT_S_WU-> List(Str("fcvt.s.wu "), FMT_FX), 785 | // FCVT_D_WU-> List(Str("fcvt.d.wu "), FMT_FX), 786 | // FCVT_S_L-> List(Str("fcvt.s.l "), FMT_FX), 787 | // FCVT_D_L-> List(Str("fcvt.d.l "), FMT_FX), 788 | // FCVT_S_LU-> List(Str("fcvt.s.lu "), FMT_FX), 789 | // FCVT_D_LU-> List(Str("fcvt.d.lu "), FMT_FX), 790 | // FLW-> List(Str("flw "), FMT_FLD), 791 | // FLD-> List(Str("fld "), FMT_FLD), 792 | // FSW-> List(Str("fsw "), FMT_FST), 793 | // FSD-> List(Str("fsd "), FMT_FST), 794 | // 795 | // VVCFGIVL-> List(Str("vecInst "), FMT_0), 796 | // VVCFG-> List(Str("vecInst "), FMT_0), 797 | // VSETVL-> List(Str("vecInst "), FMT_0), 798 | // VF-> List(Str("vecInst "), FMT_0), 799 | // VMVV-> List(Str("vecInst "), FMT_0), 800 | // VMSV-> List(Str("vecInst "), FMT_0), 801 | // VFMVV-> List(Str("vecInst "), FMT_0), 802 | // FENCE_V_L-> List(Str("vecInst "), FMT_0), 803 | // FENCE_V_G-> List(Str("vecInst "), FMT_0), 804 | // VLD-> List(Str("vecInst "), FMT_0), 805 | // VLW-> List(Str("vecInst "), FMT_0), 806 | // VLWU-> List(Str("vecInst "), FMT_0), 807 | // VLH-> List(Str("vecInst "), FMT_0), 808 | // VLHU-> List(Str("vecInst "), FMT_0), 809 | // VLB-> List(Str("vecInst "), FMT_0), 810 | // VLBU-> List(Str("vecInst "), FMT_0), 811 | // VSD-> List(Str("vecInst "), FMT_0), 812 | // VSW-> List(Str("vecInst "), FMT_0), 813 | // VSH-> List(Str("vecInst "), FMT_0), 814 | // VSB-> List(Str("vecInst "), FMT_0), 815 | // VFLD-> List(Str("vecInst "), FMT_0), 816 | // VFLW-> List(Str("vecInst "), FMT_0), 817 | // VFSD-> List(Str("vecInst "), FMT_0), 818 | // VFSW-> List(Str("vecInst "), FMT_0), 819 | // VLSTD-> List(Str("vecInst "), FMT_0), 820 | // VLSTW-> List(Str("vecInst "), FMT_0), 821 | // VLSTWU-> List(Str("vecInst "), FMT_0), 822 | // VLSTH-> List(Str("vecInst "), FMT_0), 823 | // VLSTHU-> List(Str("vecInst "), FMT_0), 824 | // VLSTB-> List(Str("vecInst "), FMT_0), 825 | // VLSTBU-> List(Str("vecInst "), FMT_0), 826 | // VSSTD-> List(Str("vecInst "), FMT_0), 827 | // VSSTW-> List(Str("vecInst "), FMT_0), 828 | // VSSTH-> List(Str("vecInst "), FMT_0), 829 | // VSSTB-> List(Str("vecInst "), FMT_0), 830 | // VFLSTD-> List(Str("vecInst "), FMT_0), 831 | // VFLSTW-> List(Str("vecInst "), FMT_0), 832 | // VFSSTD-> List(Str("vecInst "), FMT_0), 833 | // VFSSTW-> List(Str("vecInst "), FMT_0), 834 | // 835 | // VENQCMD-> List(Str("vecInst "), FMT_0), 836 | // VENQIMM1-> List(Str("vecInst "), FMT_0), 837 | // VENQIMM2-> List(Str("vecInst "), FMT_0), 838 | // VENQCNT-> List(Str("vecInst "), FMT_0), 839 | // VXCPTEVAC-> List(Str("vecInst "), FMT_0), 840 | // VXCPTKILL-> List(Str("vecInst "), FMT_0), 841 | // VXCPTHOLD-> List(Str("vecInst "), FMT_0) 842 | // */ 843 | // ) 844 | //} -------------------------------------------------------------------------------- /chisel/src/main/scala/core/Tile.scala: -------------------------------------------------------------------------------- 1 | 2 | package bad 3 | 4 | import chisel3._ 5 | import chisel3.util._ 6 | 7 | class Tile extends Module { 8 | val io = IO(new Bundle { 9 | val led = Output(UInt(4.W)) 10 | }) 11 | 12 | val core = Module(new Core()) 13 | 14 | io.led := core.io.imem_addr(3, 0) 15 | } -------------------------------------------------------------------------------- /chisel/src/main/scala/fpga/Arty100TTop.scala: -------------------------------------------------------------------------------- 1 | package bad 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import chisel3.experimental.Analog 6 | 7 | class Arty100TTop extends RawModule { 8 | val CLK100MHZ = IO(Input(Clock())) 9 | val ck_rst = IO(Input(Bool())) 10 | 11 | val uart_rxd_out = IO(Output(Bool())) 12 | 13 | val ja = IO(Analog(8.W)) 14 | 15 | 16 | 17 | 18 | val uart = withClockAndReset(CLK100MHZ, !ck_rst){ Module(new UART()) } 19 | 20 | uart.io.en := true.B 21 | uart.io.in.valid := true.B 22 | uart.io.in.bits := 0x55.U 23 | 24 | uart.io.div := 868.U - 1.U 25 | 26 | uart.io.word_length := 8.U 27 | uart.io.parity := 0.U 28 | uart.io.stop_bits := 1.U 29 | uart.io.msb_first := true.B 30 | 31 | uart_rxd_out := uart.io.out 32 | } 33 | -------------------------------------------------------------------------------- /chisel/src/main/scala/peripheral/UART.scala: -------------------------------------------------------------------------------- 1 | package bad 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | 6 | object UARTRegMap { 7 | val CR1 = 0x00 8 | val CR2 = 0x04 9 | val BRR = 0x08 10 | val ISR = 0x0A 11 | val ICR = 0x0C 12 | val RDR = 0x10 13 | val TDR = 0x14 14 | val PRESC = 0x18 15 | } 16 | 17 | 18 | case class UARTParams( 19 | address: BigInt, 20 | dataBits: Int = 8, 21 | stopBits: Int = 2, 22 | divisorBits: Int = 16, 23 | oversample: Int = 4, 24 | nSamples: Int = 3, 25 | nTxEntries: Int = 8, 26 | nRxEntries: Int = 8, 27 | includeFourWire: Boolean = false, 28 | includeParity: Boolean = false, 29 | includeIndependentParity: Boolean = false, // Tx and Rx have opposite parity modes 30 | initBaudRate: BigInt = BigInt(115200), 31 | ) { 32 | def oversampleFactor = 1 << oversample 33 | require(divisorBits > oversample) 34 | require(oversampleFactor > nSamples) 35 | require((dataBits == 8) || (dataBits == 9)) 36 | } 37 | 38 | 39 | class UART(maxDataBits: Int = 8, divisorBits: Int = 16) extends Module { 40 | val io = IO(new Bundle { 41 | /** enable signal of the TX module */ 42 | val en = Input(Bool()) 43 | /** data in from memory bus */ 44 | val in = Flipped(Decoupled(UInt(maxDataBits.W))) 45 | 46 | val div = Input(UInt(divisorBits.W)) 47 | 48 | val word_length = Input(UInt(2.W)) 49 | val parity = Input(UInt(2.W)) 50 | val stop_bits = Input(UInt(2.W)) 51 | val msb_first = Input(Bool()) 52 | 53 | /** TXD pin to external */ 54 | val out = Output(Bool()) 55 | }) 56 | 57 | val tx = Module(new UARTTX(maxDataBits, divisorBits)) 58 | 59 | tx.io.en := io.en 60 | tx.io.in <> io.in 61 | tx.io.div := io.div 62 | tx.io.word_length := io.word_length 63 | tx.io.parity := io.parity 64 | tx.io.stop_bits := io.stop_bits 65 | tx.io.msb_first := io.msb_first 66 | io.out := tx.io.out 67 | } 68 | 69 | 70 | /** 71 | * UART 72 | * 73 | * @param maxDataBits maximum data bits 74 | * @param divisorBits divisor bits 75 | * 76 | */ 77 | class UARTTX(maxDataBits: Int = 8, divisorBits: Int = 16) extends Module { 78 | val io = IO(new Bundle { 79 | /** enable signal of the TX module */ 80 | val en = Input(Bool()) 81 | /** data in from memory bus */ 82 | val in = Flipped(Decoupled(UInt(maxDataBits.W))) 83 | 84 | val div = Input(UInt(divisorBits.W)) 85 | 86 | val word_length = Input(UInt(2.W)) 87 | val parity = Input(UInt(2.W)) 88 | val stop_bits = Input(UInt(2.W)) 89 | val msb_first = Input(Bool()) 90 | 91 | /** TXD pin to external */ 92 | val out = Output(Bool()) 93 | }) 94 | 95 | val stop_bits = 1.U 96 | val parity = 0.U 97 | val data_bits = 8.U 98 | 99 | val shifter = Reg(UInt(maxDataBits.W)) 100 | val out = RegInit(1.U(1.W)) 101 | 102 | val prescaler = RegInit(0.U(divisorBits.W)) 103 | val counter = RegInit(0.U((log2Ceil((1 + maxDataBits + 1 + 2) + 1)).W)) 104 | val sending_stop = counter === 0.U 105 | val pulse = prescaler === 0.U 106 | val busy = !(sending_stop && pulse) 107 | 108 | io.in.ready := !busy 109 | io.out := out 110 | 111 | when (io.in.fire) { 112 | // admit new data 113 | 114 | // reload prescaler 115 | prescaler := io.div 116 | 117 | // load counter and shift register with correct data and format 118 | counter := data_bits + parity + stop_bits 119 | shifter := Cat(1.U(1.W), Mux(io.msb_first, io.in.bits, Reverse(io.in.bits))) 120 | 121 | // pre-load TXD with start bit 122 | out := 0.U 123 | } 124 | 125 | when (pulse && !sending_stop) { 126 | // send the next bit 127 | counter := counter - 1.U 128 | shifter := Cat(1.U(1.W), shifter >> 1) 129 | out := shifter(0) 130 | } 131 | 132 | when (busy) { 133 | // baudrate generator 134 | prescaler := Mux(pulse, io.div, prescaler - 1.U) 135 | } 136 | 137 | } 138 | 139 | class UARTRX extends Module { 140 | val io = IO(new Bundle { 141 | val en = Input(Bool()) 142 | val out = Output(Bool()) 143 | }) 144 | 145 | val out = RegInit(1.U(1.W)) 146 | 147 | io.out := out 148 | } 149 | -------------------------------------------------------------------------------- /docs/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T-K-233/RISC-V-Single-Cycle-CPU/ca807fe88ca54eea48e50cf75a2ba3835de6d028/docs/cover.jpg -------------------------------------------------------------------------------- /docs/result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T-K-233/RISC-V-Single-Cycle-CPU/ca807fe88ca54eea48e50cf75a2ba3835de6d028/docs/result.jpg -------------------------------------------------------------------------------- /verilog/lib/ram_artix7.v: -------------------------------------------------------------------------------- 1 | `include "ba201rv32i_consts.vh" 2 | 3 | module RAM_Artix7 ( 4 | input clk, 5 | input rst, 6 | 7 | input [31:0] io_imem_addr, 8 | output [31:0] io_imem_rdata, 9 | input [31:0] io_dmem_addr, 10 | input io_dmem_type, 11 | input [31:0] io_dmem_wdata, 12 | input [3:0] io_dmem_wmask, 13 | output [31:0] io_dmem_rdata 14 | ); 15 | 16 | wire [31:0] DOA; 17 | wire [31:0] DOB; 18 | wire [9:0] ADDRA; 19 | wire [9:0] ADDRB; 20 | wire CLKA; 21 | wire CLKB; 22 | wire [31:0] DIA; 23 | wire [31:0] DIB; 24 | wire ENA; 25 | wire ENB; 26 | wire RSTA; 27 | wire RSTB; 28 | wire [3:0] WEA; 29 | wire [3:0] WEB; 30 | 31 | 32 | assign io_imem_rdata = DOA; 33 | assign io_dmem_rdata = DOB; 34 | 35 | assign ADDRA = io_imem_addr[11:2]; 36 | assign ADDRB = io_dmem_addr[11:2]; 37 | 38 | assign CLKA = clk; 39 | assign CLKB = clk; 40 | 41 | assign DIA = 'h0; 42 | assign DIB = io_dmem_wdata; 43 | 44 | assign RSTA = rst; 45 | assign RSTB = rst; 46 | 47 | assign WEA = 'h0; 48 | assign WEB = io_dmem_wmask; 49 | 50 | 51 | // BRAM_TDP_MACRO: True Dual Port RAM 52 | // Artix-7 53 | // Xilinx HDL Language Template, version 2023.2 54 | 55 | ////////////////////////////////////////////////////////////////////////// 56 | // DATA_WIDTH_A/B | BRAM_SIZE | RAM Depth | ADDRA/B Width | WEA/B Width // 57 | // ===============|===========|===========|===============|=============// 58 | // 19-36 | "36Kb" | 1024 | 10-bit | 4-bit // 59 | // 10-18 | "36Kb" | 2048 | 11-bit | 2-bit // 60 | // 10-18 | "18Kb" | 1024 | 10-bit | 2-bit // 61 | // 5-9 | "36Kb" | 4096 | 12-bit | 1-bit // 62 | // 5-9 | "18Kb" | 2048 | 11-bit | 1-bit // 63 | // 3-4 | "36Kb" | 8192 | 13-bit | 1-bit // 64 | // 3-4 | "18Kb" | 4096 | 12-bit | 1-bit // 65 | // 2 | "36Kb" | 16384 | 14-bit | 1-bit // 66 | // 2 | "18Kb" | 8192 | 13-bit | 1-bit // 67 | // 1 | "36Kb" | 32768 | 15-bit | 1-bit // 68 | // 1 | "18Kb" | 16384 | 14-bit | 1-bit // 69 | ////////////////////////////////////////////////////////////////////////// 70 | 71 | BRAM_TDP_MACRO #( 72 | .BRAM_SIZE("18Kb"), // Target BRAM: "18Kb" or "36Kb" 73 | .DEVICE("7SERIES"), // Target device: "7SERIES" 74 | .DOA_REG(0), // Optional port A output register (0 or 1) 75 | .DOB_REG(0), // Optional port B output register (0 or 1) 76 | .INIT_A(36'h0000000), // Initial values on port A output port 77 | .INIT_B(36'h00000000), // Initial values on port B output port 78 | .INIT_FILE("NONE"), 79 | .READ_WIDTH_A(32), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") 80 | .READ_WIDTH_B(32), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") 81 | .SIM_COLLISION_CHECK ("ALL"), // Collision check enable "ALL", "WARNING_ONLY", 82 | // "GENERATE_X_ONLY" or "NONE" 83 | .SRVAL_A(36'h00000000), // Set/Reset value for port A output 84 | .SRVAL_B(36'h00000000), // Set/Reset value for port B output 85 | .WRITE_MODE_A("WRITE_FIRST"), // "WRITE_FIRST", "READ_FIRST", or "NO_CHANGE" 86 | .WRITE_MODE_B("WRITE_FIRST"), // "WRITE_FIRST", "READ_FIRST", or "NO_CHANGE" 87 | .WRITE_WIDTH_A(32), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") 88 | .WRITE_WIDTH_B(32), // Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") 89 | .INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000), 90 | .INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000), 91 | .INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000), 92 | .INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000), 93 | .INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000), 94 | .INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000), 95 | .INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000), 96 | .INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000), 97 | .INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000), 98 | .INIT_09(256'h0000000000000000000000000000000000000000000000000000000000000000), 99 | .INIT_0A(256'h0000000000000000000000000000000000000000000000000000000000000000), 100 | .INIT_0B(256'h0000000000000000000000000000000000000000000000000000000000000000), 101 | .INIT_0C(256'h0000000000000000000000000000000000000000000000000000000000000000), 102 | .INIT_0D(256'h0000000000000000000000000000000000000000000000000000000000000000), 103 | .INIT_0E(256'h0000000000000000000000000000000000000000000000000000000000000000), 104 | .INIT_0F(256'h0000000000000000000000000000000000000000000000000000000000000000), 105 | .INIT_10(256'h0000000000000000000000000000000000000000000000000000000000000000), 106 | .INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000), 107 | .INIT_12(256'h0000000000000000000000000000000000000000000000000000000000000000), 108 | .INIT_13(256'h0000000000000000000000000000000000000000000000000000000000000000), 109 | .INIT_14(256'h0000000000000000000000000000000000000000000000000000000000000000), 110 | .INIT_15(256'h0000000000000000000000000000000000000000000000000000000000000000), 111 | .INIT_16(256'h0000000000000000000000000000000000000000000000000000000000000000), 112 | .INIT_17(256'h0000000000000000000000000000000000000000000000000000000000000000), 113 | .INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000), 114 | .INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000), 115 | .INIT_1A(256'h0000000000000000000000000000000000000000000000000000000000000000), 116 | .INIT_1B(256'h0000000000000000000000000000000000000000000000000000000000000000), 117 | .INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000), 118 | .INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000), 119 | .INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000), 120 | .INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000), 121 | .INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000), 122 | .INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000), 123 | .INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000), 124 | .INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000), 125 | .INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000), 126 | .INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000), 127 | .INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000), 128 | .INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000), 129 | .INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000), 130 | .INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000), 131 | .INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000), 132 | .INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000), 133 | .INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000), 134 | .INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000), 135 | .INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000), 136 | .INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000), 137 | .INIT_30(256'h0000000000000000000000000000000000000000000000000000000000000000), 138 | .INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000), 139 | .INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000), 140 | .INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000), 141 | .INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000), 142 | .INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000), 143 | .INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000), 144 | .INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000), 145 | .INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000), 146 | .INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000), 147 | .INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000), 148 | .INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000), 149 | .INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000), 150 | .INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000), 151 | .INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000), 152 | .INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000), 153 | 154 | // The next set of INIT_xx are valid when configured as 36Kb 155 | .INIT_40(256'h0000000000000000000000000000000000000000000000000000000000000000), 156 | .INIT_41(256'h0000000000000000000000000000000000000000000000000000000000000000), 157 | .INIT_42(256'h0000000000000000000000000000000000000000000000000000000000000000), 158 | .INIT_43(256'h0000000000000000000000000000000000000000000000000000000000000000), 159 | .INIT_44(256'h0000000000000000000000000000000000000000000000000000000000000000), 160 | .INIT_45(256'h0000000000000000000000000000000000000000000000000000000000000000), 161 | .INIT_46(256'h0000000000000000000000000000000000000000000000000000000000000000), 162 | .INIT_47(256'h0000000000000000000000000000000000000000000000000000000000000000), 163 | .INIT_48(256'h0000000000000000000000000000000000000000000000000000000000000000), 164 | .INIT_49(256'h0000000000000000000000000000000000000000000000000000000000000000), 165 | .INIT_4A(256'h0000000000000000000000000000000000000000000000000000000000000000), 166 | .INIT_4B(256'h0000000000000000000000000000000000000000000000000000000000000000), 167 | .INIT_4C(256'h0000000000000000000000000000000000000000000000000000000000000000), 168 | .INIT_4D(256'h0000000000000000000000000000000000000000000000000000000000000000), 169 | .INIT_4E(256'h0000000000000000000000000000000000000000000000000000000000000000), 170 | .INIT_4F(256'h0000000000000000000000000000000000000000000000000000000000000000), 171 | .INIT_50(256'h0000000000000000000000000000000000000000000000000000000000000000), 172 | .INIT_51(256'h0000000000000000000000000000000000000000000000000000000000000000), 173 | .INIT_52(256'h0000000000000000000000000000000000000000000000000000000000000000), 174 | .INIT_53(256'h0000000000000000000000000000000000000000000000000000000000000000), 175 | .INIT_54(256'h0000000000000000000000000000000000000000000000000000000000000000), 176 | .INIT_55(256'h0000000000000000000000000000000000000000000000000000000000000000), 177 | .INIT_56(256'h0000000000000000000000000000000000000000000000000000000000000000), 178 | .INIT_57(256'h0000000000000000000000000000000000000000000000000000000000000000), 179 | .INIT_58(256'h0000000000000000000000000000000000000000000000000000000000000000), 180 | .INIT_59(256'h0000000000000000000000000000000000000000000000000000000000000000), 181 | .INIT_5A(256'h0000000000000000000000000000000000000000000000000000000000000000), 182 | .INIT_5B(256'h0000000000000000000000000000000000000000000000000000000000000000), 183 | .INIT_5C(256'h0000000000000000000000000000000000000000000000000000000000000000), 184 | .INIT_5D(256'h0000000000000000000000000000000000000000000000000000000000000000), 185 | .INIT_5E(256'h0000000000000000000000000000000000000000000000000000000000000000), 186 | .INIT_5F(256'h0000000000000000000000000000000000000000000000000000000000000000), 187 | .INIT_60(256'h0000000000000000000000000000000000000000000000000000000000000000), 188 | .INIT_61(256'h0000000000000000000000000000000000000000000000000000000000000000), 189 | .INIT_62(256'h0000000000000000000000000000000000000000000000000000000000000000), 190 | .INIT_63(256'h0000000000000000000000000000000000000000000000000000000000000000), 191 | .INIT_64(256'h0000000000000000000000000000000000000000000000000000000000000000), 192 | .INIT_65(256'h0000000000000000000000000000000000000000000000000000000000000000), 193 | .INIT_66(256'h0000000000000000000000000000000000000000000000000000000000000000), 194 | .INIT_67(256'h0000000000000000000000000000000000000000000000000000000000000000), 195 | .INIT_68(256'h0000000000000000000000000000000000000000000000000000000000000000), 196 | .INIT_69(256'h0000000000000000000000000000000000000000000000000000000000000000), 197 | .INIT_6A(256'h0000000000000000000000000000000000000000000000000000000000000000), 198 | .INIT_6B(256'h0000000000000000000000000000000000000000000000000000000000000000), 199 | .INIT_6C(256'h0000000000000000000000000000000000000000000000000000000000000000), 200 | .INIT_6D(256'h0000000000000000000000000000000000000000000000000000000000000000), 201 | .INIT_6E(256'h0000000000000000000000000000000000000000000000000000000000000000), 202 | .INIT_6F(256'h0000000000000000000000000000000000000000000000000000000000000000), 203 | .INIT_70(256'h0000000000000000000000000000000000000000000000000000000000000000), 204 | .INIT_71(256'h0000000000000000000000000000000000000000000000000000000000000000), 205 | .INIT_72(256'h0000000000000000000000000000000000000000000000000000000000000000), 206 | .INIT_73(256'h0000000000000000000000000000000000000000000000000000000000000000), 207 | .INIT_74(256'h0000000000000000000000000000000000000000000000000000000000000000), 208 | .INIT_75(256'h0000000000000000000000000000000000000000000000000000000000000000), 209 | .INIT_76(256'h0000000000000000000000000000000000000000000000000000000000000000), 210 | .INIT_77(256'h0000000000000000000000000000000000000000000000000000000000000000), 211 | .INIT_78(256'h0000000000000000000000000000000000000000000000000000000000000000), 212 | .INIT_79(256'h0000000000000000000000000000000000000000000000000000000000000000), 213 | .INIT_7A(256'h0000000000000000000000000000000000000000000000000000000000000000), 214 | .INIT_7B(256'h0000000000000000000000000000000000000000000000000000000000000000), 215 | .INIT_7C(256'h0000000000000000000000000000000000000000000000000000000000000000), 216 | .INIT_7D(256'h0000000000000000000000000000000000000000000000000000000000000000), 217 | .INIT_7E(256'h0000000000000000000000000000000000000000000000000000000000000000), 218 | .INIT_7F(256'h0000000000000000000000000000000000000000000000000000000000000000), 219 | 220 | // The next set of INITP_xx are for the parity bits 221 | .INITP_00(256'h0000000000000000000000000000000000000000000000000000000000000000), 222 | .INITP_01(256'h0000000000000000000000000000000000000000000000000000000000000000), 223 | .INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000), 224 | .INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000), 225 | .INITP_04(256'h0000000000000000000000000000000000000000000000000000000000000000), 226 | .INITP_05(256'h0000000000000000000000000000000000000000000000000000000000000000), 227 | .INITP_06(256'h0000000000000000000000000000000000000000000000000000000000000000), 228 | .INITP_07(256'h0000000000000000000000000000000000000000000000000000000000000000), 229 | 230 | // The next set of INITP_xx are valid when configured as 36Kb 231 | .INITP_08(256'h0000000000000000000000000000000000000000000000000000000000000000), 232 | .INITP_09(256'h0000000000000000000000000000000000000000000000000000000000000000), 233 | .INITP_0A(256'h0000000000000000000000000000000000000000000000000000000000000000), 234 | .INITP_0B(256'h0000000000000000000000000000000000000000000000000000000000000000), 235 | .INITP_0C(256'h0000000000000000000000000000000000000000000000000000000000000000), 236 | .INITP_0D(256'h0000000000000000000000000000000000000000000000000000000000000000), 237 | .INITP_0E(256'h0000000000000000000000000000000000000000000000000000000000000000), 238 | .INITP_0F(256'h0000000000000000000000000000000000000000000000000000000000000000) 239 | ) BRAM_TDP_MACRO_inst ( 240 | .DOA(DOA), // Output port-A data, width defined by READ_WIDTH_A parameter 241 | .DOB(DOB), // Output port-B data, width defined by READ_WIDTH_B parameter 242 | .ADDRA(ADDRA), // Input port-A address, width defined by Port A depth 243 | .ADDRB(ADDRB), // Input port-B address, width defined by Port B depth 244 | .CLKA(CLKA), // 1-bit input port-A clock 245 | .CLKB(CLKB), // 1-bit input port-B clock 246 | .DIA(DIA), // Input port-A data, width defined by WRITE_WIDTH_A parameter 247 | .DIB(DIB), // Input port-B data, width defined by WRITE_WIDTH_B parameter 248 | .ENA('b1), // 1-bit input port-A enable 249 | .ENB('b1), // 1-bit input port-B enable 250 | .REGCEA('b1), // 1-bit input port-A output register enable 251 | .REGCEB('b1), // 1-bit input port-B output register enable 252 | .RSTA(RSTA), // 1-bit input port-A reset 253 | .RSTB(RSTB), // 1-bit input port-B reset 254 | .WEA(WEA), // Input port-A write enable, width defined by Port A depth 255 | .WEB(WEB) // Input port-B write enable, width defined by Port B depth 256 | ); 257 | 258 | // End of BRAM_TDP_MACRO_inst instantiation 259 | 260 | endmodule -------------------------------------------------------------------------------- /verilog/lib/ram_simple.v: -------------------------------------------------------------------------------- 1 | module RAM_Simple #( 2 | parameter DEPTH = 16384 3 | )( 4 | input clk, 5 | 6 | input [13:0] addr, 7 | input op, 8 | input [3:0] mask, 9 | input [31:0] wdata, 10 | output [31:0] rdata 11 | ); 12 | // See page 133 of the Vivado Synthesis Guide for the template 13 | // https://www.xilinx.com/support/documentation/sw_manuals/xilinx2016_4/ug901-vivado-synthesis.pdf 14 | 15 | reg [31:0] mem [DEPTH-1:0]; 16 | 17 | assign rdata = mem[addr]; 18 | 19 | always @(posedge clk) begin 20 | if (op == 'b1) begin 21 | mem[addr] <= ( 22 | (mask == 'b1111) ? wdata : 23 | (mask == 'b0011) ? {mem[addr][31:16], wdata[15:0]} : 24 | (mask == 'b1100) ? {wdata[31:16], mem[addr][15:0]} : 25 | (mask == 'b0001) ? {mem[addr][31:8], wdata[7:0]} : 26 | (mask == 'b0010) ? {mem[addr][31:16], wdata[15:8], mem[addr][7:0]} : 27 | (mask == 'b0100) ? {mem[addr][31:24], wdata[23:16], mem[addr][15:0]} : 28 | (mask == 'b1000) ? {wdata[31:24], mem[addr][23:0]} : 29 | mem[addr] 30 | ); 31 | end 32 | end 33 | endmodule -------------------------------------------------------------------------------- /verilog/lib/register.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | // Register of D-Type Flip-flops 4 | module Register (q, d, clk); 5 | parameter N = 1; 6 | input clk; 7 | output reg [N-1:0] q; 8 | input [N-1:0] d; 9 | initial q = {N{1'b0}}; 10 | always @(posedge clk) 11 | q <= d; 12 | endmodule // REGISTER 13 | 14 | // Register with clock enable 15 | module Register_CE (q, d, ce, clk); 16 | parameter N = 1; 17 | input clk; 18 | output reg [N-1:0] q; 19 | input [N-1:0] d; 20 | input ce; 21 | initial q = {N{1'b0}}; 22 | always @(posedge clk) 23 | if (ce) q <= d; 24 | endmodule // REGISTER_CE 25 | 26 | // Register with reset value 27 | module Register_R (q, d, rst, clk); 28 | parameter N = 1; 29 | parameter INIT = {N{1'b0}}; 30 | input clk; 31 | input rst; 32 | output reg [N-1:0] q; 33 | input [N-1:0] d; 34 | initial q = INIT; 35 | always @(posedge clk) 36 | if (rst) q <= INIT; 37 | else q <= d; 38 | endmodule // REGISTER_R 39 | 40 | // Register with reset and clock enable 41 | // Reset works independently of clock enable 42 | module Register_R_CE (q, d, rst, ce, clk); 43 | parameter N = 1; 44 | parameter INIT = {N{1'b0}}; 45 | input clk; 46 | input rst; 47 | output reg [N-1:0] q; 48 | input [N-1:0] d; 49 | input ce; 50 | initial q = INIT; 51 | always @(posedge clk) 52 | if (rst) q <= INIT; 53 | else if (ce) q <= d; 54 | endmodule // REGISTER_R_CE -------------------------------------------------------------------------------- /verilog/lib/rom.v: -------------------------------------------------------------------------------- 1 | module ROM #( 2 | parameter DEPTH = 16384 3 | )( 4 | input clk, 5 | input [11:0] addr, 6 | output [31:0] dout 7 | ); 8 | 9 | reg [31:0] mem [DEPTH-1:0]; 10 | 11 | assign dout = mem[addr]; 12 | 13 | initial begin 14 | $readmemh("firmware.mem", mem); 15 | end 16 | 17 | endmodule -------------------------------------------------------------------------------- /verilog/rtl/alu.v: -------------------------------------------------------------------------------- 1 | `include "consts.vh" 2 | 3 | /** 4 | * @brief ALU module 5 | * 6 | * @param io_sel 11-bit ALU operation selection 7 | * @param io_in_a 32-bit input A 8 | * @param io_in_b 32-bit input B 9 | * @param io_out 32-bit output 10 | * 11 | */ 12 | module ALU ( 13 | input [`ALU_SEL_WIDTH-1:0] io_sel, 14 | input [31:0] io_in_a, 15 | input [31:0] io_in_b, 16 | output [31:0] io_out 17 | ); 18 | 19 | wire [31:0] out_add, out_and, out_or, out_sll, out_slt, 20 | out_sltu, out_sra, out_srl, out_sub, out_xor; 21 | 22 | wire signed [31:0] a_signed, b_signed; 23 | 24 | assign a_signed = io_in_a; 25 | assign b_signed = io_in_b; 26 | 27 | assign out_add = io_in_a + io_in_b; 28 | assign out_sub = io_in_a - io_in_b; 29 | assign out_sll = io_in_a << io_in_b[4:0]; 30 | assign out_slt = (a_signed < b_signed) ? 'h01 : 'h00; 31 | assign out_sltu = (io_in_a < io_in_b) ? 'h01 : 'h00; 32 | assign out_xor = io_in_a ^ io_in_b; 33 | assign out_srl = io_in_a >> io_in_b[4:0]; 34 | assign out_sra = a_signed >>> io_in_b[4:0]; 35 | assign out_or = io_in_a | io_in_b; 36 | assign out_and = io_in_a & io_in_b; 37 | 38 | assign io_out = ( 39 | (io_sel == `ALU_SEL_ADD) ? out_add : 40 | (io_sel == `ALU_SEL_SUB) ? out_sub : 41 | (io_sel == `ALU_SEL_SLL) ? out_sll : 42 | (io_sel == `ALU_SEL_SRL) ? out_srl : 43 | (io_sel == `ALU_SEL_SRA) ? out_sra : 44 | (io_sel == `ALU_SEL_AND) ? out_and : 45 | (io_sel == `ALU_SEL_OR) ? out_or : 46 | (io_sel == `ALU_SEL_XOR) ? out_xor : 47 | (io_sel == `ALU_SEL_SLT) ? out_slt : 48 | (io_sel == `ALU_SEL_SLTU) ? out_sltu : 49 | (io_sel == `ALU_SEL_COPYB) ? io_in_b : 50 | 'h0); 51 | 52 | endmodule 53 | 54 | -------------------------------------------------------------------------------- /verilog/rtl/consts.vh: -------------------------------------------------------------------------------- 1 | 2 | `ifndef __CONSTS_H 3 | `define __CONSTS_H 4 | 5 | 6 | // PC Select Signal 7 | `define PC_SEL_WIDTH 3 8 | `define PC_SEL_PC4 3'h0 9 | `define PC_SEL_BR 3'h1 10 | `define PC_SEL_JAL 3'h2 11 | `define PC_SEL_JALR 3'h3 12 | `define PC_SEL_EXC 3'h4 13 | 14 | // Immediate Generation Type 15 | `define IMM_SEL_WIDTH 3 16 | `define IMM_SEL_R 3'h0 17 | `define IMM_SEL_I 3'h1 18 | `define IMM_SEL_S 3'h2 19 | `define IMM_SEL_B 3'h3 20 | `define IMM_SEL_U 3'h4 21 | `define IMM_SEL_J 3'h5 22 | `define IMM_SEL_Z 3'h6 23 | 24 | // ALU OP1 Operand Select Signal 25 | `define OP1_SEL_WIDTH 1 26 | `define OP1_SEL_RS1 'h0 27 | `define OP1_SEL_PC 'h1 28 | 29 | // ALU OP2 Operand Select Signal 30 | `define OP2_SEL_WIDTH 1 31 | `define OP2_SEL_RS2 'h0 32 | `define OP2_SEL_IMM 'h1 33 | 34 | // Register File Write Enable Signal 35 | `define WEN_SEL_WIDTH 1 36 | `define WEN_SEL_DISABLE 'h0 37 | `define WEN_SEL_ENABLE 'h1 38 | 39 | // ALU Operation Signal 40 | `define ALU_SEL_WIDTH 4 41 | `define ALU_SEL_ADD 4'h0 42 | `define ALU_SEL_SUB 4'h1 43 | `define ALU_SEL_SLL 4'h2 44 | `define ALU_SEL_SRL 4'h3 45 | `define ALU_SEL_SRA 4'h4 46 | `define ALU_SEL_AND 4'h5 47 | `define ALU_SEL_OR 4'h6 48 | `define ALU_SEL_XOR 4'h7 49 | `define ALU_SEL_SLT 4'h8 50 | `define ALU_SEL_SLTU 4'h9 51 | `define ALU_SEL_COPYB 4'hA 52 | 53 | // Memory Request Type (Read,Write,Fence) Signal 54 | `define MEM_OP_WIDTH 1 55 | `define MEM_OP_READ 'h0 56 | `define MEM_OP_WRITE 'h1 57 | 58 | // Writeback Select Signal 59 | `define WB_SEL_WIDTH 2 60 | `define WB_SEL_ALU 2'h0 61 | `define WB_SEL_MEM 2'h1 62 | `define WB_SEL_PC4 2'h2 63 | `define WB_SEL_CSR 2'h3 64 | 65 | 66 | `endif -------------------------------------------------------------------------------- /verilog/rtl/core.v: -------------------------------------------------------------------------------- 1 | `include "consts.vh" 2 | 3 | module Core ( 4 | input clk, 5 | input rst, 6 | 7 | input io_interrupt, 8 | input [3:0] io_hart_id, 9 | input [31:0] io_reset_vector, 10 | 11 | output [31:0] io_imem_addr, 12 | input [31:0] io_imem_rdata, 13 | output [31:0] io_dmem_addr, 14 | output [`MEM_OP_WIDTH-1:0] io_dmem_op, 15 | output [3:0] io_dmem_mask, 16 | output [31:0] io_dmem_wdata, 17 | input [31:0] io_dmem_rdata 18 | ); 19 | 20 | wire [1:0] dmem_addr_offset; 21 | 22 | wire ctl_stall; 23 | wire [`PC_SEL_WIDTH-1:0] ctl_pc_sel; 24 | wire [`IMM_SEL_WIDTH-1:0] ctl_imm_sel; 25 | wire ctl_op1_sel; 26 | wire ctl_op2_sel; 27 | wire [`ALU_SEL_WIDTH-1:0] ctl_alu_sel; 28 | wire ctl_mem_signed; 29 | wire [`WB_SEL_WIDTH-1:0] ctl_wb_sel; 30 | wire ctl_rf_wen; 31 | 32 | wire [31:0] dat_inst; 33 | wire dat_br_eq; 34 | wire dat_br_lt; 35 | wire dat_br_ltu; 36 | 37 | assign dmem_addr_offset = io_dmem_addr[1:0]; 38 | 39 | 40 | ControlPath ctrlpath ( 41 | .clk(clk), 42 | .rst(rst), 43 | 44 | .io_dmem_addr_offset(dmem_addr_offset), 45 | .io_dmem_op(io_dmem_op), 46 | .io_dmem_mask(io_dmem_mask), 47 | 48 | .io_ctl_stall(ctl_stall), 49 | .io_ctl_pc_sel(ctl_pc_sel), 50 | .io_ctl_imm_sel(ctl_imm_sel), 51 | .io_ctl_op1_sel(ctl_op1_sel), 52 | .io_ctl_op2_sel(ctl_op2_sel), 53 | .io_ctl_alu_sel(ctl_alu_sel), 54 | .io_ctl_mem_signed(ctl_mem_signed), 55 | .io_ctl_wb_sel(ctl_wb_sel), 56 | .io_ctl_rf_wen(ctl_rf_wen), 57 | 58 | .io_dat_inst(dat_inst), 59 | .io_dat_br_eq(dat_br_eq), 60 | .io_dat_br_lt(dat_br_lt), 61 | .io_dat_br_ltu(dat_br_ltu) 62 | ); 63 | 64 | DataPath datapath ( 65 | .clk(clk), 66 | .rst(rst), 67 | 68 | .io_interrupt(io_interrupt), 69 | .io_hart_id(io_hart_id), 70 | .io_reset_vector(io_reset_vector), 71 | 72 | .io_imem_addr(io_imem_addr), 73 | .io_imem_rdata(io_imem_rdata), 74 | .io_dmem_addr(io_dmem_addr), 75 | .io_dmem_mask(io_dmem_mask), 76 | .io_dmem_wdata(io_dmem_wdata), 77 | .io_dmem_rdata(io_dmem_rdata), 78 | 79 | .io_ctl_stall(ctl_stall), 80 | .io_ctl_pc_sel(ctl_pc_sel), 81 | .io_ctl_imm_sel(ctl_imm_sel), 82 | .io_ctl_op1_sel(ctl_op1_sel), 83 | .io_ctl_op2_sel(ctl_op2_sel), 84 | .io_ctl_alu_sel(ctl_alu_sel), 85 | .io_ctl_mem_signed(ctl_mem_signed), 86 | .io_ctl_wb_sel(ctl_wb_sel), 87 | .io_ctl_rf_wen(ctl_rf_wen), 88 | 89 | .io_dat_inst(dat_inst), 90 | .io_dat_br_eq(dat_br_eq), 91 | .io_dat_br_lt(dat_br_lt), 92 | .io_dat_br_ltu(dat_br_ltu) 93 | ); 94 | 95 | endmodule 96 | 97 | -------------------------------------------------------------------------------- /verilog/rtl/ctrlpath.v: -------------------------------------------------------------------------------- 1 | `include "consts.vh" 2 | 3 | module ControlPath ( 4 | input clk, 5 | input rst, 6 | 7 | 8 | input [1:0] io_dmem_addr_offset, 9 | output [`MEM_OP_WIDTH-1:0] io_dmem_op, 10 | output [3:0] io_dmem_mask, 11 | 12 | // from data path 13 | input [31:0] io_dat_inst, 14 | // input imiss, 15 | input io_dat_br_eq, 16 | input io_dat_br_lt, 17 | input io_dat_br_ltu, 18 | // input csr_eret = Output(Bool()) 19 | // input csr_interrupt = Output(Bool()) 20 | // input inst_misaligned = Output(Bool()) 21 | 22 | // to data path 23 | output io_ctl_stall, 24 | // output dmiss, 25 | output [`PC_SEL_WIDTH-1:0] io_ctl_pc_sel, 26 | output [`IMM_SEL_WIDTH-1:0] io_ctl_imm_sel, 27 | output io_ctl_op1_sel, // 0: rs1, 1: immediate 28 | output io_ctl_op2_sel, // 0: rs2, 1: immediate 29 | output [`ALU_SEL_WIDTH-1:0] io_ctl_alu_sel, 30 | output io_ctl_mem_signed, 31 | output [`WB_SEL_WIDTH-1:0] io_ctl_wb_sel, 32 | output io_ctl_rf_wen 33 | // output io_ctl_csr_cmd = Output(UInt(CSR.SZ.W)) 34 | // output io_ctl_exception = Output(Bool()) 35 | // output io_ctl_exception_cause = Output(UInt(32.W)) 36 | // output io_ctl_pc_sel_no_xept = Output(UInt(PC_4.getWidth.W)) // Use only for instuction misalignment detection 37 | 38 | 39 | ); 40 | 41 | // extract instruction fields 42 | wire [7:0] opcode; 43 | wire [2:0] funct3; 44 | wire [6:0] funct7; 45 | wire [11:0] funct12; 46 | 47 | assign opcode = io_dat_inst[6:0]; 48 | assign funct3 = io_dat_inst[14:12]; 49 | assign funct7 = io_dat_inst[31:25]; 50 | assign imm_i = io_dat_inst[31:20]; 51 | 52 | // instruction matching 53 | wire opcode_is_load; 54 | wire opcode_is_fence; 55 | wire opcode_is_alu_i; 56 | wire opcode_is_auipc; 57 | wire opcode_is_alu_iw; 58 | wire opcode_is_store; 59 | wire opcode_is_alu_r; 60 | wire opcode_is_lui; 61 | wire opcode_is_alu_rw; 62 | wire opcode_is_branch; 63 | wire opcode_is_jalr; 64 | wire opcode_is_jal; 65 | wire opcode_is_sys; 66 | 67 | wire opcode_is_type_r; 68 | wire opcode_is_type_i; 69 | wire opcode_is_type_s; 70 | wire opcode_is_type_b; 71 | wire opcode_is_type_u; 72 | wire opcode_is_type_j; 73 | wire opcode_is_type_z; 74 | 75 | wire inst_is_lb; 76 | wire inst_is_lh; 77 | wire inst_is_lw; 78 | // wire inst_is_ld; 79 | wire inst_is_lbu; 80 | wire inst_is_lhu; 81 | // wire inst_is_lwu; 82 | wire inst_is_fence; 83 | wire inst_is_fence_i; 84 | wire inst_is_addi; 85 | wire inst_is_slli; 86 | wire inst_is_slti; 87 | wire inst_is_sltiu; 88 | wire inst_is_xori; 89 | wire inst_is_srli; 90 | wire inst_is_srai; 91 | wire inst_is_ori; 92 | wire inst_is_andi; 93 | wire inst_is_auipc; 94 | // wire inst_is_addiw; 95 | // wire inst_is_slliw; 96 | // wire inst_is_srliw; 97 | // wire inst_is_sraiw; 98 | wire inst_is_sb; 99 | wire inst_is_sh; 100 | wire inst_is_sw; 101 | // wire inst_is_sd; 102 | wire inst_is_add; 103 | wire inst_is_sub; 104 | wire inst_is_sll; 105 | wire inst_is_slt; 106 | wire inst_is_sltu; 107 | wire inst_is_xor; 108 | wire inst_is_srl; 109 | wire inst_is_sra; 110 | wire inst_is_or; 111 | wire inst_is_and; 112 | wire inst_is_lui; 113 | // wire inst_is_addw; 114 | // wire inst_is_subw; 115 | // wire inst_is_sllw; 116 | // wire inst_is_srlw; 117 | // wire inst_is_sraw; 118 | wire inst_is_beq; 119 | wire inst_is_bne; 120 | wire inst_is_blt; 121 | wire inst_is_bge; 122 | wire inst_is_bltu; 123 | wire inst_is_bgeu; 124 | wire inst_is_jalr; 125 | wire inst_is_jal; 126 | wire inst_is_ecall; 127 | wire inst_is_ebreak; 128 | wire inst_is_csrrw; 129 | wire inst_is_csrrs; 130 | wire inst_is_csrrc; 131 | wire inst_is_csrrwi; 132 | wire inst_is_csrrsi; 133 | wire inst_is_csrrci; 134 | 135 | assign opcode_is_load = opcode === 'b0000011; 136 | assign opcode_is_fence = opcode === 'b0001111; 137 | assign opcode_is_alu_i = opcode === 'b0010011; 138 | assign opcode_is_auipc = opcode === 'b0010111; 139 | assign opcode_is_alu_iw = opcode === 'b0011011; 140 | assign opcode_is_store = opcode === 'b0100011; 141 | assign opcode_is_alu_r = opcode === 'b0110011; 142 | assign opcode_is_lui = opcode === 'b0110111; 143 | assign opcode_is_alu_rw = opcode === 'b0110011; 144 | assign opcode_is_branch = opcode === 'b1100011; 145 | assign opcode_is_jalr = opcode === 'b1100111; 146 | assign opcode_is_jal = opcode === 'b1101111; 147 | assign opcode_is_sys = opcode === 'b1110011; // csr and ecall, ebreak 148 | 149 | assign opcode_is_type_r = opcode_is_alu_rw | opcode_is_alu_r; 150 | assign opcode_is_type_i = opcode_is_sys | opcode_is_jalr | opcode_is_alu_iw | opcode_is_alu_i | opcode_is_fence | opcode_is_load; 151 | assign opcode_is_type_s = opcode_is_store; 152 | assign opcode_is_type_b = opcode_is_branch; 153 | assign opcode_is_type_u = opcode_is_lui | opcode_is_auipc; 154 | assign opcode_is_type_j = opcode_is_jal; 155 | assign opcode_is_type_z = inst_is_csrrwi | inst_is_csrrsi | inst_is_csrrci; 156 | 157 | assign inst_is_lb = opcode_is_load & (funct3 === 'b000); 158 | assign inst_is_lh = opcode_is_load & (funct3 === 'b001); 159 | assign inst_is_lw = opcode_is_load & (funct3 === 'b010); 160 | // assign inst_is_ld = opcode_is_load & (funct3 === 'b011); 161 | assign inst_is_lbu = opcode_is_load & (funct3 === 'b100); 162 | assign inst_is_lhu = opcode_is_load & (funct3 === 'b101); 163 | // assign inst_is_lwu = opcode_is_load & (funct3 === 'b110); 164 | assign inst_is_fence = opcode_is_fence; 165 | assign inst_is_fence_i= opcode_is_fence & (funct3 === 'b001); 166 | assign inst_is_addi = opcode_is_alu_i & (funct3 === 'b000); 167 | assign inst_is_slli = opcode_is_alu_i & (funct3 === 'b001) & (funct7 === 'b0000000); 168 | assign inst_is_slti = opcode_is_alu_i & (funct3 === 'b010); 169 | assign inst_is_sltiu = opcode_is_alu_i & (funct3 === 'b011); 170 | assign inst_is_xori = opcode_is_alu_i & (funct3 === 'b100); 171 | assign inst_is_srli = opcode_is_alu_i & (funct3 === 'b101) & (funct7 === 'b0000000); 172 | assign inst_is_srai = opcode_is_alu_i & (funct3 === 'b101) & (funct7 === 'b0100000); 173 | assign inst_is_ori = opcode_is_alu_i & (funct3 === 'b110); 174 | assign inst_is_andi = opcode_is_alu_i & (funct3 === 'b111); 175 | assign inst_is_auipc = opcode_is_auipc; 176 | // assign inst_is_addiw = opcode_is_alu_iw & (funct3 === 'b000); 177 | // assign inst_is_slliw = opcode_is_alu_iw & (funct3 === 'b001) & (funct7 === 'b0000000); 178 | // assign inst_is_srliw = opcode_is_alu_iw & (funct3 === 'b101) & (funct7 === 'b0000000); 179 | // assign inst_is_sraiw = opcode_is_alu_iw & (funct3 === 'b101) & (funct7 === 'b0100000); 180 | assign inst_is_sb = opcode_is_store & (funct3 === 'b000); 181 | assign inst_is_sh = opcode_is_store & (funct3 === 'b001); 182 | assign inst_is_sw = opcode_is_store & (funct3 === 'b010); 183 | // assign inst_is_sd = opcode_is_store & (funct3 === 'b011); 184 | assign inst_is_add = opcode_is_alu_r & (funct3 === 'b000) & (funct7 === 'b0000000); 185 | assign inst_is_sub = opcode_is_alu_r & (funct3 === 'b000) & (funct7 === 'b0100000); 186 | assign inst_is_sll = opcode_is_alu_r & (funct3 === 'b001) & (funct7 === 'b0000000); 187 | assign inst_is_slt = opcode_is_alu_r & (funct3 === 'b010) & (funct7 === 'b0000000); 188 | assign inst_is_sltu = opcode_is_alu_r & (funct3 === 'b011) & (funct7 === 'b0000000); 189 | assign inst_is_xor = opcode_is_alu_r & (funct3 === 'b100) & (funct7 === 'b0000000); 190 | assign inst_is_srl = opcode_is_alu_r & (funct3 === 'b101) & (funct7 === 'b0000000); 191 | assign inst_is_sra = opcode_is_alu_r & (funct3 === 'b101) & (funct7 === 'b0100000); 192 | assign inst_is_or = opcode_is_alu_r & (funct3 === 'b110) & (funct7 === 'b0000000); 193 | assign inst_is_and = opcode_is_alu_r & (funct3 === 'b111) & (funct7 === 'b0000000); 194 | assign inst_is_lui = opcode_is_lui; 195 | // assign inst_is_addw = opcode_is_alu_rw & (funct3 === 'b000) & (funct7 === 'b0000000); 196 | // assign inst_is_subw = opcode_is_alu_rw & (funct3 === 'b000) & (funct7 === 'b0100000); 197 | // assign inst_is_sllw = opcode_is_alu_rw & (funct3 === 'b001) & (funct7 === 'b0000000); 198 | // assign inst_is_srlw = opcode_is_alu_rw & (funct3 === 'b101) & (funct7 === 'b0000000); 199 | // assign inst_is_sraw = opcode_is_alu_rw & (funct3 === 'b101) & (funct7 === 'b0100000); 200 | assign inst_is_beq = opcode_is_branch & (funct3 === 'b000); 201 | assign inst_is_bne = opcode_is_branch & (funct3 === 'b001); 202 | assign inst_is_blt = opcode_is_branch & (funct3 === 'b100); 203 | assign inst_is_bge = opcode_is_branch & (funct3 === 'b101); 204 | assign inst_is_bltu = opcode_is_branch & (funct3 === 'b110); 205 | assign inst_is_bgeu = opcode_is_branch & (funct3 === 'b111); 206 | assign inst_is_jalr = opcode_is_jalr; 207 | assign inst_is_jal = opcode_is_jal; 208 | assign inst_is_ecall = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b000000000000); 209 | assign inst_is_ebreak = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b000000000001); 210 | assign inst_is_uret = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b000000000010); 211 | // assign inst_is_sret = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b000100000010); 212 | // assign inst_is_hret = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b001000000010); 213 | assign inst_is_mret = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b001100000010); 214 | assign inst_is_sfence_vm = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b000100000100); 215 | assign inst_is_wfi = opcode_is_sys & (funct3 === 'b000) & (funct12 === 'b000100000101); 216 | assign inst_is_csrrw = opcode_is_sys & (funct3 === 'b001) & (funct7 === 'b0000000); 217 | assign inst_is_csrrs = opcode_is_sys & (funct3 === 'b010) & (funct7 === 'b0000000); 218 | assign inst_is_csrrc = opcode_is_sys & (funct3 === 'b011) & (funct7 === 'b0000000); 219 | assign inst_is_csrrwi = opcode_is_sys & (funct3 === 'b101) & (funct7 === 'b0000000); 220 | assign inst_is_csrrsi = opcode_is_sys & (funct3 === 'b110) & (funct7 === 'b0000000); 221 | assign inst_is_csrrci = opcode_is_sys & (funct3 === 'b111) & (funct7 === 'b0000000); 222 | 223 | 224 | wire is_branch_hit; 225 | assign is_branch_hit = ((inst_is_beq && io_dat_br_eq) 226 | || (inst_is_bne && !io_dat_br_eq) 227 | || (inst_is_blt && io_dat_br_lt) 228 | || (inst_is_bge && !io_dat_br_lt) 229 | || (inst_is_bltu && io_dat_br_ltu) 230 | || (inst_is_bgeu && !io_dat_br_ltu) 231 | ); 232 | 233 | // control signals 234 | // assign io_ctl_stall = io_dat_imiss || io_ctl_dmiss; 235 | assign io_ctl_stall = 'b0; 236 | 237 | assign io_ctl_pc_sel = ( 238 | // (io_ctl_exception || io_dat_csr_eret) ? `PC_SEL_EXC : 239 | // io_dat_csr_interrupt ? `PC_SEL_EXC : 240 | opcode_is_jal ? `PC_SEL_JAL : 241 | opcode_is_jalr ? `PC_SEL_JALR : 242 | (opcode_is_branch && is_branch_hit) ? `PC_SEL_BR : 243 | `PC_SEL_PC4 244 | ); 245 | 246 | assign io_ctl_imm_sel = ( 247 | opcode_is_type_r ? `IMM_SEL_R : 248 | opcode_is_type_i ? `IMM_SEL_I : 249 | opcode_is_type_s ? `IMM_SEL_S : 250 | opcode_is_type_b ? `IMM_SEL_B : 251 | opcode_is_type_u ? `IMM_SEL_U : 252 | opcode_is_type_j ? `IMM_SEL_J : 253 | opcode_is_type_z ? `IMM_SEL_Z : 254 | `IMM_SEL_R 255 | ); 256 | 257 | assign io_ctl_op1_sel = (opcode_is_auipc || opcode_is_type_j || opcode_is_type_b) ? `OP1_SEL_PC : `OP1_SEL_RS1; 258 | 259 | assign io_ctl_op2_sel = opcode_is_type_r ? `OP2_SEL_RS2 : `OP2_SEL_IMM; 260 | 261 | assign io_ctl_alu_sel = ( 262 | inst_is_add ? `ALU_SEL_ADD : 263 | inst_is_sub ? `ALU_SEL_SUB : 264 | (inst_is_sll || inst_is_slli) ? `ALU_SEL_SLL : 265 | (inst_is_srl || inst_is_srli) ? `ALU_SEL_SRL : 266 | (inst_is_sra || inst_is_srai) ? `ALU_SEL_SRA : 267 | (inst_is_and || inst_is_andi) ? `ALU_SEL_AND : 268 | (inst_is_or || inst_is_ori) ? `ALU_SEL_OR : 269 | (inst_is_xor || inst_is_xori) ? `ALU_SEL_XOR : 270 | (inst_is_slt || inst_is_slti) ? `ALU_SEL_SLT : 271 | (inst_is_sltu || inst_is_sltiu) ? `ALU_SEL_SLTU : 272 | (inst_is_lui || opcode_is_sys) ? `ALU_SEL_COPYB : 273 | `ALU_SEL_ADD 274 | ); 275 | 276 | assign io_dmem_op = ( 277 | opcode_is_load ? `MEM_OP_READ : 278 | opcode_is_store ? `MEM_OP_WRITE : 279 | `MEM_OP_READ 280 | ); 281 | 282 | assign io_dmem_mask = ( 283 | (inst_is_sw || inst_is_lw) ? 4'b1111 : 284 | ((inst_is_sh || inst_is_lh || inst_is_lhu) && (io_dmem_addr_offset == 'b00)) ? 4'b0011 : 285 | // ((inst_is_sh || inst_is_lh || inst_is_lhu) && (io_dmem_addr_offset == 'b01)) ? 4'b0110 : 286 | ((inst_is_sh || inst_is_lh || inst_is_lhu) && (io_dmem_addr_offset == 'b10)) ? 4'b1100 : 287 | // ((inst_is_sh || inst_is_lh || inst_is_lhu) && (io_dmem_addr_offset == 'b11)) ? 4'b1001 : 288 | ((inst_is_sb || inst_is_lb || inst_is_lbu) && (io_dmem_addr_offset == 'b00)) ? 4'b0001 : 289 | ((inst_is_sb || inst_is_lb || inst_is_lbu) && (io_dmem_addr_offset == 'b01)) ? 4'b0010 : 290 | ((inst_is_sb || inst_is_lb || inst_is_lbu) && (io_dmem_addr_offset == 'b10)) ? 4'b0100 : 291 | ((inst_is_sb || inst_is_lb || inst_is_lbu) && (io_dmem_addr_offset == 'b11)) ? 4'b1000 : 292 | 4'b0000 293 | ); 294 | 295 | assign io_ctl_mem_signed = inst_is_lw || inst_is_lh || inst_is_lb; 296 | 297 | assign io_ctl_wb_sel = ( 298 | opcode_is_load ? `WB_SEL_MEM : 299 | (opcode_is_jal || opcode_is_jalr) ? `WB_SEL_PC4 : 300 | opcode_is_sys ? `WB_SEL_CSR : 301 | `WB_SEL_ALU 302 | ); 303 | 304 | assign io_ctl_rf_wen = ( 305 | opcode_is_load ? `WEN_SEL_ENABLE : 306 | (inst_is_auipc || inst_is_lui) ? `WEN_SEL_ENABLE : 307 | (opcode_is_alu_i || opcode_is_alu_r) ? `WEN_SEL_ENABLE : 308 | // (opcode_is_alu_iw || opcode_is_alu_rw) ? `WEN_SEL_ENABLE : 309 | (opcode_is_jal || opcode_is_jalr) ? `WEN_SEL_ENABLE : 310 | (inst_is_csrrc || inst_is_csrrs || inst_is_csrrw || inst_is_csrrci || inst_is_csrrsi || inst_is_csrrwi) ? `WEN_SEL_ENABLE : 311 | `WEN_SEL_DISABLE 312 | ); 313 | 314 | endmodule -------------------------------------------------------------------------------- /verilog/rtl/datapath.v: -------------------------------------------------------------------------------- 1 | `include "consts.vh" 2 | 3 | module DataPath ( 4 | input clk, 5 | input rst, 6 | 7 | input io_interrupt, 8 | input [3:0] io_hart_id, 9 | input [31:0] io_reset_vector, 10 | 11 | output [31:0] io_imem_addr, 12 | input [31:0] io_imem_rdata, 13 | output [31:0] io_dmem_addr, 14 | input [3:0] io_dmem_mask, 15 | output [31:0] io_dmem_wdata, 16 | input [31:0] io_dmem_rdata, 17 | 18 | // from control path 19 | input io_ctl_stall, 20 | // input dmiss, 21 | input [`PC_SEL_WIDTH-1:0] io_ctl_pc_sel, 22 | input [`IMM_SEL_WIDTH-1:0] io_ctl_imm_sel, 23 | input io_ctl_op1_sel, // 0: rs1, 1: immediate 24 | input io_ctl_op2_sel, // 0: rs2, 1: immediate 25 | input [`ALU_SEL_WIDTH-1:0] io_ctl_alu_sel, 26 | input io_ctl_mem_signed, 27 | input [`WB_SEL_WIDTH-1:0] io_ctl_wb_sel, 28 | input io_ctl_rf_wen, 29 | // input io_ctl_csr_cmd = Output(UInt(CSR.SZ.W)) 30 | // input io_ctl_exception = Output(Bool()) 31 | // input io_ctl_exception_cause = Output(UInt(32.W)) 32 | // input io_ctl_pc_sel_no_xept = Output(UInt(PC_4.getWidth.W)) // Use only for instuction misalignment detection 33 | 34 | // to control path 35 | output [31:0] io_dat_inst, 36 | // output imiss, 37 | output io_dat_br_eq, 38 | output io_dat_br_lt, 39 | output io_dat_br_ltu 40 | // output csr_eret = Output(Bool()) 41 | // output csr_interrupt = Output(Bool()) 42 | // output inst_misaligned = Output(Bool()) 43 | ); 44 | 45 | 46 | wire [31:0] pc; 47 | wire [31:0] pc_next; 48 | 49 | wire [31:0] pc_4; 50 | wire [31:0] br_target; 51 | wire [31:0] jump_target; 52 | wire [31:0] jump_reg_target; 53 | wire [31:0] exception_target; 54 | 55 | 56 | // PC Register 57 | Register_R_CE #( 58 | .N(32), 59 | .INIT(32'h00000000) 60 | ) pc_reg ( 61 | .clk(clk), 62 | .rst(rst), 63 | .ce(~io_ctl_stall), 64 | .d(pc_next), 65 | .q(pc) 66 | ); 67 | 68 | assign pc_4 = pc + 32'h00000004; 69 | 70 | // TODO: make sure we are word aligned? 71 | assign pc_next = ( 72 | (io_ctl_pc_sel == `PC_SEL_PC4) ? pc_4 : 73 | (io_ctl_pc_sel == `PC_SEL_BR) ? br_target : 74 | (io_ctl_pc_sel == `PC_SEL_JAL) ? jump_target : 75 | (io_ctl_pc_sel == `PC_SEL_JALR) ? jump_reg_target : 76 | (io_ctl_pc_sel == `PC_SEL_EXC) ? exception_target : 77 | pc_4 78 | ); 79 | 80 | // Instruction memory fetching 81 | assign io_imem_addr = pc; 82 | 83 | wire [31:0] inst; 84 | assign inst = io_imem_rdata; 85 | 86 | // Decode 87 | 88 | // extract addr fields 89 | wire [4:0] rd_addr; 90 | wire [4:0] rs1_addr; 91 | wire [4:0] rs2_addr; 92 | 93 | assign rd_addr = inst[11:7]; 94 | assign rs1_addr = inst[19:15]; 95 | assign rs2_addr = inst[24:20]; 96 | 97 | 98 | // Register File 99 | wire [31:0] rs1_data; 100 | wire [31:0] rs2_data; 101 | wire signed [31:0] rs1_data_signed; 102 | wire signed [31:0] rs2_data_signed; 103 | wire [31:0] wb_data; 104 | wire rd_wen; 105 | 106 | assign rs1_data_signed = rs1_data; 107 | assign rs2_data_signed = rs2_data; 108 | 109 | assign rd_wen = io_ctl_rf_wen; 110 | 111 | RegFile regfile ( 112 | .clk(clk), 113 | .io_rd_addr(rd_addr), 114 | .io_rd_wen(rd_wen), 115 | .io_rd_data(wb_data), 116 | .io_rs1_addr(rs1_addr), 117 | .io_rs1_data(rs1_data), 118 | .io_rs2_addr(rs2_addr), 119 | .io_rs2_data(rs2_data) 120 | ); 121 | 122 | wire [31:0] imm_i; 123 | wire [31:0] imm_s; 124 | wire [31:0] imm_b; 125 | wire [31:0] imm_u; 126 | wire [31:0] imm_j; 127 | wire [31:0] imm_z; 128 | wire [31:0] imm; 129 | 130 | // immediate number generation 131 | assign imm_i = {{20{inst[31]}}, inst[31:20]}; 132 | assign imm_s = {{20{inst[31]}}, inst[31:25], inst[11:7]}; 133 | assign imm_b = {{19{inst[31]}}, inst[31], inst[7], inst[30:25], inst[11:8], 1'b0}; 134 | assign imm_u = {inst[31:12], {12{1'b0}}}; 135 | assign imm_j = {{19{inst[31]}}, inst[31], inst[19:12], inst[20], inst[30:21], 1'b0}; 136 | assign imm_z = {{27{1'b0}}, inst[19:15]}; 137 | 138 | assign imm = ( 139 | (io_ctl_imm_sel == `IMM_SEL_R) ? imm_i : 140 | (io_ctl_imm_sel == `IMM_SEL_I) ? imm_i : 141 | (io_ctl_imm_sel == `IMM_SEL_S) ? imm_s : 142 | (io_ctl_imm_sel == `IMM_SEL_B) ? imm_b : 143 | (io_ctl_imm_sel == `IMM_SEL_U) ? imm_u : 144 | (io_ctl_imm_sel == `IMM_SEL_J) ? imm_j : 145 | (io_ctl_imm_sel == `IMM_SEL_Z) ? imm_z : 146 | 'h0 147 | ); 148 | 149 | wire [31:0] alu_in_a; 150 | wire [31:0] alu_in_b; 151 | wire [31:0] alu_out; 152 | 153 | assign alu_in_a = ( 154 | (io_ctl_op1_sel == `OP1_SEL_RS1) ? rs1_data : 155 | (io_ctl_op1_sel == `OP1_SEL_PC) ? pc : 156 | 'h0 157 | ); 158 | 159 | assign alu_in_b = ( 160 | (io_ctl_op2_sel == `OP2_SEL_RS2) ? rs2_data : 161 | (io_ctl_op2_sel == `OP2_SEL_IMM) ? imm : 162 | 'h0 163 | ); 164 | 165 | ALU alu ( 166 | .io_sel(io_ctl_alu_sel), 167 | .io_in_a(alu_in_a), 168 | .io_in_b(alu_in_b), 169 | .io_out(alu_out) 170 | ); 171 | 172 | 173 | // Branch/Jump Target Calculation 174 | assign br_target = pc + imm_b; 175 | assign jump_target = pc + imm_j; 176 | assign jump_reg_target = rs1_data + imm_i; 177 | 178 | 179 | wire [31:0] csr_rdata; 180 | 181 | 182 | // Memory load data formatting 183 | wire [31:0] load_data; 184 | 185 | assign load_data = ( 186 | (io_dmem_mask == 'b1111) ? io_dmem_rdata : 187 | (io_ctl_mem_signed && (io_dmem_mask == 'b0011)) ? {{16{io_dmem_rdata[15]}}, io_dmem_rdata[15:0]} : 188 | (io_ctl_mem_signed && (io_dmem_mask == 'b1100)) ? {{16{io_dmem_rdata[31]}}, io_dmem_rdata[31:16]} : 189 | (io_ctl_mem_signed && (io_dmem_mask == 'b0001)) ? {{24{io_dmem_rdata[7]}}, io_dmem_rdata[7:0]} : 190 | (io_ctl_mem_signed && (io_dmem_mask == 'b0010)) ? {{24{io_dmem_rdata[15]}}, io_dmem_rdata[15:8]} : 191 | (io_ctl_mem_signed && (io_dmem_mask == 'b0100)) ? {{24{io_dmem_rdata[23]}}, io_dmem_rdata[23:16]} : 192 | (io_ctl_mem_signed && (io_dmem_mask == 'b1000)) ? {{24{io_dmem_rdata[31]}}, io_dmem_rdata[31:24]} : 193 | (!io_ctl_mem_signed && (io_dmem_mask == 'b0011)) ? {{16'h0}, io_dmem_rdata[15:0]} : 194 | (!io_ctl_mem_signed && (io_dmem_mask == 'b1100)) ? {{16'h0}, io_dmem_rdata[31:16]} : 195 | (!io_ctl_mem_signed && (io_dmem_mask == 'b0001)) ? {{24'h0}, io_dmem_rdata[7:0]} : 196 | (!io_ctl_mem_signed && (io_dmem_mask == 'b0010)) ? {{24'h0}, io_dmem_rdata[15:8]} : 197 | (!io_ctl_mem_signed && (io_dmem_mask == 'b0100)) ? {{24'h0}, io_dmem_rdata[23:16]} : 198 | (!io_ctl_mem_signed && (io_dmem_mask == 'b1000)) ? {{24'h0}, io_dmem_rdata[31:24]} : 199 | 'h0 200 | ); 201 | 202 | assign io_dmem_wdata = rs2_data << (8 * io_dmem_addr[1:0]); 203 | 204 | // WB Mux 205 | assign wb_data = ( 206 | (io_ctl_wb_sel == `WB_SEL_ALU) ? alu_out : 207 | (io_ctl_wb_sel == `WB_SEL_MEM) ? load_data : 208 | (io_ctl_wb_sel == `WB_SEL_PC4) ? pc_4 : 209 | (io_ctl_wb_sel == `WB_SEL_CSR) ? csr_rdata : 210 | alu_out 211 | ); 212 | 213 | // datapath to controlpath outputs 214 | assign io_dat_inst = inst; 215 | assign io_dat_br_eq = rs1_data == rs2_data; 216 | assign io_dat_br_lt = rs1_data_signed < rs2_data_signed; 217 | assign io_dat_br_ltu = rs1_data < rs2_data; 218 | 219 | 220 | // datapath to data memory outputs 221 | assign io_dmem_addr = alu_out; 222 | assign io_dmem_data = rs2_data; 223 | 224 | 225 | 226 | 227 | endmodule 228 | 229 | -------------------------------------------------------------------------------- /verilog/rtl/gpio.v: -------------------------------------------------------------------------------- 1 | `include "consts.vh" 2 | 3 | module GPIO ( 4 | input clk, 5 | input rst, 6 | 7 | input [31:0] io_addr, 8 | input io_op, 9 | input [3:0] io_mask, 10 | input [31:0] io_wdata, 11 | output [31:0] io_rdata, 12 | 13 | output [1:0] io_gpio 14 | ); 15 | 16 | reg [1:0] out_val; 17 | 18 | assign io_gpio = out_val; 19 | 20 | assign rdata = {30'h0, out_val}; 21 | 22 | always @(posedge clk) begin 23 | if (rst) begin 24 | out_val <= 2'h0; 25 | end 26 | else begin 27 | if (io_op) begin 28 | out_val <= io_wdata[1:0]; 29 | end 30 | end 31 | end 32 | 33 | endmodule 34 | 35 | -------------------------------------------------------------------------------- /verilog/rtl/regfile.v: -------------------------------------------------------------------------------- 1 | 2 | module RegFile ( 3 | input clk, 4 | input [4:0] io_rd_addr, 5 | input io_rd_wen, 6 | input [31:0] io_rd_data, 7 | 8 | input [4:0] io_rs1_addr, 9 | output [31:0] io_rs1_data, 10 | input [4:0] io_rs2_addr, 11 | output [31:0] io_rs2_data 12 | ); 13 | 14 | (* ram_style = "distributed" *) reg [31:0] mem[31-1:0]; 15 | 16 | always @(posedge clk) begin 17 | if (io_rd_wen && (io_rd_addr !== 'h0)) begin 18 | mem[io_rd_addr-1] <= io_rd_data; 19 | end 20 | end 21 | 22 | assign io_rs1_data = io_rs1_addr !== 'h0 ? mem[io_rs1_addr-1] : 'h0; 23 | assign io_rs2_data = io_rs2_addr !== 'h0 ? mem[io_rs2_addr-1] : 'h0; 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /verilog/rtl/tile.v: -------------------------------------------------------------------------------- 1 | 2 | module Tile ( 3 | input clk, 4 | input rst, 5 | 6 | output [3:0] led 7 | ); 8 | 9 | wire clk; 10 | wire rst; 11 | 12 | wire io_interrupt; 13 | 14 | wire [3:0] io_hart_id; 15 | wire [31:0] io_reset_vector; 16 | 17 | parameter DMEM_BASE = 32'h08000000; 18 | parameter GPIO_BASE = 32'h10010000; 19 | 20 | wire [31:0] imem_addr; 21 | wire [31:0] imem_rdata; 22 | 23 | wire [31:0] dmem_addr; 24 | wire dmem_op; 25 | wire [3:0] dmem_mask; 26 | wire [31:0] dmem_wdata; 27 | wire [31:0] dmem_rdata; 28 | 29 | wire dmem_mem_op; 30 | wire dmem_gpio_op; 31 | 32 | wire [31:0] dmem_mem_addr; 33 | wire [31:0] dmem_mem_rdata; 34 | wire [31:0] dmem_gpio_addr; 35 | wire [31:0] dmem_gpio_rdata; 36 | 37 | wire gpio_selected = (dmem_addr >= GPIO_BASE) && (dmem_addr < GPIO_BASE + 'h1000); 38 | wire dmem_selected = (dmem_addr >= DMEM_BASE) && (dmem_addr < DMEM_BASE + 'h1000); 39 | 40 | assign dmem_rdata = gpio_selected ? dmem_gpio_rdata : dmem_mem_rdata; 41 | assign dmem_mem_op = dmem_selected ? dmem_op : 1'b0; 42 | assign dmem_gpio_op = gpio_selected ? dmem_op : 1'b0; 43 | 44 | assign dmem_mem_addr = dmem_addr - DMEM_BASE; 45 | assign dmem_gpio_addr = dmem_addr - GPIO_BASE; 46 | 47 | 48 | Core core ( 49 | .clk(clk), 50 | .rst(rst), 51 | 52 | .io_interrupt(io_interrupt), 53 | .io_hart_id(io_hart_id), 54 | .io_reset_vector(io_reset_vector), 55 | 56 | .io_imem_addr(imem_addr), 57 | .io_imem_rdata(imem_rdata), 58 | .io_dmem_addr(dmem_addr), 59 | .io_dmem_op(dmem_op), 60 | .io_dmem_mask(dmem_mask), 61 | .io_dmem_wdata(dmem_wdata), 62 | .io_dmem_rdata(dmem_rdata) 63 | ); 64 | 65 | ROM imem ( 66 | .clk(clk), 67 | .addr(imem_addr[15:2]), 68 | .dout(imem_rdata) 69 | ); 70 | 71 | RAM_Simple dmem ( 72 | .clk(clk), 73 | .addr(dmem_mem_addr[15:2]), 74 | .op(dmem_mem_op), 75 | .mask(dmem_mask), 76 | .wdata(dmem_wdata), 77 | .rdata(dmem_mem_rdata) 78 | ); 79 | 80 | GPIO gpio ( 81 | .clk(clk), 82 | .rst(rst), 83 | 84 | .io_addr(dmem_gpio_addr), 85 | .io_op(dmem_gpio_op), 86 | .io_mask(dmem_mask), 87 | .io_wdata(dmem_wdata), 88 | .io_rdata(dmem_gpio_rdata), 89 | 90 | .io_gpio(led[1:0]) 91 | ); 92 | 93 | assign led[2] = 1'b1; 94 | assign led[3] = 1'b0; 95 | 96 | 97 | endmodule 98 | 99 | -------------------------------------------------------------------------------- /verilog/rtl/top.v: -------------------------------------------------------------------------------- 1 | 2 | module Top ( 3 | input CLK100MHZ, 4 | input ck_rst, 5 | 6 | output [3:0] led 7 | ); 8 | 9 | wire clk; 10 | wire rst; 11 | 12 | assign rst = ~ck_rst; 13 | 14 | clk_wiz_0 clk_wiz_0 ( 15 | .clk_out1(clk), 16 | .reset(rst), 17 | .clk_in1(CLK100MHZ) 18 | ); 19 | 20 | Tile tile ( 21 | .clk(clk), 22 | .rst(rst), 23 | 24 | // .io_interrupt(io_interrupt), 25 | // .io_hart_id(io_hart_id), 26 | // .io_reset_vector(io_reset_vector), 27 | 28 | .led(led) 29 | ); 30 | 31 | 32 | endmodule 33 | 34 | -------------------------------------------------------------------------------- /verilog/sim/tb_alu.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | `include "consts.vh" 4 | 5 | // test bench for ALU module 6 | module TB_ALU(); 7 | parameter CLOCK_FREQ = 100_000_000; 8 | parameter CLOCK_PERIOD = 1_000_000_000 / CLOCK_FREQ; 9 | 10 | // setup clock and reset 11 | reg clk, rst; 12 | initial clk = 'b0; 13 | always #(CLOCK_PERIOD/2) clk = ~clk; 14 | 15 | reg test_passed = 1; 16 | 17 | localparam A_VALUE = -100; 18 | localparam B_VALUE = 200; 19 | localparam SHAMT = 20; 20 | 21 | 22 | // test signals 23 | reg signed [31:0] in_a, in_b; 24 | reg signed [`ALU_SEL_WIDTH-1:0] sel; 25 | wire signed [31:0] out; 26 | 27 | 28 | ALU dut ( 29 | .io_sel(sel), 30 | .io_in_a(in_a), 31 | .io_in_b(in_b), 32 | .io_out(out) 33 | ); 34 | 35 | initial begin 36 | #0; 37 | rst = 0; 38 | $display("[TEST]\tRESET pulled LOW."); 39 | repeat(2) @(posedge clk); 40 | 41 | @(negedge clk); 42 | rst = 1; 43 | $display("[TEST]\tRESET pulled HIGH."); 44 | repeat(2) @(posedge clk); 45 | 46 | rst = 0; 47 | 48 | in_a = A_VALUE; 49 | in_b = B_VALUE; 50 | 51 | // addition 52 | sel = `ALU_SEL_ADD; 53 | repeat(1) @(posedge clk); 54 | assert (out == in_a + in_b) else begin $display("[TEST]\tAddition Test Failed: %d + %d = %d", in_a, in_b, out); test_passed = 0; end 55 | 56 | // subtraction 57 | sel = `ALU_SEL_SUB; 58 | repeat(1) @(posedge clk); 59 | assert (out == in_a - in_b) else begin $display("[TEST]\tSubtraction Test Failed: %d - %d = %d", in_a, in_b, out); test_passed = 0; end 60 | 61 | // set less than 62 | sel = `ALU_SEL_SLT; 63 | repeat(1) @(posedge clk); 64 | assert (out == (in_a < in_b) ? 1 : 0) else begin $display("[TEST]\tSet Less Than Test Failed: %d < %d = %d", in_a, in_b, out); test_passed = 0; end 65 | 66 | // set less than unsigned 67 | sel = `ALU_SEL_SLTU; 68 | repeat(1) @(posedge clk); 69 | assert (out == (unsigned'(in_a) < unsigned'(in_b)) ? 1 : 0) else begin $display("[TEST]\tSet Less Than Unsigned Test Failed: %d < %d = %d", in_a, in_b, out); test_passed = 0; end 70 | 71 | // xor 72 | sel = `ALU_SEL_XOR; 73 | repeat(1) @(posedge clk); 74 | assert (out == (in_a ^ in_b)) else begin $display("[TEST]\tXOR Test Failed: %d ^ %d = %d", in_a, in_b, out); test_passed = 0; end 75 | 76 | // or 77 | sel = `ALU_SEL_OR; 78 | repeat(1) @(posedge clk); 79 | assert (out == (in_a | in_b)) else begin $display("[TEST]\tOR Test Failed: %d | %d = %d", in_a, in_b, out); test_passed = 0; end 80 | 81 | // and 82 | sel = `ALU_SEL_AND; 83 | repeat(1) @(posedge clk); 84 | assert (out == (in_a & in_b)) else begin $display("[TEST]\tAND Test Failed: %d & %d = %d", in_a, in_b, out); test_passed = 0; end 85 | 86 | // B 87 | sel = `ALU_SEL_COPYB; 88 | repeat(1) @(posedge clk); 89 | assert (out == in_b) else begin $display("[TEST]\tB Test Failed: %d = %d", in_b, out); test_passed = 0; end 90 | 91 | in_a = A_VALUE; 92 | in_b = SHAMT; 93 | 94 | // shift left logical 95 | sel = `ALU_SEL_SLL; 96 | repeat(1) @(posedge clk); 97 | assert (out == in_a << in_b) else begin $display("[TEST]\tShift Left Logical Test Failed: %d << %d = %d", in_a, in_b, out); test_passed = 0; end 98 | 99 | // shift right logical 100 | sel = `ALU_SEL_SRL; 101 | repeat(1) @(posedge clk); 102 | assert (out == in_a >> in_b) else begin $display("[TEST]\tShift Right Logical Test Failed: %d >> %d = %d", in_a, in_b, out); test_passed = 0; end 103 | 104 | // shift right arithmetic 105 | sel = `ALU_SEL_SRA; 106 | repeat(1) @(posedge clk); 107 | assert (out == in_a >>> in_b) else begin $display("[TEST]\tShift Right Arithmetic Test Failed: %d >>> %d = %d", in_a, in_b, out); test_passed = 0; end 108 | 109 | 110 | if (test_passed) begin 111 | $display("[TEST]\tAll tests passed."); 112 | end else begin 113 | $display("[TEST]\tSome tests failed."); 114 | end 115 | 116 | 117 | $finish(); 118 | end 119 | 120 | endmodule 121 | -------------------------------------------------------------------------------- /verilog/sim/tb_core.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | `include "consts.vh" 4 | 5 | `define REGFILE_PATH dut.datapath.regfile.mem 6 | `define DMEM_PATH dmem.mem 7 | 8 | 9 | // test bench for Core module 10 | module TB_Core(); 11 | parameter CLOCK_FREQ = 100_000_000; 12 | parameter CLOCK_PERIOD = 1_000_000_000 / CLOCK_FREQ; 13 | 14 | // setup clock and reset 15 | reg clk, rst; 16 | initial clk = 'b0; 17 | always #(CLOCK_PERIOD/2) clk = ~clk; 18 | 19 | reg [31:0] debug; 20 | 21 | 22 | wire [31:0] imem_addr; 23 | wire [31:0] imem_rdata; 24 | wire [31:0] dmem_addr; 25 | wire dmem_op; 26 | wire [3:0] dmem_mask; 27 | wire [31:0] dmem_wdata; 28 | wire [31:0] dmem_rdata; 29 | 30 | reg [31:0] imem [16384-1:0]; 31 | 32 | assign imem_rdata = imem[imem_addr[17:2]]; 33 | 34 | Core dut ( 35 | .clk(clk), 36 | .rst(rst), 37 | 38 | .io_interrupt(1'b0), 39 | .io_hart_id(4'h0), 40 | .io_reset_vector(32'h0), 41 | 42 | .io_imem_addr(imem_addr), 43 | .io_imem_rdata(imem_rdata), 44 | .io_dmem_addr(dmem_addr), 45 | .io_dmem_op(dmem_op), 46 | .io_dmem_mask(dmem_mask), 47 | .io_dmem_wdata(dmem_wdata), 48 | .io_dmem_rdata(dmem_rdata) 49 | ); 50 | 51 | RAM_Simple dmem ( 52 | .clk(clk), 53 | .addr(dmem_addr[15:2]), 54 | .op(dmem_op), 55 | .mask(dmem_mask), 56 | .wdata(dmem_wdata), 57 | .rdata(dmem_rdata) 58 | ); 59 | 60 | 61 | task resetDUT; 62 | @(negedge clk); 63 | rst = 1; 64 | @(negedge clk); 65 | rst = 0; 66 | $display("[TEST]\tRESET CPU."); 67 | endtask 68 | 69 | 70 | task initRegfile; 71 | integer i; 72 | begin 73 | for (i = 1; i < 32; i = i + 1) begin 74 | `REGFILE_PATH[i-1] = 100 * i + 1; 75 | end 76 | end 77 | endtask 78 | 79 | task clearMemory; 80 | begin 81 | integer i; 82 | for (i = 1; i < 32; i = i + 1) begin 83 | `REGFILE_PATH[i-1] = 0; 84 | end 85 | for (i = 0; i < 16384; i = i + 1) begin 86 | imem[i] = 0; 87 | end 88 | for (i = 0; i < 16384; i = i + 1) begin 89 | `DMEM_PATH[i] = 0; 90 | end 91 | end 92 | endtask 93 | 94 | wire [31:0] timeout_cycle = 10; 95 | 96 | reg [31:0] cycle; 97 | reg done; 98 | reg [31:0] current_test_id = 0; 99 | reg [255:0] current_test_type; 100 | reg [31:0] current_output; 101 | reg [31:0] current_result; 102 | reg all_tests_passed = 0; 103 | 104 | 105 | integer i; 106 | reg [4:0] RD, RS1, RS2; 107 | reg [31:0] RD1, RD2; 108 | reg [4:0] SHAMT; 109 | reg [31:0] IMM, IMM0, IMM1, IMM2, IMM3; 110 | reg [14:0] INST_ADDR; 111 | reg [14:0] DATA_ADDR; 112 | reg [14:0] DATA_ADDR0, DATA_ADDR1, DATA_ADDR2, DATA_ADDR3; 113 | reg [14:0] DATA_ADDR4, DATA_ADDR5, DATA_ADDR6, DATA_ADDR7; 114 | reg [14:0] DATA_ADDR8, DATA_ADDR9; 115 | 116 | reg [31:0] JUMP_ADDR; 117 | 118 | reg [31:0] BR_TAKEN_OP1 [5:0]; 119 | reg [31:0] BR_TAKEN_OP2 [5:0]; 120 | reg [31:0] BR_NTAKEN_OP1 [5:0]; 121 | reg [31:0] BR_NTAKEN_OP2 [5:0]; 122 | reg [31:0] BR_INST [5:0]; 123 | reg [255:0] BR_NAME_TK1 [5:0]; 124 | reg [255:0] BR_NAME_TK2 [5:0]; 125 | reg [255:0] BR_NAME_NTK [5:0]; 126 | 127 | // Check for timeout 128 | // If a test does not return correct value in a given timeout cycle, 129 | // we terminate the testbench 130 | initial begin 131 | while (all_tests_passed === 0) begin 132 | @(posedge clk); 133 | if (cycle === timeout_cycle) begin 134 | $display("[Failed] Timeout at [%d] test %s, expected_result = %h, got = %h", 135 | current_test_id, current_test_type, current_result, current_output); 136 | $finish(); 137 | end 138 | end 139 | end 140 | 141 | always @(posedge clk) begin 142 | if (done === 0) 143 | cycle <= cycle + 1; 144 | else 145 | cycle <= 0; 146 | end 147 | 148 | task checkResultRF; 149 | input [31:0] rf_wa; 150 | input [31:0] result; 151 | input [255:0] test_type; 152 | begin 153 | done = 0; 154 | current_test_id = current_test_id + 1; 155 | current_test_type = test_type; 156 | current_result = result; 157 | while (`REGFILE_PATH[rf_wa-1] !== result) begin 158 | current_output = `REGFILE_PATH[rf_wa-1]; 159 | @(posedge clk); 160 | end 161 | cycle = 0; 162 | done = 1; 163 | $display("[%d] Test %s passed!", current_test_id, test_type); 164 | end 165 | endtask 166 | 167 | task checkResultDMEM; 168 | input [31:0] addr; 169 | input [31:0] result; 170 | input [255:0] test_type; 171 | begin 172 | done = 0; 173 | current_test_id = current_test_id + 1; 174 | current_test_type = test_type; 175 | current_result = result; 176 | while (`DMEM_PATH[addr] !== result) begin 177 | current_output = `DMEM_PATH[addr]; 178 | @(posedge clk); 179 | end 180 | cycle = 0; 181 | done = 1; 182 | $display("[%d] Test %s passed!", current_test_id, test_type); 183 | end 184 | endtask 185 | 186 | 187 | 188 | 189 | initial begin 190 | 191 | $dumpfile("tb_core.vcd"); 192 | $dumpvars(0, TB_Core); 193 | 194 | #0; 195 | 196 | // Test R-Type Insts -------------------------------------------------- 197 | // - ADD, SUB, SLL, SLT, SLTU, XOR, OR, AND, SRL, SRA 198 | // - SLLI, SRLI, SRAI 199 | clearMemory(); 200 | 201 | `REGFILE_PATH[1-1] = -100; 202 | `REGFILE_PATH[2-1] = 200; 203 | 204 | imem[0] = 32'h002081B3; // add x3, x1, x2 205 | imem[1] = 32'h40208233; // sub x4, x1, x2 206 | imem[2] = 32'h002092B3; // sll x5, x1, x2 207 | imem[3] = 32'h0020A333; // slt x6, x1, x2 208 | imem[4] = 32'h0020B3B3; // sltu x7, x1, x2 209 | imem[5] = 32'h0020C433; // xor x8, x1, x2 210 | imem[6] = 32'h0020E4B3; // or x9, x1, x2 211 | imem[7] = 32'h0020F533; // and x10, x1, x2 212 | imem[8] = 32'h0020D5B3; // srl x11, x1, x2 213 | imem[9] = 32'h4020D633; // sra x12, x1, x2 214 | imem[10] = 32'h01409693; // slli x13, x1, 20 215 | imem[11] = 32'h0140D713; // srli x14, x1, 20 216 | imem[12] = 32'h4140D793; // srai x15, x1, 20 217 | 218 | resetDUT(); 219 | 220 | checkResultRF(5'd3, 32'h00000064, "R-Type ADD"); 221 | checkResultRF(5'd4, 32'hfffffed4, "R-Type SUB"); 222 | checkResultRF(5'd5, 32'hffff9c00, "R-Type SLL"); 223 | checkResultRF(5'd6, 32'h1, "R-Type SLT"); 224 | checkResultRF(5'd7, 32'h0, "R-Type SLTU"); 225 | checkResultRF(5'd8, 32'hffffff54, "R-Type XOR"); 226 | checkResultRF(5'd9, 32'hffffffdc, "R-Type OR"); 227 | checkResultRF(5'd10, 32'h00000088, "R-Type AND"); 228 | checkResultRF(5'd11, 32'h00ffffff, "R-Type SRL"); 229 | checkResultRF(5'd12, 32'hffffffff, "R-Type SRA"); 230 | checkResultRF(5'd13, 32'hf9c00000, "R-Type SLLI"); 231 | checkResultRF(5'd14, 32'h00000fff, "R-Type SRLI"); 232 | checkResultRF(5'd15, 32'hffffffff, "R-Type SRAI"); 233 | 234 | 235 | 236 | // Test I-Type Insts -------------------------------------------------- 237 | // - ADDI, SLTI, SLTUI, XORI, ORI, ANDI 238 | // - LW, LH, LB, LHU, LBU 239 | // - JALR 240 | 241 | // Test I-type arithmetic instructions 242 | clearMemory(); 243 | 244 | `REGFILE_PATH[1-1] = -100; 245 | 246 | imem[0] = 32'hF3808193; // addi x3, x1, -200 247 | imem[1] = 32'hF380A213; // slti x4, x1, -200 248 | imem[2] = 32'hF380B293; // sltiu x5, x1, -200 249 | imem[3] = 32'hF380C313; // xori x6, x1, -200 250 | imem[4] = 32'hF380E393; // ori x7, x1, -200 251 | imem[5] = 32'hF380F413; // andi x8, x1, -200 252 | 253 | resetDUT(); 254 | 255 | checkResultRF(5'd3, 32'hfffffed4, "I-Type ADD"); 256 | checkResultRF(5'd4, 32'h00000000, "I-Type SLT"); 257 | checkResultRF(5'd5, 32'h00000000, "I-Type SLTU"); 258 | checkResultRF(5'd6, 32'h000000a4, "I-Type XOR"); 259 | checkResultRF(5'd7, 32'hffffffbc, "I-Type OR"); 260 | checkResultRF(5'd8, 32'hffffff18, "I-Type AND"); 261 | 262 | // Test I-type load instructions 263 | clearMemory(); 264 | 265 | `REGFILE_PATH[1-1] = 'h1000; 266 | 267 | imem[0] = 32'h0000A103; // lw x2, 0(x1) 268 | imem[1] = 32'h00009183; // lh x3, 0(x1) 269 | // imem[2] = 32'h00109203; // lh x4, 1(x1) 270 | imem[3] = 32'h00209283; // lh x5, 2(x1) 271 | // imem[4] = 32'h00309303; // lh x6, 3(x1) 272 | imem[5] = 32'h00008383; // lb x7, 0(x1) 273 | imem[6] = 32'h00108403; // lb x8, 1(x1) 274 | imem[7] = 32'h00208483; // lb x9, 2(x1) 275 | imem[8] = 32'h00308503; // lb x10, 3(x1) 276 | imem[9] = 32'h0000D583; // lhu x11, 0(x1) 277 | // imem[10] = 32'h0010D603; // lhu x12, 1(x1) 278 | imem[11] = 32'h0020D683; // lhu x13, 2(x1) 279 | // imem[12] = 32'h0030D703; // lhu x14, 3(x1) 280 | imem[13] = 32'h0000C783; // lbu x15, 0(x1) 281 | imem[14] = 32'h0010C803; // lbu x16, 1(x1) 282 | imem[15] = 32'h0020C883; // lbu x17, 2(x1) 283 | imem[16] = 32'h0030C903; // lbu x18, 3(x1) 284 | 285 | 286 | `DMEM_PATH[`REGFILE_PATH[1-1]>>2] = 32'hdeadbeef; 287 | 288 | resetDUT(); 289 | 290 | checkResultRF(5'd2, 32'hdeadbeef, "I-Type LW"); 291 | checkResultRF(5'd3, 32'hffffbeef, "I-Type LH 0"); 292 | // checkResultRF(5'd4, 32'hffffbeef, "I-Type LH 1"); 293 | checkResultRF(5'd5, 32'hffffdead, "I-Type LH 2"); 294 | // checkResultRF(5'd6, 32'hffffdead, "I-Type LH 3"); 295 | checkResultRF(5'd7, 32'hffffffef, "I-Type LB 0"); 296 | checkResultRF(5'd8, 32'hffffffbe, "I-Type LB 1"); 297 | checkResultRF(5'd9, 32'hffffffad, "I-Type LB 2"); 298 | checkResultRF(5'd10, 32'hffffffde, "I-Type LB 3"); 299 | checkResultRF(5'd11, 32'h0000beef, "I-Type LHU 0"); 300 | // checkResultRF(5'd12, 32'h0000beef, "I-Type LHU 1"); 301 | checkResultRF(5'd13, 32'h0000dead, "I-Type LHU 2"); 302 | // checkResultRF(5'd14, 32'h0000dead, "I-Type LHU 3"); 303 | checkResultRF(5'd15, 32'h000000ef, "I-Type LBU 0"); 304 | checkResultRF(5'd16, 32'h000000be, "I-Type LBU 1"); 305 | checkResultRF(5'd17, 32'h000000ad, "I-Type LBU 2"); 306 | checkResultRF(5'd18, 32'h000000de, "I-Type LBU 3"); 307 | 308 | 309 | 310 | // Test S-Type Insts -------------------------------------------------- 311 | // - SW, SH, SB 312 | clearMemory(); 313 | 314 | `REGFILE_PATH[1-1] = 32'h12345678; 315 | 316 | `REGFILE_PATH[2-1] = 32'h0000_0010; 317 | 318 | `REGFILE_PATH[3-1] = 32'h0000_0020; 319 | `REGFILE_PATH[4-1] = 32'h0000_0030; 320 | `REGFILE_PATH[5-1] = 32'h0000_0040; 321 | `REGFILE_PATH[6-1] = 32'h0000_0050; 322 | 323 | `REGFILE_PATH[7-1] = 32'h0000_0060; 324 | `REGFILE_PATH[8-1] = 32'h0000_0070; 325 | `REGFILE_PATH[9-1] = 32'h0000_0080; 326 | `REGFILE_PATH[10-1] = 32'h0000_0090; 327 | 328 | imem[0] = 32'h10112023; // sw x1, 0x100(x2) 329 | imem[1] = 32'h10119023; // sh x1, 0x100(x3) 330 | // imem[2] = 32'h101210A3; // sh x1, 0x101(x4) 331 | imem[3] = 32'h10129123; // sh x1, 0x102(x5) 332 | // imem[4] = 32'h101311A3; // sh x1, 0x103(x6) 333 | imem[5] = 32'h10138023; // sb x1, 0x100(x7) 334 | imem[6] = 32'h101400A3; // sb x1, 0x101(x8) 335 | imem[7] = 32'h10148123; // sb x1, 0x102(x9) 336 | imem[8] = 32'h101501A3; // sb x1, 0x103(x10) 337 | 338 | resetDUT(); 339 | 340 | debug = (`REGFILE_PATH[2-1] + 'h100) >> 2; 341 | 342 | checkResultDMEM((`REGFILE_PATH[2-1] + 'h100) >> 2, 32'h12345678, "S-Type SW"); 343 | checkResultDMEM((`REGFILE_PATH[3-1] + 'h100) >> 2, 32'h00005678, "S-Type SH 1"); 344 | // checkResultDMEM((`REGFILE_PATH[4-1] + 'h101) >> 2, 32'h00005678, "S-Type SH 2"); 345 | checkResultDMEM((`REGFILE_PATH[5-1] + 'h102) >> 2, 32'h56780000, "S-Type SH 3"); 346 | // checkResultDMEM((`REGFILE_PATH[6-1] + 'h103) >> 2, 32'h56780000, "S-Type SH 4"); 347 | checkResultDMEM((`REGFILE_PATH[7-1] + 'h100) >> 2, 32'h00000078, "S-Type SB 1"); 348 | checkResultDMEM((`REGFILE_PATH[8-1] + 'h101) >> 2, 32'h00007800, "S-Type SB 2"); 349 | checkResultDMEM((`REGFILE_PATH[9-1] + 'h102) >> 2, 32'h00780000, "S-Type SB 3"); 350 | checkResultDMEM((`REGFILE_PATH[10-1] + 'h103) >> 2, 32'h78000000, "S-Type SB 4"); 351 | 352 | 353 | // Test U-Type Insts -------------------------------------------------- 354 | // - LUI, AUIPC 355 | clearMemory(); 356 | 357 | imem[0] = 32'h7FFF01B7; // lui x3, 0x7FFF0 358 | imem[1] = 32'h7FFF0217; // auipc x4, 0x7FFF0 359 | 360 | resetDUT(); 361 | 362 | checkResultRF(5'd3, 32'h7fff0000, "U-Type LUI"); 363 | checkResultRF(5'd4, 32'h7fff0004, "U-Type AUIPC"); // assume PC is 0000_0004 364 | 365 | 366 | // Test J-Type Insts -------------------------------------------------- 367 | // - JAL 368 | clearMemory(); 369 | 370 | `REGFILE_PATH[1-1] = 100; 371 | `REGFILE_PATH[2-1] = 200; 372 | `REGFILE_PATH[3-1] = 300; 373 | `REGFILE_PATH[4-1] = 400; 374 | 375 | imem[0] = 32'h7F1002EF; // jal x5, 0x0FF0 376 | imem[1] = 32'h00208333; // add x6, x1, x2 377 | imem['h0FF0 >> 2] = 32'h004183B3; // add x7, x3, x4 378 | 379 | resetDUT(); 380 | 381 | checkResultRF(5'd5, 32'h0000_0004, "J-Type JAL"); 382 | checkResultRF(5'd7, 700, "J-Type JAL"); 383 | checkResultRF(5'd6, 0, "J-Type JAL"); 384 | 385 | // Test I-Type JALR Insts --------------------------------------------- 386 | // - JALR 387 | clearMemory(); 388 | 389 | `REGFILE_PATH[1-1] = 32'h0000_0100; 390 | `REGFILE_PATH[2-1] = 200; 391 | `REGFILE_PATH[3-1] = 300; 392 | `REGFILE_PATH[4-1] = 400; 393 | 394 | imem[0] = 32'h7F8082E7; // jalr x5, x1, 0x7F8 395 | imem[1] = 32'h00208333; // add x6, x1, x2 396 | imem[(`REGFILE_PATH[1-1] + 'h7F8) >> 2] = 32'h004183B3; // add x7, x3, x4 397 | 398 | resetDUT(); 399 | 400 | checkResultRF(5'd5, 32'h0000_0004, "J-Type JALR"); 401 | checkResultRF(5'd7, 700, "J-Type JALR"); 402 | checkResultRF(5'd6, 0, "J-Type JALR"); 403 | 404 | 405 | 406 | // Test B-Type Insts -------------------------------------------------- 407 | // - BEQ, BNE, BLT, BGE, BLTU, BGEU 408 | BR_INST[0] = 'h7E2088E3; // beq 409 | BR_NAME_TK1[0] = "B-Type BEQ Taken 1"; 410 | BR_NAME_TK2[0] = "B-Type BEQ Taken 2"; 411 | BR_NAME_NTK[0] = "B-Type BEQ Not Taken"; 412 | BR_TAKEN_OP1[0] = 100; BR_TAKEN_OP2[0] = 100; 413 | BR_NTAKEN_OP1[0] = 100; BR_NTAKEN_OP2[0] = 200; 414 | 415 | BR_INST[1] = 'h7E2098E3; // bne 416 | BR_NAME_TK1[1] = "B-Type BNE Taken 1"; 417 | BR_NAME_TK2[1] = "B-Type BNE Taken 2"; 418 | BR_NAME_NTK[1] = "B-Type BNE Not Taken"; 419 | BR_TAKEN_OP1[1] = 100; BR_TAKEN_OP2[1] = 200; 420 | BR_NTAKEN_OP1[1] = 100; BR_NTAKEN_OP2[1] = 100; 421 | 422 | BR_INST[2] = 'h7E20C8E3; // blt 423 | BR_NAME_TK1[2] = "B-Type BLT Taken 1"; 424 | BR_NAME_TK2[2] = "B-Type BLT Taken 2"; 425 | BR_NAME_NTK[2] = "B-Type BLT Not Taken"; 426 | BR_TAKEN_OP1[2] = 100; BR_TAKEN_OP2[2] = 200; 427 | BR_NTAKEN_OP1[2] = 200; BR_NTAKEN_OP2[2] = 100; 428 | 429 | BR_INST[3] = 'h7E20D8E3; // bge 430 | BR_NAME_TK1[3] = "B-Type BGE Taken 1"; 431 | BR_NAME_TK2[3] = "B-Type BGE Taken 2"; 432 | BR_NAME_NTK[3] = "B-Type BGE Not Taken"; 433 | BR_TAKEN_OP1[3] = 300; BR_TAKEN_OP2[3] = 200; 434 | BR_NTAKEN_OP1[3] = 100; BR_NTAKEN_OP2[3] = 200; 435 | 436 | BR_INST[4] = 'h7E20E8E3; // bltu 437 | BR_NAME_TK1[4] = "B-Type BLTU Taken 1"; 438 | BR_NAME_TK2[4] = "B-Type BLTU Taken 2"; 439 | BR_NAME_NTK[4] = "B-Type BLTU Not Taken"; 440 | BR_TAKEN_OP1[4] = 32'h0000_0001; BR_TAKEN_OP2[4] = 32'hFFFF_0000; 441 | BR_NTAKEN_OP1[4] = 32'hFFFF_0000; BR_NTAKEN_OP2[4] = 32'h0000_0001; 442 | 443 | BR_INST[5] = 'h7E20F8E3; // bgeu 444 | BR_NAME_TK1[5] = "B-Type BGEU Taken 1"; 445 | BR_NAME_TK2[5] = "B-Type BGEU Taken 2"; 446 | BR_NAME_NTK[5] = "B-Type BGEU Not Taken"; 447 | BR_TAKEN_OP1[5] = 32'hFFFF_0000; BR_TAKEN_OP2[5] = 32'h0000_0001; 448 | BR_NTAKEN_OP1[5] = 32'h0000_0001; BR_NTAKEN_OP2[5] = 32'hFFFF_0000; 449 | 450 | for (i = 0; i < 6; i = i + 1) begin 451 | clearMemory(); 452 | 453 | `REGFILE_PATH[1-1] = BR_TAKEN_OP1[i]; 454 | `REGFILE_PATH[2-1] = BR_TAKEN_OP2[i]; 455 | `REGFILE_PATH[3-1] = 300; 456 | `REGFILE_PATH[4-1] = 400; 457 | 458 | // Test branch taken 459 | imem[0] = BR_INST[i]; // branch? x1, x2, 0x0FF0 460 | imem[1] = 'h004182B3; // add x5, x3, x4 461 | imem['h0FF0 >> 2] = 'h00418333; // add x6, x3, x4 462 | 463 | resetDUT(); 464 | 465 | checkResultRF(5'd5, 0, BR_NAME_TK1[i]); 466 | checkResultRF(5'd6, 700, BR_NAME_TK2[i]); 467 | 468 | clearMemory(); 469 | 470 | `REGFILE_PATH[1-1] = BR_NTAKEN_OP1[i]; 471 | `REGFILE_PATH[2-1] = BR_NTAKEN_OP2[i]; 472 | `REGFILE_PATH[3-1] = 300; 473 | `REGFILE_PATH[4-1] = 400; 474 | 475 | // Test branch not taken 476 | imem[0] = BR_INST[i]; // branch? x1, x2, 0x0FF0 477 | imem[1] = 'h004182B3; // add x5, x3, x4 478 | 479 | resetDUT(); 480 | checkResultRF(5'd5, 700, BR_NAME_NTK[i]); 481 | end 482 | 483 | 484 | 485 | $finish(); 486 | end 487 | 488 | endmodule 489 | -------------------------------------------------------------------------------- /verilog/sim/tb_tile.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | `include "consts.vh" 4 | 5 | // test bench for entire tile 6 | module TB_Tile(); 7 | parameter CLOCK_FREQ = 100_000_000; 8 | parameter CLOCK_PERIOD = 1_000_000_000 / CLOCK_FREQ; 9 | 10 | // setup clock and reset 11 | reg clk, rst; 12 | initial clk = 'b0; 13 | always #(CLOCK_PERIOD/2) clk = ~clk; 14 | 15 | Tile dut ( 16 | .clk(clk), 17 | .rst(rst), 18 | 19 | .led() 20 | ); 21 | 22 | initial begin 23 | #0; 24 | rst = 1; 25 | $display("[TEST]\tRESET pulled HIGH."); 26 | repeat(2) @(posedge clk); 27 | 28 | @(negedge clk); 29 | rst = 0; 30 | $display("[TEST]\tRESET pulled LOW."); 31 | @(posedge clk); 32 | 33 | 34 | repeat(10000) @(posedge clk); 35 | 36 | 37 | 38 | 39 | $finish(); 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /verilog/software/firmware.S: -------------------------------------------------------------------------------- 1 | 2 | # GPIO base address 3 | li s0, 0x10010000 4 | 5 | # delay amount 6 | li s1, 1000000 7 | 8 | # led status 9 | li s2, 0x1 10 | 11 | sw s2, 0(s0) 12 | 13 | loop: 14 | li t0, 0 15 | delay: 16 | addi t0, t0, 1 17 | blt t0, s1, delay 18 | 19 | # update LED state 20 | sw s2, 0(s0) 21 | 22 | # alternate the LED state 23 | li t0, 1 24 | sub s2, t0, s2 25 | 26 | j loop 27 | 28 | -------------------------------------------------------------------------------- /verilog/software/firmware.mem: -------------------------------------------------------------------------------- 1 | 0x10010437 2 | 0x00040413 3 | 0x000F44B7 4 | 0x24048493 5 | 0x00100913 6 | 0x01242023 7 | 0x00000293 8 | 0x00128293 9 | 0xFE92CEE3 10 | 0x01242023 11 | 0x00100293 12 | 0x41228933 13 | 0xFE9FF06F 14 | --------------------------------------------------------------------------------