1
0
mirror of https://github.com/antonblanchard/chiselwatt.git synced 2026-04-12 07:15:43 +00:00

Initial import

This commit is contained in:
Anton Blanchard
2019-10-18 08:08:43 +11:00
committed by Anton Blanchard
commit f138ab7c7c
2063 changed files with 76244 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
project/
target/
obj_dir/
out/
*.anno.json
*.fir
*.vcd

8
LICENSE Normal file
View File

@@ -0,0 +1,8 @@
© IBM Corp. 2019
This softcore is licensed under and subject to the terms of the CC-BY 4.0
license (https://creativecommons.org/licenses/by/4.0/legalcode).
Additional rights, including the right to physically implement a softcore
that is compliant with the required sections of the Power ISA
Specification, will be available at no cost via the OpenPOWER Foundation.
This README will be updated with additional information when OpenPOWER's
license is available.

86
Makefile Normal file
View File

@@ -0,0 +1,86 @@
all: chiselwatt
scala_files = $(wildcard src/main/scala/*scala)
verilog_files = Core.v MemoryBlackBox.v
verilator_binary = chiselwatt
$(verilog_files): $(scala_files)
sbt 'runMain CoreObj'
$(verilator_binary): $(verilog_files) chiselwatt.cpp uart.c
# Warnings disabled until we fix the Chisel issues
#verilator -O3 -Wall --assert --cc Core.v --exe chiselwatt.cpp uart.c #--trace
verilator -O3 --assert --cc Core.v --exe chiselwatt.cpp uart.c -o $@ #--trace
make -C obj_dir -f VCore.mk
@cp -f obj_dir/chiselwatt chiselwatt
clean:
@rm -f Core.fir firrtl_black_box_resource_files.f Core.v Core.anno.json MemoryBlackBox.v
@rm -rf obj_dir test_run_dir target project
@rm -f chiselwatt
@rm -f *.bit *.json *.svf *.config
@rm -f LoadStoreInsns.hex MemoryBlackBoxInsns.hex
scala_tests: $(verilator_binary)
sbt testOnly
tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out)))
check: scala_tests $(tests)
$(tests): $(verilator_binary)
@./scripts/run_test.sh $@
# Use local tools for synthesis
#YOSYS = yosys
#NEXTPNR = nextpnr-ecp5
#ECPPACK = ecppack
#OPENOCD = openocd
# Use Docker images for synthesis
DOCKER=docker
#DOCKER=podman
#
PWD = $(shell pwd)
DOCKERARGS = run --rm -v $(PWD):/src -w /src
#
YOSYS = $(DOCKER) $(DOCKERARGS) ghdl/synth:beta yosys
NEXTPNR = $(DOCKER) $(DOCKERARGS) ghdl/synth:nextpnr-ecp5 nextpnr-ecp5
ECPPACK = $(DOCKER) $(DOCKERARGS) ghdl/synth:trellis ecppack
OPENOCD = $(DOCKER) $(DOCKERARGS) --device /dev/bus/usb ghdl/synth:prog openocd
# OrangeCrab with ECP85
#LPF=constraints/orange-crab.lpf
#PACKAGE=CSFBGA285
#NEXTPNR_FLAGS=--um5g-85k --freq 50
#OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
#OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
# ECP5-EVN
LPF=constraints/ecp5-evn.lpf
PACKAGE=CABGA381
NEXTPNR_FLAGS=--um5g-85k --freq 12
OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg
OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
synth: chiselwatt.bit
chiselwatt.json: $(verilog_files) insns.hex pll_ecp5_evn.v toplevel.v
$(YOSYS) -p "read_verilog -sv pll_ecp5_evn.v toplevel.v Core.v MemoryBlackBox.v; synth_ecp5 -json $@ -top toplevel"
chiselwatt_out.config: chiselwatt.json $(LPF)
$(NEXTPNR) --json $< --lpf $(LPF) --textcfg $@ $(NEXTPNR_FLAGS) --package $(PACKAGE)
chiselwatt.bit: chiselwatt_out.config
$(ECPPACK) --svf chiselwatt.svf $< $@
chiselwatt.svf: chiselwatt.bit
prog: chiselwatt.svf
$(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $<; exit"
.PHONY: clean prog
.PRECIOUS: chiselwatt.json chiselwatt_out.config chiselwatt.bit

77
README.md Normal file
View File

@@ -0,0 +1,77 @@
# Chiselwatt
A tiny POWER Open ISA soft processor written in Chisel.
## Simulation using verilator
* Chiselwatt uses verilator for simulation. Either install this from your distro or build it. Chisel uses sbt (the scala build tool), so install that too. Next build chiselwatt:
```
git clone https://github.com/antonblanchard/chiselwatt
cd chiselwatt
make
```
* A micropython image is included in the repo. To use it, link the memory image into chiselwatt:
```
ln -s micropython/firmware.hex insns.hex
```
* Now run chiselwatt:
```
./chiselwatt
```
## Building micropython from scratch
* You can also build micropython from scratch. If you aren't building natively on a ppc64le box you will need a cross compiler. This may be available on your distro, otherwise grab the the powerpc64le-power8 toolchain from https://toolchains.bootlin.com/. If you are cross compiling, point CROSS_COMPILE at the toolchain. In the example below I installed it in usr/local/powerpc64le-power8--glibc--bleeding-edge-2018.11-1/bin/ and the tools begin with powerpc64-linux-
```
git clone https://github.com/micropython/micropython.git
cd micropython
cd ports/powerpc
make CROSS_COMPILE=/usr/local/powerpc64le-power8--glibc--bleeding-edge-2018.11-1/bin/powerpc64le-linux- -j$(nproc)
cd ../../../
```
* Build chiselwatt, import the the micropython image and run it:
```
cd chiselwatt
make
scripts/bin2hex.py ../micropython/ports/powerpc/build/firmware.bin > insns.hex
./chiselwatt
```
## Synthesis
Synthesis on FPGAs is supported with yosys/nextpnr. It uses Docker images, so no software other
than Docker needs to be installed. If you prefer podman you can use that too.
Edit Makefile.synth to configure your FPGA, JTAG device etc. You will also need to configure the
amount of block RAM your FPGA supports, by editing `src/main/scala/Core.scala`. Here we are using
128kB of block RAM:
```
chisel3.Driver.execute(Array[String](), () => new Core(64, 128*1024, "insns.hex", 0x0))
```
Unfortunately due to an issue in yosys/nextpnr, dual port RAMs are not working. This means we use
twice as much block RAM as you would expect.
To build:
```
make -f Makefile.synth
```
and to program the FPGA:
```
make -f Makefile.synth prog
```
## Issues
- We still have a few instructions to add

58
build.sbt Normal file
View File

@@ -0,0 +1,58 @@
// See README.md for license details.
def scalacOptionsVersion(scalaVersion: String): Seq[String] = {
Seq() ++ {
// If we're building with Scala > 2.11, enable the compile option
// switch to support our anonymous Bundle definitions:
// https://github.com/scala/bug/issues/10047
CrossVersion.partialVersion(scalaVersion) match {
case Some((2, scalaMajor: Long)) if scalaMajor < 12 => Seq()
case _ => Seq("-Xsource:2.11")
}
}
}
def javacOptionsVersion(scalaVersion: String): Seq[String] = {
Seq() ++ {
// Scala 2.12 requires Java 8. We continue to generate
// Java 7 compatible code for Scala 2.11
// for compatibility with old clients.
CrossVersion.partialVersion(scalaVersion) match {
case Some((2, scalaMajor: Long)) if scalaMajor < 12 =>
Seq("-source", "1.7", "-target", "1.7")
case _ =>
Seq("-source", "1.8", "-target", "1.8")
}
}
}
name := "chisel-module-template"
version := "3.2.0"
scalaVersion := "2.12.10"
crossScalaVersions := Seq("2.12.10", "2.11.12")
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases")
)
// Provide a managed dependency on X if -DXVersion="" is supplied on the command line.
val defaultVersions = Map(
"chisel3" -> "3.2.+",
"chisel-iotesters" -> "1.3.+"
)
libraryDependencies ++= Seq("chisel3","chisel-iotesters").map {
dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }
scalacOptions ++= scalacOptionsVersion(scalaVersion.value)
javacOptions ++= javacOptionsVersion(scalaVersion.value)
scalacOptions ++= Seq("-unchecked", "-deprecation", "-language:reflectiveCalls", "-feature")
scalacOptions ++= Seq("-Ywarn-value-discard", "-Ywarn-dead-code", "-Ywarn-unused")
libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "0.2-SNAPSHOT"

115
chiselwatt.cpp Normal file
View File

@@ -0,0 +1,115 @@
#include <stdlib.h>
#include "VCore.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
/*
* Current simulation time
* This is a 64-bit integer to reduce wrap over issues and
* allow modulus. You can also use a double, if you wish.
*/
vluint64_t main_time = 0;
/*
* Called by $time in Verilog
* converts to double, to match
* what SystemC does
*/
double sc_time_stamp(void)
{
return main_time;
}
#if VM_TRACE
VerilatedVcdC *tfp;
#endif
void tick(VCore *top)
{
top->clock = 1;
top->eval();
#if VM_TRACE
if (tfp)
tfp->dump((double) main_time);
#endif
main_time++;
top->clock = 0;
top->eval();
#if VM_TRACE
if (tfp)
tfp->dump((double) main_time);
#endif
main_time++;
}
void uart_tx(unsigned char tx);
unsigned char uart_rx(void);
int main(int argc, char **argv)
{
Verilated::commandArgs(argc, argv);
// init top verilog instance
VCore* top = new VCore;
#if VM_TRACE
// init trace dump
Verilated::traceEverOn(true);
tfp = new VerilatedVcdC;
top->trace(tfp, 99);
tfp->open("Core.vcd");
#endif
// Reset
top->reset = 1;
for (unsigned long i = 0; i < 5; i++)
tick(top);
top->reset = 0;
while(!Verilated::gotFinish()) {
tick(top);
//VL_PRINTF("NIA %" VL_PRI64 "x\n", top->Core__DOT__executeNia);
uart_tx(top->io_tx);
top->io_rx = uart_rx();
if (top->io_terminate) {
for (unsigned long j = 0; j < 32; j++)
VL_PRINTF("GPR%d %016" VL_PRI64 "X\n", j, top->Core__DOT__regFile__DOT__regs[j]);
VL_PRINTF("CR 00000000%01X%01X%01X%01X%01X%01X%01X%01X\n",
top->Core__DOT__conditionRegister_0,
top->Core__DOT__conditionRegister_1,
top->Core__DOT__conditionRegister_2,
top->Core__DOT__conditionRegister_3,
top->Core__DOT__conditionRegister_4,
top->Core__DOT__conditionRegister_5,
top->Core__DOT__conditionRegister_6,
top->Core__DOT__conditionRegister_7);
VL_PRINTF("LR %016" VL_PRI64 "X\n",
top->Core__DOT__linkRegister);
VL_PRINTF("CTR %016" VL_PRI64 "X\n",
top->Core__DOT__countRegister);
/*
* We run for one more tick to allow any debug
* prints in this cycle to make it out.
*/
tick(top);
#if VM_TRACE
tfp->close();
#endif
exit(1);
}
}
#if VM_TRACE
tfp->close();
delete tfp;
#endif
delete top;
}

19
constraints/ecp5-evn.lpf Normal file
View File

@@ -0,0 +1,19 @@
LOCATE COMP "clock" SITE "A10";
IOBUF PORT "clock" IO_TYPE=LVCMOS33;
LOCATE COMP "reset" SITE "P4";
IOBUF PORT "reset" IO_TYPE=LVCMOS33;
LOCATE COMP "io_tx" SITE "P3";
LOCATE COMP "io_rx" SITE "P2";
IOBUF PORT "io_tx" IO_TYPE=LVCMOS33;
IOBUF PORT "io_rx" IO_TYPE=LVCMOS33;
LOCATE COMP "io_terminate" SITE "A13";
LOCATE COMP "io_ledB" SITE "A12";
LOCATE COMP "io_ledC" SITE "B19";
IOBUF PORT "io_terminate" IO_TYPE=LVCMOS25;
IOBUF PORT "io_ledB" IO_TYPE=LVCMOS25;
IOBUF PORT "io_ledC" IO_TYPE=LVCMOS25;

View File

@@ -0,0 +1,19 @@
LOCATE COMP "clock" SITE "A9";
IOBUF PORT "clock" IO_TYPE=LVCMOS33;
LOCATE COMP "reset" SITE "J2";
IOBUF PORT "reset" PULLMODE=DOWN IO_TYPE=LVCMOS33 DRIVE=4;
LOCATE COMP "io_tx" SITE "N17";
LOCATE COMP "io_rx" SITE "M18";
IOBUF PORT "io_tx" IO_TYPE=LVCMOS25;
IOBUF PORT "io_rx" IO_TYPE=LVCMOS25;
LOCATE COMP "io_terminate" SITE "V17";
LOCATE COMP "io_ledB" SITE "T17";
LOCATE COMP "io_ledC" SITE "J3";
IOBUF PORT "io_terminate" IO_TYPE=LVCMOS25;
IOBUF PORT "io_ledB" IO_TYPE=LVCMOS25;
IOBUF PORT "io_ledC" IO_TYPE=LVCMOS25;

BIN
hello_world/hello_world.bin Executable file

Binary file not shown.

BIN
hello_world/hello_world.elf Executable file

Binary file not shown.

586
hello_world/hello_world.hex Normal file
View File

@@ -0,0 +1,586 @@
000000004800012c
0000000000000000
4800002408000048
01006b69a600607d
a602487d05009f42
a64b5a7d14004a39
2402004ca64b7b7d
00000000480000f4
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
4800002408000048
01006b69a600607d
a602487d05009f42
a64b5a7d14004a39
2402004ca64b7b7d
3c20000048000004
782107c660210000
60211f0064210000
618c00003d800000
658c0000798c07c6
7d8903a6618c113c
480000004e800421
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
e8010010ebc1fff0
7c0803a6ebe1fff8
3c4000014e800020
3d20c0003842a000
6129200060000000
f922800079290020
3940001a3d20c000
7929002061292018
4e800020f9490000
0000000000000000
3c40000100000000
600000003842a000
390a0010e9428000
71290001e9280000
e86a00084082fff8
4e8000205463063e
0000000000000000
3c40000100000000
600000003842a000
390a0010e9428000
71290008e9280000
f86a00004082fff8
000000004e800020
0000000000000000
3842a0003c400001
fbc1fff07c0802a6
7fc32214fbe1fff8
f80100107c7f1b78
7fbff040f821ffd1
38210030409e000c
887f00004bffff10
4bffff993bff0001
000000004bffffe4
0000028001000000
7d4348ae39200000
409e000c2f8a0000
4e8000207d234b78
4bffffe839290001
0000000000000000
3c40000100000000
7c0802a63842a000
3fe2fffffbe1fff8
f80100103bff7190
4bfffec1f821ffd1
4bffffad7fe3fb78
7fe3fb787c641b78
4bfffee94bffff59
4bffff195463063e
000000004bfffff4
0000018001000000
6f57206f6c6c6548
0000000a0d646c72
0000000000000010
0141780400527a01
0000001000010c1b
fffffe5800000018
0000000000000040
0000002c00000010
00000038fffffe84
0000001000000000
fffffea800000040
0000000000000034
0000005400000028
00000050fffffec8
9f029e0041094500
437e4111300e4401
4106dedf41000e0a
000000100000000b
fffffeec00000080
000000000000002c
000000940000001c
00000054ffffff04
44019f0041094400
0000007e4111300e

BIN
micropython/firmware.bin Normal file

Binary file not shown.

BIN
micropython/firmware.elf Executable file

Binary file not shown.

33124
micropython/firmware.hex Normal file

File diff suppressed because it is too large Load Diff

1
openocd/LFE5U-25F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41111043

1
openocd/LFE5U-45F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41112043

1
openocd/LFE5U-85F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41113043

1
openocd/LFE5UM-25F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01111043

1
openocd/LFE5UM-45F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01112043

1
openocd/LFE5UM-85F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01113043

1
openocd/LFE5UM5G-25F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81111043

1
openocd/LFE5UM5G-45F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81112043

1
openocd/LFE5UM5G-85F.cfg Normal file
View File

@@ -0,0 +1 @@
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043

13
openocd/ecp5-evn.cfg Normal file
View File

@@ -0,0 +1,13 @@
# this supports ECP5 Evaluation Board
interface ftdi
ftdi_device_desc "Lattice ECP5 Evaluation Board"
ftdi_vid_pid 0x0403 0x6010
# channel 1 does not have any functionality
ftdi_channel 0
# just TCK TDI TDO TMS, no reset
ftdi_layout_init 0xfff8 0xfffb
reset_config none
# default speed
adapter_khz 5000

View File

@@ -0,0 +1,17 @@
#
# Olimex ARM-USB-TINY-H
#
# http://www.olimex.com/dev/arm-usb-tiny-h.html
#
interface ftdi
ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
ftdi_vid_pid 0x15ba 0x002a
ftdi_layout_init 0x0808 0x0a1b
ftdi_layout_signal nSRST -oe 0x0200
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal LED -data 0x0800
# default speed
adapter_khz 5000

30
pll_ecp5_evn.v Normal file
View File

@@ -0,0 +1,30 @@
module pll_ecp5_evn(input clki, output clko, output lock);
(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
EHXPLLL #(
.PLLRST_ENA("DISABLED"),
.INTFB_WAKE("DISABLED"),
.STDBY_ENABLE("DISABLED"),
.DPHASE_SOURCE("DISABLED"),
.CLKOP_FPHASE(0),
.CLKOP_CPHASE(11),
.OUTDIVIDER_MUXA("DIVA"),
.CLKOP_ENABLE("ENABLED"),
.CLKOP_DIV(12),
.CLKFB_DIV(25),
.CLKI_DIV(6),
.FEEDBK_PATH("CLKOP")
) pll_i (
.CLKI(clki),
.CLKFB(clko),
.CLKOP(clko),
.LOCK(lock),
.RST(1'b0),
.STDBY(1'b0),
.PHASESEL0(1'b0),
.PHASESEL1(1'b0),
.PHASEDIR(1'b0),
.PHASESTEP(1'b0),
.PLLWAKESYNC(1'b0),
.ENCLKOP(1'b0),
);
endmodule

17
scripts/bin2hex.py Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/python3
import sys
import subprocess
import struct
with open(sys.argv[1], "rb") as f:
while True:
word = f.read(8)
if len(word) == 8:
print("%016x" % struct.unpack('Q', word));
elif len(word) == 4:
print("00000000%08x" % struct.unpack('I', word));
elif len(word) == 0:
exit(0);
else:
raise Exception("Bad length")

57
scripts/gen-decode-table.py Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/python3
import yaml
# Print all the common keys in order each time, makes diffing between
# versions easier.
base_keys = [ 'unit', 'internalOp', 'rA', 'rB', 'rS', 'rOut', 'carryIn', 'carryOut', 'crIn', 'crOut', 'compare', 'is32bit', 'signed', 'invertIn', 'invertOut', 'rightShift', 'clearLeft', 'clearRight', 'length', 'byteReverse', 'update', 'reservation', 'high', 'extended', 'countRight' ]
all_keys = list()
all_lengths = list()
with open('instructions.yaml') as fh:
insns = yaml.safe_load(fh)
all_keys = list()
for key in base_keys:
all_keys.append(key)
all_lengths.append(len(key) + 1)
# Add all the keys and find the maximum length of either the name or the value
for insn in insns:
for key in insns[insn].keys():
if key not in all_keys:
all_keys.append(key)
keylen = len(key) + 1
vallen = len(insns[insn][key]) + 2
all_lengths.append(max(keylen, vallen))
else:
i = all_keys.index(key)
all_lengths[i] = max(all_lengths[i], len(insns[insn][key]) + 2)
print(" // ", end = '')
for i in range(len(all_keys)):
key = all_keys[i]
length = all_lengths[i]
print("%-*s" % (length, key), end = '')
print("")
for insn in insns:
print(" %-13s -> List(" % (insn.upper()), end = '')
for i in range(len(all_keys)):
key = all_keys[i]
length = all_lengths[i]
if (i == (len(all_keys)-1)):
append = '),'
else:
append = ','
if key in insns[insn]:
val = insns[insn][key] + append
else:
val = 'DC' + append
print("%-*s" % (length, val), end = '')
print("")

1793
scripts/instructions.yaml Normal file

File diff suppressed because it is too large Load Diff

32
scripts/run_test.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash -e
if [ $# -ne 1 ]; then
echo "Usage: run_test.sh <test>"
exit 1
fi
TEST=$1
TMPDIR=$(mktemp -d)
function finish {
rm -rf "$TMPDIR"
}
trap finish EXIT
CHISELWATT_DIR=$PWD
cd $TMPDIR
${CHISELWATT_DIR}/scripts/bin2hex.py ${CHISELWATT_DIR}/tests/${TEST}.bin > insns.hex
${CHISELWATT_DIR}/chiselwatt 2> test.err | grep -v "^$" | grep -v GPR31 > test.out || true
grep -v "^$" ${CHISELWATT_DIR}/tests/${TEST}.out | grep -v GPR31 | grep -v XER > exp.out
diff -q test.out exp.out && echo "$TEST PASS" && exit 0
cat test.err
echo "$TEST FAIL ********"
exit 1

View File

@@ -0,0 +1,37 @@
import chisel3._
class Adder(n: Int) extends Module {
val io = IO(new Bundle {
val a = Input(UInt(n.W))
val b = Input(UInt(n.W))
val carryIn = Input(UInt(1.W))
val invertIn = Input(UInt(1.W))
val is32bit = Input(UInt(1.W))
val signed = Input(UInt(1.W))
val out = Output(UInt(n.W))
val carryOut = Output(UInt(1.W))
val ltOut = Output(UInt(1.W))
})
val a = Mux(io.invertIn.asBool, ~io.a, io.a)
val x = a +& io.b + io.carryIn
val aSign = if (n == 64) Mux(io.is32bit.asBool, io.a(31), io.a(63)) else io.a(31)
val bSign = if (n == 64) Mux(io.is32bit.asBool, io.b(31), io.b(63)) else io.b(31)
val xSign = if (n == 64) Mux(io.is32bit.asBool, x(31), x(63)) else x(31)
/*
* Our adder does b - a, which is reverse to what compare wants, so
* we invert the sign of x. We calculate the rest of the compare bits
* in a subsequent cycle.
*/
io.ltOut := Mux(aSign === bSign, ~xSign,
Mux(io.signed.asBool, aSign, bSign))
io.out := x((n-1), 0)
io.carryOut := x(n)
}
object AdderObj extends App {
chisel3.Driver.execute(Array[String](), () => new Adder(64))
}

View File

@@ -0,0 +1,326 @@
import chisel3._
import chisel3.util.{ListLookup}
object Control {
val Y = true.B
val N = false.B
val DC = false.B
// Unit
val U_ADD = 0.U(4.W)
val U_LOG = 1.U(4.W)
val U_ROT = 2.U(4.W)
val U_MUL = 3.U(4.W)
val U_DIV = 4.U(4.W)
val U_LDST = 5.U(4.W)
val U_BR = 6.U(4.W)
val U_CR = 7.U(4.W)
val U_ZER = 8.U(4.W)
val U_POP = 9.U(4.W)
val U_SPR = 10.U(4.W)
val U_ILL = 11.U(4.W)
val U_NONE = 12.U(4.W)
// Internal ops
val LOG_AND = 0.U(2.W)
val LOG_OR = 1.U(2.W)
val LOG_XOR = 2.U(2.W)
val LOG_EXTS = 3.U(2.W)
val LDST_LOAD = 0.U(2.W)
val LDST_STORE = 1.U(2.W)
val DIV_DIV = 0.U(2.W)
val DIV_MOD = 1.U(2.W)
val SPR_MF = 0.U(2.W)
val SPR_MT = 1.U(2.W)
val CR_MF = 0.U(2.W)
val CR_MT = 1.U(2.W)
val BR_UNCOND = 0.U(2.W)
val BR_COND = 1.U(2.W)
// Input registers
val RA_RA = 1.U(2.W)
val RA_RA_OR_ZERO = 2.U(2.W)
val RA_ZERO = 3.U(2.W)
val RB_RB = 1.U(4.W)
val RB_CONST_UI = 2.U(4.W)
val RB_CONST_SI = 3.U(4.W)
val RB_CONST_SI_HI = 4.U(4.W)
val RB_CONST_UI_HI = 5.U(4.W)
val RB_CONST_DS = 6.U(4.W)
val RB_CONST_M1 = 7.U(4.W)
val RB_CONST_ZERO = 8.U(4.W)
val RB_CONST_SH = 9.U(4.W)
val RB_CONST_SH32 = 10.U(4.W)
val RS_RS = 1.U(1.W)
// Output registers
val ROUT_NONE = 0.U(2.W)
val ROUT_RT = 1.U(2.W)
val ROUT_RA = 2.U(2.W)
val CMP_RC_0 = 0.U(2.W)
val CMP_RC_RC = 1.U(2.W)
val CMP_RC_1 = 2.U(2.W)
val CMP_CMP = 3.U(2.W)
val CA_0 = 0.U(2.W)
val CA_CA = 1.U(2.W)
val CA_1 = 2.U(2.W)
val LEN_1B = 0.U(2.W)
val LEN_2B = 1.U(2.W)
val LEN_4B = 2.U(2.W)
val LEN_8B = 3.U(2.W)
val FXM = 0.U(2.W)
val FXM_FF = 1.U(2.W)
val FXM_ONEHOT = 2.U(2.W)
val BR_TARGET_NONE = 0.U(2.W)
val BR_TARGET_CTR = 1.U(2.W)
val BR_TARGET_LR = 2.U(2.W)
import Instructions._
val default =
List(U_ILL, DC, DC, DC, DC, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC)
val map = Array(
// unit internalOp rA rB rS rOut carryIn carryOut crIn crOut compare is32bit signed invertIn invertOut rightShift clearLeft clearRight length byteReverse update reservation high extended countRight fxm brTarget
ADDIC -> List(U_ADD, DC, RA_RA, RB_CONST_SI, DC, ROUT_RT, CA_0, Y, DC, DC, CMP_RC_0, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDIC_DOT -> List(U_ADD, DC, RA_RA, RB_CONST_SI, DC, ROUT_RT, CA_0, Y, DC, DC, CMP_RC_1, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDI -> List(U_ADD, DC, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, CA_0, N, DC, DC, CMP_RC_0, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDIS -> List(U_ADD, DC, RA_RA_OR_ZERO, RB_CONST_SI_HI, DC, ROUT_RT, CA_0, N, DC, DC, CMP_RC_0, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SUBFIC -> List(U_ADD, DC, RA_RA, RB_CONST_SI, DC, ROUT_RT, CA_1, Y, DC, DC, CMP_RC_0, DC, DC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADD -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_RT, CA_0, N, DC, DC, CMP_RC_RC, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDC -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_RT, CA_0, Y, DC, DC, CMP_RC_RC, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDE -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_RT, CA_CA, Y, DC, DC, CMP_RC_RC, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDME -> List(U_ADD, DC, RA_RA, RB_CONST_M1, DC, ROUT_RT, CA_CA, Y, DC, DC, CMP_RC_RC, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ADDZE -> List(U_ADD, DC, RA_RA, RB_CONST_ZERO, DC, ROUT_RT, CA_CA, Y, DC, DC, CMP_RC_RC, DC, DC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SUBF -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_RT, CA_1, N, DC, DC, CMP_RC_RC, DC, DC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SUBFC -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_RT, CA_1, Y, DC, DC, CMP_RC_RC, DC, DC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SUBFE -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_RT, CA_CA, Y, DC, DC, CMP_RC_RC, DC, DC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SUBFME -> List(U_ADD, DC, RA_RA, RB_CONST_M1, DC, ROUT_RT, CA_CA, Y, DC, DC, CMP_RC_RC, DC, DC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SUBFZE -> List(U_ADD, DC, RA_RA, RB_CONST_ZERO, DC, ROUT_RT, CA_CA, Y, DC, DC, CMP_RC_RC, DC, DC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
NEG -> List(U_ADD, DC, RA_RA, RB_CONST_ZERO, DC, ROUT_RT, CA_1, N, DC, DC, CMP_RC_RC, DC, DC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ANDI_DOT -> List(U_LOG, LOG_AND, DC, RB_CONST_UI, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_1, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ANDIS_DOT -> List(U_LOG, LOG_AND, DC, RB_CONST_UI_HI, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_1, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
AND -> List(U_LOG, LOG_AND, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ANDC -> List(U_LOG, LOG_AND, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
NAND -> List(U_LOG, LOG_AND, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ORI -> List(U_LOG, LOG_OR, DC, RB_CONST_UI, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ORIS -> List(U_LOG, LOG_OR, DC, RB_CONST_UI_HI, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
NOR -> List(U_LOG, LOG_OR, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
OR -> List(U_LOG, LOG_OR, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ORC -> List(U_LOG, LOG_OR, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
XORI -> List(U_LOG, LOG_XOR, DC, RB_CONST_UI, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
XORIS -> List(U_LOG, LOG_XOR, DC, RB_CONST_UI_HI, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
EQV -> List(U_LOG, LOG_XOR, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
XOR -> List(U_LOG, LOG_XOR, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
EXTSB -> List(U_LOG, LOG_EXTS, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, N, DC, DC, DC, LEN_1B, DC, DC, DC, DC, DC, DC, DC, DC),
EXTSH -> List(U_LOG, LOG_EXTS, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, N, DC, DC, DC, LEN_2B, DC, DC, DC, DC, DC, DC, DC, DC),
EXTSW -> List(U_LOG, LOG_EXTS, DC, RB_RB, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, DC, DC, N, N, DC, DC, DC, LEN_4B, DC, DC, DC, DC, DC, DC, DC, DC),
RLWIMI -> List(U_ROT, DC, RA_RA, RB_CONST_SH32, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, Y, N, DC, DC, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLWINM -> List(U_ROT, DC, RA_ZERO, RB_CONST_SH32, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, Y, N, DC, DC, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLWNM -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, Y, N, DC, DC, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLDIC -> List(U_ROT, DC, RA_ZERO, RB_CONST_SH, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLDICL -> List(U_ROT, DC, RA_ZERO, RB_CONST_SH, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLDICR -> List(U_ROT, DC, RA_ZERO, RB_CONST_SH, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLDIMI -> List(U_ROT, DC, RA_RA, RB_CONST_SH, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLDCL -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
RLDCR -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SLD -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, N, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SLW -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, Y, N, DC, DC, N, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SRAD -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, Y, DC, DC, CMP_RC_RC, N, Y, DC, DC, Y, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SRADI -> List(U_ROT, DC, RA_ZERO, RB_CONST_SH, RS_RS, ROUT_RA, DC, Y, DC, DC, CMP_RC_RC, N, Y, DC, DC, Y, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SRAW -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, Y, DC, DC, CMP_RC_RC, Y, Y, DC, DC, Y, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SRAWI -> List(U_ROT, DC, RA_ZERO, RB_CONST_SH32, RS_RS, ROUT_RA, DC, Y, DC, DC, CMP_RC_RC, Y, Y, DC, DC, Y, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SRD -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, N, N, DC, DC, Y, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
SRW -> List(U_ROT, DC, RA_ZERO, RB_RB, RS_RS, ROUT_RA, DC, N, DC, DC, CMP_RC_RC, Y, N, DC, DC, Y, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC),
LBZ -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_1B, N, N, N, DC, DC, DC, DC, DC),
LBZU -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_1B, N, Y, N, DC, DC, DC, DC, DC),
LHA -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, Y, DC, DC, DC, DC, DC, LEN_2B, N, N, N, DC, DC, DC, DC, DC),
LHAU -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, Y, N, DC, DC, DC, DC, LEN_2B, N, Y, N, DC, DC, DC, DC, DC),
LHZ -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, N, N, N, DC, DC, DC, DC, DC),
LHZU -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_2B, N, Y, N, DC, DC, DC, DC, DC),
LWA -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_DS, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, Y, DC, DC, DC, DC, DC, LEN_4B, N, N, N, DC, DC, DC, DC, DC),
LWZ -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, N, N, N, DC, DC, DC, DC, DC),
LWZU -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_SI, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_4B, N, Y, N, DC, DC, DC, DC, DC),
LD -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_DS, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, N, N, N, DC, DC, DC, DC, DC),
LDU -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_CONST_DS, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_8B, N, Y, N, DC, DC, DC, DC, DC),
LBARX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_1B, N, N, Y, DC, DC, DC, DC, DC),
LBZX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_1B, N, N, N, DC, DC, DC, DC, DC),
LBZUX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_1B, N, Y, N, DC, DC, DC, DC, DC),
LHARX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, N, N, Y, DC, DC, DC, DC, DC),
LHAX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, Y, DC, DC, DC, DC, DC, LEN_2B, N, N, N, DC, DC, DC, DC, DC),
LHAUX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, Y, N, DC, DC, DC, DC, LEN_2B, N, Y, N, DC, DC, DC, DC, DC),
LHBRX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, Y, N, N, DC, DC, DC, DC, DC),
LHZX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, N, N, N, DC, DC, DC, DC, DC),
LHZUX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_2B, N, Y, N, DC, DC, DC, DC, DC),
LWARX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, N, N, Y, DC, DC, DC, DC, DC),
LWAX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, Y, DC, DC, DC, DC, DC, LEN_4B, N, N, N, DC, DC, DC, DC, DC),
LWAUX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, Y, N, DC, DC, DC, DC, LEN_4B, N, Y, N, DC, DC, DC, DC, DC),
LWBRX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, Y, N, N, DC, DC, DC, DC, DC),
LWZX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, N, N, N, DC, DC, DC, DC, DC),
LWZUX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_4B, N, Y, N, DC, DC, DC, DC, DC),
LDARX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, N, N, Y, DC, DC, DC, DC, DC),
LDBRX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, Y, N, N, DC, DC, DC, DC, DC),
LDX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, N, N, N, DC, DC, DC, DC, DC),
LDUX -> List(U_LDST, LDST_LOAD, RA_RA_OR_ZERO, RB_RB, DC, ROUT_RT, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_8B, N, Y, N, DC, DC, DC, DC, DC),
STB -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_SI, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_1B, N, N, N, DC, DC, DC, DC, DC),
STBU -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_SI, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_1B, N, Y, N, DC, DC, DC, DC, DC),
STH -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_SI, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, N, N, N, DC, DC, DC, DC, DC),
STHU -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_SI, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_2B, N, Y, N, DC, DC, DC, DC, DC),
STW -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_SI, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, N, N, N, DC, DC, DC, DC, DC),
STWU -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_SI, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_4B, N, Y, N, DC, DC, DC, DC, DC),
STD -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_DS, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, N, N, N, DC, DC, DC, DC, DC),
STDU -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_CONST_DS, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_8B, N, Y, N, DC, DC, DC, DC, DC),
STBCX_DOT -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_1B, N, N, Y, DC, DC, DC, DC, DC),
STBX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_1B, N, N, N, DC, DC, DC, DC, DC),
STBUX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_1B, N, Y, N, DC, DC, DC, DC, DC),
STHBRX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, Y, N, N, DC, DC, DC, DC, DC),
STHCX_DOT -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, N, N, Y, DC, DC, DC, DC, DC),
STHX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_2B, N, N, N, DC, DC, DC, DC, DC),
STHUX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_2B, N, Y, N, DC, DC, DC, DC, DC),
STWBRX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, Y, N, N, DC, DC, DC, DC, DC),
STWCX_DOT -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, N, N, Y, DC, DC, DC, DC, DC),
STWX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_4B, N, N, N, DC, DC, DC, DC, DC),
STWUX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_4B, N, Y, N, DC, DC, DC, DC, DC),
STDBRX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, Y, N, N, DC, DC, DC, DC, DC),
STDCX_DOT -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, N, N, Y, DC, DC, DC, DC, DC),
STDX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, N, DC, DC, DC, DC, DC, LEN_8B, N, N, N, DC, DC, DC, DC, DC),
STDUX -> List(U_LDST, LDST_STORE, RA_RA_OR_ZERO, RB_RB, RS_RS, ROUT_NONE, CA_0, DC, DC, DC, CMP_RC_0, DC, N, N, DC, DC, DC, DC, LEN_8B, N, Y, N, DC, DC, DC, DC, DC),
MULLI -> List(U_MUL, DC, RA_RA, RB_CONST_SI, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC, DC),
MULHD -> List(U_MUL, DC, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC, DC),
MULHDU -> List(U_MUL, DC, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC, DC),
MULHW -> List(U_MUL, DC, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC, DC),
MULHWU -> List(U_MUL, DC, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC, DC),
MULLD -> List(U_MUL, DC, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC, DC),
MULLW -> List(U_MUL, DC, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC, DC),
DIVDEU -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC),
DIVWEU -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC),
DIVDE -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC),
DIVWE -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC, DC),
DIVDU -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
DIVWU -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
DIVD -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
DIVW -> List(U_DIV, DIV_DIV, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
MODUD -> List(U_DIV, DIV_MOD, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
MODUW -> List(U_DIV, DIV_MOD, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
MODSD -> List(U_DIV, DIV_MOD, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
MODSW -> List(U_DIV, DIV_MOD, RA_RA, RB_RB, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_RC, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC, DC),
SYNC -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ISYNC -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
DCBF -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
DCBST -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
DCBT -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
DCBTST -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ICBI -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
ICBT -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CNTLZD -> List(U_ZER, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC),
CNTLZW -> List(U_ZER, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, N, DC, DC),
CNTTZD -> List(U_ZER, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, N, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC),
CNTTZW -> List(U_ZER, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_RC, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, Y, DC, DC),
POPCNTB -> List(U_POP, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, LEN_1B, DC, DC, DC, DC, DC, DC, DC, DC),
POPCNTW -> List(U_POP, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, LEN_4B, DC, DC, DC, DC, DC, DC, DC, DC),
POPCNTD -> List(U_POP, DC, DC, DC, RS_RS, ROUT_RA, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, LEN_8B, DC, DC, DC, DC, DC, DC, DC, DC),
CMPDI -> List(U_ADD, DC, RA_RA, RB_CONST_SI, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPWI -> List(U_ADD, DC, RA_RA, RB_CONST_SI, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, Y, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPD -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, N, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPW -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, Y, Y, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPLDI -> List(U_ADD, DC, RA_RA, RB_CONST_UI, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, N, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPLWI -> List(U_ADD, DC, RA_RA, RB_CONST_UI, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, Y, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPLD -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, N, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
CMPLW -> List(U_ADD, DC, RA_RA, RB_RB, DC, ROUT_NONE, CA_1, DC, DC, Y, CMP_CMP, Y, N, Y, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
MFSPR -> List(U_SPR, SPR_MF, DC, DC, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
MTSPR -> List(U_SPR, SPR_MT, DC, DC, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC),
MFCR -> List(U_CR, CR_MF, DC, DC, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, FXM_FF, DC),
MFOCRF -> List(U_CR, CR_MF, DC, DC, DC, ROUT_RT, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, FXM_ONEHOT, DC),
MTCRF -> List(U_CR, CR_MT, DC, DC, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, FXM, DC),
MTOCRF -> List(U_CR, CR_MT, DC, DC, RS_RS, ROUT_NONE, DC, DC, DC, DC, CMP_RC_0, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, FXM_ONEHOT, DC),
B -> List(U_BR, BR_UNCOND, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, BR_TARGET_NONE),
BC -> List(U_BR, BR_COND, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, BR_TARGET_NONE),
BCLR -> List(U_BR, BR_COND, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, BR_TARGET_LR),
BCCTR -> List(U_BR, BR_COND, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, BR_TARGET_CTR),
TDI -> List(U_NONE, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC, DC)
)
}
class ControlSignals extends Bundle {
val unit = UInt(4.W)
val internalOp = UInt(2.W)
val rA = UInt(2.W)
val rB = UInt(4.W)
val rS = UInt(1.W)
val rOut = UInt(2.W)
val carryIn = UInt(2.W)
val carryOut = UInt(1.W)
val crIn = UInt(1.W)
val crOut = UInt(1.W)
val compare = UInt(2.W)
val is32bit = UInt(1.W)
val signed = UInt(1.W)
val invertIn = UInt(1.W)
val invertOut = UInt(1.W)
val rightShift = UInt(1.W)
val clearLeft = UInt(1.W)
val clearRight = UInt(1.W)
val length = UInt(2.W)
val byteReverse = UInt(1.W)
val update = UInt(1.W)
val reservation = UInt(1.W)
val high = UInt(1.W)
val extended = UInt(1.W)
val countRight = UInt(1.W)
val fxm = UInt(2.W)
val brTarget = UInt(2.W)
}
class Control(val n: Int) extends Module {
val io = IO(new Bundle {
val insn = Input(UInt(32.W))
val out = Output(new ControlSignals())
})
val ctrlSignals = ListLookup(io.insn, Control.default, Control.map)
io.out.unit := ctrlSignals(0)
io.out.internalOp := ctrlSignals(1)
io.out.rA := ctrlSignals(2)
io.out.rB := ctrlSignals(3)
io.out.rS := ctrlSignals(4)
io.out.rOut := ctrlSignals(5)
io.out.carryIn := ctrlSignals(6)
io.out.carryOut := ctrlSignals(7)
io.out.crIn := ctrlSignals(8)
io.out.crOut := ctrlSignals(9)
io.out.compare := ctrlSignals(10)
io.out.is32bit := ctrlSignals(11)
io.out.signed := ctrlSignals(12)
io.out.invertIn := ctrlSignals(13)
io.out.invertOut := ctrlSignals(14)
io.out.rightShift := ctrlSignals(15)
io.out.clearLeft := ctrlSignals(16)
io.out.clearRight := ctrlSignals(17)
io.out.length := ctrlSignals(18)
io.out.byteReverse := ctrlSignals(19)
io.out.update := ctrlSignals(20)
io.out.reservation := ctrlSignals(21)
io.out.high := ctrlSignals(22)
io.out.extended := ctrlSignals(23)
io.out.countRight := ctrlSignals(24)
io.out.fxm := ctrlSignals(25)
io.out.brTarget := ctrlSignals(26)
}
object ControlObj extends App {
chisel3.Driver.execute(Array[String](), () => new Control(64))
}

396
src/main/scala/Core.scala Normal file
View File

@@ -0,0 +1,396 @@
import chisel3._
import chisel3.util._
import Control._
import Helpers._
import InstructionHelpers._
class Core(bits: Int, memSize: Int, memFileName: String, resetAddr: Int) extends Module {
val io = IO(new Bundle {
val tx = Output(UInt(1.W))
val rx = Input(UInt(1.W))
val terminate = Output(Bool())
val ledB = Output(UInt(1.W))
val ledC = Output(UInt(1.W))
})
val memWords = memSize/(bits/8)
val nia = Module(new Nia(bits, resetAddr))
val fetch = Module(new Fetch(bits, memWords))
val adder = Module(new Adder(bits))
val logical = Module(new Logical(bits))
val rotator = Module(new Rotator(bits))
val populationCount = Module(new PopulationCount(bits))
val countZeroes = Module(new CountZeroes(bits))
val multiplier = Module(new SimpleMultiplier(bits))
val divider = Module(new SimpleDivider(bits))
val mem = Module(new MemoryBlackBoxWrapper(bits, memWords, memFileName))
val loadStore = Module(new LoadStore(bits, memWords))
val control = Module(new Control(bits))
val regFile = Module(new RegisterFile(32, bits, 3, 1, false))
val carry = RegInit(0.U(1.W))
val conditionRegister = RegInit(VecInit(Seq.fill(8)(0.U(4.W))))
val linkRegister = RegInit(0.U(bits.W))
val countRegister = RegInit(0.U(bits.W))
val illegal = WireDefault(false.B)
mem.io.loadStorePort <> loadStore.io.mem
mem.io.fetchPort <> fetch.io.mem
nia.io.redirect := false.B
nia.io.redirect_nia := 0.U
/* Blink an LED, this proves we are out of reset */
val led = RegInit(0.U(1.W))
val (counterValue, counterWrap) = Counter(true.B, 50000000)
when (counterWrap) {
led := ~led
}
io.ledB := led
io.ledC := 1.U
io.tx := loadStore.io.tx
loadStore.io.rx := io.rx
fetch.io.nia := nia.io.nia.bits
val decodeInsn = RegNext(fetch.io.insn)
val decodeNia = RegNext(nia.io.nia.bits)
val decodeValid = RegNext(nia.io.nia.valid)
// Decode
control.io.insn := decodeInsn
regFile.io.rd(0).addr := insn_ra(decodeInsn)
regFile.io.rd(1).addr := insn_rb(decodeInsn)
regFile.io.rd(2).addr := insn_rs(decodeInsn)
val decodeRa = MuxCase(regFile.io.rd(0).data, Seq(
(control.io.out.rA === RA_ZERO) -> 0.U(bits.W),
((control.io.out.rA === RA_RA_OR_ZERO) && (insn_ra(decodeInsn) === 0.U)) -> 0.U(bits.W)
))
val decodeRb = MuxLookup(control.io.out.rB, regFile.io.rd(1).data, Array(
RB_CONST_UI -> insn_ui(decodeInsn),
RB_CONST_SI -> insn_si(decodeInsn).signExtend(16, bits),
RB_CONST_UI_HI -> insn_ui(decodeInsn) ## 0.U(16.W),
RB_CONST_SI_HI -> (insn_si(decodeInsn) ## 0.U(16.W)).signExtend(32, bits),
RB_CONST_DS -> (insn_ds(decodeInsn) ## 0.U(2.W)).signExtend(16, bits),
RB_CONST_M1 -> Fill(bits, 1.U),
RB_CONST_ZERO -> 0.U(bits.W),
RB_CONST_SH -> insn_sh(decodeInsn),
RB_CONST_SH32 -> insn_sh32(decodeInsn)
))
val decodeRs = regFile.io.rd(2).data
val decodeCarry = MuxLookup(control.io.out.carryIn, carry, Array(
CA_0 -> 0.U,
CA_1 -> 1.U
))
val ctrl = RegNext(control.io.out)
val executeInsn = RegNext(decodeInsn)
val executeRa = RegNext(decodeRa)
val executeRb = RegNext(decodeRb)
val executeRs = RegNext(decodeRs)
val executeCarry = RegNext(decodeCarry)
val executeValid = RegNext(decodeValid)
val executeNia = RegNext(decodeNia)
// Execute
val executeFastOp = MuxLookup(ctrl.unit, true.B, Array(
U_MUL -> false.B,
U_DIV -> false.B,
U_LDST -> false.B
))
adder.io.a := executeRa
adder.io.b := executeRb
adder.io.carryIn := executeCarry
adder.io.invertIn := ctrl.invertIn
adder.io.is32bit := ctrl.is32bit
adder.io.signed := ctrl.signed
logical.io.a := executeRs
logical.io.b := executeRb
logical.io.internalOp := ctrl.internalOp
logical.io.invertIn := ctrl.invertIn
logical.io.invertOut := ctrl.invertOut
logical.io.length := ctrl.length
rotator.io.ra := executeRa
rotator.io.shift := executeRb
rotator.io.rs := executeRs
rotator.io.is32bit := ctrl.is32bit
rotator.io.signed := ctrl.signed
rotator.io.rightShift := ctrl.rightShift
rotator.io.clearLeft := ctrl.clearLeft
rotator.io.clearRight := ctrl.clearRight
rotator.io.insn := executeInsn
populationCount.io.a := executeRs
populationCount.io.length := ctrl.length
countZeroes.io.a := executeRs
countZeroes.io.countRight := ctrl.countRight
countZeroes.io.is32bit := ctrl.is32bit
multiplier.io.in.bits.a := executeRa
multiplier.io.in.bits.b := executeRb
multiplier.io.in.bits.is32bit := ctrl.is32bit
multiplier.io.in.bits.signed := ctrl.signed
multiplier.io.in.bits.high := ctrl.high
multiplier.io.in.valid := false.B
when (executeValid && (ctrl.unit === U_MUL)) {
multiplier.io.in.valid := true.B
}
divider.io.in.bits.dividend := executeRa
divider.io.in.bits.divisor := executeRb
divider.io.in.bits.is32bit := ctrl.is32bit
divider.io.in.bits.signed := ctrl.signed
divider.io.in.bits.extended := ctrl.extended
divider.io.in.bits.modulus := 0.U // fixme
divider.io.in.valid := false.B
when (executeValid && (ctrl.unit === U_DIV)) {
divider.io.in.valid := true.B
}
loadStore.io.in.bits.a := executeRa
loadStore.io.in.bits.b := executeRb
loadStore.io.in.bits.data := executeRs
loadStore.io.in.bits.internalOp := ctrl.internalOp
loadStore.io.in.bits.length := ctrl.length
loadStore.io.in.bits.signed := ctrl.signed
loadStore.io.in.bits.byteReverse := ctrl.byteReverse
loadStore.io.in.bits.update := ctrl.update
loadStore.io.in.bits.reservation := ctrl.reservation
loadStore.io.in.valid := false.B
when (executeValid && (ctrl.unit === U_LDST)) {
loadStore.io.in.valid := true.B
}
val xerRegisterNum = 1
val linkRegisterNum = 8
val CountRegisterNum = 9
val sprOut = RegInit(0.U(bits.W))
when (executeValid && (ctrl.unit === U_SPR)) {
when (ctrl.internalOp === SPR_MF) {
when (insn_spr(executeInsn) === linkRegisterNum.asUInt) {
sprOut := linkRegister
} .elsewhen (insn_spr(executeInsn) === CountRegisterNum.asUInt) {
sprOut := countRegister
} .elsewhen (insn_spr(executeInsn) === xerRegisterNum.asUInt) {
sprOut := carry << 29
} .otherwise {
illegal := true.B
}
} .elsewhen (ctrl.internalOp === SPR_MT) {
when (insn_spr(executeInsn) === linkRegisterNum.asUInt) {
linkRegister := executeRs
} .elsewhen (insn_spr(executeInsn) === CountRegisterNum.asUInt) {
countRegister := executeRs
} .elsewhen (insn_spr(executeInsn) === xerRegisterNum.asUInt) {
carry := executeRs(29)
} .otherwise {
illegal := true.B
}
}
}
val crOut = RegInit(0.U(bits.W))
when (executeValid && (ctrl.unit === U_CR)) {
val fxm = WireDefault(UInt(8.W), 0.U)
when (ctrl.fxm === FXM_FF) {
fxm := "hFF".U
} .elsewhen (ctrl.fxm === FXM) {
fxm := insn_fxm(executeInsn)
} .elsewhen (ctrl.fxm === FXM_ONEHOT) {
val f = insn_fxm_onehot(executeInsn)
fxm := Mux(f === 0.U, "h80".U, f)
}
when (ctrl.internalOp === CR_MF) {
crOut := fxm.asBools.zip(conditionRegister).map({ case (f, c) =>
Mux(f, c, 0.U)
}).reduce(_ ## _)
} .elsewhen (ctrl.internalOp === CR_MT) {
conditionRegister := fxm.asBools.zip(conditionRegister).zip(executeRs(31, 0).nibbles().reverse).map({ case ((fxm, cr), reg) =>
Mux(fxm, reg, cr)
})
}
}
when (executeValid && (ctrl.unit === U_BR)) {
val branchTaken = WireDefault(Bool(), false.B)
val target = MuxCase((insn_bd(executeInsn) ## 0.U(2.W)).signExtend(16, bits) + executeNia, Seq(
(ctrl.internalOp === BR_UNCOND) -> ((insn_li(executeInsn) ## 0.U(2.W)).signExtend(26, bits) + executeNia),
(ctrl.brTarget === BR_TARGET_CTR) -> countRegister,
(ctrl.brTarget === BR_TARGET_LR) -> linkRegister,
))
nia.io.redirect_nia := target
when (ctrl.internalOp === BR_UNCOND) {
branchTaken := true.B
} .otherwise {
val bo = insn_bo(executeInsn)
val bi = insn_bi(executeInsn)
val cnt = WireDefault(countRegister)
val counterIsTarget = (ctrl.brTarget === BR_TARGET_CTR)
when ((counterIsTarget === 0.U) && (bo(4-2) === 0.U)) {
cnt := countRegister - 1.U
countRegister := cnt
}
val crBit = (conditionRegister.reduce(_ ## _))(31.U-bi)
val crBitMatch = (crBit === bo(4-1))
val ctrOk = (bo(4-2).asBool || (cnt.orR ^ bo(4-3)).asBool)
val condOk = bo(4-0).asBool || crBitMatch
when ((counterIsTarget || ctrOk) && condOk) {
branchTaken := true.B
}
}
when (branchTaken) {
nia.io.redirect := true.B
when (insn_lr(executeInsn).asBool) {
linkRegister := executeNia + 4.U
}
}
}
val adderOut = RegNext(adder.io.out)
val adderCarryOut = RegNext(adder.io.carryOut)
val adderLtOut = RegNext(adder.io.ltOut.asBool)
val logicalOut = RegNext(logical.io.out)
val rotatorOut = RegNext(rotator.io.out)
val rotatorCarryOut = RegNext(rotator.io.carryOut)
val populationCountOut = RegNext(populationCount.io.out)
val countZeroesOut = RegNext(countZeroes.io.out)
when (executeValid && (ctrl.unit === U_ILL)) {
illegal := true.B
}
io.terminate := false.B
when (illegal) {
printf("ILLEGAL (%x) at %x\n", executeInsn, executeNia)
io.terminate := true.B
/* Send it into an infinite loop */
nia.io.redirect := true.B
nia.io.redirect_nia := executeNia
}
/* Handle load and store with update instructions */
val writebackLoadStoreAddr = RegNext(insn_ra(executeInsn))
val writebackLoadStore = RegInit(false.B)
writebackLoadStore := false.B
when (executeValid && (ctrl.unit === U_LDST) && ctrl.update.asBool) {
writebackLoadStore := true.B
}
val writebackFastValid = RegNext(executeValid && executeFastOp)
val writebackFastCarryValid = RegNext(ctrl.carryOut.asBool)
// We need to gate these with executeValid because slow units need it
val writebackUnit = RegInit(U_NONE)
val writebackRValid = RegInit(false.B)
val writebackAddr = RegInit(0.U)
val writebackRc = RegInit(false.B)
when (executeValid) {
writebackUnit := ctrl.unit
writebackRValid := ctrl.rOut =/= ROUT_NONE
writebackAddr := Mux(ctrl.rOut === ROUT_RA, insn_ra(executeInsn), insn_rt(executeInsn))
writebackRc := (ctrl.compare === CMP_RC_1) || ((ctrl.compare === CMP_RC_RC) && insn_rc(executeInsn).asBool)
}
val writebackCmp = RegNext(ctrl.compare === CMP_CMP)
val writebackCrField = RegNext(insn_bf(executeInsn))
// Compare instructions need to know if a comparison is 32 bit
val writebackIs32bit = RegNext(ctrl.is32bit.asBool)
// Writeback
val wrData = MuxLookup(writebackUnit, adderOut, Array(
U_LOG -> logicalOut,
U_ROT -> rotatorOut,
U_POP -> populationCountOut,
U_ZER -> countZeroesOut,
U_SPR -> sprOut,
U_CR -> crOut,
U_MUL -> multiplier.io.out.bits,
U_DIV -> divider.io.out.bits,
U_LDST -> loadStore.io.out.bits))
when (writebackLoadStore) {
regFile.io.wr(0).bits.addr := writebackLoadStoreAddr
regFile.io.wr(0).bits.data := adderOut
regFile.io.wr(0).fire() := true.B
}. otherwise {
regFile.io.wr(0).bits.addr := writebackAddr
regFile.io.wr(0).bits.data := wrData
when (multiplier.io.out.valid || divider.io.out.valid || (loadStore.io.out.valid && writebackRValid)) {
regFile.io.wr(0).fire() := true.B
} .otherwise {
regFile.io.wr(0).fire() := writebackFastValid && writebackRValid
}
}
when (writebackFastValid && writebackFastCarryValid) {
carry := MuxLookup(writebackUnit, adderCarryOut, Array(
U_ROT -> rotatorCarryOut
))
}
private def cmp(res: UInt, lt: Bool, is32bit: Bool): UInt = {
val isZero = Mux(is32bit, res(31, 0) === 0.U, res === 0.U)
val crLt = "b1000".U
val crGt = "b0100".U
val crZero = "b0010".U
MuxCase(crGt, Seq(
isZero -> crZero,
lt -> crLt
))
}
when (writebackRc && (writebackFastValid || multiplier.io.out.valid || divider.io.out.valid)) {
conditionRegister(0) := cmp(wrData, wrData(bits-1).asBool, false.B)
} .elsewhen (writebackFastValid && writebackCmp) {
conditionRegister(writebackCrField) :=
cmp(wrData, adderLtOut, writebackIs32bit)
}
val completed = RegNext(writebackFastValid || multiplier.io.out.valid || loadStore.io.out.valid || divider.io.out.valid)
val sFirst :: sSecond :: sThird :: Nil = Enum(3)
val initState = RegInit(sFirst)
switch (initState) {
is (sFirst) {
initState := sSecond
}
is (sSecond) {
initState := sThird
}
}
// One instruction in the entire pipeline at a time
nia.io.nia.ready := completed || (initState === sSecond)
}
object CoreObj extends App {
chisel3.Driver.execute(Array[String](), () => new Core(64, 384*1024, "insns.hex", 0x0))
}

View File

@@ -0,0 +1,94 @@
import chisel3._
import chisel3.util.{log2Ceil, MuxCase, Reverse}
/** Module for counting leading zeroes in a [[UInt]]
* @param n the width of the [[UInt]]
*/
class CountZeroes(bits: Int) extends Module {
val io = IO(new Bundle {
val a = Input(UInt(bits.W))
val countRight = Input(Bool())
val is32bit = Input(Bool())
val out = Output(UInt(log2Ceil(bits+1).W))
})
/** Count leading zeroes in a pair of bits:
* 00 -> 2
* 01 -> 1
* else -> 0
*/
private def clzTwoBit(a: UInt): UInt = MuxCase(0.U, Seq((a === 0.U) -> 2.U, (a === 1.U) -> 1.U))
/** Reduction step. We take two numbers that contain the number of
* leading zero bits in each limb and reduce that to a single number
* representing the total number of leading zero bits. The result
* is one bit larger.
*
* eg for n = 4:
* 1aaa 1zzz -> 10000 (No '1' bits in either)
* 01ab zzzz -> 001ab (A '1' in the upper region)
* 1aaa zyxw -> 01zyx (A '1' in the lower region)
*/
private def clzReduce(hi: UInt, lo: UInt, n: Int): UInt = {
val x = Wire(UInt((n+1).W))
when (hi(n-1) === 0.U) { x := (hi(n-1) & lo(n-1)) ## 0.U(1.W) ## hi(n-2, 0) }
.otherwise { x := (hi(n-1) & lo(n-1)) ## ~lo(n-1) ## lo(n-2, 0) }
x
}
/** Recursively calculate the number of leading zeroes */
private def sumZeroes(n: Int, offset: Int): UInt = n match {
case 1 => clzTwoBit(a(offset*2+1, offset*2))
case _ => clzReduce(sumZeroes(n-1, offset*2+1), sumZeroes(n-1, offset*2), n)
}
val reversed = Mux(io.countRight, Reverse(io.a), io.a)
val a = WireDefault(UInt((bits).W), reversed)
when (io.is32bit) {
when (!io.countRight) {
a := reversed(31, 0) ## reversed(31, 0) | ((1L << 31).U)
}.otherwise {
a := reversed | ((1L << 31).U)
}
}
io.out := sumZeroes(log2Ceil(bits), 0)
}
object CountZeroesObj extends App {
chisel3.Driver.execute(Array[String](), () => new CountZeroes(64))
}
/** Utilities for counting zeroes */
object CountLeadingZeroes {
/** Return a [[UInt]] containing the number of leading zeroes in some [[Data]]
* @param a a hardware type
* @tparam A some data
*/
def apply[A <: Data](a: A): UInt = {
val count = Module(new CountZeroes(a.getWidth))
count.io.a := a.asUInt
count.io.countRight := false.B
count.io.is32bit := false.B
count.io.out
}
}
object CountTrailingZeroes {
/** Return a [[UInt]] containing the number of leading zeroes in some [[Data]]
* @param a a hardware type
* @tparam A some data
*/
def apply[A <: Data](a: A): UInt = {
val count = Module(new CountZeroes(a.getWidth))
count.io.a := a.asUInt
count.io.countRight := true.B
count.io.is32bit := false.B
count.io.out
}
}

View File

@@ -0,0 +1,30 @@
import chisel3._
import chisel3.util.log2Ceil
class Fetch(val bits: Int, val words: Int) extends Module {
val io = IO(new Bundle {
val nia = Input(UInt(bits.W))
val insn = Output(UInt(32.W))
val mem = new MemoryPort(bits, words, false)
})
io.mem.readEnable := true.B
io.mem.addr := io.nia >> log2Ceil(bits/8)
/* Issues with conditional entries in ports */
io.mem.writeEnable := false.B
io.mem.writeMask := 0.U
io.mem.writeData := 0.U
val niaNext = RegNext(io.nia)
if (bits == 64) {
when (niaNext(2).asBool) {
io.insn := io.mem.readData(63, 32)
} .otherwise {
io.insn := io.mem.readData(31, 0)
}
} else {
io.insn := io.mem.readData(31, 0)
}
}

View File

@@ -0,0 +1,53 @@
import chisel3._
import chisel3.util.MuxLookup
import Control._
object Helpers {
implicit class BitsHelpers(a: Bits) {
def nibbles(): Vec[UInt] = {
require(a.isWidthKnown, "Conversion to 'nibbles' requires width to be known!")
a.asTypeOf(Vec(a.getWidth/4, UInt(4.W)))
}
def nibbles(n: Int): UInt = a((n + 1) * 4 - 1, n * 4)
def bytes(): Vec[UInt] = {
require(a.isWidthKnown, "Conversion to 'bytes' requires width to be known!")
a.asTypeOf(Vec(a.getWidth/8, UInt(8.W)))
}
def bytes(n: Int): UInt = a((n + 1) * 8 - 1, n * 8)
def halfwords(): Vec[UInt] = {
require(a.isWidthKnown, "Conversion to 'halfwords' requires width to be known!")
a.asTypeOf(Vec(a.getWidth/16, UInt(16.W)))
}
def halfwords(n: Int): UInt = a((n + 1) * 16 - 1, n * 16)
def words(): Vec[UInt] = {
require(a.isWidthKnown, "Conversion to 'words' requires width to be known!")
a.asTypeOf(Vec(a.getWidth/32, UInt(32.W)))
}
def words(n: Int): UInt = a((n + 1) * 32 - 1, n * 32)
}
implicit class signExtend(a: Bits) {
def signExtend(from: Int, to: Int): UInt = a(from-1, 0).asSInt.pad(to).asUInt
def signExtend(from: UInt): UInt = {
val lookupTable = Seq(LEN_1B, LEN_2B, LEN_4B).zip(Seq(8, 16, 32).map(frm => a(frm-1, 0).asSInt.pad(a.getWidth).asUInt))
MuxLookup(from, lookupTable.head._2, lookupTable)
}
}
implicit class zeroExtend(a: Bits) {
def zeroExtend(from: Int, to: Int): UInt = a(from-1, 0).pad(to)
def zeroExtend(from: UInt): UInt = {
val lookupTable = Seq(LEN_1B, LEN_2B, LEN_4B, LEN_8B).zip(Seq(8, 16, 32, 64).map(frm => a(frm-1, 0).pad(a.getWidth)))
MuxLookup(from, lookupTable.head._2, lookupTable)
}
}
}

View File

@@ -0,0 +1,41 @@
import chisel3._
import chisel3.util.{PriorityEncoderOH, Reverse}
object InstructionHelpers {
def insn_rs(insn: UInt) = insn(25, 21)
def insn_rt(insn: UInt) = insn(25, 21)
def insn_ra(insn: UInt) = insn(20, 16)
def insn_rb(insn: UInt) = insn(15, 11)
def insn_si(insn: UInt) = insn(15, 0)
def insn_ui(insn: UInt) = insn(15, 0)
def insn_l(insn: UInt) = insn(21)
def insn_sh32(insn: UInt) = insn(15, 11)
def insn_mb32(insn: UInt) = insn(10, 6)
def insn_me32(insn: UInt) = insn(5, 1)
def insn_li(insn: UInt) = insn(25, 2)
def insn_lk(insn: UInt) = insn(0)
def insn_aa(insn: UInt) = insn(1)
def insn_rc(insn: UInt) = insn(0)
def insn_bd(insn: UInt) = insn(15, 2)
def insn_bf(insn: UInt) = insn(25, 23)
def insn_bfa(insn: UInt) = insn(20, 18)
/* These are BE bit fields */
def insn_fxm(insn: UInt) = Reverse(insn(19, 12))
def insn_fxm_onehot(insn: UInt) = PriorityEncoderOH(Reverse(insn(19, 12)))
def insn_bo(insn: UInt) = insn(25, 21)
def insn_bi(insn: UInt) = insn(20, 16)
def insn_bh(insn: UInt) = insn(12, 11)
def insn_d(insn: UInt) = insn(15, 0)
def insn_ds(insn: UInt) = insn(15, 2)
def insn_to(insn: UInt) = insn(25, 21)
def insn_bc(insn: UInt) = insn(10, 6)
def insn_sh(insn: UInt) = insn(1) ## insn(15, 11)
def insn_me(insn: UInt) = insn(5) ## insn(10, 6)
def insn_mb(insn: UInt) = insn(5) ## insn(10, 6)
def insn_spr(insn: UInt) = insn(15, 11) ## insn(20, 16)
def insn_lr(insn: UInt) = insn(0)
def insn_bt(insn: UInt) = insn(25, 21)
def insn_ba(insn: UInt) = insn(20, 16)
def insn_bb(insn: UInt) = insn(15, 11)
}

View File

@@ -0,0 +1,238 @@
import chisel3.util.BitPat
object Instructions {
// Add/subtract
def ADD = BitPat("b011111???????????????0100001010?")
def ADDC = BitPat("b011111???????????????0000001010?")
def ADDE = BitPat("b011111???????????????0010001010?")
def ADDI = BitPat("b001110??????????????????????????")
def ADDIC = BitPat("b001100??????????????????????????")
def ADDIC_DOT = BitPat("b001101??????????????????????????")
def ADDIS = BitPat("b001111??????????????????????????")
def ADDME = BitPat("b011111???????????????0011101010?")
def ADDZE = BitPat("b011111???????????????0011001010?")
def SUBF = BitPat("b011111???????????????0000101000?")
def SUBFC = BitPat("b011111???????????????0000001000?")
def SUBFE = BitPat("b011111???????????????0010001000?")
def SUBFIC = BitPat("b001000??????????????????????????")
def SUBFME = BitPat("b011111???????????????0011101000?")
def SUBFZE = BitPat("b011111???????????????0011001000?")
def NEG = BitPat("b011111???????????????0001101000?")
// Logical
def AND = BitPat("b011111???????????????0000011100?")
def ANDC = BitPat("b011111???????????????0000111100?")
def ANDI_DOT = BitPat("b011100??????????????????????????")
def ANDIS_DOT = BitPat("b011101??????????????????????????")
def EQV = BitPat("b011111???????????????0100011100?")
def NAND = BitPat("b011111???????????????0111011100?")
def NOR = BitPat("b011111???????????????0001111100?")
def OR = BitPat("b011111???????????????0110111100?")
def ORC = BitPat("b011111???????????????0110011100?")
def ORI = BitPat("b011000??????????????????????????")
def ORIS = BitPat("b011001??????????????????????????")
def XOR = BitPat("b011111???????????????0100111100?")
def XORI = BitPat("b011010??????????????????????????")
def XORIS = BitPat("b011011??????????????????????????")
def EXTSB = BitPat("b011111???????????????1110111010?")
def EXTSH = BitPat("b011111???????????????1110011010?")
def EXTSW = BitPat("b011111???????????????1111011010?")
// Rotate/shift
def RLDCL = BitPat("b011110?????????????????????1000?")
def RLDCR = BitPat("b011110?????????????????????1001?")
def RLDIC = BitPat("b011110?????????????????????010??")
def RLDICL = BitPat("b011110?????????????????????000??")
def RLDICR = BitPat("b011110?????????????????????001??")
def RLDIMI = BitPat("b011110?????????????????????011??")
def RLWIMI = BitPat("b010100??????????????????????????")
def RLWINM = BitPat("b010101??????????????????????????")
def RLWNM = BitPat("b010111??????????????????????????")
def SLD = BitPat("b011111???????????????0000011011?")
def SLW = BitPat("b011111???????????????0000011000?")
def SRAD = BitPat("b011111???????????????1100011010?")
def SRADI = BitPat("b011111???????????????110011101??")
def SRAW = BitPat("b011111???????????????1100011000?")
def SRAWI = BitPat("b011111???????????????1100111000?")
def SRD = BitPat("b011111???????????????1000011011?")
def SRW = BitPat("b011111???????????????1000011000?")
// Multiply
def MULHD = BitPat("b011111????????????????001001001?")
def MULHDU = BitPat("b011111????????????????000001001?")
def MULHW = BitPat("b011111????????????????001001011?")
def MULHWU = BitPat("b011111????????????????000001011?")
def MULLD = BitPat("b011111???????????????0011101001?")
def MULLI = BitPat("b000111??????????????????????????")
def MULLW = BitPat("b011111???????????????0011101011?")
// Divide
def DIVD = BitPat("b011111???????????????0111101001?")
def DIVDE = BitPat("b011111???????????????0110101001?")
def DIVDEU = BitPat("b011111???????????????0110001001?")
def DIVDU = BitPat("b011111???????????????0111001001?")
def DIVW = BitPat("b011111???????????????0111101011?")
def DIVWE = BitPat("b011111???????????????0110101011?")
def DIVWEU = BitPat("b011111???????????????0110001011?")
def DIVWU = BitPat("b011111???????????????0111001011?")
def MODSD = BitPat("b011111???????????????1100001001?")
def MODSW = BitPat("b011111???????????????1100001011?")
def MODUD = BitPat("b011111???????????????0100001001?")
def MODUW = BitPat("b011111???????????????0100001011?")
// Load/store
def LBARX = BitPat("b011111???????????????0000110100?")
def LBZ = BitPat("b100010??????????????????????????")
def LBZCIX = BitPat("b011111???????????????1101010101?")
def LBZU = BitPat("b100011??????????????????????????")
def LBZUX = BitPat("b011111???????????????0001110111?")
def LBZX = BitPat("b011111???????????????0001010111?")
def LD = BitPat("b111010????????????????????????00")
def LDARX = BitPat("b011111???????????????0001010100?")
def LDBRX = BitPat("b011111???????????????1000010100?")
def LDCIX = BitPat("b011111???????????????1101110101?")
def LDU = BitPat("b111010????????????????????????01")
def LDUX = BitPat("b011111???????????????0000110101?")
def LDX = BitPat("b011111???????????????0000010101?")
def LHA = BitPat("b101010??????????????????????????")
def LHARX = BitPat("b011111???????????????0001110100?")
def LHAU = BitPat("b101011??????????????????????????")
def LHAUX = BitPat("b011111???????????????0101110111?")
def LHAX = BitPat("b011111???????????????0101010111?")
def LHBRX = BitPat("b011111???????????????1100010110?")
def LHZ = BitPat("b101000??????????????????????????")
def LHZCIX = BitPat("b011111???????????????1100110101?")
def LHZU = BitPat("b101001??????????????????????????")
def LHZUX = BitPat("b011111???????????????0100110111?")
def LHZX = BitPat("b011111???????????????0100010111?")
def LWA = BitPat("b111010????????????????????????10")
def LWARX = BitPat("b011111???????????????0000010100?")
def LWAUX = BitPat("b011111???????????????0101110101?")
def LWAX = BitPat("b011111???????????????0101010101?")
def LWBRX = BitPat("b011111???????????????1000010110?")
def LWZ = BitPat("b100000??????????????????????????")
def LWZCIX = BitPat("b011111???????????????1100010101?")
def LWZU = BitPat("b100001??????????????????????????")
def LWZUX = BitPat("b011111???????????????0000110111?")
def LWZX = BitPat("b011111???????????????0000010111?")
def STB = BitPat("b100110??????????????????????????")
def STBCIX = BitPat("b011111???????????????1111010101?")
def STBCX_DOT = BitPat("b011111???????????????10101101101")
def STBU = BitPat("b100111??????????????????????????")
def STBUX = BitPat("b011111???????????????0011110111?")
def STBX = BitPat("b011111???????????????0011010111?")
def STD = BitPat("b111110????????????????????????00")
def STDBRX = BitPat("b011111???????????????1010010100?")
def STDCIX = BitPat("b011111???????????????1111110101?")
def STDCX_DOT = BitPat("b011111???????????????00110101101")
def STDU = BitPat("b111110????????????????????????01")
def STDUX = BitPat("b011111???????????????0010110101?")
def STDX = BitPat("b011111???????????????0010010101?")
def STH = BitPat("b101100??????????????????????????")
def STHBRX = BitPat("b011111???????????????1110010110?")
def STHCIX = BitPat("b011111???????????????1110110101?")
def STHCX_DOT = BitPat("b011111???????????????10110101101")
def STHU = BitPat("b101101??????????????????????????")
def STHUX = BitPat("b011111???????????????0110110111?")
def STHX = BitPat("b011111???????????????0110010111?")
def STW = BitPat("b100100??????????????????????????")
def STWBRX = BitPat("b011111???????????????1010010110?")
def STWCIX = BitPat("b011111???????????????1110010101?")
def STWCX_DOT = BitPat("b011111???????????????00100101101")
def STWU = BitPat("b100101??????????????????????????")
def STWUX = BitPat("b011111???????????????0010110111?")
def STWX = BitPat("b011111???????????????0010010111?")
// Branch and trap
def B = BitPat("b010010????????????????????????0?")
def BC = BitPat("b010000????????????????????????0?")
def BCCTR = BitPat("b010011???????????????1000010000?")
def BCLR = BitPat("b010011???????????????0000010000?")
// Compare
def CMPD = BitPat("b011111????1??????????0000000000?")
def CMPW = BitPat("b011111????0??????????0000000000?")
def CMPDI = BitPat("b001011????1?????????????????????")
def CMPWI = BitPat("b001011????0?????????????????????")
def CMPLD = BitPat("b011111????1??????????0000100000?")
def CMPLW = BitPat("b011111????0??????????0000100000?")
def CMPLDI = BitPat("b001010????1?????????????????????")
def CMPLWI = BitPat("b001010????0?????????????????????")
// CR
def MFCR = BitPat("b011111?????0?????????0000010011?")
def MFOCRF = BitPat("b011111?????1?????????0000010011?")
def MTCRF = BitPat("b011111?????0?????????0010010000?")
def MTOCRF = BitPat("b011111?????1?????????0010010000?")
// SPR read/write
def MFSPR = BitPat("b011111???????????????0101010011?")
def MTSPR = BitPat("b011111???????????????0111010011?")
// Cache control
def DCBF = BitPat("b011111???????????????0001010110?")
def DCBST = BitPat("b011111???????????????0000110110?")
def DCBT = BitPat("b011111???????????????0100010110?")
def DCBTST = BitPat("b011111???????????????0011110110?")
def ICBI = BitPat("b011111???????????????1111010110?")
def ICBT = BitPat("b011111???????????????0000010110?")
def ISYNC = BitPat("b010011???????????????0010010110?")
def SYNC = BitPat("b011111???????????????1001010110?")
// Population count
def POPCNTB = BitPat("b011111???????????????0001111010?")
def POPCNTD = BitPat("b011111???????????????0111111010?")
def POPCNTW = BitPat("b011111???????????????0101111010?")
// Count zeroes
def CNTLZD = BitPat("b011111???????????????0000111010?")
def CNTLZW = BitPat("b011111???????????????0000011010?")
def CNTTZD = BitPat("b011111???????????????1000111010?")
def CNTTZW = BitPat("b011111???????????????1000011010?")
// Not currently implemented
// CR logical
//def CRAND = BitPat("b010011???????????????0100000001?")
//def CRANDC = BitPat("b010011???????????????0010000001?")
//def CREQV = BitPat("b010011???????????????0100100001?")
//def CRNAND = BitPat("b010011???????????????0011100001?")
//def CRNOR = BitPat("b010011???????????????0000100001?")
//def CROR = BitPat("b010011???????????????0111000001?")
//def CRORC = BitPat("b010011???????????????0110100001?")
//def CRXOR = BitPat("b010011???????????????0011000001?")
// This is treated as a NOP for now to allow the endian switch code to work
def TDI = BitPat("b000010??????????????????????????")
//def TD = BitPat("b011111???????????????0001000100?")
//def TW = BitPat("b011111???????????????0000000100?")
//def TWI = BitPat("b000011??????????????????????????")
//def BA = BitPat("b010010????????????????????????1?")
//def BCA = BitPat("b010000????????????????????????1?")
//def BCTAR = BitPat("b010011???????????????1000110000?") // 2.07
//def DCBZ = BitPat("b011111???????????????1111110110?")
//def MCRF = BitPat("b010011???????????????0000000000?")
//def ISEL = BitPat("b011111????????????????????01111?") // 2.03
//def PRTYD = BitPat("b011111???????????????0010111010?") // 2.05
//def PRTYW = BitPat("b011111???????????????0010011010?") // 2.05
//def CMPB = BitPat("b011111???????????????0111111100?") // 2.05
// v3.0 Instructions
//def MADDHD = BitPat("b000100????????????????????110000") // 3.0
//def MADDHDU = BitPat("b000100????????????????????110001") // 3.0
//def MADDLD = BitPat("b000100????????????????????110011") // 3.0
//def ADDEX = BitPat("b011111?????????????????10101010?") // 3.0
//def BPERM = BitPat("b011111???????????????0011111100?") // 3.0
//def SETB = BitPat("b011111???????????????0010000000?") // 3.0
//def CMPEQB = BitPat("b011111???????????????0011100000?") // 3.0
//def CMPRB = BitPat("b011111???????????????0011000000?") // 3.0
//def ADDPCIS = BitPat("b010011????????????????????00010?") // 3.0
//def DARN = BitPat("b011111???????????????1011110011?") // 3.0
//def MCRXRX = BitPat("b011111???????????????1001000000?") // 3.0
//def EXTSWSLI = BitPat("b011111???????????????110111101??") // 3.0
}

View File

@@ -0,0 +1,205 @@
import chisel3._
import chisel3.util._
import Control._
import Helpers._
import LoadStoreByteReverse._
class LoadStoreInput(val bits: Int) extends Bundle {
val a = Input(UInt(bits.W))
val b = Input(UInt(bits.W))
val data = Input(UInt(bits.W))
val internalOp = Input(UInt(1.W))
val length = Input(UInt(2.W))
val signed = Input(UInt(1.W))
val byteReverse = Input(UInt(1.W))
val update = Input(UInt(1.W))
val reservation = Input(UInt(1.W))
}
/*
* Simple non pipelined load/store unit
*
* if load:
* 1C: a+b,
* 2C: load data
* 3C: de align, byte swap or sign extend data
*
* if store:
* 1C: a+b
* byte swap or sign extend, align data
* 2C: form store mask, store data
*/
class LoadStore(val bits: Int, val words: Int) extends Module {
val io = IO(new Bundle {
val in = Flipped(Valid(new LoadStoreInput(bits)))
val out = Output(Valid(UInt(bits.W)))
val mem = new MemoryPort(bits, words, true)
val tx = Output(UInt(1.W))
val rx = Input(UInt(1.W))
})
io.out.valid := false.B
io.out.bits := 0.U
io.mem.addr := 0.U
io.mem.readEnable := false.B
io.mem.writeMask := 0.U
io.mem.writeData := 0.U
io.mem.writeEnable := false.B
val addr = Reg(UInt(bits.W))
val data = Reg(UInt(bits.W))
val internalOp = Reg(UInt(2.W))
val length = Reg(UInt(2.W))
val signed = Reg(UInt(1.W))
val byteReverse = Reg(UInt(1.W))
val reservation = Reg(UInt(1.W))
val sIdle :: sAccess :: sLoadFormat :: Nil = Enum(3)
val state = RegInit(sIdle)
val fifoLength = 128
val rxOverclock = 16
val uart = Module(new Uart(fifoLength, rxOverclock))
io.tx := uart.io.tx
uart.io.rx := io.rx
uart.io.txQueue.valid := false.B
uart.io.txQueue.bits := 0.U
uart.io.rxQueue.ready := false.B
val clockDivisor = RegInit(0.U(8.W))
uart.io.clockDivisor := clockDivisor
switch (state) {
is (sIdle) {
when (io.in.valid) {
val a = io.in.bits.a + io.in.bits.b
val offset = a(log2Ceil(bits/8)-1, 0)*8.U
addr := a
internalOp := io.in.bits.internalOp
length := io.in.bits.length
signed := io.in.bits.signed
byteReverse := io.in.bits.byteReverse
reservation := io.in.bits.reservation
state := sAccess
when (io.in.bits.internalOp === LDST_STORE) {
/* Byte swap or sign extend data. We never do both. */
when (io.in.bits.signed.asBool) {
data := io.in.bits.data.signExtend(io.in.bits.length) << offset
} .elsewhen (io.in.bits.byteReverse.asBool) {
data := LoadStoreByteReverse(io.in.bits.data, io.in.bits.length) << offset
} .otherwise {
data := io.in.bits.data << offset
}
}
}
}
is (sAccess) {
when (internalOp === LDST_STORE) {
val offset = addr(log2Ceil(bits/8)-1, 0)
val lookupTable = Seq(LEN_1B -> "h1".U, LEN_2B -> "h3".U, LEN_4B -> "hf".U, LEN_8B -> "hff".U)
val mask = Wire(UInt((bits/8).W))
mask := MuxLookup(length, lookupTable.head._2, lookupTable) << offset
/* UART */
when (addr(31, 8) === "hc00020".U) {
when (addr(7, 0) === "h00".U) {
/* TX */
uart.io.txQueue.valid := true.B
uart.io.txQueue.bits := data(7, 0)
} .elsewhen (addr === "hc0002018".U) {
/* clock divisor */
clockDivisor := data(7, 0)
} .otherwise {
/* ERROR */
}
} .otherwise {
/* memory */
io.mem.addr := addr >> log2Ceil(bits/8).U
io.mem.writeEnable := true.B
io.mem.writeMask := mask
io.mem.writeData := data
}
/* Done */
io.out.valid := true.B
state := sIdle
} .otherwise {
io.mem.addr := addr >> log2Ceil(bits/8).U
io.mem.readEnable := true.B
state := sLoadFormat
}
}
is (sLoadFormat) {
val offset = addr(log2Ceil(bits/8)-1, 0)*8.U
val d = io.mem.readData >> offset
/* Byte swap or sign extend data. We never do both. */
when (signed.asBool) {
io.out.bits := d.signExtend(length)
} .elsewhen (byteReverse.asBool) {
io.out.bits := LoadStoreByteReverse(d, length)
} .otherwise {
io.out.bits := d.zeroExtend(length)
}
/* UART */
when (addr(31, 8) === "hc00020".U) {
when (addr(7, 0) === "h08".U) {
/* RX */
when (uart.io.rxQueue.valid) {
uart.io.rxQueue.ready := true.B
io.out.bits := uart.io.rxQueue.bits
}
} .elsewhen (addr(7, 0) === "h10".U) {
/* Status */
io.out.bits := uart.io.txFull ## uart.io.rxFull ## uart.io.txEmpty ## uart.io.rxEmpty
} .elsewhen (addr(7, 0) === "h18".U) {
/* clock divisor */
io.out.bits := clockDivisor
} .otherwise {
/* ERROR */
io.out.bits := 0.U
}
}
/* Done */
io.out.valid := true.B
state := sIdle
}
}
}
class LoadStoreWrapper(val bits: Int, val size: Int, filename: String) extends Module {
val io = IO(new Bundle {
val in = Flipped(Valid(new LoadStoreInput(bits)))
val out = Output(Valid(UInt(bits.W)))
})
val loadStore = Module(new LoadStore(bits, size/(bits/8)))
val mem = Module(new MemoryBlackBoxWrapper(bits, size/(bits/8), filename))
io.in <> loadStore.io.in
io.out <> loadStore.io.out
loadStore.io.mem <> mem.io.loadStorePort
loadStore.io.rx := loadStore.io.tx
/* Fetch port is unused */
mem.io.fetchPort.writeData := 0.U
mem.io.fetchPort.readEnable := false.B
mem.io.fetchPort.writeEnable := false.B
mem.io.fetchPort.addr := 0.U
mem.io.fetchPort.writeMask := 0.U
}
object LoadStoreObj extends App {
chisel3.Driver.execute(Array[String](), () => new LoadStoreWrapper(64, 128*1024, "test.hex"))
}

View File

@@ -0,0 +1,45 @@
import chisel3._
import chisel3.util.{MuxLookup}
import Control._
import Helpers._
class LoadStoreByteReverse(bits: Int) extends Module {
val io = IO(
new Bundle {
val in = Input(UInt(bits.W))
val length = Input(UInt(2.W))
val out = Output(UInt(bits.W))
}
)
val lengths = Seq(2, 4, 8)
val lengthNames = Seq(LEN_2B, LEN_4B, LEN_8B)
val lookupTable = lengthNames.zip(
lengths.map(l =>
io.in.bytes().zipWithIndex.filter({case (b@_, i) => (i < l)}).map({case (b, i@_) => b}).reduce(_ ## _)
)
)
io.out := MuxLookup(io.length, lookupTable.head._2, lookupTable)
}
object LoadStoreByteReverseObj extends App {
chisel3.Driver.execute(Array[String](), () => new LoadStoreByteReverse(64))
}
object LoadStoreByteReverse {
/** Return a [[UInt]] the number of leading zeroes in some [[Data]]
* @param in a hardware type
* @tparam A some data
* @param length a hardware type
* @tparam B some data
*/
def apply[A <: Data, B <: Data](in: A, length: B): UInt = {
val count = Module(new LoadStoreByteReverse(in.getWidth))
count.io.in := in.asUInt
count.io.length := length.asUInt
count.io.out
}
}

View File

@@ -0,0 +1,36 @@
import chisel3._
import chisel3.util.{MuxCase, MuxLookup}
import Control._
import Helpers._
class Logical(bits: Int) extends Module {
val io = IO(new Bundle {
val a = Input(UInt(bits.W))
val b = Input(UInt(bits.W))
val internalOp = Input(UInt(4.W))
val invertIn = Input(UInt(1.W))
val invertOut = Input(UInt(1.W))
val length = Input(UInt(2.W))
val out = Output(UInt(bits.W))
})
val b = Mux(io.invertIn.asBool, ~io.b, io.b)
val ext = MuxLookup(io.length, io.a.signExtend(8, bits), Array(
LEN_2B -> io.a.signExtend(16, bits),
LEN_4B -> io.a.signExtend(32, bits)))
val tmp = MuxCase(io.a, Seq(
(io.internalOp === LOG_AND) -> (io.a & b),
(io.internalOp === LOG_OR) -> (io.a | b),
(io.internalOp === LOG_XOR) -> (io.a ^ b),
(io.internalOp === LOG_EXTS) -> ext
))
io.out := Mux(io.invertOut.asBool, ~tmp, tmp)
}
object LogicalObj extends App {
chisel3.Driver.execute(Array[String](), () => new Logical(64))
}

View File

@@ -0,0 +1,103 @@
import chisel3._
import chisel3.util.{log2Ceil,HasBlackBoxInline}
class MemoryBlackBox(val bits: Int, val words: Int, val filename: String) extends BlackBox with HasBlackBoxInline {
val io = IO(new Bundle() {
val clock = Input(Clock())
val readEnable1 = Input(Bool())
val writeEnable1 = Input(Bool())
val writeMask1 = Input(UInt((bits/8).W))
val addr1 = Input(UInt(log2Ceil(words).W))
val readData1 = Output(UInt(bits.W))
val writeData1 = Input(UInt(bits.W))
val readEnable2 = Input(Bool())
val readAddr2 = Input(UInt(log2Ceil(words).W))
val readData2 = Output(UInt(bits.W))
})
setInline("MemoryBlackBox.v",
s"""
|module MemoryBlackBox #(
| parameter BITS = $bits,
| parameter WORDS = $words
|) (
| input clock,
|
| input readEnable1,
| input writeEnable1,
| input [BITS/8-1:0] writeMask1,
| input [$$clog2(WORDS)-1:0] addr1,
| output logic [BITS-1:0] readData1,
| input [BITS-1:0] writeData1,
|
| input readEnable2,
| input [$$clog2(WORDS)-1:0] readAddr2,
| output logic [BITS-1:0] readData2
|);
|
|integer i;
|logic [BITS-1:0] ram[0:WORDS-1];
|
|always_ff@(posedge clock)
|begin
| if (writeEnable1)
| begin
| for (i = 0; i < BITS/8; i = i + 1)
| begin
| if (writeMask1[i]) ram[addr1][i*8+:8] <= writeData1[i*8+:8];
| end
| end
| else if (readEnable1)
| begin
| readData1 <= ram[addr1];
| end
|
| if (readEnable2) readData2 <= ram[readAddr2];
|end
|initial begin
| $$readmemh("$filename", ram);
|end
|endmodule
|""".stripMargin)
}
class MemoryPort(val bits: Int, val words: Int, val rw: Boolean) extends Bundle {
val addr = Output(UInt(log2Ceil(words).W))
val readEnable = Output(Bool())
val readData = Input(UInt(bits.W))
//val writeEnable = if (rw) Some(Output(Bool())) else None
//val writeMask = if (rw) Some(Output(UInt((bits/8).W))) else None
//val writeData = if (rw) Some(Output(UInt(bits.W))) else None
val writeEnable = (Output(Bool()))
val writeMask = (Output(UInt((bits/8).W)))
val writeData = (Output(UInt(bits.W)))
}
class MemoryBlackBoxWrapper(val bits: Int, val words: Int, val filename: String) extends Module {
val io = IO(new Bundle() {
val loadStorePort = Flipped(new MemoryPort(bits, words, true))
val fetchPort = Flipped(new MemoryPort(bits, words, false))
})
val m = Module(new MemoryBlackBox(bits, words, filename))
m.io.clock := clock
m.io.readEnable1 := io.loadStorePort.readEnable
m.io.writeEnable1 := io.loadStorePort.writeEnable
m.io.writeMask1 := io.loadStorePort.writeMask
m.io.addr1 := io.loadStorePort.addr
io.loadStorePort.readData := m.io.readData1
m.io.writeData1 := io.loadStorePort.writeData
m.io.readEnable2 := io.fetchPort.readEnable
m.io.readAddr2 := io.fetchPort.addr
io.fetchPort.readData := m.io.readData2
}
object MemoryBlackBoxObj extends App {
chisel3.Driver.execute(Array[String](), () => new MemoryBlackBoxWrapper(64, 1024, "test.hex"))
}

28
src/main/scala/Nia.scala Normal file
View File

@@ -0,0 +1,28 @@
import chisel3._
import chisel3.util.Decoupled
class Nia(val bits: Int, val resetAddr: Int) extends Module {
val io = IO(new Bundle {
val nia = Decoupled(UInt(bits.W))
val redirect = Input(Bool())
val redirect_nia = Input(UInt(bits.W))
})
val nia = RegInit(resetAddr.U(bits.W))
io.nia.valid := false.B
when (io.redirect) {
nia := io.redirect_nia
} .elsewhen (io.nia.ready) {
nia := nia + 4.U
io.nia.valid := true.B
}
io.nia.bits := nia
}
object NiaObj extends App {
chisel3.Driver.execute(Array[String](), () => new Nia(32, 0x100))
}

View File

@@ -0,0 +1,53 @@
import chisel3._
import chisel3.util.{PopCount, MuxLookup}
import Control._
import Helpers._
class PopulationCount(bits: Int) extends Module {
val io = IO(new Bundle {
val a = Input(UInt(bits.W))
val length = Input(UInt(2.W))
val out = Output(UInt(bits.W))
})
// Move helper to somewhere common
def lengthToBits(n: UInt) = {
val lengths = Seq(8, 16, 32, 64)
val lengthNames = Seq(LEN_1B, LEN_2B, LEN_4B, LEN_8B)
lengthNames.zip(lengths).toMap.get(n).getOrElse(0)
}
// Note that halfword population count is not in the architecture, so we skip it
val lengthSeq = if (bits == 64) Seq(LEN_1B, LEN_4B, LEN_8B) else Seq(LEN_1B, LEN_4B)
val bitSeq = lengthSeq.map(l => lengthToBits(l))
val b: Seq[UInt] = (((bits/8)-1) to 0 by -1).map{ case i => PopCount(io.a.bytes(i)) }
val valueSeq = {
if (bits == 64) {
val w : Seq[UInt] = {
val (first, second) = b.splitAt(4)
// Would a tree reduction be faster?
Seq(first, second).map{ case a => a.reduce(_ +& _) }
}
val d: Seq[UInt] = Seq(w.reduce(_ +& _))
Seq(b, w, d)
} else {
val w: Seq[UInt] = Seq(b.reduce(_ +& _))
Seq(b, w)
}
}
val popCounts = lengthSeq.zip({
// Pad values to element size
valueSeq.zip(bitSeq)
.map{ case (a, padWidth) => a.map(_.pad(padWidth)).reduce(_ ## _) }
})
io.out := MuxLookup(io.length, popCounts.head._1, popCounts)
}
object PopulationCountObj extends App {
chisel3.Driver.execute(Array[String](), () => new PopulationCount(64))
}

View File

@@ -0,0 +1,40 @@
import chisel3._
import chisel3.util.{log2Ceil, Valid}
object RegisterFile {
sealed trait PortDirection
final case object Read extends PortDirection
final case object Write extends PortDirection
}
import RegisterFile._
class AddrData(val bits: Int, val rw: PortDirection) extends Bundle {
val addr = Input(UInt(log2Ceil(bits+1).W))
val data = rw match {
case Read => Output(UInt(bits.W))
case Write => Input(UInt(bits.W))
}
}
class RegisterFilePorts(val bits: Int, val numReadPorts: Int, val numWritePorts: Int) extends Bundle {
val rd = Vec(numReadPorts, new AddrData(bits, Read))
val wr = Vec(numWritePorts, Flipped(Valid(new AddrData(bits, Write))))
}
class RegisterFile(numRegs: Int, bits: Int, numReadPorts: Int, numWritePorts: Int, bypass: Boolean) extends Module {
val io = IO(new RegisterFilePorts(bits, numReadPorts, numWritePorts))
val regs = Mem(numRegs, UInt(bits.W))
io.rd.foreach{i => i.data := regs.read(i.addr)}
io.wr.foreach{i => when (i.fire()) { regs.write(i.bits.addr, i.bits.data) } }
if (bypass) {
io.rd.foreach{r => io.wr.foreach{w => when (w.fire() && w.bits.addr === r.addr) { r.data := w.bits.data } } }
}
}
object RegisterFileObj extends App {
chisel3.Driver.execute(Array[String](), () => new RegisterFile(32, 64, 3, 1, true))
}

View File

@@ -0,0 +1,115 @@
import chisel3._
import chisel3.util.log2Ceil
import InstructionHelpers._
class Rotator(bits: Int) extends Module {
val io = IO(new Bundle {
val ra = Input(UInt(bits.W))
val shift = Input(UInt(log2Ceil(bits+1).W))
val rs = Input(UInt(bits.W))
val is32bit = Input(Bool())
val signed = Input(Bool())
val rightShift = Input(Bool())
val clearLeft = Input(Bool())
val clearRight = Input(Bool())
val insn = Input(UInt(32.W))
val out = Output(UInt(bits.W))
val carryOut = Output(UInt(1.W))
})
def formRightMask(maskBegin: UInt, bits: Int): UInt = {
val ret = Wire(UInt(bits.W))
ret := 0.U
for (i <- 0 until bits) {
when (maskBegin === i.asUInt) { ret := ((BigInt(1) << (64-i)).asUInt-1.U) }
}
ret
}
def formLeftMask(maskEnd: UInt, bits: Int): UInt = {
val ret = Wire(UInt(bits.W))
ret := 0.U
when (maskEnd(6) === 0.U) {
for (i <- 0 until bits) {
when (maskEnd === i.asUInt) { ret := (~((BigInt(1) << (63-i)).asUInt(bits.W)-1.U)) }
}
}
ret
}
def rotateLeft(n: UInt, shift: UInt): UInt = {
val ret = Wire(UInt(bits.W))
ret := ((n ## n) << shift >> 64.U)
ret
}
/* First replicate bottom 32 bits to both halves if 32-bit */
val rs = Mux(io.is32bit, io.rs(31, 0) ## io.rs(31, 0), io.rs)
/* Negate shift count for right shifts */
val rotateCount = Mux(io.rightShift, -io.shift(5, 0), io.shift(5, 0))
val rotated = rotateLeft(rs, rotateCount)
/* Trim shift count to 6 bits for 32-bit shifts */
val sh = (io.shift(6) && ~io.is32bit) ## io.shift(5, 0)
val mb = Wire(UInt(7.W))
val me = Wire(UInt(7.W))
/* Work out mask begin/end indexes (caution, big-endian bit numbering) */
when (io.clearLeft) {
when (io.is32bit) {
mb := 1.U(2.W) ## insn_mb32(io.insn)
} .otherwise {
mb := 0.U(1.W) ## insn_mb(io.insn)
}
} .elsewhen (io.rightShift) {
/* this is basically mb <= sh + (is_32bit? 32: 0) */
when (io.is32bit) {
mb := sh(5) ## ~sh(5) ## sh(4, 0)
} .otherwise {
mb := sh
}
} .otherwise {
mb := 0.U(1.W) ## io.is32bit ## 0.U(5.W)
}
when (io.clearRight && io.is32bit) {
me := 1.U(2.W) ## insn_me32(io.insn)
} .elsewhen (io.clearRight && !io.clearLeft) {
me := 0.U(1.W) ## insn_me(io.insn)
} .otherwise {
/* effectively, 63 - sh */
me := sh(6) ## ~sh(5, 0);
}
/* Calculate left and right masks */
val rightMask = formRightMask(mb, bits);
val leftMask = formLeftMask(me, bits);
io.carryOut := 0.U
when ((io.clearLeft && !io.clearRight) || io.rightShift) {
when (io.signed && rs(63)) {
io.out := rotated | ~rightMask
/* Generate carry output for arithmetic shift right of negative value */
io.carryOut := (io.rs & ~leftMask).orR
} .otherwise {
io.out := rotated & rightMask
}
} .otherwise {
/* Mask insert instructions */
when (io.clearRight && mb(5, 0) > me(5, 0)) {
/* The mask wraps */
io.out := (rotated & (rightMask | leftMask)) | (io.ra & ~(rightMask | leftMask))
} .otherwise {
io.out := (rotated & (rightMask & leftMask)) | (io.ra & ~(rightMask & leftMask))
}
}
}
object RotatorObj extends App {
chisel3.Driver.execute(Array[String](), () => new Rotator(64))
}

View File

@@ -0,0 +1,89 @@
import chisel3._
import chisel3.util.{Valid, Decoupled, log2Ceil}
import Helpers._
class DividerInput(val bits: Int) extends Bundle {
val dividend = UInt(bits.W)
val divisor = UInt(bits.W)
val is32bit = Bool()
val signed = Bool()
val extended = Bool()
val modulus = Bool()
}
class SimpleDivider(val bits: Int) extends Module {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new DividerInput(bits)))
val out = Output(Valid(UInt(bits.W)))
})
val dividend = Reg(UInt((bits*2+1).W))
val divisor = Reg(UInt(bits.W))
val quotient = Reg(UInt((bits+1).W))
val is32bit = Reg(Bool())
//val signed = Reg(Bool())
val modulus = Reg(Bool())
val count = Reg(UInt(log2Ceil(bits+1).W))
val busy = RegInit(false.B)
io.in.ready := !busy
when (io.in.valid && !busy) {
when (io.in.bits.is32bit) {
when (io.in.bits.extended) {
dividend := io.in.bits.dividend(31, 0) ## 0.U(32.W)
} .otherwise {
dividend := io.in.bits.dividend(31, 0)
}
divisor := io.in.bits.divisor(31, 0)
} .otherwise {
when (io.in.bits.extended) {
dividend := io.in.bits.dividend ## 0.U(bits.W)
} .otherwise {
dividend := 0.U((bits+1).W) ## io.in.bits.dividend
}
divisor := io.in.bits.divisor
}
is32bit := io.in.bits.is32bit
quotient := 0.U
count := 0.U
modulus := io.in.bits.modulus
busy := true.B
}
when (busy) {
when ((dividend(bits*2) === 1.U) || (dividend(bits*2-1, bits) >= divisor)) {
dividend := (dividend(bits*2-1, bits) - divisor) ## dividend(bits-1, 0) ## 0.U(1.W)
quotient := quotient(bits-2, 0) ## 1.U(1.W)
} .otherwise {
dividend := dividend((bits*2-1), 0) ## 0.U(1.W)
quotient := quotient(bits-2, 0) ## 0.U(1.W)
}
count := count + 1.U
}
// Did we shift out a 1? This also handles divide by zero
val overflow = Reg(Bool())
overflow := quotient(bits-1)
when (is32bit) {
overflow := quotient(63, 31).orR
}
io.out.bits := quotient
when (overflow) {
io.out.bits := 0.U
} .elsewhen (is32bit && !modulus) {
io.out.bits := 0.U(32.W) ## quotient(31, 0)
}
io.out.valid := (count === (bits+1).U) && busy
when (io.out.valid) {
busy := false.B
}
}
object SimpleDividerObj extends App {
chisel3.Driver.execute(Array[String](), () => new SimpleDivider(64))
}

View File

@@ -0,0 +1,79 @@
import chisel3._
import chisel3.util.{Valid, Decoupled}
import Helpers._
class MultiplierInput(val bits: Int) extends Bundle {
val a = UInt(bits.W)
val b = UInt(bits.W)
val is32bit = Bool()
val signed = Bool()
val high = Bool()
}
class SimpleMultiplier(val bits: Int) extends Module {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new MultiplierInput(bits)))
val out = Output(Valid(UInt(bits.W)))
})
val a = Reg(UInt((2*bits).W))
val b = Reg(UInt((2*bits).W))
val is32bit = Reg(Bool())
val high = Reg(Bool())
val res = Reg(UInt((2*bits).W))
val busy = RegInit(false.B)
io.in.ready := !busy
when (io.in.valid && !busy) {
when (io.in.bits.is32bit) {
when (io.in.bits.signed) {
a := io.in.bits.a.signExtend(32, 2*bits)
b := io.in.bits.b.signExtend(32, 2*bits)
} .otherwise {
a := io.in.bits.a(31, 0)
b := io.in.bits.b(31, 0)
}
} .otherwise {
when (io.in.bits.signed) {
a := io.in.bits.a.signExtend(64, 2*bits)
b := io.in.bits.b.signExtend(64, 2*bits)
} .otherwise {
a := io.in.bits.a
b := io.in.bits.b
}
}
is32bit := io.in.bits.is32bit
high := io.in.bits.high
res := 0.U
busy := true.B
}
when (busy) {
when (a(0) === 1.U) {
res := res + b
}
b := b << 1
a := a >> 1
}
io.out.bits := res
when (high) {
when (is32bit) {
io.out.bits := res(63, 32) ## res(63, 32)
} .otherwise {
io.out.bits := res(127, 64)
}
}
io.out.valid := (a === 0.U) && busy
when (io.out.valid) {
busy := false.B
}
}
object SimpleMultiplierObj extends App {
chisel3.Driver.execute(Array[String](), () => new SimpleMultiplier(64))
}

202
src/main/scala/Uart.scala Normal file
View File

@@ -0,0 +1,202 @@
import chisel3._
import chisel3.util._
/*
* A simple TTL serial module. Idle is high. Start bits are low, stop bits
* are high and we send each byte out LSB first. We only implement 8n1,
* ie 1 start bit, no parity and 1 stop bit. There is no flow control, so
* we might overflow the RX fifo if the rxQueue consumer can't keep up.
*
* We oversample RX. clockDivisor is set as follows:
*
* clockDivisor = (clock_freq / (baudrate * rxOverclock)) - 1
*
* When programming the divider, software currently assumes we overclock 16x.
*
* Also note that if the input clock frequency is low enough then the errors
* introduced by oversampling might be significant. Eg at 10MHz, 115200 baud,
* 16x oversampling we have almost 8% error and the UART fails to work.
*/
class Uart(val fifoLength: Int, val rxOverclock: Int) extends Module {
val io = IO(new Bundle {
val rx = Input(UInt(1.W))
val tx = Output(UInt(1.W))
val rxQueue = Decoupled(UInt(8.W))
val txQueue = Flipped(Decoupled(UInt(8.W)))
val rxEmpty = Output(Bool())
val txEmpty = Output(Bool())
val rxFull = Output(Bool())
val txFull = Output(Bool())
val clockDivisor = Input(UInt(8.W))
})
require(isPow2(rxOverclock))
val sampleClk = RegInit(0.U(1.W))
val sampleClkCounter = RegInit(0.U(8.W))
val txQueue = Module(new Queue(UInt(8.W), fifoLength))
val rxQueue = Module(new Queue(UInt(8.W), fifoLength))
io.rxEmpty := (rxQueue.io.count === 0.U)
io.txEmpty := (txQueue.io.count === 0.U)
io.rxFull := (rxQueue.io.count === fifoLength.U)
io.txFull := (txQueue.io.count === fifoLength.U)
val uartEnabled = io.clockDivisor.orR
when (uartEnabled) {
when (sampleClkCounter === io.clockDivisor) {
sampleClk := 1.U
sampleClkCounter := 0.U
} .otherwise {
sampleClk := 0.U
sampleClkCounter := sampleClkCounter + 1.U
}
} .otherwise {
sampleClk := 0.U
sampleClkCounter := 0.U
}
/*
* Our TX clock needs to match our baud rate. This means we need to
* further divide sampleClk by rxOverclock.
*/
val (txCounterValue, txCounterWrap) = Counter(sampleClk === 1.U, rxOverclock)
val txClk = txCounterWrap
/* TX */
val sTxIdle :: sTxTx :: sTxStop :: Nil = Enum(3)
val txState = RegInit(sTxIdle)
val txByte = Reg(UInt(8.W))
val txByteBit = Reg(UInt(3.W))
/* RS232 idle state is high */
val tx = RegInit(1.U(1.W))
txQueue.io.deq.ready := false.B
/* We run the tx state machine off the txClk */
when (txClk === 1.U) {
switch (txState) {
is (sTxIdle) {
/* Does the FIFO contain data? */
when (txQueue.io.deq.valid) {
txQueue.io.deq.ready := true.B
txByte := txQueue.io.deq.bits
txByteBit := 0.U
txState := sTxTx
/* Send start bit */
tx := 0.U
} .otherwise {
tx := 1.U
}
}
is (sTxTx) {
when (txByteBit === 7.U) {
txState := sTxStop
}
tx := txByte(txByteBit)
txByteBit := txByteBit + 1.U
}
is (sTxStop) {
txState := sTxIdle
/* Send stop bit */
tx := 1.U
}
}
}
io.tx := tx
/* RX */
val sRxIdle :: sRxStart :: sRxRx :: sRxStop :: sRxError1 :: sRxError2 :: Nil = Enum(6)
val rxState = RegInit(sRxIdle)
val rxCounter = RegInit(0.U(log2Ceil(rxOverclock).W))
val rxByte = RegInit(VecInit(Seq.fill(8)(0.U(1.W))))
val rxByteBit = RegInit(0.U(3.W))
rxQueue.io.enq.bits := 0.U
rxQueue.io.enq.valid := false.B
/* Synchronize the input to avoid any metastability issues */
val rx = RegNext(RegNext(RegNext(io.rx)))
when (sampleClk === 1.U) {
switch (rxState) {
is (sRxIdle) {
when (rx === 0.U) {
rxState := sRxStart
rxCounter := 1.U
rxByte := Seq.fill(8){0.U}
rxByteBit := 0.U
}
}
is (sRxStart) {
rxCounter := rxCounter + 1.U
/* We should be at the middle of the start bit */
when (rxCounter === (rxOverclock/2).U) {
rxCounter := 1.U
rxState := sRxRx
}
}
is (sRxRx) {
rxCounter := rxCounter + 1.U
when (rxCounter === 0.U) {
when (rxByteBit === 7.U) {
rxState := sRxStop
}
rxByte(rxByteBit) := rx
rxByteBit := rxByteBit + 1.U
}
}
is (sRxStop) {
rxCounter := rxCounter + 1.U
when (rxCounter === 0.U) {
/* Ensure the stop bit is high */
when (rx === 1.U) {
/* We might overflow the queue if we can't keep up */
rxQueue.io.enq.bits := rxByte.reverse.reduce(_ ## _)
rxQueue.io.enq.valid := true.B
rxState := sRxIdle
} .otherwise {
/* Something went wrong */
rxState := sRxError1
}
}
}
/*
* We might not have synchronised on a start bit. Delay 2 bits on
* each error so we eventually line up with the start bit.
*/
is (sRxError1) {
/* Delay one bit */
rxCounter := rxCounter + 1.U
when (rxCounter === 0.U) {
rxState := sRxError2
}
}
is (sRxError2) {
/* Delay another bit */
rxCounter := rxCounter + 1.U
when (rxCounter === 0.U) {
rxState := sRxIdle
}
}
}
}
rxQueue.io.deq <> io.rxQueue
txQueue.io.enq <> io.txQueue
}
object UartObj extends App {
chisel3.Driver.execute(Array[String](), () => new Uart(64, 16))
}

View File

@@ -0,0 +1,73 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import TestValues._
class CountZeroesUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "CountZeroes"
it should "pass a unit test" in {
test(new CountZeroes(64)) { c =>
def clz(x: BigInt): Int = {
for (i <- 0 until 64) {
if (((x >> (63 - i)) & 1) == 1) {
return i
}
}
return 64;
}
for (x <- testValues) {
c.io.a.poke(x.asUInt)
c.io.out.expect(clz(x).asUInt)
}
def clz32(x: BigInt): Int = {
for (i <- 0 until 32) {
if (((x >> (31 - i)) & 1) == 1) {
return i
}
}
return 32;
}
c.io.is32bit.poke(true.B)
for (x <- testValues) {
c.io.a.poke(x.asUInt)
c.io.out.expect(clz32(x).asUInt)
}
c.io.is32bit.poke(false.B)
def ctz(x: BigInt): Int = {
for (i <- 0 until 64) {
if (((x >> i) & 1) == 1) {
return i
}
}
return 64;
}
c.io.countRight.poke(true.B)
for (x <- testValues) {
c.io.a.poke(x.asUInt)
c.io.out.expect(ctz(x).asUInt)
}
def ctz32(x: BigInt): Int = {
for (i <- 0 until 32) {
if (((x >> i) & 1) == 1) {
return i
}
}
return 32;
}
c.io.is32bit.poke(true.B)
for (x <- testValues) {
c.io.a.poke(x.asUInt)
c.io.out.expect(ctz32(x).asUInt)
}
}
}
}

View File

@@ -0,0 +1,114 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.{VerilatorBackendAnnotation, WriteVcdAnnotation}
import treadle.executable.ClockInfo
import treadle.{ClockInfoAnnotation}
import Control._
class LoadStoreUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
val bits = 64
val words = 1024
val filename = "LoadStoreInsns.hex"
private def doOneRead(m: LoadStoreWrapper, a: UInt, b: UInt, length: UInt, signed: UInt, byteReverse: UInt, expected: UInt) = {
m.io.in.bits.a.poke(a)
m.io.in.bits.b.poke(b)
m.io.in.bits.internalOp.poke(LDST_LOAD)
m.io.in.bits.length.poke(length)
m.io.in.bits.signed.poke(signed)
m.io.in.bits.byteReverse.poke(byteReverse)
m.io.in.bits.update.poke(0.U)
m.io.in.bits.reservation.poke(0.U)
m.io.in.valid.poke(true.B)
m.io.out.valid.expect(false.B)
m.clock.step()
m.io.in.valid.poke(false.B)
m.io.out.valid.expect(false.B)
m.clock.step()
m.io.out.valid.expect(true.B)
m.io.out.bits.expect(expected)
m.clock.step()
}
private def doOneWrite(m: LoadStoreWrapper, a: UInt, b: UInt, length: UInt, signed: UInt, byteReverse: UInt, data: UInt) = {
m.io.in.bits.a.poke(a)
m.io.in.bits.b.poke(b)
m.io.in.bits.data.poke(data)
m.io.in.bits.internalOp.poke(LDST_STORE)
m.io.in.bits.length.poke(length)
m.io.in.bits.signed.poke(signed)
m.io.in.bits.byteReverse.poke(byteReverse)
m.io.in.bits.update.poke(0.U)
m.io.in.bits.reservation.poke(0.U)
m.io.in.valid.poke(true.B)
m.io.out.valid.expect(false.B)
m.clock.step()
m.io.in.valid.poke(false.B)
m.io.out.valid.expect(true.B)
m.clock.step()
doOneRead(m, a, b, length, signed, byteReverse, data)
}
reflect.io.File(filename).writeAll("0001020304050607\r\n08090A0B0C0D0E0F\r\n0F0E0D0C0B0A0908\r\n8080808080808080\r\n")
behavior of "LoadStore"
it should "pass a unit test" in {
test(new LoadStoreWrapper(bits, words, filename)).withAnnotations(Seq(VerilatorBackendAnnotation, WriteVcdAnnotation, ClockInfoAnnotation(Seq(ClockInfo(period = 2))))) { m =>
doOneRead(m, 0.U, 0.U, LEN_1B, 0.U, 0.U, "h07".U)
doOneRead(m, 0.U, 0.U, LEN_2B, 0.U, 0.U, "h0607".U)
doOneRead(m, 0.U, 0.U, LEN_4B, 0.U, 0.U, "h04050607".U)
doOneRead(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "h0001020304050607".U)
/* Test offsets within 64 bits */
doOneRead(m, 1.U, 0.U, LEN_1B, 0.U, 0.U, "h06".U)
doOneRead(m, 1.U, 1.U, LEN_2B, 0.U, 0.U, "h0405".U)
doOneRead(m, 2.U, 2.U, LEN_4B, 0.U, 0.U, "h00010203".U)
/* Test byte reverse */
doOneRead(m, 0.U, 0.U, LEN_2B, 0.U, 1.U, "h0706".U)
doOneRead(m, 0.U, 0.U, LEN_4B, 0.U, 1.U, "h07060504".U)
doOneRead(m, 0.U, 0.U, LEN_8B, 0.U, 1.U, "h0706050403020100".U)
/* Test sign extension */
doOneRead(m, 24.U, 0.U, LEN_1B, 1.U, 0.U, "hFFFFFFFFFFFFFF80".U)
doOneRead(m, 24.U, 0.U, LEN_2B, 1.U, 0.U, "hFFFFFFFFFFFF8080".U)
doOneRead(m, 24.U, 0.U, LEN_4B, 1.U, 0.U, "hFFFFFFFF80808080".U)
/* Test basic writes */
doOneWrite(m, 0.U, 0.U, LEN_1B, 0.U, 0.U, "h5A".U)
doOneWrite(m, 0.U, 0.U, LEN_2B, 0.U, 0.U, "h9875".U)
doOneWrite(m, 0.U, 0.U, LEN_4B, 0.U, 0.U, "h03562598".U)
doOneWrite(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "hBADBADBADC0FFEE0".U)
/* Test offsets within 64 bits */
doOneWrite(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "h0706050403020100".U)
doOneWrite(m, 1.U, 0.U, LEN_1B, 0.U, 0.U, "h77".U)
doOneRead(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "h0706050403027700".U)
doOneWrite(m, 2.U, 0.U, LEN_2B, 0.U, 0.U, "h2941".U)
doOneRead(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "h0706050429417700".U)
doOneWrite(m, 4.U, 0.U, LEN_4B, 0.U, 0.U, "h71492952".U)
doOneRead(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "h7149295229417700".U)
/* Test byte reverse */
doOneWrite(m, 0.U, 0.U, LEN_8B, 0.U, 0.U, "h0706050403020100".U)
doOneWrite(m, 0.U, 0.U, LEN_2B, 0.U, 1.U, "h0706".U)
doOneWrite(m, 0.U, 0.U, LEN_4B, 0.U, 1.U, "h07060504".U)
doOneWrite(m, 0.U, 0.U, LEN_8B, 0.U, 1.U, "h0706050403020100".U)
/* Test sign extend */
doOneWrite(m, 8.U, 0.U, LEN_1B, 1.U, 0.U, "hFFFFFFFFFFFFFF81".U)
doOneWrite(m, 8.U, 0.U, LEN_2B, 1.U, 0.U, "hFFFFFFFFFFFF8181".U)
doOneWrite(m, 8.U, 0.U, LEN_4B, 1.U, 0.U, "hFFFFFFFF81818181".U)
}
}
}

View File

@@ -0,0 +1,19 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
class AlignStoreTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "AlignStore"
it should "pass a unit test" in {
test(new LoadStoreAlign(64)) { p =>
val x = BigInt(0x0102030405060708L)
p.io.in.poke(x.U)
for (offset <- 0 until 7) {
val y = (x << (offset*8)) & BigInt("FFFFFFFFFFFFFFFF", 16)
p.io.offset.poke(offset.U)
p.io.out.expect(y.U)
}
}
}
}

View File

@@ -0,0 +1,26 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import Control._
class LoadStoreByteReverseTester extends FlatSpec with ChiselScalatestTester with Matchers {
val x = BigInt("0123456789ABCDEF", 16)
val bits = 64
behavior of "LoadStoreByteReverse"
it should "pass a unit test" in {
test(new LoadStoreByteReverse(bits)) { br =>
br.io.in.poke(x.U)
br.io.length.poke(LEN_2B)
br.io.out.expect("h000000000000EFCD".U)
br.io.length.poke(LEN_4B)
br.io.out.expect("h00000000EFCDAB89".U)
br.io.length.poke(LEN_8B)
br.io.out.expect("hEFCDAB8967452301".U)
}
}
}

View File

@@ -0,0 +1,19 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
class DeAlignStoreTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "AlignStore"
it should "pass a unit test" in {
test(new LoadStoreDeAlign(64)) { p =>
val x = BigInt(0x0102030405060708L)
p.io.in.poke(x.U)
for (offset <- 0 until 7) {
val y = (x >> (offset*8)) & BigInt("FFFFFFFFFFFFFFFF", 16)
p.io.offset.poke(offset.U)
p.io.out.expect(y.U)
}
}
}
}

View File

@@ -0,0 +1,47 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import chiseltest.experimental.TestOptionBuilder._
import chiseltest.internal.{VerilatorBackendAnnotation, WriteVcdAnnotation}
import treadle.executable.ClockInfo
import treadle.{ClockInfoAnnotation}
class MemoryBlackBoxUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
val bits = 64
val words = 1024
val filename = "MemoryBlackBoxInsns.hex"
reflect.io.File(filename).writeAll("0001020304050607\r\n08090A0B0C0D0E0F\r\n0F0E0D0C0B0A0908\r\n0706050403020100\r\n")
behavior of "MemoryBlackBox"
it should "pass a unit test" in {
test(new MemoryBlackBoxWrapper(bits, words, filename)).withAnnotations(Seq(VerilatorBackendAnnotation, WriteVcdAnnotation, ClockInfoAnnotation(Seq(ClockInfo(period = 2))))) { m =>
m.io.fetchPort.readEnable.poke(true.B)
m.io.fetchPort.addr.poke(0.U)
m.io.fetchPort.readEnable.expect(true.B)
m.clock.step()
m.io.fetchPort.readData.expect("h0001020304050607".U)
m.io.fetchPort.addr.poke(1.U)
m.clock.step()
m.io.fetchPort.readData.expect("h08090A0B0C0D0E0F".U)
m.io.loadStorePort.addr.poke(0.U)
m.io.loadStorePort.writeData.poke("hAAAAAAAAAAAAAAAA".U)
m.io.loadStorePort.writeEnable.poke(true.B)
m.io.loadStorePort.writeMask.poke("hFF".U)
m.clock.step()
m.io.loadStorePort.writeEnable.poke(false.B)
m.io.loadStorePort.writeMask.poke(0.U)
m.io.fetchPort.addr.poke(0.U)
m.clock.step()
m.io.fetchPort.readData.expect("hAAAAAAAAAAAAAAAA".U)
}
}
}

View File

@@ -0,0 +1,54 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import Control._
import TestValues._
class PopulationCountUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "PopulationCount"
private def popcntb(x: BigInt): BigInt = {
var ret : BigInt = 0
for (i <- 0 until 8) {
ret = ret + (BigInt(((x >> (i*8)) & 0xff).bitCount) << (i*8))
}
ret
}
private def popcntw(x: BigInt): BigInt = {
var ret : BigInt = 0
for (i <- 0 until 2) {
ret = ret + (BigInt(((x >> (i*32)) & 0xffffffffL).bitCount) << (i*32))
}
ret
}
private def popcntd(x: BigInt): BigInt = x.bitCount
it should "pass a unit test" in {
test(new PopulationCount(64)) { p =>
p.io.length.poke(LEN_1B)
for (x <- testValues) {
p.io.a.poke(x.U)
p.io.out.expect(popcntb(x).U)
}
p.io.length.poke(LEN_4B)
for (x <- testValues) {
p.io.a.poke(x.U)
p.io.out.expect(popcntw(x).U)
}
p.io.length.poke(LEN_8B)
for (x <- testValues) {
p.io.a.poke(x.U)
p.io.out.expect(popcntd(x).U)
}
}
}
}

View File

@@ -0,0 +1,58 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
class RegisterFileUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "RegisterFile"
it should "pass a unit test" in {
val numRegs = 32
test(new RegisterFile(numRegs, 64, 2, 2, true)) { r =>
println("RegisterFileUnitTester begin")
// Write initial values to registers
r.io.wr(0).fire().poke(true.B)
for (x <- (0 until numRegs)) {
r.io.wr(0).bits.data.poke(x.U)
r.io.wr(0).bits.addr.poke(x.U)
r.clock.step()
}
r.io.wr(0).fire().poke(false.B)
r.clock.step()
// Read them back
for (x <- (0 until numRegs)) {
r.io.rd(0).addr.poke(x.U)
r.io.rd(0).data.expect(x.U)
r.io.rd(1).addr.poke(x.U)
r.io.rd(1).data.expect(x.U)
}
// Check bypassing works
r.io.wr(0).fire().poke(true.B)
r.io.wr(0).bits.data.poke("hBADC0FFEE0DDF00D".U)
r.io.wr(0).bits.addr.poke(11.U)
r.io.wr(1).fire().poke(true.B)
r.io.wr(1).bits.data.poke("hFEE1DEADABADCAFE".U)
r.io.wr(1).bits.addr.poke(24.U)
r.io.rd(0).addr.poke(11.U)
r.io.rd(0).data.expect("hBADC0FFEE0DDF00D".U)
r.io.rd(1).addr.poke(24.U)
r.io.rd(1).data.expect("hFEE1DEADABADCAFE".U)
r.clock.step()
r.io.wr(0).fire().poke(false.B)
r.io.wr(1).fire().poke(false.B)
r.clock.step()
r.io.rd(0).data.expect("hBADC0FFEE0DDF00D".U)
r.io.rd(1).data.expect("hFEE1DEADABADCAFE".U)
println("RegisterFileUnitTester end")
}
}
}

View File

@@ -0,0 +1,43 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import TestValues._
class SimpleDividerUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "SimpleDivider"
val tests = for {
//x <- testValuesShort
//y <- testValuesShort
x <- testValuesRealShort
y <- testValuesRealShort
} yield (x, y)
def divide(a: BigInt, b: BigInt): BigInt = (a / b) & BigInt("ffffffffffffffff", 16)
def divideExtended(a: BigInt, b: BigInt): BigInt = (((a << 64) / b) >> 64) & BigInt("ffffffffffffffff", 16)
it should "pass a unit test" in {
test(new SimpleDivider(64)) { m =>
for ((x, y) <- tests) {
while (m.io.in.ready.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.in.bits.dividend.poke(x.U)
m.io.in.bits.divisor.poke(y.U)
m.io.in.valid.poke(true.B)
m.clock.step(1)
m.io.in.valid.poke(false.B)
while (m.io.out.valid.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.out.bits.expect(divide(x, y).U)
}
}
}
}

View File

@@ -0,0 +1,89 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import TestValues._
class SimpleMultiplierUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "SimpleMultiplier"
val tests = for {
//x <- testValuesShort
//y <- testValuesShort
x <- testValuesRealShort
y <- testValuesRealShort
} yield (x, y)
def mult(a: BigInt, b: BigInt): BigInt = (a * b) & BigInt("ffffffffffffffff", 16)
def multHigh(a: BigInt, b: BigInt): BigInt = ((a * b) >> 64) & BigInt("ffffffffffffffff", 16)
def multHighSigned(a: BigInt, b: BigInt): BigInt = {
val aSigned = if (a.testBit(63)) (BigInt("ffffffffffffffff", 16) << 64) + a else a
val bSigned = if (b.testBit(63)) (BigInt("ffffffffffffffff", 16) << 64) + b else b
multHigh(aSigned, bSigned)
}
it should "pass a unit test" in {
test(new SimpleMultiplier(64)) { m =>
for ((x, y) <- tests) {
while (m.io.in.ready.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.in.bits.a.poke(x.U)
m.io.in.bits.b.poke(y.U)
m.io.in.valid.poke(true.B)
m.clock.step(1)
m.io.in.valid.poke(false.B)
while (m.io.out.valid.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.out.bits.expect(mult(x, y).U)
}
m.io.in.bits.high.poke(true.B)
for ((x, y) <- tests) {
while (m.io.in.ready.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.in.bits.a.poke(x.U)
m.io.in.bits.b.poke(y.U)
m.io.in.valid.poke(true.B)
m.clock.step(1)
m.io.in.valid.poke(false.B)
while (m.io.out.valid.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.out.bits.expect(multHigh(x, y).U)
}
m.io.in.bits.signed.poke(true.B)
for ((x, y) <- tests) {
while (m.io.in.ready.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.in.bits.a.poke(x.U)
m.io.in.bits.b.poke(y.U)
m.io.in.valid.poke(true.B)
m.clock.step(1)
m.io.in.valid.poke(false.B)
while (m.io.out.valid.peek().litToBoolean == false) {
m.clock.step(1)
}
m.io.out.bits.expect(multHighSigned(x, y).U)
}
}
}
}

View File

@@ -0,0 +1,45 @@
import chisel3._
object TestValues {
val range1 : Seq[BigInt] = (0 to 63).map(c => BigInt(1) << c)
val range2 : Seq[BigInt] = (0 to 64).map(c => (BigInt(1) << c)-1)
val range3 : Seq[BigInt] = range2.map(c => c^ (BigInt("ffffffffffffffff", 16)))
val range4 : Seq[BigInt] = Seq(
BigInt("1111111111111111", 16), /* low bits */
BigInt("8888888888888888", 16), /* high bits */
BigInt("00000000FFFFFFFF", 16), /* 32 bit all ones */
BigInt("FFFFFFFF00000000", 16), /* high 32 bits all ones */
BigInt("0000000100000000", 16), /* 2 ^ 32 */
BigInt("00000000ffffff80", 16), /* signed char min */
BigInt("000000000000007f", 16), /* signed char max */
BigInt("00000000000000ff", 16), /* unsigned char max */
BigInt("00000000ffff8000", 16), /* short min */
BigInt("0000000000007fff", 16), /* short max */
BigInt("000000000000ffff", 16), /* unsigned short max */
BigInt("0000000080000000", 16), /* int min */
BigInt("000000007fffffff", 16), /* int max */
BigInt("00000000ffffffff", 16), /* unsigned int max */
BigInt("8000000000000000", 16), /* long max */
BigInt("7fffffffffffffff", 16), /* long min */
BigInt("ffffffffffffffff", 16), /* unsigned long max */
BigInt("0001020304050607", 16),
BigInt("0706050403020100", 16),
BigInt("0011223344556677", 16),
BigInt("7766554433221100", 16),
BigInt("0000000100020003", 16),
BigInt("0003000200010001", 16),
BigInt("0000111122223333", 16),
BigInt("3333222211110000", 16),
BigInt("00FF00FF00FF00FF", 16),
BigInt("FF00FF00FF00FF00", 16),
BigInt("a5a5a5a5a5a5a5a5", 16)
)
val range5 = Seq.fill(1000)(BigInt(64, scala.util.Random))
val testValuesRealShort = range4
val testValuesShort = range1 ++ range2 ++ range3 ++ range4
val testValues = range1 ++ range2 ++ range3 ++ range4 ++ range5
val chiselTestValues = testValues.map(c => c.asUInt)
}

79
src/test/scala/Uart.scala Normal file
View File

@@ -0,0 +1,79 @@
import org.scalatest._
import chisel3.tester._
import chisel3._
import chiseltest.experimental.TestOptionBuilder._
import treadle.{WriteVcdAnnotation}
class UartUnitTester extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "Uart"
val rxOverclock = 16
val fpgaClock = 15000000
val baudRate = 115200
val divider = Math.round((1.0f * fpgaClock / (baudRate*rxOverclock)) - 1)
def clockSerial(clk: Clock) = clk.step(fpgaClock/baudRate)
private def rxOne(u: Uart, c: UInt) = {
/* Start bit */
u.io.rx.poke(0.U)
clockSerial(u.clock)
/*
* This doesn't work:
* c.pad(8).asBools.foreach({cc =>
*/
c.asBools.foreach({cc =>
u.io.rx.poke(cc)
clockSerial(u.clock)
})
/* Have to do this instead: */
u.io.rx.poke(0.U)
clockSerial(u.clock)
/* Stop bit */
u.io.rx.poke(1.U)
clockSerial(u.clock)
}
it should "pass a unit test" in {
test(new Uart(64, rxOverclock)).withAnnotations(Seq(WriteVcdAnnotation)) { u =>
u.clock.setTimeout(10000)
u.io.clockDivisor.poke(divider.U)
u.io.rxQueue.ready.poke(false.B)
val testChars = Seq("h41".U, "h6E".U, "h74".U, "h6F".U, "h6E".U)
testChars.foreach({c => rxOne(u, c)})
u.io.rxQueue.ready.poke(true.B)
testChars.foreach({c =>
u.io.rxQueue.valid.expect(true.B)
u.io.rxQueue.bits.expect(c)
u.clock.step()
})
u.io.rxQueue.ready.poke(false.B)
u.io.rxFull.expect(false.B)
u.io.txFull.expect(false.B)
rxOne(u, "h5a".U)
u.io.rxFull.expect(false.B)
(0 to 64).foreach(_ => rxOne(u, "h5a".U))
u.io.rxFull.expect(true.B)
u.io.txQueue.bits.poke("h75".U)
u.io.txQueue.valid.poke(true.B)
u.clock.step()
u.io.txFull.expect(false.B)
(0 to 64).foreach(_ => u.clock.step())
u.io.txFull.expect(true.B)
}
}
}

BIN
tests/1.bin Normal file

Binary file not shown.

37
tests/1.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 00000000000001E0
GPR1 0000000000000000
GPR2 000000000000011E
GPR3 0000000000000000
GPR4 0000000028884000
GPR5 0000000000000008
GPR6 FFFFFFFF80000000
GPR7 00000000101F00FF
GPR8 0000000000000000
GPR9 00000000288840FF
GPR10 000000D800000000
GPR11 FFFFFFFFFFFFFFFE
GPR12 000000000000011E
GPR13 0000000000007188
GPR14 0000000000000000
GPR15 0000000000000000
GPR16 0000000000000001
GPR17 BFFFFFFFBFFFFFE0
GPR18 0000000000000000
GPR19 FFFFFFF8FFFFFFF8
GPR20 FFFFFFFFFFFFFEE0
GPR21 0000000000000008
GPR22 EFFFFFF8000FFFFF
GPR23 BFFFFFFFBFFFFEFF
GPR24 0000000000000000
GPR25 0000000000000000
GPR26 0000000000000000
GPR27 0000000000000001
GPR28 0000000080000000
GPR29 0000000000000040
GPR30 0000000000000000
GPR31
CR 0000000040080000
LR 0000000000000000
CTR 0000000000000000
XER 0000000000000000

BIN
tests/10.bin Normal file

Binary file not shown.

37
tests/10.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 0000000000001D24
GPR1 FFFFFFFFFFFFFFFF
GPR2 00000000000001B9
GPR3 0000000000000000
GPR4 0000000000000000
GPR5 0000000000002D87
GPR6 0000000009000000
GPR7 0000000000000020
GPR8 0000000000000000
GPR9 FFFFFFFFFFFFE7B6
GPR10 0000004000000000
GPR11 0000070020000000
GPR12 0000000000000000
GPR13 0000000000000006
GPR14 00000000C0200000
GPR15 0000000000000000
GPR16 7FFFE93C7E7FE93C
GPR17 000000000001C020
GPR18 0000004000000000
GPR19 0000000000000000
GPR20 0000000000000000
GPR21 0000000000000000
GPR22 0000000000000000
GPR23 0000000000000004
GPR24 0000000069D50000
GPR25 0000000000000006
GPR26 0000000000000000
GPR27 0000000000000000
GPR28 000000000001C008
GPR29 FFFFFFFFFFFFFFFF
GPR30 FFFFFFFFFFFFFFFA
GPR31
CR 0000000029000840
LR 0000000000004A27
CTR FFFFFFFFFFFFFFFF
XER 0000000000000000

BIN
tests/100.bin Normal file

Binary file not shown.

37
tests/100.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 00000000FFFF1FEF
GPR1 000000000001F000
GPR2 0000000000000040
GPR3 0000000000000040
GPR4 00000000840848F2
GPR5 0000000000000000
GPR6 FFFFFFFFFFFFFFFB
GPR7 0000000000000020
GPR8 FFFFFFFFFFFF5D1E
GPR9 FFFFFFFFFFFFFFFF
GPR10 0000000000000000
GPR11 0000000000000001
GPR12 000000000000E016
GPR13 0000000000000000
GPR14 FFFFFFFFCB220000
GPR15 0000000000000000
GPR16 FFFFFFFFFFFFFF85
GPR17 000000000000A2DB
GPR18 0000000000000000
GPR19 0000000080000000
GPR20 0000000000000000
GPR21 000000000000003A
GPR22 FFFFFFFFFFFFFFFF
GPR23 000000000001C02C
GPR24 0000000000000000
GPR25 0000000000000000
GPR26 0000000000000000
GPR27 0000000000FFFFC0
GPR28 FFFFFFFFFFFFFFFF
GPR29 FFFFFFFFFFFFFF84
GPR30 FFFFFFFFFFFFFFFD
GPR31
CR 0000000024044888
LR 0000000600000006
CTR 0000000000008079
XER 0000000000000000

BIN
tests/1000.bin Normal file

Binary file not shown.

37
tests/1000.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FFFFFFFFFFF925B4
GPR1 00000020000067CB
GPR2 000000002002F400
GPR3 0000000000000000
GPR4 0000000000000000
GPR5 0000000000000000
GPR6 0000000000000000
GPR7 0000000000000000
GPR8 0000000000000000
GPR9 0000000091810280
GPR10 0000000000000020
GPR11 0000002000000020
GPR12 FFFFFFFFFFF8AD1F
GPR13 FFFFFFFFFFFFFFFF
GPR14 0000000000000000
GPR15 0000000000000000
GPR16 FFFFFFFFFFFFB67B
GPR17 0000000000000000
GPR18 FFFFFFFFFFFFFFFF
GPR19 FFFFFFFFF31EFFC4
GPR20 0000000000000000
GPR21 FFFFFFFF54A6FFFE
GPR22 0000000000000000
GPR23 0000000000000000
GPR24 0000000000000000
GPR25 0000000000000020
GPR26 0000000000070080
GPR27 000007FFFFD4417F
GPR28 0000000000000000
GPR29 FFFFFFFFFFFFFFFF
GPR30 0000000000000002
GPR31
CR 000000008000F400
LR 0000000000000000
CTR 0000000000006E31
XER 0000000000000000

BIN
tests/101.bin Normal file

Binary file not shown.

37
tests/101.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FF800000A729EDF7
GPR1 0000000000000000
GPR2 0000000000000020
GPR3 09200000091E3FDF
GPR4 FFFFFFFFFFFFEDB7
GPR5 0000000000000000
GPR6 FFFFFFFFFFFF7FBF
GPR7 0000000000000040
GPR8 0000000000009CB3
GPR9 0000000000008040
GPR10 0000000000000000
GPR11 FFFFFFFFFFFFEDB7
GPR12 0000000000001248
GPR13 0000000000000000
GPR14 0000000000000000
GPR15 000000000009CB30
GPR16 000000000001C020
GPR17 0000000000000000
GPR18 0000000000000020
GPR19 FFFFFFFFFFFFFFFF
GPR20 000000002B860004
GPR21 0000000000000000
GPR22 0000000000080040
GPR23 0000000000000000
GPR24 0808080408080844
GPR25 0000000000000020
GPR26 FFFFFFFFFFFFDDB2
GPR27 0000000000000004
GPR28 0000000000000000
GPR29 FFFFFFFFFFFFFFFF
GPR30 09200000091FFFFF
GPR31
CR 0000000040484848
LR 0000FFF58DE55790
CTR 0000000000000000
XER 0000000000000000

BIN
tests/102.bin Normal file

Binary file not shown.

37
tests/102.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 007F800000000075
GPR1 FFFFFFFEFFFFC84A
GPR2 FFFFFFFFBFFFFFFF
GPR3 0000000000020000
GPR4 FFFFFFFFFFFFFFF0
GPR5 FFFFFFFFFFF87F8A
GPR6 0000000000008000
GPR7 0000000000078000
GPR8 0000000040020001
GPR9 FFFFFFFFFFFFFFFF
GPR10 000F800000000000
GPR11 0000000000000000
GPR12 0000000000000000
GPR13 0000000000000004
GPR14 00000000FFFFFFFE
GPR15 0400000000000000
GPR16 000000001FC2D580
GPR17 FFFFFFFF00000001
GPR18 000000000000000E
GPR19 0000000000000000
GPR20 000000000000000F
GPR21 0000000000000000
GPR22 0000000040000000
GPR23 0000000000000000
GPR24 0000000000000000
GPR25 000000000001C020
GPR26 FFFFFFFFFFFFFFFF
GPR27 000000000000000F
GPR28 0FFFFE008E00D7FF
GPR29 00000000E94FB175
GPR30 000000000000001C
GPR31
CR 0000000080080004
LR FFFFFFFC0010351D
CTR 0000000000000000
XER 0000000000000000

BIN
tests/103.bin Normal file

Binary file not shown.

37
tests/103.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FFFFFFFFFFFE3BBB
GPR1 0000000000000000
GPR2 0000000000000000
GPR3 000000004FFF4494
GPR4 0000000000000000
GPR5 0000000000001CA3
GPR6 0000000000000040
GPR7 FFFFFFFFFFFE3BFB
GPR8 FFFFFFFFFFFFFFFF
GPR9 0000000000000000
GPR10 0000000000000000
GPR11 FFFFFFFFFF83FFFF
GPR12 0000000000000000
GPR13 0000000000000000
GPR14 FFFFFFFFFFFFFFFF
GPR15 0000000000000000
GPR16 3221E7883221E788
GPR17 0000000000000019
GPR18 FFFFFFFFFFFE401F
GPR19 0000000001FFE0FF
GPR20 0000000327CE0003
GPR21 0000000000000000
GPR22 0001092C00010924
GPR23 FFFFFFFFFFFFFFFF
GPR24 0000000000000424
GPR25 0001092300010923
GPR26 0000000000000000
GPR27 0000000000000000
GPR28 000000000000113B
GPR29 0000000000000001
GPR30 000000000001C020
GPR31
CR 000000002FFF4494
LR FFFFFFFFFFFFFFFF
CTR FFFFFFFFFFFFFFFB
XER 0000000000000000

BIN
tests/104.bin Normal file

Binary file not shown.

37
tests/104.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 000FFFFFFFFC7FC1
GPR1 001AD982BFCDBA72
GPR2 FFFFFFFFFFFFC020
GPR3 FFFFFFFFFFFFFFFF
GPR4 0000003FFFEF915B
GPR5 00017A7380400000
GPR6 FFFFFFFFFFFFFFFF
GPR7 0000000000000000
GPR8 000000F1FF000000
GPR9 FFFFFFFFFFFC7FC0
GPR10 0000000000000038
GPR11 FFFFFFFFFFFFFFFF
GPR12 0000000000000000
GPR13 000000000001007E
GPR14 0000000000000000
GPR15 000000000003803F
GPR16 FFFFFFFFFFFFFFFF
GPR17 00000000000034C4
GPR18 00000000001069C8
GPR19 000000000003803F
GPR20 0000000000000000
GPR21 FFFFFFFFFFFE4E35
GPR22 0000000000000000
GPR23 0000000000000000
GPR24 FFFFFFFFFFFFFFFF
GPR25 00000000000001C0
GPR26 000000000000C020
GPR27 0000000000000000
GPR28 0000000000000000
GPR29 FFFFFFFFFFFFFFFF
GPR30 0000000000000000
GPR31
CR 0000000080442920
LR 0000000000000000
CTR 4000000000000000
XER 0000000000000000

BIN
tests/105.bin Normal file

Binary file not shown.

37
tests/105.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FFFFFCFEFFFFFFFD
GPR1 0000000000000000
GPR2 0000000000000000
GPR3 0000000000000000
GPR4 FFFFFFFFFFFF8681
GPR5 0000000000000000
GPR6 0000000000007CF4
GPR7 0000000000000000
GPR8 0000000000000000
GPR9 0000000000000C33
GPR10 0000000000000000
GPR11 0000000000008000
GPR12 0000000000007CF4
GPR13 FFFFFFFFFFFF7FFF
GPR14 0000030100000001
GPR15 FFFFFFFFFFFF8681
GPR16 0000000000000000
GPR17 0000000000000001
GPR18 0000000000000004
GPR19 FFFFFFFFFFFFFFFE
GPR20 0000030100000001
GPR21 0000000000000000
GPR22 0000000000000040
GPR23 0000000000000020
GPR24 0000000000000001
GPR25 0000000000000020
GPR26 0000000000000010
GPR27 0000000000000010
GPR28 FFFFFFFFFFFFFFF0
GPR29 0000000000000C34
GPR30 0000000000000000
GPR31
CR 0000000022048408
LR 000000000001C020
CTR 0000000000000002
XER 0000000000000000

BIN
tests/106.bin Normal file

Binary file not shown.

37
tests/106.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 0000000000000020
GPR1 0000000000000000
GPR2 0000000000000040
GPR3 0000000000000000
GPR4 FFFFFE9F000000FF
GPR5 000000000001C020
GPR6 000000000001C02C
GPR7 0000000000000020
GPR8 0000000000000000
GPR9 0000000000000000
GPR10 0000000000000ECA
GPR11 0000000000000020
GPR12 0000000000000000
GPR13 000000004FDEB6F7
GPR14 FFFFFFFFFFFFFFFF
GPR15 FFFFFFFFFFFFFFFF
GPR16 000000200000ECA3
GPR17 0000000000000000
GPR18 0000002000000020
GPR19 0000000000002C9E
GPR20 00000014000007DF
GPR21 0000000000000000
GPR22 FFFFFFFFFFFFFFFF
GPR23 0000000000000000
GPR24 00000000000027EF
GPR25 0000000000000000
GPR26 0000000000000000
GPR27 0000000000000000
GPR28 0000000000000000
GPR29 0000000000000000
GPR30 0000000000000000
GPR31
CR 0000000042FE3088
LR 0000000000000000
CTR 000000005F5369F0
XER 0000000000000000

BIN
tests/107.bin Normal file

Binary file not shown.

37
tests/107.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 0000000000000011
GPR1 0000000000000FD2
GPR2 0000000000000000
GPR3 0000000000000000
GPR4 0000000000000006
GPR5 0400000000000000
GPR6 000000000000001F
GPR7 000000000000003D
GPR8 0000000000000000
GPR9 0000000000000000
GPR10 0000000000007BDF
GPR11 0000000000003BD7
GPR12 FFFFFFFFFFFF9E78
GPR13 0000000000005A48
GPR14 0000000000000000
GPR15 FFFFFFFFFFFF9E78
GPR16 000000000001C040
GPR17 0000000000000000
GPR18 FFFFFFFFFFFFFFC0
GPR19 0000000000000002
GPR20 0000000600000006
GPR21 0000000000000000
GPR22 0000000000000000
GPR23 0000000000000000
GPR24 0000000000000000
GPR25 FFFFFFF9FFFFFFFA
GPR26 FFFFFFFFFFFFFFFF
GPR27 0000000000000000
GPR28 000000000001C020
GPR29 FFFFFFFFFFFE3FE0
GPR30 0000000000000005
GPR31
CR 00000000200FFFCA
LR 0000000000000000
CTR FFFFFFFFFFFFFFFF
XER 0000000000000000

BIN
tests/108.bin Normal file

Binary file not shown.

37
tests/108.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FFFFFFF9000003FF
GPR1 0000000000000000
GPR2 0000000002048088
GPR3 0000000000000000
GPR4 0000000000000000
GPR5 0000000017CDD064
GPR6 0000000000000000
GPR7 0000000010000000
GPR8 0000000000000000
GPR9 0000000000000000
GPR10 00000000FFFF9091
GPR11 0000000000000000
GPR12 0000000000000000
GPR13 0000000000000000
GPR14 00000000000060D4
GPR15 0000000000000000
GPR16 0000000000000000
GPR17 0000000000080000
GPR18 0000000000000000
GPR19 0000000000000000
GPR20 0000000000000000
GPR21 0000000000000000
GPR22 FFFFFFFFFFFFFFFE
GPR23 FFFFFFFFFFF80000
GPR24 FFFFFFFFFFFFFFF5
GPR25 0000000000000000
GPR26 0000000000000000
GPR27 0000000000000000
GPR28 0000000000000000
GPR29 FFFFFFF9000803FF
GPR30 0000000000000000
GPR31
CR 0000000022048088
LR 0000000100000001
CTR FFFFFFFFFFFFFFFF
XER 0000000000000000

BIN
tests/109.bin Normal file

Binary file not shown.

37
tests/109.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 F825FFFFFFFFCF06
GPR1 0000000000000000
GPR2 FFFFFFFF2002FFFF
GPR3 00000000000000BC
GPR4 0000000000000040
GPR5 000000000000003F
GPR6 0000000000000000
GPR7 0000000000000000
GPR8 000000000000FFC2
GPR9 0000000000000000
GPR10 D900003FFFCA1326
GPR11 0000000000000000
GPR12 0000000000010201
GPR13 0000000010600A12
GPR14 FFFFFFFFFFFFCF05
GPR15 FFFFFFFFFBFFFBF7
GPR16 0000000000000000
GPR17 0000000020000000
GPR18 0000000000000000
GPR19 00000000DFBD0000
GPR20 0000000004000408
GPR21 00000000DFBD0000
GPR22 FFFFFFFFFFFFE7B2
GPR23 0000000000000000
GPR24 0000000000000000
GPR25 00000000010800FF
GPR26 0000000000000000
GPR27 F1AC28504DD5F5EE
GPR28 0000000000000000
GPR29 0000000000F00000
GPR30 0000000000000000
GPR31
CR 0000000080F0048F
LR 0000000000000000
CTR 000000000007DFFF
XER 0000000000000000

BIN
tests/11.bin Normal file

Binary file not shown.

37
tests/11.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FFFFFFFFFFFFDA79
GPR1 0000000000000000
GPR2 0000000000000000
GPR3 0000000000000004
GPR4 000000004000C01F
GPR5 01FC000680000000
GPR6 01FC000680000000
GPR7 000000004000E5A6
GPR8 0000000000700000
GPR9 FFFFFFFFBFFF3FE1
GPR10 FFFFFFFFFFFFC01F
GPR11 FFFFFFFFFFFFFFFF
GPR12 8F337EB19C336FE0
GPR13 0003800000000000
GPR14 01FF800680000000
GPR15 0000000000000000
GPR16 0000000000000000
GPR17 0000000000000001
GPR18 8F3360019C000000
GPR19 FFFFFFFFFFFFFFFC
GPR20 FFFFFFFFBFFF3FE1
GPR21 FFFFFFFFFFFFBB59
GPR22 FFFFFFFFFFFFFFFE
GPR23 03F8000F8E80470E
GPR24 0000000000000000
GPR25 000000000000003F
GPR26 FFFFFFFFFFFFDA79
GPR27 000000004000C01F
GPR28 FFFFFFFFFFFFDA79
GPR29 FFFFE00FFC00000F
GPR30 00007FFFE00F8000
GPR31
CR 000000002000C01F
LR 0003800000000000
CTR 8F337EB19C336FE1
XER 0000000000000000

BIN
tests/110.bin Normal file

Binary file not shown.

37
tests/110.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 0000000000000000
GPR1 0000000000000000
GPR2 FFFFFFFFFFFFFFFF
GPR3 0000000000000048
GPR4 FFFFFFFFFFFFF3F5
GPR5 42FFFFFFFE000000
GPR6 0000000000000000
GPR7 0000000000052486
GPR8 7008000000000000
GPR9 FFFFFFFFEFDE0004
GPR10 0000000000000000
GPR11 00000000001C0200
GPR12 0000000000000000
GPR13 0000000000000000
GPR14 0000000000000040
GPR15 0000000000000040
GPR16 0000000000000040
GPR17 000000000C160000
GPR18 0000000000000000
GPR19 0000000000000009
GPR20 FFFFFFFFFFFE3FE0
GPR21 0000000000000000
GPR22 00000000000009F5
GPR23 0000000000000000
GPR24 FFFFFFFFFFFFFFF7
GPR25 FFFFFFFFFFFFFD0B
GPR26 000000000001C020
GPR27 0000000000000008
GPR28 FFFFFFFFFFFFFFF6
GPR29 000000000000978F
GPR30 000000000001C004
GPR31
CR 0000000040000080
LR 0000000000000000
CTR FFFFFFFFFFFFFFFD
XER 0000000000000000

BIN
tests/111.bin Normal file

Binary file not shown.

37
tests/111.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 0000000040023FB2
GPR1 000000004002B580
GPR2 FFFFFFFFFFFFFFFF
GPR3 FFFFFFFFFFFFC00D
GPR4 FFFFFFFFFFFFDF85
GPR5 FFFF8FFCBFFD4AC1
GPR6 0000000000000000
GPR7 0000000000000000
GPR8 0000000000000040
GPR9 000000007D0F0000
GPR10 FFFFFFFF4002B57E
GPR11 0000000000000000
GPR12 FFFFFFFFFFFF86BC
GPR13 47503DCF87503DD0
GPR14 8EA07BA08EA07B9F
GPR15 0000000000000000
GPR16 FFFFFFFFFFFFFFF3
GPR17 0000000000000000
GPR18 0000000000003FF3
GPR19 0000000000000000
GPR20 8EA07BA08EA07B9F
GPR21 FFFFFFFFBFFD4A80
GPR22 0000000000000000
GPR23 0000000080020040
GPR24 FFFFFFFFFFFFFFF3
GPR25 FFFFFFFFFFFFB5C7
GPR26 FFFFFFFFFFFFC00D
GPR27 0000000000000000
GPR28 FFFFFFFFFFFFFFFF
GPR29 0000000000680000
GPR30 0000000000000000
GPR31
CR 0000000020020040
LR 000000000001C016
CTR 0000000000000000
XER 0000000000000000

BIN
tests/112.bin Normal file

Binary file not shown.

37
tests/112.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 00000000FFFFD39A
GPR1 0000000000000000
GPR2 0000000000000000
GPR3 0000000000000000
GPR4 0000000000000000
GPR5 0000000000000000
GPR6 0000000000000000
GPR7 0000000000000000
GPR8 0000000000000011
GPR9 0000000089570000
GPR10 0000000000000000
GPR11 0000000000000000
GPR12 300000EA00000000
GPR13 FFFFFFFFFFFFFFFF
GPR14 000000000000001E
GPR15 000000000001C020
GPR16 000000000000001E
GPR17 0000000000800000
GPR18 00000000A6270020
GPR19 0000000000000001
GPR20 0000000000000020
GPR21 0000000000000000
GPR22 0000000000000040
GPR23 FFFFFFFFFFFFFFFF
GPR24 000000000000001A
GPR25 000000000000001E
GPR26 0000000000000000
GPR27 0000000000000000
GPR28 FFFFFFFFFFFFFFFF
GPR29 0000000000000000
GPR30 0000000000003F52
GPR31
CR 0000000020084430
LR 0000000000000020
CTR FFFFFFFFFFFFFFFF
XER 0000000000000000

BIN
tests/113.bin Normal file

Binary file not shown.

37
tests/113.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 FFFFFFFFFFFFFFFF
GPR1 0000000044444848
GPR2 000000200000001A
GPR3 FFFFFFFFFFFFFF90
GPR4 0000000000000000
GPR5 0000000000000005
GPR6 FFFFFFFFFFFFAEF1
GPR7 FFFFFFFFFFFFF87E
GPR8 0000000000000000
GPR9 0000000000280000
GPR10 0000137ADC420000
GPR11 F7FFFF2337ADC420
GPR12 00F8000000000000
GPR13 0000000000000000
GPR14 6800000000000000
GPR15 FFFFFF90FF801F90
GPR16 FFFFFFFFFFFFFFFF
GPR17 0000000000000000
GPR18 F7FFFF2337ADC420
GPR19 00000000FFFFFFFF
GPR20 0000000000010604
GPR21 000000000000001F
GPR22 FFFFFFFFFFFFFFFF
GPR23 000000000000001A
GPR24 000000001FFFFFFE
GPR25 000000001BD6A62F
GPR26 FFFFFFFFFFFFFFFF
GPR27 0000000000010604
GPR28 0000000000000000
GPR29 FFFFFFFFFFFFFFFF
GPR30 000000001BD6E20F
GPR31
CR 0000000044444848
LR 000000000000001A
CTR FFFFFFFFFFFFFFFF
XER 0000000000000000

BIN
tests/114.bin Normal file

Binary file not shown.

37
tests/114.out Normal file
View File

@@ -0,0 +1,37 @@
GPR0 00000000000FF02B
GPR1 0000000000000000
GPR2 0000000000000000
GPR3 0000000000000000
GPR4 0000000000000000
GPR5 0000000000000020
GPR6 0000000080000000
GPR7 0000000000000000
GPR8 00000000000E4074
GPR9 00000003FFFFC000
GPR10 00000000000E4073
GPR11 0000000000000000
GPR12 0000000000000020
GPR13 000000000000982B
GPR14 000000000000003A
GPR15 0000000000000000
GPR16 000000000001C005
GPR17 0000000000000000
GPR18 0000000000000000
GPR19 FFFFFFFFFFFFFFFF
GPR20 0000000000000000
GPR21 000000000000003A
GPR22 000000000000001A
GPR23 000000000000003A
GPR24 FFFFFFFFFFF1BF8D
GPR25 000007FFFFFFFFFF
GPR26 0000000000000000
GPR27 000000000000003A
GPR28 0000000000100093
GPR29 0000000000000000
GPR30 0000000000000000
GPR31
CR 00000000428180B4
LR 0000000000000000
CTR 0000000000000000
XER 0000000000000000

BIN
tests/115.bin Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More