Add Chisel source for picorF0, no changes to main design
diff --git a/README.md b/README.md
index 0d7a31d..1ea1296 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
# caravel-picoRF0
- CAN bus controller for autonomous vehicles, connected to caravel and with it's I/O and debug interfaces exposed on I/O pins (developed by Natalia Machado)
+ - See [nxmq/Can_Core](https://github.com/nxmq/Can_Core) for CAN controller Chisel source code
-- picoRF0 - a multicycle CPU core running a simplified RISC ISA (used for teaching, normally on FPGAs). Connected to caravel for memory interfacing and I/O usage
- - can be tied to the CAN bus controller through caravel
+- picoRF0 - a multicycle CPU core running a simplified RISC ISA (targeted for teaching purposes). Connected to caravel for memory interfacing and I/O usage
+ - See `picoRF0` directory for CPU Chisel source code
- Tiny VGA pong game controller to test I/O interface speed
diff --git a/picorF0/.gitignore b/picorF0/.gitignore
new file mode 100644
index 0000000..12033d3
--- /dev/null
+++ b/picorF0/.gitignore
@@ -0,0 +1,341 @@
+### Project Specific stuff
+test_run_dir/*
+### XilinxISE template
+# intermediate build files
+*.bgn
+*.bit
+*.bld
+*.cmd_log
+*.drc
+*.ll
+*.lso
+*.msd
+*.msk
+*.ncd
+*.ngc
+*.ngd
+*.ngr
+*.pad
+*.par
+*.pcf
+*.prj
+*.ptwx
+*.rbb
+*.rbd
+*.stx
+*.syr
+*.twr
+*.twx
+*.unroutes
+*.ut
+*.xpi
+*.xst
+*_bitgen.xwbt
+*_envsettings.html
+*_map.map
+*_map.mrp
+*_map.ngm
+*_map.xrpt
+*_ngdbuild.xrpt
+*_pad.csv
+*_pad.txt
+*_par.xrpt
+*_summary.html
+*_summary.xml
+*_usage.xml
+*_xst.xrpt
+
+# project-wide generated files
+*.gise
+par_usage_statistics.html
+usage_statistics_webtalk.html
+webtalk.log
+webtalk_pn.xml
+
+# generated folders
+iseconfig/
+xlnx_auto_0_xdb/
+xst/
+_ngo/
+_xmsgs/
+### Eclipse template
+*.pydevproject
+.metadata
+.gradle
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+
+# Eclipse Core
+.project
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# TeXlipse plugin
+.texlipse
+### C template
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+### SBT template
+# Simple Build Tool
+# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
+
+target/
+lib_managed/
+src_managed/
+project/boot/
+.history
+.cache
+### Emacs template
+# -*- mode: gitignore; -*-
+*~
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+auto-save-list
+tramp
+.\#*
+
+# Org-mode
+.org-id-locations
+*_archive
+
+# flymake-mode
+*_flymake.*
+
+# eshell files
+/eshell/history
+/eshell/lastdir
+
+# elpa packages
+/elpa/
+
+# reftex files
+*.rel
+
+# AUCTeX auto folder
+/auto/
+
+# cask packages
+.cask/
+### Vim template
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
+
+*.iml
+
+## Directory-based project format:
+.idea/
+# if you remove the above rule, at least ignore the following:
+
+# User-specific stuff:
+# .idea/workspace.xml
+# .idea/tasks.xml
+# .idea/dictionaries
+
+# Sensitive or high-churn files:
+# .idea/dataSources.ids
+# .idea/dataSources.xml
+# .idea/sqlDataSources.xml
+# .idea/dynamic.xml
+# .idea/uiDesigner.xml
+
+# Gradle:
+# .idea/gradle.xml
+# .idea/libraries
+
+# Mongo Explorer plugin:
+# .idea/mongoSettings.xml
+
+## File-based project format:
+*.ipr
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+### C++ template
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+### OSX template
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+### Xcode template
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## Build generated
+build/
+DerivedData
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+
+## Other
+*.xccheckout
+*.moved-aside
+*.xcuserstate
+### Scala template
+*.class
+*.log
+/.bsp
+
+# sbt specific
+.cache
+.history
+.lib/
+dist/*
+target/
+lib_managed/
+src_managed/
+project/boot/
+project/plugins/project/
+
+# Scala-IDE specific
+.scala_dependencies
+.worksheet
+### Java template
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
diff --git a/picorF0/build.sbt b/picorF0/build.sbt
new file mode 100644
index 0000000..b3c97b7
--- /dev/null
+++ b/picorF0/build.sbt
@@ -0,0 +1,26 @@
+// See README.md for license details.
+
+ThisBuild / scalaVersion := "2.12.13"
+ThisBuild / version := "0.1.0"
+ThisBuild / organization := "com.anishsinghani"
+
+lazy val root = (project in file("."))
+ .settings(
+ name := "picorF0",
+ libraryDependencies ++= Seq(
+ "edu.berkeley.cs" %% "chisel3" % "3.4.3",
+ "edu.berkeley.cs" %% "chiseltest" % "0.3.3" % "test"
+ ),
+ scalacOptions ++= Seq(
+ "-Xsource:2.11",
+ "-language:reflectiveCalls",
+ "-deprecation",
+ "-feature",
+ "-Xcheckinit",
+ // Enables autoclonetype2 in 3.4.x (on by default in 3.5)
+ "-P:chiselplugin:useBundlePlugin"
+ ),
+ addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % "3.4.3" cross CrossVersion.full),
+ addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full)
+ )
+
diff --git a/picorF0/build.sc b/picorF0/build.sc
new file mode 100644
index 0000000..d095a55
--- /dev/null
+++ b/picorF0/build.sc
@@ -0,0 +1,34 @@
+// import Mill dependency
+import mill._
+import mill.define.Sources
+import mill.modules.Util
+import mill.scalalib.TestModule.ScalaTest
+import scalalib._
+// support BSP
+import mill.bsp._
+
+object noc-generator extends SbtModule { m =>
+ override def millSourcePath = os.pwd
+ override def scalaVersion = "2.12.13"
+ override def scalacOptions = Seq(
+ "-Xsource:2.11",
+ "-language:reflectiveCalls",
+ "-deprecation",
+ "-feature",
+ "-Xcheckinit",
+ // Enables autoclonetype2 in 3.4.x (on by default in 3.5)
+ "-P:chiselplugin:useBundlePlugin"
+ )
+ override def ivyDeps = Agg(
+ ivy"edu.berkeley.cs::chisel3:3.4.3",
+ )
+ override def scalacPluginIvyDeps = Agg(
+ ivy"edu.berkeley.cs:::chisel3-plugin:3.4.3",
+ ivy"org.scalamacros:::paradise:2.1.1"
+ )
+ object test extends Tests with ScalaTest {
+ override def ivyDeps = m.ivyDeps() ++ Agg(
+ ivy"edu.berkeley.cs::chiseltest:0.3.3"
+ )
+ }
+}
diff --git a/picorF0/project/build.properties b/picorF0/project/build.properties
new file mode 100644
index 0000000..ddffd37
--- /dev/null
+++ b/picorF0/project/build.properties
@@ -0,0 +1 @@
+sbt.version = 1.4.9
diff --git a/picorF0/project/plugins.sbt b/picorF0/project/plugins.sbt
new file mode 100644
index 0000000..5708f81
--- /dev/null
+++ b/picorF0/project/plugins.sbt
@@ -0,0 +1 @@
+logLevel := Level.Warn
diff --git a/picorF0/src/main/scala/components/ALU.scala b/picorF0/src/main/scala/components/ALU.scala
new file mode 100644
index 0000000..eef15b1
--- /dev/null
+++ b/picorF0/src/main/scala/components/ALU.scala
@@ -0,0 +1,83 @@
+package components
+
+import chisel3._
+import chisel3.util._
+import chisel3.experimental.ChiselEnum
+
+object ALUOp extends ChiselEnum {
+ val ADD, AND, NOT, OR, SLL, SLT, SRA, SRL, SUB, XOR = Value
+}
+
+class ZCNV extends Bundle {
+ val z = Bool()
+ val c = Bool()
+ val n = Bool()
+ val v = Bool()
+}
+
+class ALU extends Module {
+ val io = IO(new Bundle {
+ val in1 = Input(UInt(16.W))
+ val in2 = Input(UInt(16.W))
+ val op = Input(ALUOp())
+
+ val out = Output(UInt(16.W))
+ val cc = Output(new ZCNV)
+ })
+
+ val in1 = Wire(UInt(17.W))
+ val in2 = Wire(UInt(17.W))
+ in1 := io.in1
+ in2 := io.in2
+
+ val result = Wire(UInt(17.W))
+ io.out := result(15, 0)
+
+ val in1_minus_in2 = Wire(UInt(17.W))
+ in1_minus_in2 := in1 - in2
+
+ result := 0.U
+
+ // Compute result
+ switch (io.op) {
+ is (ALUOp.ADD) { result := in1 + in2 }
+ is (ALUOp.AND) { result := in1 & in2 }
+ is (ALUOp.NOT) { result := ~in1 }
+ is (ALUOp.OR) { result := in1 | in2 }
+ is (ALUOp.SLL) { result := in1 << in2(3, 0) }
+ is (ALUOp.SLT) { result := Cat(0.U(15.W), (in1(15, 0).asSInt() < in2(15, 0).asSInt())(0)) }
+ is (ALUOp.SRA) { result := (in1(15, 0).asSInt() >> in2(3, 0)).asUInt()(15,0) }
+ is (ALUOp.SRL) { result := in1 >> in2(3, 0) }
+ is (ALUOp.SUB) { result := in1_minus_in2 }
+ is (ALUOp.XOR) { result := in1 ^ in2 }
+ }
+
+ // Compute flags
+ when (io.op === ALUOp.ADD) {
+ io.cc.z := (io.out === 0.U)
+ io.cc.c := result(16)
+ io.cc.n := result(15)
+ io.cc.v := (in1(15) && in2(15) && !io.out(15)) ||
+ (!in1(15) && !in2(15) && io.out(15))
+ }
+ .elsewhen (io.op === ALUOp.SUB) {
+ io.cc.z := (io.out === 0.U)
+ io.cc.c := (in2 >= in1) // Weird but works
+ io.cc.n := result(15)
+ io.cc.v := (in1(15) && !in2(15) && !io.out(15)) ||
+ (!in1(15) && in2(15) && io.out(15))
+ }
+ .elsewhen (io.op === ALUOp.SLT) {
+ io.cc.z := (in1_minus_in2 === 0.U)
+ io.cc.c := (in2 >= in1)
+ io.cc.n := in1_minus_in2(15)
+ io.cc.v := (in1(15) && !in2(15) && !in1_minus_in2(15)) ||
+ (!in1(15) && in2(15) && in1_minus_in2(15))
+ }
+ .otherwise {
+ io.cc.z := (io.out === 0.U)
+ io.cc.c := false.B
+ io.cc.n := result(15)
+ io.cc.v := false.B
+ }
+}
diff --git a/picorF0/src/main/scala/components/InstrDecoder.scala b/picorF0/src/main/scala/components/InstrDecoder.scala
new file mode 100644
index 0000000..2f9cb89
--- /dev/null
+++ b/picorF0/src/main/scala/components/InstrDecoder.scala
@@ -0,0 +1,145 @@
+package components
+
+import chisel3._
+import chisel3.experimental.ChiselEnum
+import utils.MathUtils.BinStrToInt
+
+object CCMode extends ChiselEnum {
+ // ALU = use CC values from ALU
+ // WB = use ZN from write-back value, C = 0, V = 0
+ // NONE = don't change CC flags
+ val ALU, WB, NONE = Value
+}
+
+class Instruction extends Bundle {
+ val rs1 = UInt(3.W)
+ val rs2 = UInt(3.W)
+ val rd = UInt(3.W)
+ val imm = UInt(16.W)
+
+ val cc_mode = CCMode()
+ val alu_op = ALUOp()
+ val bra_mask = new ZCNV // Which CC bits to branch on
+
+ val has_jump = Bool()
+ val has_stop = Bool()
+ val has_branch = Bool()
+ val has_mem = Bool()
+ val has_wb = Bool()
+ val has_imm = Bool()
+
+ val is_valid = Bool()
+}
+
+object OpCode {
+ val ADD = b"0000 000"
+ val ADDI = b"0011 000"
+ val AND = b"1001 000"
+ val BRA = b"1111 100"
+ val BRC = b"1010 100"
+ val BRN = b"1001 100"
+ val BRNZ = b"1101 100"
+ val BRV = b"1011 100"
+ val BRZ = b"1100 100"
+ // LI = ADDI
+ val LW = b"0010 100"
+ val MV = b"0010 000"
+ val NOT = b"1000 000"
+ val OR = b"1010 000"
+ val SLL = b"1100 000"
+ val SLLI = b"1100 001"
+ val SLT = b"0101 000"
+ val SLTI = b"0101 001"
+ val SRA = b"1111 000"
+ val SRAI = b"1111 001"
+ val SRL = b"1110 000"
+ val SRLI = b"1110 001"
+ val STOP = b"1111 111"
+ val SUB = b"0001 000"
+ val SW = b"0011 100"
+ val XOR = b"1011 000"
+}
+
+class InstrDecoder extends Module {
+ val io = IO(new Bundle {
+ val instr = Input(UInt(16.W))
+ val imm = Input(UInt(16.W))
+
+ val decoded = Output(new Instruction)
+ })
+
+ val instructions = Map(
+ // Opcode ALU op CC mode BRA mask jmp stp bra mem wb imm
+ OpCode.ADD -> (Some(ALUOp.ADD), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // ADD
+ OpCode.ADDI -> (Some(ALUOp.ADD), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 1 ), // ADDI
+ OpCode.AND -> (Some(ALUOp.AND), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // AND
+ OpCode.BRA -> (None, CCMode.NONE, b"0000", 1, 0, 0, 0, 0, 1 ), // BRA
+ OpCode.BRC -> (None, CCMode.NONE, b"0100", 0, 0, 1, 0, 0, 1 ), // BRC
+ OpCode.BRN -> (None, CCMode.NONE, b"0010", 0, 0, 1, 0, 0, 1 ), // BRN
+ OpCode.BRNZ -> (None, CCMode.NONE, b"1010", 0, 0, 1, 0, 0, 1 ), // BRNZ
+ OpCode.BRV -> (None, CCMode.NONE, b"0001", 0, 0, 1, 0, 0, 1 ), // BRV
+ OpCode.BRZ -> (None, CCMode.NONE, b"1000", 0, 0, 1, 0, 0, 1 ), // BRZ
+ // LI does not have its own encoding, it uses ADDI with rs1 = 0
+ OpCode.LW -> (Some(ALUOp.ADD), CCMode.WB, b"0000", 0, 0, 0, 1, 1, 1 ), // LW
+ OpCode.MV -> (Some(ALUOp.ADD), CCMode.NONE, b"0000", 0, 0, 0, 0, 1, 0 ), // MV (ADD, rs2 = 0)
+ OpCode.NOT -> (Some(ALUOp.NOT), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // NOT
+ OpCode.OR -> (Some(ALUOp.OR), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // OR
+ OpCode.SLL -> (Some(ALUOp.SLL), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // SLL
+ OpCode.SLLI -> (Some(ALUOp.SLL), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 1 ), // SLLI
+ OpCode.SLT -> (Some(ALUOp.SLT), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // SLT
+ OpCode.SLTI -> (Some(ALUOp.SLT), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 1 ), // SLTI
+ OpCode.SRA -> (Some(ALUOp.SRA), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // SRA
+ OpCode.SRAI -> (Some(ALUOp.SRA), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 1 ), // SRAI
+ OpCode.SRL -> (Some(ALUOp.SRL), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // SRL
+ OpCode.SRLI -> (Some(ALUOp.SRL), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 1 ), // SRLI
+ OpCode.STOP -> (None, CCMode.NONE, b"0000", 0, 1, 0, 0, 0, 0 ), // STOP
+ OpCode.SUB -> (Some(ALUOp.SUB), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // SUB
+ OpCode.SW -> (Some(ALUOp.ADD), CCMode.NONE, b"0000", 0, 0, 0, 1, 0, 1 ), // SW
+ OpCode.XOR -> (Some(ALUOp.XOR), CCMode.ALU, b"0000", 0, 0, 0, 0, 1, 0 ), // XOR
+ )
+
+ val opcode = io.instr(15, 9)
+
+ // Operands
+ io.decoded.imm := io.imm
+ io.decoded.rd := io.instr(8, 6) // When instruction has no write-back it's always zero - useful feature of the ISA
+ io.decoded.rs1 := io.instr(5, 3)
+ io.decoded.rs2 := io.instr(2, 0)
+
+ // Default values
+ io.decoded.cc_mode := CCMode.NONE
+ io.decoded.alu_op := ALUOp.ADD
+ io.decoded.bra_mask.z := false.B
+ io.decoded.bra_mask.c := false.B
+ io.decoded.bra_mask.n := false.B
+ io.decoded.bra_mask.v := false.B
+ io.decoded.has_jump := false.B
+ io.decoded.has_stop := false.B
+ io.decoded.has_branch := false.B
+ io.decoded.has_mem := false.B
+ io.decoded.has_wb := false.B
+ io.decoded.has_imm := false.B
+ io.decoded.is_valid := false.B
+
+ for ((inst_opcode, (aluop, ccmode, bramask, jmp, stp, bra, mem, wb, imm)) <- instructions) {
+ when (inst_opcode.U === opcode) {
+ io.decoded.cc_mode := ccmode
+ io.decoded.alu_op := aluop getOrElse ALUOp.ADD
+
+ io.decoded.bra_mask.z := ((bramask & b"1000") != 0).B
+ io.decoded.bra_mask.c := ((bramask & b"0100") != 0).B
+ io.decoded.bra_mask.n := ((bramask & b"0010") != 0).B
+ io.decoded.bra_mask.v := ((bramask & b"0001") != 0).B
+
+ io.decoded.has_jump := jmp.B
+ io.decoded.has_stop := stp.B
+ io.decoded.has_branch := bra.B
+ io.decoded.has_mem := mem.B
+ io.decoded.has_wb := wb.B
+ io.decoded.has_imm := imm.B
+
+ io.decoded.is_valid := true.B
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/picorF0/src/main/scala/components/RegFile.scala b/picorF0/src/main/scala/components/RegFile.scala
new file mode 100644
index 0000000..d272465
--- /dev/null
+++ b/picorF0/src/main/scala/components/RegFile.scala
@@ -0,0 +1,45 @@
+package components
+
+import chisel3._
+import chisel3.util._
+import chisel3.experimental.ChiselEnum
+
+class RegFile extends Module {
+ val io = IO(new Bundle {
+ val rs1 = Input(UInt(3.W))
+ val rs2 = Input(UInt(3.W))
+
+ val rs1_dat = Output(UInt(16.W))
+ val rs2_dat = Output(UInt(16.W))
+
+ val rd = Input(UInt(3.W))
+ val rd_dat = Input(UInt(16.W))
+ val rd_en = Input(Bool())
+
+ val cc_in = Input(new ZCNV)
+ val cc_mask = Input(new ZCNV)
+ val cc_en = Input(Bool())
+
+ val cc_out = Output(new ZCNV)
+ })
+
+ val rf = Reg(Vec(8, UInt(16.W)))
+
+ // Handle reads
+ io.rs1_dat := Mux(io.rs1 === 0.U, 0.U, rf(io.rs1))
+ io.rs2_dat := Mux(io.rs2 === 0.U, 0.U, rf(io.rs2))
+
+ // Handle writes
+ when (io.rd_en) { rf(io.rd) := io.rd_dat }
+
+ // Handle ZCNV
+ val cc_reg = Reg(new ZCNV)
+ io.cc_out := cc_reg
+
+ when (io.cc_en) {
+ when (io.cc_mask.z) { cc_reg.z := io.cc_in.z }
+ when (io.cc_mask.c) { cc_reg.c := io.cc_in.c }
+ when (io.cc_mask.n) { cc_reg.n := io.cc_in.n }
+ when (io.cc_mask.v) { cc_reg.v := io.cc_in.v }
+ }
+}
diff --git a/picorF0/src/main/scala/core/ControlPath.scala b/picorF0/src/main/scala/core/ControlPath.scala
new file mode 100644
index 0000000..305dce6
--- /dev/null
+++ b/picorF0/src/main/scala/core/ControlPath.scala
@@ -0,0 +1,99 @@
+package core
+
+import chisel3._
+import chisel3.experimental.ChiselEnum
+import chisel3.util.{switch, is}
+import components.Instruction
+
+import ControlPath._
+
+object ControlPath {
+ object S extends ChiselEnum {
+ val IF, IF_WAIT, DECODE, EXEC, MEM, MEM_WAIT, WB, HALT = Value
+ }
+}
+
+class ControlPath extends Module {
+
+ val io = IO(new Bundle {
+ val instr = Input(new Instruction)
+
+ val issue_if = Output(Bool())
+ val if_done = Input(Bool())
+
+ val issue_mem = Output(Bool())
+ val mem_we = Output(Bool())
+ val mem_done = Input(Bool())
+
+ val waiting = Output(Bool())
+ val halted = Output(Bool())
+
+ val state = Output(S())
+
+ val restart_core = Input(Bool())
+ val restart = Output(Bool()) // to datapath
+ })
+
+ val restart_reg = RegInit(false.B)
+ io.restart := io.restart_core || restart_reg
+
+ val state = RegInit(S.IF)
+ io.state := state
+
+ val is_store_instr = (io.instr.has_mem && !io.instr.has_wb)
+
+ io.issue_if := (state === S.IF)
+ io.issue_mem := (state === S.MEM)
+ io.mem_we := is_store_instr
+
+ io.waiting := (state === S.IF_WAIT || state === S.MEM_WAIT)
+ io.halted := (state === S.HALT)
+
+ // State-transition logic
+ switch (state) {
+ is (S.IF) {
+ state := S.IF_WAIT
+ }
+ is (S.IF_WAIT) {
+ state := Mux(io.if_done, S.DECODE, S.IF_WAIT)
+ }
+ is (S.DECODE) {
+ state := S.EXEC
+ }
+ is (S.EXEC) {
+ when (io.instr.has_stop) {
+ state := S.HALT
+ }.elsewhen (io.instr.has_jump || io.instr.has_branch) {
+ state := S.IF
+ }.elsewhen (io.instr.has_mem) {
+ state := S.MEM
+ }.otherwise {
+ state := S.WB
+ }
+ }
+ is (S.MEM) {
+ state := S.MEM_WAIT
+ }
+ is (S.MEM_WAIT) {
+ state := Mux(io.mem_done,
+ Mux(is_store_instr, S.IF, S.WB),
+ S.MEM_WAIT)
+ }
+ is (S.WB) {
+ state := S.IF
+ }
+ is (S.HALT) {
+ state := S.HALT
+ }
+ }
+
+ when (io.restart_core) {
+ restart_reg := true.B
+ }
+
+ when (restart_reg && (state =/= S.IF) && (state =/= S.IF_WAIT) && (state =/= S.MEM) && (state =/= S.MEM_WAIT)) {
+ restart_reg := false.B
+ state := S.IF
+ }
+
+}
\ No newline at end of file
diff --git a/picorF0/src/main/scala/core/Core.scala b/picorF0/src/main/scala/core/Core.scala
new file mode 100644
index 0000000..5f93fb0
--- /dev/null
+++ b/picorF0/src/main/scala/core/Core.scala
@@ -0,0 +1,61 @@
+package core
+
+import chisel3._
+import components._
+import _root_.core.ControlPath._
+
+class Core(val INIT_PC: Int = 0) extends Module {
+ val io = IO(new Bundle {
+ val ibus_addr = Output(UInt(16.W))
+ val ibus_data_rd = Input(UInt(32.W))
+ val ibus_stb = Output(Bool())
+ val ibus_ack = Input(Bool())
+
+ val dbus_addr = Output(UInt(16.W))
+ val dbus_we = Output(Bool())
+ val dbus_data_rd = Input(UInt(16.W))
+ val dbus_data_wr = Output(UInt(16.W))
+ val dbus_stb = Output(Bool())
+ val dbus_ack = Input(Bool())
+
+ val restart_pc = Input(UInt(16.W))
+ val restart_core = Input(Bool())
+
+ val waiting = Output(Bool())
+ val halted = Output(Bool())
+ })
+
+ val dpath = Module(new Datapath(INIT_PC))
+ dpath.io.ibus_addr <> io.ibus_addr
+ dpath.io.ibus_data_rd <> io.ibus_data_rd
+ dpath.io.ibus_stb <> io.ibus_stb
+ dpath.io.ibus_ack <> io.ibus_ack
+
+ dpath.io.dbus_addr <> io.dbus_addr
+ dpath.io.dbus_we <> io.dbus_we
+ dpath.io.dbus_data_rd <> io.dbus_data_rd
+ dpath.io.dbus_data_wr <> io.dbus_data_wr
+ dpath.io.dbus_stb <> io.dbus_stb
+ dpath.io.dbus_ack <> io.dbus_ack
+
+ dpath.io.restart_pc <> io.restart_pc
+
+ val cpath = Module(new ControlPath)
+ cpath.io.instr <> dpath.io.instr
+
+ cpath.io.issue_if <> dpath.io.issue_if
+ cpath.io.if_done <> dpath.io.if_done
+ cpath.io.issue_mem <> dpath.io.issue_mem
+ cpath.io.mem_we <> dpath.io.mem_we
+ cpath.io.mem_done <> dpath.io.mem_done
+
+ cpath.io.waiting <> io.waiting
+ cpath.io.halted <> io.halted
+ cpath.io.state <> dpath.io.state
+
+ cpath.io.restart_core <> io.restart_core
+ cpath.io.restart <> dpath.io.restart
+
+}
+
+
diff --git a/picorF0/src/main/scala/core/Datapath.scala b/picorF0/src/main/scala/core/Datapath.scala
new file mode 100644
index 0000000..88ef6bc
--- /dev/null
+++ b/picorF0/src/main/scala/core/Datapath.scala
@@ -0,0 +1,138 @@
+package core
+
+import chisel3._
+import chisel3.util.{is, switch}
+import components.{ALU, CCMode, InstrDecoder, Instruction, RegFile, ZCNV}
+import ControlPath._
+
+class Datapath(val INIT_PC: Int = 0) extends Module {
+ val io = IO(new Bundle {
+ val instr = Output(new Instruction)
+
+ val issue_if = Input(Bool())
+ val if_done = Output(Bool())
+ val issue_mem = Input(Bool())
+ val mem_we = Input(Bool())
+ val mem_done = Output(Bool())
+ val state = Input(S())
+
+ val ibus_addr = Output(UInt(16.W))
+ val ibus_data_rd = Input(UInt(32.W))
+ val ibus_stb = Output(Bool())
+ val ibus_ack = Input(Bool())
+
+ val dbus_addr = Output(UInt(16.W))
+ val dbus_we = Output(Bool())
+ val dbus_data_rd = Input(UInt(16.W))
+ val dbus_data_wr = Output(UInt(16.W))
+ val dbus_stb = Output(Bool())
+ val dbus_ack = Input(Bool())
+
+ val restart_pc = Input(UInt(16.W))
+ val restart = Input(Bool())
+ })
+
+ val pc_reg = RegInit(INIT_PC.U(16.W))
+ val ifetch_reg = RegInit(0.U(32.W))
+ val instr_reg = RegInit(0.U.asTypeOf(new Instruction))
+ val rs1_reg = RegInit(0.U(16.W))
+ val rs2_reg = RegInit(0.U(16.W))
+ val cc_reg = RegInit(0.U(4.W).asTypeOf(new ZCNV))
+
+ val result_reg = RegInit(0.U(16.W))
+ val result_cc_reg = RegInit(0.U(4.W).asTypeOf(new ZCNV))
+
+ io.instr := instr_reg
+
+ // Next PC
+ when (io.restart) {
+ // When rising edge of restart, set the PC to restart PC
+ // otherwise don't let the PC change
+ when (!RegNext(io.restart)) {
+ pc_reg := io.restart_pc
+ }
+ } .elsewhen (io.state === S.EXEC) {
+ pc_reg := pc_reg + Mux(io.instr.has_imm, 4.U, 2.U)
+
+ val take_branch = (io.instr.bra_mask.asUInt() & cc_reg.asUInt()).orR()
+ when (io.instr.has_jump || (io.instr.has_branch && take_branch)) {
+ pc_reg := io.instr.imm
+ }
+ }
+
+ // IFetch
+ io.ibus_addr := pc_reg
+ io.ibus_stb := io.issue_if
+ io.if_done := io.ibus_ack
+ when (io.ibus_ack) { ifetch_reg := io.ibus_data_rd }
+
+ // Decoder
+ val decoder = Module(new InstrDecoder)
+ decoder.io.instr := ifetch_reg(31, 16)
+ decoder.io.imm := ifetch_reg(15, 0)
+ var instr_decoded = decoder.io.decoded
+ when (io.state === S.DECODE) {
+ instr_reg := instr_decoded
+ }
+
+ // ALU
+ val alu = Module(new ALU)
+ alu.io.in1 := rs1_reg
+ alu.io.in2 := Mux(instr_reg.has_imm, instr_reg.imm, rs2_reg)
+ alu.io.op := instr_reg.alu_op
+ when (io.state === S.EXEC) {
+ result_reg := alu.io.out
+ result_cc_reg := alu.io.cc
+ }
+
+ // Data memory
+ io.dbus_addr := result_reg
+ io.dbus_we := io.mem_we
+ io.dbus_data_wr := rs2_reg
+ io.dbus_stb := io.issue_mem
+ io.mem_done := io.dbus_ack
+ when (io.state === S.MEM_WAIT && !io.mem_we && io.dbus_ack) {
+ result_reg := io.dbus_data_rd
+ }
+
+ // Register file (in decode / WB stages)
+ // RF read happens in decode stage so it should use instr_decoded instead of instr_reg
+ val regfile = Module(new RegFile)
+ regfile.io.rs1 := instr_decoded.rs1
+ regfile.io.rs2 := instr_decoded.rs2
+ regfile.io.rd := instr_reg.rd
+
+ regfile.io.rd_en := false.B
+ regfile.io.cc_en := false.B
+
+ regfile.io.cc_mask.z := true.B
+ regfile.io.cc_mask.c := true.B
+ regfile.io.cc_mask.n := true.B
+ regfile.io.cc_mask.v := true.B
+
+ regfile.io.rd_dat := result_reg
+
+ when (io.state === S.DECODE) {
+ rs1_reg := regfile.io.rs1_dat
+ rs2_reg := regfile.io.rs2_dat
+ cc_reg := regfile.io.cc_out
+ }
+
+ when (io.state === S.WB) {
+ regfile.io.rd_en := true.B
+ regfile.io.cc_en := (instr_reg.cc_mode =/= CCMode.NONE)
+ }
+
+ when (instr_reg.cc_mode === CCMode.ALU) {
+ regfile.io.cc_in.z := result_cc_reg.z
+ regfile.io.cc_in.c := result_cc_reg.c
+ regfile.io.cc_in.n := result_cc_reg.n
+ regfile.io.cc_in.v := result_cc_reg.v
+ } .otherwise {
+ regfile.io.cc_in.z := (result_reg === 0.U)
+ regfile.io.cc_in.c := false.B
+ regfile.io.cc_in.n := result_reg(15)
+ regfile.io.cc_in.v := false.B
+ }
+
+}
\ No newline at end of file
diff --git a/picorF0/src/main/scala/top/CoreTop.scala b/picorF0/src/main/scala/top/CoreTop.scala
new file mode 100644
index 0000000..f1e734b
--- /dev/null
+++ b/picorF0/src/main/scala/top/CoreTop.scala
@@ -0,0 +1,80 @@
+package top
+
+import chisel3._
+import chisel3.util._
+import _root_.core.Core
+
+// Connect the core to the caravel logic analyzer to use as it's memory interface
+class CoreTop extends Module {
+ val INIT_PC: Int = 0
+
+ val io = IO(new Bundle {
+ val la_data_in = Input(UInt(128.W))
+ val la_data_out = Output(UInt(128.W))
+ val la_oenb = Input(UInt(128.W))
+ })
+
+ val la_data_in = RegNext(Mux(io.la_oenb(127, 64).orR, 0.U(128.W), Cat(io.la_data_in(127, 64), 0.U(64.W))))
+
+ val ibus_stb_latch = RegInit(false.B)
+ val ibus_ack_in = Wire(Bool())
+ val ibus_stb_clear = Wire(Bool())
+
+ val dbus_stb_latch = RegInit(false.B)
+ val dbus_ack_in = Wire(Bool())
+ val dbus_stb_clear = Wire(Bool())
+
+ val core = Module(new Core(INIT_PC))
+
+ when (core.io.ibus_stb) { ibus_stb_latch := true.B }
+ when (ibus_stb_clear && !RegNext(ibus_stb_clear)) { ibus_stb_latch := false.B }
+ core.io.ibus_ack := ibus_ack_in && !RegNext(ibus_ack_in) // Rising edge
+
+ when (core.io.dbus_stb) { dbus_stb_latch := true.B }
+ when (dbus_stb_clear && !RegNext(dbus_stb_clear)) { dbus_stb_latch := false.B }
+ core.io.dbus_ack := dbus_ack_in && !RegNext(dbus_ack_in) // Rising edge
+
+ // LA[15:0] = ibus_addr
+ // LA[31:16] = dbus_addr
+ // LA[47:32] = dbus_data_wr
+ // LA[48] = ibus_stb
+ // LA[49] = dbus_stb
+ // LA[50] = dbus_we
+ // LA[51] = waiting
+ // LA[52] = halted
+ // LA[63:53] = reserved (core -> caravel)
+ io.la_data_out := RegNext(Cat(
+ core.io.halted,
+ core.io.waiting,
+ core.io.dbus_we,
+ dbus_stb_latch,
+ ibus_stb_latch,
+ core.io.dbus_data_wr,
+ core.io.dbus_addr,
+ core.io.ibus_addr
+ ))
+
+ // LA[95:64] = data_rd / restart_pc
+ core.io.ibus_data_rd := la_data_in(95, 64)
+ core.io.dbus_data_rd := la_data_in(79, 64)
+ core.io.restart_pc := la_data_in(95, 80)
+
+ // LA[96] = ibus_ack
+ ibus_ack_in := la_data_in(96)
+
+ // LA[97] = ibus_stb_clear
+ ibus_stb_clear := la_data_in(97)
+
+ // LA[98] = dbus_ack
+ dbus_ack_in := la_data_in(98)
+
+ // LA[99] = dbus_stb_clear
+ dbus_stb_clear := la_data_in(99)
+
+ // LA[100] = restart_core
+ core.io.restart_core := la_data_in(100) && !RegNext(la_data_in(100))
+
+ // LA[127:101] = reserved (caravel -> core)
+}
+
+
diff --git a/picorF0/src/main/scala/top/GenerateVerilog.scala b/picorF0/src/main/scala/top/GenerateVerilog.scala
new file mode 100644
index 0000000..b6a9035
--- /dev/null
+++ b/picorF0/src/main/scala/top/GenerateVerilog.scala
@@ -0,0 +1,8 @@
+package top
+
+import chisel3.stage.ChiselStage
+import top.CoreTop
+
+object GenerateVerilog extends App {
+ (new ChiselStage).emitVerilog(new CoreTop)
+}
diff --git a/picorF0/src/main/scala/utils/MathUtils.scala b/picorF0/src/main/scala/utils/MathUtils.scala
new file mode 100644
index 0000000..1ac7072
--- /dev/null
+++ b/picorF0/src/main/scala/utils/MathUtils.scala
@@ -0,0 +1,25 @@
+package utils
+
+object MathUtils {
+ def intLog2(x: Int): Int = {
+ val log = (Math.log(x) / Math.log(2.0)).round.toInt
+ assert((1 << log) == x)
+ return log
+ }
+
+ implicit class BinStrToInt(val sc: StringContext) extends AnyVal {
+ def b(args: Any*): Int = {
+ val strings = sc.parts.iterator
+ val expressions = args.iterator
+ val buf = new StringBuilder(strings.next())
+ while(strings.hasNext) {
+ buf.append(expressions.next())
+ buf.append(strings.next())
+ }
+
+ Integer.parseInt("0" + buf.toString
+ .replaceAll("_", "")
+ .replaceAll(" ", ""), 2)
+ }
+ }
+}
\ No newline at end of file
diff --git a/picorF0/src/test/scala/core/CoreTests.scala b/picorF0/src/test/scala/core/CoreTests.scala
new file mode 100644
index 0000000..4a937ef
--- /dev/null
+++ b/picorF0/src/test/scala/core/CoreTests.scala
@@ -0,0 +1,255 @@
+package core
+
+import chisel3._
+import chisel3.tester._
+import components.OpCode._
+import org.scalatest.FreeSpec
+import utils.MathUtils.BinStrToInt
+
+import scala.io.Source
+import scala.util.Random
+import scala.util.control.Breaks._
+
+class CoreTests extends FreeSpec with ChiselScalatestTester {
+
+ def asm(opcode: Int, rd: Int = 0, rs1: Int = 0, rs2: Int = 0): Int =
+ ((opcode & b"1111 111") << 9) |
+ ((rd & b"111") << 6) |
+ ((rs1 & b"111") << 3) |
+ ((rs2 & b"111") << 0)
+
+ // `program` is an array of 16-bit memory words
+ def handleIFetch(dut: Core, program: Array[Int], verbose: Boolean = false): Unit = {
+ val prog = program :+ 0 // Allows fetching last instruction in program if it is a short-style instruction
+
+ breakable {
+ while (true) {
+ while (!dut.io.ibus_stb.peek().litToBoolean) {
+ dut.clock.step()
+ if (dut.io.halted.peek().litToBoolean) break
+ }
+
+ val addr = dut.io.ibus_addr.peek().litValue().toInt
+ val result = (BigInt(prog(addr >> 1)) << 16) | BigInt(prog((addr >> 1) + 1)) // 32-bit fetch
+
+ for (_ <- 0 until (Random.nextInt(3) + 2)) { // 2-5 cycle latency
+ dut.clock.step()
+ dut.io.ibus_stb.expect(false.B)
+ }
+
+ dut.io.ibus_data_rd.poke(result.U)
+ dut.io.ibus_ack.poke(true.B)
+ dut.clock.step()
+ dut.io.ibus_ack.poke(false.B)
+
+ if (verbose) {
+ println(f"IF[0x$addr%04X] => 0x$result%08X")
+ }
+ }
+ }
+ }
+
+ // `data` is 64K-element array of 16-bit memory words
+ // it will be modified upon stores
+ def handleDMem(dut: Core, data: collection.mutable.Map[Int, Int], verbose: Boolean = false): Unit = {
+
+ breakable {
+ while (true) {
+ while (!dut.io.dbus_stb.peek().litToBoolean) {
+ dut.clock.step()
+ if (dut.io.halted.peek().litToBoolean) break
+ }
+
+ val addr = (dut.io.dbus_addr.peek().litValue().toInt >> 1) << 1
+ var result = 0
+ if (dut.io.dbus_we.peek().litToBoolean) {
+ data.put(addr, dut.io.dbus_data_wr.peek().litValue().toInt)
+ if (verbose) {
+ println(f"M[0x$addr%04X] <= 0x${dut.io.dbus_data_wr.peek().litValue().toInt}%08X")
+ }
+
+ } else {
+ result = data.getOrElse(addr, 0)
+
+ if (verbose) {
+ println(f"M[0x$addr%04X] => 0x$result%08X")
+ }
+ }
+
+ for (_ <- 0 until (Random.nextInt(3) + 2)) { // 2-5 cycle latency
+ dut.clock.step()
+ dut.io.dbus_stb.expect(false.B)
+ }
+
+ dut.io.dbus_data_rd.poke(result.U)
+ dut.io.dbus_ack.poke(true.B)
+ dut.clock.step()
+ dut.io.dbus_ack.poke(false.B)
+ }
+ }
+ }
+
+ def waitForHalt(dut: Core): Unit = {
+ while (!dut.io.halted.peek().litToBoolean) dut.clock.step()
+ }
+
+ "should fetch instructions" in {
+ test(new Core(0x0000)) { dut =>
+ val rand = new Random
+
+ dut.io.ibus_ack.poke(false.B)
+ dut.io.dbus_ack.poke(false.B)
+
+ dut.io.restart_core.poke(false.B)
+
+ dut.io.waiting.expect(false.B)
+ dut.io.halted.expect(false.B)
+
+ // Expect instruction fetch
+ dut.io.ibus_stb.expect(true.B)
+ dut.io.ibus_addr.expect(0.U)
+
+ for (_ <- 0 until (Random.nextInt(10) + 2)) {
+ dut.clock.step()
+ dut.io.ibus_stb.expect(false.B)
+ }
+
+ dut.io.ibus_ack.poke(true.B)
+ dut.io.ibus_data_rd.poke(0.U) // ADD r0, r0, r0
+
+ var i = 0
+ while (!dut.io.ibus_stb.peek().litToBoolean) {
+ dut.clock.step()
+ i += 1
+ }
+
+ println(s"ADD r0, r0, r0 took $i cycles")
+ }
+ }
+
+ "should issue loads" in {
+ test(new Core(0x0000)) { dut =>
+ dut.io.ibus_ack.poke(false.B)
+ dut.io.dbus_ack.poke(false.B)
+ dut.io.restart_core.poke(false.B)
+
+ dut.io.waiting.expect(false.B)
+ dut.io.halted.expect(false.B)
+
+ val program = Array (
+ b"0010 100 001 000 000", // LW r1, r0
+ 0x1234,
+ b"1111 111 000 000 000", // STOP
+ )
+
+ fork { handleIFetch(dut, program, verbose = true) } .fork {
+
+ while(!dut.io.dbus_stb.peek().litToBoolean) dut.clock.step(1)
+ println(f"LOAD, 0x${dut.io.dbus_addr.peek().litValue().toInt}%04X")
+
+ dut.clock.step(2)
+ dut.io.dbus_data_rd.poke(0.U)
+ dut.io.dbus_ack.poke(true.B)
+ dut.clock.step(1)
+ dut.io.dbus_ack.poke(false.B)
+
+ }.join()
+ }
+ }
+
+ "should issue loads and stores" in {
+ test(new Core(0x0000)) { dut =>
+ dut.io.ibus_ack.poke(false.B)
+ dut.io.dbus_ack.poke(false.B)
+ dut.io.restart_core.poke(false.B)
+
+ dut.io.waiting.expect(false.B)
+ dut.io.halted.expect(false.B)
+
+ val program = Array (
+ asm(LW, rd = 1, rs1 = 0),
+ 0x1000,
+ asm(SW, rs1 = 0, rs2 = 1),
+ 0x1002,
+ asm(STOP)
+ )
+
+ val dmem = collection.mutable.Map (
+ 0x1000 -> 0xABCD
+ )
+
+ fork { handleIFetch(dut, program, verbose = true) }
+ .fork { handleDMem(dut, dmem, verbose = true) } .fork {
+
+ waitForHalt(dut)
+ assert(dmem(0x1002) == dmem(0x1000))
+
+ }.join()
+ }
+ }
+
+ "should pass a test suite" in {
+ test(new Core(0x0000)) { dut =>
+ dut.io.ibus_ack.poke(false.B)
+ dut.io.dbus_ack.poke(false.B)
+ dut.io.restart_core.poke(false.B)
+
+ dut.io.waiting.expect(false.B)
+ dut.io.halted.expect(false.B)
+
+ val memfile = Source.fromFile("testsuite.hex")
+ val program = memfile.getLines.map(x => Integer.parseInt(x, 16)).toArray
+ memfile.close()
+
+ val dmem = collection.mutable.Map (
+ 0x1000 -> 0xABCD,
+ 0x9000 -> 0x0000
+ )
+
+ fork { handleIFetch(dut, program, verbose = true) }
+ .fork { handleDMem(dut, dmem, verbose = true) } .fork {
+
+ waitForHalt(dut)
+
+ if (dmem(0x9000) == 0xABCD) {
+ println("All tests passed")
+ } else if (dmem(0x9000) == 0x0001) {
+ println(s"Failed at test ${dmem(0x9002)}")
+ } else {
+ println("Failure: halted without reporting success or failure")
+ }
+
+ }.join()
+ }
+ }
+
+ /*"Gcd should calculate proper greatest common denominator" in {
+ test(new DecoupledGcd(16)) { dut =>
+ dut.input.initSource()
+ dut.input.setSourceClock(dut.clock)
+ dut.output.initSink()
+ dut.output.setSinkClock(dut.clock)
+
+ val testValues = for { x <- 0 to 10; y <- 0 to 10} yield (x, y)
+ val inputSeq = testValues.map { case (x, y) => (new GcdInputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U) }
+ val resultSeq = testValues.map { case (x, y) =>
+ (new GcdOutputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U, _.gcd -> BigInt(x).gcd(BigInt(y)).U)
+ }
+
+ fork {
+ // push inputs into the calculator, stall for 11 cycles one third of the way
+ val (seq1, seq2) = inputSeq.splitAt(resultSeq.length / 3)
+ dut.input.enqueueSeq(seq1)
+ dut.clock.step(11)
+ dut.input.enqueueSeq(seq2)
+ }.fork {
+ // retrieve computations from the calculator, stall for 10 cycles one half of the way
+ val (seq1, seq2) = resultSeq.splitAt(resultSeq.length / 2)
+ dut.output.expectDequeueSeq(seq1)
+ dut.clock.step(10)
+ dut.output.expectDequeueSeq(seq2)
+ }.join()
+
+ }
+ }*/
+}
diff --git a/picorF0/testsuite.hex.txt b/picorF0/testsuite.hex.txt
new file mode 100644
index 0000000..6f62e19
--- /dev/null
+++ b/picorF0/testsuite.hex.txt
@@ -0,0 +1,3055 @@
+F800
+0200
+31C0
+ABCD
+3807
+9000
+3800
+9002
+FE00
+31C0
+0001
+3807
+9000
+3801
+9002
+FE00
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+0000
+3040
+0001
+3100
+000B
+3140
+0017
+00E5
+3080
+0022
+1013
+C800
+021E
+F800
+0012
+2000
+3040
+0002
+3100
+000B
+3140
+0017
+00E5
+C800
+0012
+F800
+0236
+2000
+3040
+0003
+3100
+000B
+3140
+0017
+00E5
+A800
+0012
+F800
+024E
+2000
+3040
+0004
+3100
+000B
+3140
+0017
+00E5
+9800
+0012
+F800
+0266
+2000
+3040
+0005
+3100
+000B
+3140
+0017
+00E5
+B800
+0012
+F800
+027E
+2000
+3040
+0006
+3100
+8001
+3140
+8000
+00E5
+3080
+0001
+1013
+C800
+029C
+F800
+0012
+2000
+3040
+0007
+3100
+8001
+3140
+8000
+00E5
+C800
+0012
+F800
+02B4
+2000
+3040
+0008
+3100
+8001
+3140
+8000
+00E5
+A800
+02CC
+F800
+0012
+2000
+3040
+0009
+3100
+8001
+3140
+8000
+00E5
+9800
+0012
+F800
+02E4
+2000
+3040
+000A
+3100
+8001
+3140
+8000
+00E5
+B800
+02FC
+F800
+0012
+2000
+3040
+000B
+3100
+8000
+3140
+7FFF
+00E5
+3080
+FFFF
+1013
+C800
+031A
+F800
+0012
+2000
+3040
+000C
+3100
+8000
+3140
+7FFF
+00E5
+C800
+0012
+F800
+0332
+2000
+3040
+000D
+3100
+8000
+3140
+7FFF
+00E5
+A800
+0012
+F800
+034A
+2000
+3040
+000E
+3100
+8000
+3140
+7FFF
+00E5
+9800
+0362
+F800
+0012
+2000
+3040
+000F
+3100
+8000
+3140
+7FFF
+00E5
+B800
+0012
+F800
+037A
+2000
+3040
+0010
+3100
+8000
+3140
+8000
+00E5
+3080
+0000
+1013
+C800
+0398
+F800
+0012
+2000
+3040
+0011
+3100
+8000
+3140
+8000
+00E5
+C800
+03B0
+F800
+0012
+2000
+3040
+0012
+3100
+8000
+3140
+8000
+00E5
+A800
+03C8
+F800
+0012
+2000
+3040
+0013
+3100
+8000
+3140
+8000
+00E5
+9800
+0012
+F800
+03E0
+2000
+3040
+0014
+3100
+8000
+3140
+8000
+00E5
+B800
+03F8
+F800
+0012
+2000
+3040
+0015
+3100
+000B
+30E0
+0017
+3080
+0022
+1013
+C800
+0414
+F800
+0012
+2000
+3040
+0016
+3100
+000B
+30E0
+0017
+C800
+0012
+F800
+042A
+2000
+3040
+0017
+3100
+000B
+30E0
+0017
+A800
+0012
+F800
+0440
+2000
+3040
+0018
+3100
+000B
+30E0
+0017
+9800
+0012
+F800
+0456
+2000
+3040
+0019
+3100
+000B
+30E0
+0017
+B800
+0012
+F800
+046C
+2000
+3040
+001A
+3100
+8001
+30E0
+8000
+3080
+0001
+1013
+C800
+0488
+F800
+0012
+2000
+3040
+001B
+3100
+8001
+30E0
+8000
+C800
+0012
+F800
+049E
+2000
+3040
+001C
+3100
+8001
+30E0
+8000
+A800
+04B4
+F800
+0012
+2000
+3040
+001D
+3100
+8001
+30E0
+8000
+9800
+0012
+F800
+04CA
+2000
+3040
+001E
+3100
+8001
+30E0
+8000
+B800
+04E0
+F800
+0012
+2000
+3040
+001F
+3100
+8000
+30E0
+7FFF
+3080
+FFFF
+1013
+C800
+04FC
+F800
+0012
+2000
+3040
+0020
+3100
+8000
+30E0
+7FFF
+C800
+0012
+F800
+0512
+2000
+3040
+0021
+3100
+8000
+30E0
+7FFF
+A800
+0012
+F800
+0528
+2000
+3040
+0022
+3100
+8000
+30E0
+7FFF
+9800
+053E
+F800
+0012
+2000
+3040
+0023
+3100
+8000
+30E0
+7FFF
+B800
+0012
+F800
+0554
+2000
+3040
+0024
+3100
+8000
+30E0
+8000
+3080
+0000
+1013
+C800
+0570
+F800
+0012
+2000
+3040
+0025
+3100
+8000
+30E0
+8000
+C800
+0586
+F800
+0012
+2000
+3040
+0026
+3100
+8000
+30E0
+8000
+A800
+059C
+F800
+0012
+2000
+3040
+0027
+3100
+8000
+30E0
+8000
+9800
+0012
+F800
+05B2
+2000
+3040
+0028
+3100
+8000
+30E0
+8000
+B800
+05C8
+F800
+0012
+2000
+3040
+0029
+3100
+000B
+3140
+0017
+90E5
+3080
+0003
+1013
+C800
+05E6
+F800
+0012
+2000
+3040
+002A
+3100
+000B
+3140
+0017
+90E5
+C800
+0012
+F800
+05FE
+2000
+3040
+002B
+3100
+000B
+3140
+0017
+90E5
+A800
+0012
+F800
+0616
+2000
+3040
+002C
+3100
+000B
+3140
+0017
+90E5
+9800
+0012
+F800
+062E
+2000
+3040
+002D
+3100
+000B
+3140
+0017
+90E5
+B800
+0012
+F800
+0646
+2000
+3040
+002E
+3100
+AAAA
+3140
+5555
+90E5
+3080
+0000
+1013
+C800
+0664
+F800
+0012
+2000
+3040
+002F
+3100
+AAAA
+3140
+5555
+90E5
+C800
+067C
+F800
+0012
+2000
+3040
+0030
+3100
+AAAA
+3140
+5555
+90E5
+A800
+0012
+F800
+0694
+2000
+3040
+0031
+3100
+AAAA
+3140
+5555
+90E5
+9800
+0012
+F800
+06AC
+2000
+3040
+0032
+3100
+AAAA
+3140
+5555
+90E5
+B800
+0012
+F800
+06C4
+2000
+3040
+0033
+3100
+5381
+3140
+1AE4
+90E5
+3080
+1280
+1013
+C800
+06E2
+F800
+0012
+2000
+3040
+0034
+3100
+2342
+3140
+0123
+90E5
+3080
+0102
+1013
+C800
+0700
+F800
+0012
+2000
+3040
+0035
+3100
+0017
+3140
+000B
+10E5
+3080
+000C
+1013
+C800
+071E
+F800
+0012
+2000
+3040
+0036
+3100
+0017
+3140
+000B
+10E5
+C800
+0012
+F800
+0736
+2000
+3040
+0037
+3100
+0017
+3140
+000B
+10E5
+A800
+0012
+F800
+074E
+2000
+3040
+0038
+3100
+0017
+3140
+000B
+10E5
+9800
+0012
+F800
+0766
+2000
+3040
+0039
+3100
+0017
+3140
+000B
+10E5
+B800
+0012
+F800
+077E
+2000
+3040
+003A
+3100
+0017
+3140
+0017
+10E5
+3080
+0000
+1013
+C800
+079C
+F800
+0012
+2000
+3040
+003B
+3100
+0017
+3140
+0017
+10E5
+C800
+07B4
+F800
+0012
+2000
+3040
+003C
+3100
+0017
+3140
+0017
+10E5
+A800
+07CC
+F800
+0012
+2000
+3040
+003D
+3100
+0017
+3140
+0017
+10E5
+9800
+0012
+F800
+07E4
+2000
+3040
+003E
+3100
+0017
+3140
+0017
+10E5
+B800
+0012
+F800
+07FC
+2000
+3040
+003F
+3100
+0017
+3140
+0018
+10E5
+3080
+FFFF
+1013
+C800
+081A
+F800
+0012
+2000
+3040
+0040
+3100
+0017
+3140
+0018
+10E5
+C800
+0012
+F800
+0832
+2000
+3040
+0041
+3100
+0017
+3140
+0018
+10E5
+A800
+084A
+F800
+0012
+2000
+3040
+0042
+3100
+0017
+3140
+0018
+10E5
+9800
+0862
+F800
+0012
+2000
+3040
+0043
+3100
+0017
+3140
+0018
+10E5
+B800
+0012
+F800
+087A
+2000
+3040
+0044
+3100
+0017
+3140
+0019
+10E5
+3080
+FFFE
+1013
+C800
+0898
+F800
+0012
+2000
+3040
+0045
+3100
+0017
+3140
+0019
+10E5
+C800
+0012
+F800
+08B0
+2000
+3040
+0046
+3100
+0017
+3140
+0019
+10E5
+A800
+08C8
+F800
+0012
+2000
+3040
+0047
+3100
+0017
+3140
+0019
+10E5
+9800
+08E0
+F800
+0012
+2000
+3040
+0048
+3100
+0017
+3140
+0019
+10E5
+B800
+0012
+F800
+08F8
+2000
+3040
+0049
+3100
+8000
+3140
+0001
+10E5
+3080
+7FFF
+1013
+C800
+0916
+F800
+0012
+2000
+3040
+004A
+3100
+8000
+3140
+0001
+10E5
+C800
+0012
+F800
+092E
+2000
+3040
+004B
+3100
+8000
+3140
+0001
+10E5
+A800
+0012
+F800
+0946
+2000
+3040
+004C
+3100
+8000
+3140
+0001
+10E5
+9800
+0012
+F800
+095E
+2000
+3040
+004D
+3100
+8000
+3140
+0001
+10E5
+B800
+0976
+F800
+0012
+2000
+3040
+004E
+3100
+0017
+3140
+000B
+B0E5
+3080
+001C
+1013
+C800
+0994
+F800
+0012
+2000
+3040
+004F
+3100
+AAAA
+3140
+5555
+B0E5
+3080
+FFFF
+1013
+C800
+09B2
+F800
+0012
+2000
+3040
+0050
+3100
+0000
+3140
+0000
+B0E5
+3080
+0000
+1013
+C800
+09D0
+F800
+0012
+2000
+3040
+0051
+3100
+001F
+3140
+0000
+C0E5
+3080
+001F
+1013
+C800
+09EE
+F800
+0012
+2000
+3040
+0052
+3100
+001F
+C2E0
+0000
+3080
+001F
+1013
+C800
+0A0A
+F800
+0012
+2000
+3040
+0053
+3100
+001F
+3140
+0001
+C0E5
+3080
+003E
+1013
+C800
+0A28
+F800
+0012
+2000
+3040
+0054
+3100
+001F
+C2E0
+0001
+3080
+003E
+1013
+C800
+0A44
+F800
+0012
+2000
+3040
+0055
+3100
+001F
+3140
+0002
+C0E5
+3080
+007C
+1013
+C800
+0A62
+F800
+0012
+2000
+3040
+0056
+3100
+001F
+C2E0
+0002
+3080
+007C
+1013
+C800
+0A7E
+F800
+0012
+2000
+3040
+0057
+3100
+001F
+C2E0
+000F
+3080
+8000
+1013
+C800
+0A9A
+F800
+0012
+2000
+3040
+0058
+3100
+8000
+C2E0
+0001
+3080
+0000
+1013
+C800
+0AB6
+F800
+0012
+2000
+3040
+0059
+3100
+8000
+C2E0
+000F
+3080
+0000
+1013
+C800
+0AD2
+F800
+0012
+2000
+3040
+005A
+3100
+001F
+3140
+0000
+E0E5
+3080
+001F
+1013
+C800
+0AF0
+F800
+0012
+2000
+3040
+005B
+3100
+001F
+E2E0
+0000
+3080
+001F
+1013
+C800
+0B0C
+F800
+0012
+2000
+3040
+005C
+3100
+001F
+3140
+0001
+E0E5
+3080
+000F
+1013
+C800
+0B2A
+F800
+0012
+2000
+3040
+005D
+3100
+001F
+E2E0
+0001
+3080
+000F
+1013
+C800
+0B46
+F800
+0012
+2000
+3040
+005E
+3100
+001F
+3140
+0002
+E0E5
+3080
+0007
+1013
+C800
+0B64
+F800
+0012
+2000
+3040
+005F
+3100
+001F
+E2E0
+0002
+3080
+0007
+1013
+C800
+0B80
+F800
+0012
+2000
+3040
+0060
+3100
+001F
+E2E0
+000F
+3080
+0000
+1013
+C800
+0B9C
+F800
+0012
+2000
+3040
+0061
+3100
+8000
+E2E0
+0001
+3080
+4000
+1013
+C800
+0BB8
+F800
+0012
+2000
+3040
+0062
+3100
+8000
+E2E0
+000F
+3080
+0001
+1013
+C800
+0BD4
+F800
+0012
+2000
+3040
+0063
+3100
+001F
+3140
+0000
+F0E5
+3080
+001F
+1013
+C800
+0BF2
+F800
+0012
+2000
+3040
+0064
+3100
+001F
+F2E0
+0000
+3080
+001F
+1013
+C800
+0C0E
+F800
+0012
+2000
+3040
+0065
+3100
+001F
+3140
+0001
+F0E5
+3080
+000F
+1013
+C800
+0C2C
+F800
+0012
+2000
+3040
+0066
+3100
+001F
+F2E0
+0001
+3080
+000F
+1013
+C800
+0C48
+F800
+0012
+2000
+3040
+0067
+3100
+001F
+3140
+0002
+F0E5
+3080
+0007
+1013
+C800
+0C66
+F800
+0012
+2000
+3040
+0068
+3100
+001F
+F2E0
+0002
+3080
+0007
+1013
+C800
+0C82
+F800
+0012
+2000
+3040
+0069
+3100
+001F
+F2E0
+000F
+3080
+0000
+1013
+C800
+0C9E
+F800
+0012
+2000
+3040
+006A
+3100
+8000
+F2E0
+0001
+3080
+C000
+1013
+C800
+0CBA
+F800
+0012
+2000
+3040
+006B
+3100
+8000
+F2E0
+000F
+3080
+FFFF
+1013
+C800
+0CD6
+F800
+0012
+2000
+3040
+006C
+3100
+0017
+3140
+000B
+50E5
+3080
+0000
+1013
+C800
+0CF4
+F800
+0012
+2000
+3040
+006D
+3100
+0017
+3140
+000B
+50E5
+C800
+0012
+F800
+0D0C
+2000
+3040
+006E
+3100
+0017
+3140
+000B
+50E5
+A800
+0012
+F800
+0D24
+2000
+3040
+006F
+3100
+0017
+3140
+000B
+50E5
+9800
+0012
+F800
+0D3C
+2000
+3040
+0070
+3100
+0017
+3140
+000B
+50E5
+B800
+0012
+F800
+0D54
+2000
+3040
+0071
+3100
+0017
+52E0
+000B
+3080
+0000
+1013
+C800
+0D70
+F800
+0012
+2000
+3040
+0072
+3100
+0017
+52E0
+000B
+C800
+0012
+F800
+0D86
+2000
+3040
+0073
+3100
+0017
+52E0
+000B
+A800
+0012
+F800
+0D9C
+2000
+3040
+0074
+3100
+0017
+52E0
+000B
+9800
+0012
+F800
+0DB2
+2000
+3040
+0075
+3100
+0017
+52E0
+000B
+B800
+0012
+F800
+0DC8
+2000
+3040
+0076
+3100
+0017
+3140
+0017
+50E5
+3080
+0000
+1013
+C800
+0DE6
+F800
+0012
+2000
+3040
+0077
+3100
+0017
+3140
+0017
+50E5
+C800
+0DFE
+F800
+0012
+2000
+3040
+0078
+3100
+0017
+3140
+0017
+50E5
+A800
+0E16
+F800
+0012
+2000
+3040
+0079
+3100
+0017
+3140
+0017
+50E5
+9800
+0012
+F800
+0E2E
+2000
+3040
+007A
+3100
+0017
+3140
+0017
+50E5
+B800
+0012
+F800
+0E46
+2000
+3040
+007B
+3100
+0017
+52E0
+0017
+3080
+0000
+1013
+C800
+0E62
+F800
+0012
+2000
+3040
+007C
+3100
+0017
+52E0
+0017
+C800
+0E78
+F800
+0012
+2000
+3040
+007D
+3100
+0017
+52E0
+0017
+A800
+0E8E
+F800
+0012
+2000
+3040
+007E
+3100
+0017
+52E0
+0017
+9800
+0012
+F800
+0EA4
+2000
+3040
+007F
+3100
+0017
+52E0
+0017
+B800
+0012
+F800
+0EBA
+2000
+3040
+0080
+3100
+0017
+3140
+0018
+50E5
+3080
+0001
+1013
+C800
+0ED8
+F800
+0012
+2000
+3040
+0081
+3100
+0017
+3140
+0018
+50E5
+C800
+0012
+F800
+0EF0
+2000
+3040
+0082
+3100
+0017
+3140
+0018
+50E5
+A800
+0F08
+F800
+0012
+2000
+3040
+0083
+3100
+0017
+3140
+0018
+50E5
+9800
+0F20
+F800
+0012
+2000
+3040
+0084
+3100
+0017
+3140
+0018
+50E5
+B800
+0012
+F800
+0F38
+2000
+3040
+0085
+3100
+0017
+52E0
+0018
+3080
+0001
+1013
+C800
+0F54
+F800
+0012
+2000
+3040
+0086
+3100
+0017
+52E0
+0018
+C800
+0012
+F800
+0F6A
+2000
+3040
+0087
+3100
+0017
+52E0
+0018
+A800
+0F80
+F800
+0012
+2000
+3040
+0088
+3100
+0017
+52E0
+0018
+9800
+0F96
+F800
+0012
+2000
+3040
+0089
+3100
+0017
+52E0
+0018
+B800
+0012
+F800
+0FAC
+2000
+3040
+008A
+3100
+0017
+3140
+0019
+50E5
+3080
+0001
+1013
+C800
+0FCA
+F800
+0012
+2000
+3040
+008B
+3100
+0017
+3140
+0019
+50E5
+C800
+0012
+F800
+0FE2
+2000
+3040
+008C
+3100
+0017
+3140
+0019
+50E5
+A800
+0FFA
+F800
+0012
+2000
+3040
+008D
+3100
+0017
+3140
+0019
+50E5
+9800
+1012
+F800
+0012
+2000
+3040
+008E
+3100
+0017
+3140
+0019
+50E5
+B800
+0012
+F800
+102A
+2000
+3040
+008F
+3100
+0017
+52E0
+0019
+3080
+0001
+1013
+C800
+1046
+F800
+0012
+2000
+3040
+0090
+3100
+0017
+52E0
+0019
+C800
+0012
+F800
+105C
+2000
+3040
+0091
+3100
+0017
+52E0
+0019
+A800
+1072
+F800
+0012
+2000
+3040
+0092
+3100
+0017
+52E0
+0019
+9800
+1088
+F800
+0012
+2000
+3040
+0093
+3100
+0017
+52E0
+0019
+B800
+0012
+F800
+109E
+2000
+3040
+0094
+3100
+8000
+3140
+0001
+50E5
+3080
+0001
+1013
+C800
+10BC
+F800
+0012
+2000
+3040
+0095
+3100
+8000
+3140
+0001
+50E5
+C800
+0012
+F800
+10D4
+2000
+3040
+0096
+3100
+8000
+3140
+0001
+50E5
+A800
+0012
+F800
+10EC
+2000
+3040
+0097
+3100
+8000
+3140
+0001
+50E5
+9800
+0012
+F800
+1104
+2000
+3040
+0098
+3100
+8000
+3140
+0001
+50E5
+B800
+111C
+F800
+0012
+2000
+3040
+0099
+3100
+8000
+52E0
+0001
+3080
+0001
+1013
+C800
+1138
+F800
+0012
+2000
+3040
+009A
+3100
+8000
+52E0
+0001
+C800
+0012
+F800
+114E
+2000
+3040
+009B
+3100
+8000
+52E0
+0001
+A800
+0012
+F800
+1164
+2000
+3040
+009C
+3100
+8000
+52E0
+0001
+9800
+0012
+F800
+117A
+2000
+3040
+009D
+3100
+8000
+52E0
+0001
+B800
+1190
+F800
+0012
+2000
+3040
+009E
+3100
+0017
+3140
+000B
+50E5
+3080
+0000
+1013
+C800
+11AE
+F800
+0012
+2000
+3040
+009F
+3100
+0017
+3140
+000B
+50E5
+C800
+0012
+F800
+11C6
+2000
+3040
+00A0
+3100
+0017
+3140
+000B
+50E5
+A800
+0012
+F800
+11DE
+2000
+3040
+00A1
+3100
+0017
+3140
+000B
+50E5
+9800
+0012
+F800
+11F6
+2000
+3040
+00A2
+3100
+0017
+3140
+000B
+50E5
+B800
+0012
+F800
+120E
+2000
+3040
+00A3
+3100
+0017
+52E0
+000B
+3080
+0000
+1013
+C800
+122A
+F800
+0012
+2000
+3040
+00A4
+3100
+0017
+52E0
+000B
+C800
+0012
+F800
+1240
+2000
+3040
+00A5
+3100
+0017
+52E0
+000B
+A800
+0012
+F800
+1256
+2000
+3040
+00A6
+3100
+0017
+52E0
+000B
+9800
+0012
+F800
+126C
+2000
+3040
+00A7
+3100
+0017
+52E0
+000B
+B800
+0012
+F800
+1282
+2000
+3040
+00A8
+3100
+0017
+3140
+0017
+50E5
+3080
+0000
+1013
+C800
+12A0
+F800
+0012
+2000
+3040
+00A9
+3100
+0017
+3140
+0017
+50E5
+C800
+12B8
+F800
+0012
+2000
+3040
+00AA
+3100
+0017
+3140
+0017
+50E5
+A800
+12D0
+F800
+0012
+2000
+3040
+00AB
+3100
+0017
+3140
+0017
+50E5
+9800
+0012
+F800
+12E8
+2000
+3040
+00AC
+3100
+0017
+3140
+0017
+50E5
+B800
+0012
+F800
+1300
+2000
+3040
+00AD
+3100
+0017
+52E0
+0017
+3080
+0000
+1013
+C800
+131C
+F800
+0012
+2000
+3040
+00AE
+3100
+0017
+52E0
+0017
+C800
+1332
+F800
+0012
+2000
+3040
+00AF
+3100
+0017
+52E0
+0017
+A800
+1348
+F800
+0012
+2000
+3040
+00B0
+3100
+0017
+52E0
+0017
+9800
+0012
+F800
+135E
+2000
+3040
+00B1
+3100
+0017
+52E0
+0017
+B800
+0012
+F800
+1374
+2000
+3040
+00B2
+3100
+0017
+3140
+0018
+50E5
+3080
+0001
+1013
+C800
+1392
+F800
+0012
+2000
+3040
+00B3
+3100
+0017
+3140
+0018
+50E5
+C800
+0012
+F800
+13AA
+2000
+3040
+00B4
+3100
+0017
+3140
+0018
+50E5
+A800
+13C2
+F800
+0012
+2000
+3040
+00B5
+3100
+0017
+3140
+0018
+50E5
+9800
+13DA
+F800
+0012
+2000
+3040
+00B6
+3100
+0017
+3140
+0018
+50E5
+B800
+0012
+F800
+13F2
+2000
+3040
+00B7
+3100
+0017
+52E0
+0018
+3080
+0001
+1013
+C800
+140E
+F800
+0012
+2000
+3040
+00B8
+3100
+0017
+52E0
+0018
+C800
+0012
+F800
+1424
+2000
+3040
+00B9
+3100
+0017
+52E0
+0018
+A800
+143A
+F800
+0012
+2000
+3040
+00BA
+3100
+0017
+52E0
+0018
+9800
+1450
+F800
+0012
+2000
+3040
+00BB
+3100
+0017
+52E0
+0018
+B800
+0012
+F800
+1466
+2000
+3040
+00BC
+3100
+0017
+3140
+0019
+50E5
+3080
+0001
+1013
+C800
+1484
+F800
+0012
+2000
+3040
+00BD
+3100
+0017
+3140
+0019
+50E5
+C800
+0012
+F800
+149C
+2000
+3040
+00BE
+3100
+0017
+3140
+0019
+50E5
+A800
+14B4
+F800
+0012
+2000
+3040
+00BF
+3100
+0017
+3140
+0019
+50E5
+9800
+14CC
+F800
+0012
+2000
+3040
+00C0
+3100
+0017
+3140
+0019
+50E5
+B800
+0012
+F800
+14E4
+2000
+3040
+00C1
+3100
+0017
+52E0
+0019
+3080
+0001
+1013
+C800
+1500
+F800
+0012
+2000
+3040
+00C2
+3100
+0017
+52E0
+0019
+C800
+0012
+F800
+1516
+2000
+3040
+00C3
+3100
+0017
+52E0
+0019
+A800
+152C
+F800
+0012
+2000
+3040
+00C4
+3100
+0017
+52E0
+0019
+9800
+1542
+F800
+0012
+2000
+3040
+00C5
+3100
+0017
+52E0
+0019
+B800
+0012
+F800
+1558
+2000
+3040
+00C6
+3100
+8000
+3140
+0001
+50E5
+3080
+0001
+1013
+C800
+1576
+F800
+0012
+2000
+3040
+00C7
+3100
+8000
+3140
+0001
+50E5
+C800
+0012
+F800
+158E
+2000
+3040
+00C8
+3100
+8000
+3140
+0001
+50E5
+A800
+0012
+F800
+15A6
+2000
+3040
+00C9
+3100
+8000
+3140
+0001
+50E5
+9800
+0012
+F800
+15BE
+2000
+3040
+00CA
+3100
+8000
+3140
+0001
+50E5
+B800
+15D6
+F800
+0012
+2000
+3040
+00CB
+3100
+8000
+52E0
+0001
+3080
+0001
+1013
+C800
+15F2
+F800
+0012
+2000
+3040
+00CC
+3100
+8000
+52E0
+0001
+C800
+0012
+F800
+1608
+2000
+3040
+00CD
+3100
+8000
+52E0
+0001
+A800
+0012
+F800
+161E
+2000
+3040
+00CE
+3100
+8000
+52E0
+0001
+9800
+0012
+F800
+1634
+2000
+3040
+00CF
+3100
+8000
+52E0
+0001
+B800
+164A
+F800
+0012
+2000
+3040
+00D0
+3100
+0017
+3140
+0000
+20E0
+3080
+0017
+1013
+C800
+1668
+F800
+0012
+2000
+3040
+00D1
+3100
+0020
+3140
+0000
+20E0
+3080
+0020
+1013
+C800
+1686
+F800
+0012
+2000
+3040
+00D2
+3100
+8000
+3140
+0000
+20E0
+3080
+8000
+1013
+C800
+16A4
+F800
+0012
+2000
+3040
+00D3
+3100
+0000
+3140
+0000
+20E0
+3080
+0000
+1013
+C800
+16C2
+F800
+0012
+2000
+3040
+00D4
+3100
+0017
+3140
+0000
+80E0
+3080
+FFE8
+1013
+C800
+16E0
+F800
+0012
+2000
+3040
+00D5
+3100
+0020
+3140
+0000
+80E0
+3080
+FFDF
+1013
+C800
+16FE
+F800
+0012
+2000
+3040
+00D6
+3100
+8000
+3140
+0000
+80E0
+3080
+7FFF
+1013
+C800
+171C
+F800
+0012
+2000
+3040
+00D7
+3100
+0000
+3140
+0000
+80E0
+3080
+FFFF
+1013
+C800
+173A
+F800
+0012
+2000
+3040
+00D8
+3100
+0017
+3140
+0000
+80E0
+3080
+FFE8
+1013
+C800
+1758
+F800
+0012
+2000
+3040
+00D9
+3100
+0020
+3140
+0000
+80E0
+3080
+FFDF
+1013
+C800
+1776
+F800
+0012
+2000
+3040
+00DA
+3100
+8000
+3140
+0000
+80E0
+3080
+7FFF
+1013
+C800
+1794
+F800
+0012
+2000
+3040
+00DB
+3100
+0000
+3140
+0000
+80E0
+3080
+FFFF
+1013
+C800
+17B2
+F800
+0012
+2000
+3040
+0220
+30C0
+ABCD
+3080
+A000
+3813
+0323
+3100
+0323
+2920
+A000
+5220
+ABCD
+C800
+17D8
+F800
+0012
+2000
+F800
+0004