mirror of
https://github.com/antonblanchard/chiselwatt.git
synced 2026-04-12 07:15:43 +00:00
Initial import
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
project/
|
||||
target/
|
||||
obj_dir/
|
||||
out/
|
||||
*.anno.json
|
||||
*.fir
|
||||
*.vcd
|
||||
8
LICENSE
Normal file
8
LICENSE
Normal 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
86
Makefile
Normal 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
77
README.md
Normal 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
58
build.sbt
Normal 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
115
chiselwatt.cpp
Normal 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
19
constraints/ecp5-evn.lpf
Normal 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;
|
||||
19
constraints/orange-crab.lpf
Normal file
19
constraints/orange-crab.lpf
Normal 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
BIN
hello_world/hello_world.bin
Executable file
Binary file not shown.
BIN
hello_world/hello_world.elf
Executable file
BIN
hello_world/hello_world.elf
Executable file
Binary file not shown.
586
hello_world/hello_world.hex
Normal file
586
hello_world/hello_world.hex
Normal 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
BIN
micropython/firmware.bin
Normal file
Binary file not shown.
BIN
micropython/firmware.elf
Executable file
BIN
micropython/firmware.elf
Executable file
Binary file not shown.
33124
micropython/firmware.hex
Normal file
33124
micropython/firmware.hex
Normal file
File diff suppressed because it is too large
Load Diff
1
openocd/LFE5U-25F.cfg
Normal file
1
openocd/LFE5U-25F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41111043
|
||||
1
openocd/LFE5U-45F.cfg
Normal file
1
openocd/LFE5U-45F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41112043
|
||||
1
openocd/LFE5U-85F.cfg
Normal file
1
openocd/LFE5U-85F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41113043
|
||||
1
openocd/LFE5UM-25F.cfg
Normal file
1
openocd/LFE5UM-25F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01111043
|
||||
1
openocd/LFE5UM-45F.cfg
Normal file
1
openocd/LFE5UM-45F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01112043
|
||||
1
openocd/LFE5UM-85F.cfg
Normal file
1
openocd/LFE5UM-85F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x01113043
|
||||
1
openocd/LFE5UM5G-25F.cfg
Normal file
1
openocd/LFE5UM5G-25F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81111043
|
||||
1
openocd/LFE5UM5G-45F.cfg
Normal file
1
openocd/LFE5UM5G-45F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81112043
|
||||
1
openocd/LFE5UM5G-85F.cfg
Normal file
1
openocd/LFE5UM5G-85F.cfg
Normal file
@@ -0,0 +1 @@
|
||||
jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043
|
||||
13
openocd/ecp5-evn.cfg
Normal file
13
openocd/ecp5-evn.cfg
Normal 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
|
||||
17
openocd/olimex-arm-usb-tiny-h.cfg
Normal file
17
openocd/olimex-arm-usb-tiny-h.cfg
Normal 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
30
pll_ecp5_evn.v
Normal 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
17
scripts/bin2hex.py
Executable 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
57
scripts/gen-decode-table.py
Executable 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
1793
scripts/instructions.yaml
Normal file
File diff suppressed because it is too large
Load Diff
32
scripts/run_test.sh
Executable file
32
scripts/run_test.sh
Executable 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
|
||||
37
src/main/scala/Adder.scala
Normal file
37
src/main/scala/Adder.scala
Normal 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))
|
||||
}
|
||||
326
src/main/scala/Control.scala
Normal file
326
src/main/scala/Control.scala
Normal 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
396
src/main/scala/Core.scala
Normal 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))
|
||||
}
|
||||
94
src/main/scala/CountZeroes.scala
Normal file
94
src/main/scala/CountZeroes.scala
Normal 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
|
||||
}
|
||||
}
|
||||
30
src/main/scala/Fetch.scala
Normal file
30
src/main/scala/Fetch.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
53
src/main/scala/Helpers.scala
Normal file
53
src/main/scala/Helpers.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
41
src/main/scala/InstructionHelpers.scala
Normal file
41
src/main/scala/InstructionHelpers.scala
Normal 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)
|
||||
}
|
||||
238
src/main/scala/Instructions.scala
Normal file
238
src/main/scala/Instructions.scala
Normal 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
|
||||
}
|
||||
205
src/main/scala/LoadStore.scala
Normal file
205
src/main/scala/LoadStore.scala
Normal 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"))
|
||||
}
|
||||
45
src/main/scala/LoadStoreByteReverse.scala
Normal file
45
src/main/scala/LoadStoreByteReverse.scala
Normal 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
|
||||
}
|
||||
}
|
||||
36
src/main/scala/Logical.scala
Normal file
36
src/main/scala/Logical.scala
Normal 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))
|
||||
}
|
||||
103
src/main/scala/MemoryBlackBox.scala
Normal file
103
src/main/scala/MemoryBlackBox.scala
Normal 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
28
src/main/scala/Nia.scala
Normal 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))
|
||||
}
|
||||
53
src/main/scala/PopulationCount.scala
Normal file
53
src/main/scala/PopulationCount.scala
Normal 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))
|
||||
}
|
||||
40
src/main/scala/RegisterFile.scala
Normal file
40
src/main/scala/RegisterFile.scala
Normal 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))
|
||||
}
|
||||
115
src/main/scala/Rotator.scala
Normal file
115
src/main/scala/Rotator.scala
Normal 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))
|
||||
}
|
||||
89
src/main/scala/SimpleDivider.scala
Normal file
89
src/main/scala/SimpleDivider.scala
Normal 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))
|
||||
}
|
||||
79
src/main/scala/SimpleMultiplier.scala
Normal file
79
src/main/scala/SimpleMultiplier.scala
Normal 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
202
src/main/scala/Uart.scala
Normal 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))
|
||||
}
|
||||
73
src/test/scala/CountZeroes.scala
Normal file
73
src/test/scala/CountZeroes.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
src/test/scala/LoadStore.scala
Normal file
114
src/test/scala/LoadStore.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/test/scala/LoadStoreAlign.scala
Normal file
19
src/test/scala/LoadStoreAlign.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/test/scala/LoadStoreByteReverse.scala
Normal file
26
src/test/scala/LoadStoreByteReverse.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/test/scala/LoadStoreDeAlign.scala
Normal file
19
src/test/scala/LoadStoreDeAlign.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/test/scala/MemoryBlackBox.scala
Normal file
47
src/test/scala/MemoryBlackBox.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
54
src/test/scala/PopulationCount.scala
Normal file
54
src/test/scala/PopulationCount.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/test/scala/RegisterFile.scala
Normal file
58
src/test/scala/RegisterFile.scala
Normal 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/test/scala/SimpleDivider.scala
Normal file
43
src/test/scala/SimpleDivider.scala
Normal 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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
89
src/test/scala/SimpleMultiplier.scala
Normal file
89
src/test/scala/SimpleMultiplier.scala
Normal 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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/test/scala/TestValues.scala
Normal file
45
src/test/scala/TestValues.scala
Normal 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
79
src/test/scala/Uart.scala
Normal 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
BIN
tests/1.bin
Normal file
Binary file not shown.
37
tests/1.out
Normal file
37
tests/1.out
Normal 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
BIN
tests/10.bin
Normal file
Binary file not shown.
37
tests/10.out
Normal file
37
tests/10.out
Normal 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
BIN
tests/100.bin
Normal file
Binary file not shown.
37
tests/100.out
Normal file
37
tests/100.out
Normal 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
BIN
tests/1000.bin
Normal file
Binary file not shown.
37
tests/1000.out
Normal file
37
tests/1000.out
Normal 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
BIN
tests/101.bin
Normal file
Binary file not shown.
37
tests/101.out
Normal file
37
tests/101.out
Normal 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
BIN
tests/102.bin
Normal file
Binary file not shown.
37
tests/102.out
Normal file
37
tests/102.out
Normal 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
BIN
tests/103.bin
Normal file
Binary file not shown.
37
tests/103.out
Normal file
37
tests/103.out
Normal 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
BIN
tests/104.bin
Normal file
Binary file not shown.
37
tests/104.out
Normal file
37
tests/104.out
Normal 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
BIN
tests/105.bin
Normal file
Binary file not shown.
37
tests/105.out
Normal file
37
tests/105.out
Normal 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
BIN
tests/106.bin
Normal file
Binary file not shown.
37
tests/106.out
Normal file
37
tests/106.out
Normal 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
BIN
tests/107.bin
Normal file
Binary file not shown.
37
tests/107.out
Normal file
37
tests/107.out
Normal 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
BIN
tests/108.bin
Normal file
Binary file not shown.
37
tests/108.out
Normal file
37
tests/108.out
Normal 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
BIN
tests/109.bin
Normal file
Binary file not shown.
37
tests/109.out
Normal file
37
tests/109.out
Normal 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
BIN
tests/11.bin
Normal file
Binary file not shown.
37
tests/11.out
Normal file
37
tests/11.out
Normal 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
BIN
tests/110.bin
Normal file
Binary file not shown.
37
tests/110.out
Normal file
37
tests/110.out
Normal 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
BIN
tests/111.bin
Normal file
Binary file not shown.
37
tests/111.out
Normal file
37
tests/111.out
Normal 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
BIN
tests/112.bin
Normal file
Binary file not shown.
37
tests/112.out
Normal file
37
tests/112.out
Normal 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
BIN
tests/113.bin
Normal file
Binary file not shown.
37
tests/113.out
Normal file
37
tests/113.out
Normal 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
BIN
tests/114.bin
Normal file
Binary file not shown.
37
tests/114.out
Normal file
37
tests/114.out
Normal 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
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
Reference in New Issue
Block a user