소스 검색

Merge branch 'master' into sindre-ex1

sindre-ex1
Sindre Stephansen 6 년 전
부모
커밋
bd3b72ee91
22개의 변경된 파일716개의 추가작업 그리고 904개의 파일을 삭제
  1. +4
    -0
      .jvmopts
  2. BIN
      Images/FiveStage.png
  3. BIN
      Images/IDstage.png
  4. BIN
      Images/IFID.png
  5. BIN
      Images/MEMstage.png
  6. +75
    -20
      exercise.org
  7. +109
    -0
      exercise2.org
  8. +2
    -0
      instructions.org
  9. +10
    -6
      src/main/scala/IF.scala
  10. +8
    -5
      src/main/scala/ToplevelSignals.scala
  11. +192
    -192
      src/test/resources/tests/basic/forward1.s
  12. +201
    -201
      src/test/resources/tests/basic/forward2.s
  13. +7
    -6
      src/test/scala/RISCV/DataTypes.scala
  14. +6
    -3
      src/test/scala/RISCV/Ops.scala
  15. +27
    -25
      src/test/scala/RISCV/Parser.scala
  16. +18
    -10
      src/test/scala/RISCV/VM.scala
  17. +37
    -33
      src/test/scala/RISCV/assembler.scala
  18. +0
    -178
      src/test/scala/RISCV/deleteMe.scala
  19. +0
    -164
      src/test/scala/RISCV/deleteMe2.scala
  20. +14
    -12
      src/test/scala/RISCV/printUtils.scala
  21. +6
    -6
      src/test/scala/TestUtils.scala
  22. +0
    -43
      src/test/scala/testConf.scala

+ 4
- 0
.jvmopts 파일 보기

@@ -0,0 +1,4 @@
-Xms512M
-Xmx4096M
-Xss32M
-XX:MaxMetaspaceSize=1024M

BIN
Images/FiveStage.png 파일 보기

Before After
Width: 3674  |  Height: 1522  |  Size: 85KB

BIN
Images/IDstage.png 파일 보기

Before After
Width: 1279  |  Height: 1389  |  Size: 63KB

BIN
Images/IFID.png 파일 보기

Before After
Width: 596  |  Height: 212  |  Size: 6.6KB

BIN
Images/MEMstage.png 파일 보기

Before After
Width: 693  |  Height: 1023  |  Size: 24KB

+ 75
- 20
exercise.org 파일 보기

@@ -1,4 +1,4 @@
* Exercise 1
* Exercise description
The task in this exercise is to implement a 5-stage pipelined processor for
the [[./instructions.org][RISCV32I instruction set]].
@@ -6,14 +6,27 @@
at a time, whereas in exercise 2 your design will handle multiple instructions
at a time.
This is done by inserting 4 NOP instructions inbetween each source instruction,
enabling us to use the same tests for both exercise 1 and 2.
enabling us to use the same tests and harness for both exercise 1 and 2.
Once you are done with exercise 1, you can up the difficulty by setting nopPad
to false and start reading the [[exercise2.org][ex2 guide]].

In the project skeleton files ([[./src/main/scala/][Found here]]) you can see that a lot of code has
already been provided.
already been provided, which can make it difficult to get started.
Hopefully this document can help clear up at least some of the confusion.
First an overview of what you are designing is presented, followed by a walk-through
for getting the most basic instructions to work.
In order to orient yourself you first need a map, thus a high level overview of the
processor you're going to design is showed underneath:
Keep in mind that this is just a high level sketch, omitting many details as well
entire features (for instance branch logic)

#+CAPTION: A very high level processor schematic. Registers, Instruction and data memory are already implemented.
[[./Images/FiveStage.png]]
Before going further it is useful to get an overview of what is provided out
of the box.
Now that you have an idea of what you're building it is time to take inventory of
the files included in the skeleton, and what, if anything should be added.

+ [[./src/main/scala/Tile.scala]]
This is the top level module for the system as a whole. This is where the test
@@ -26,7 +39,11 @@
should be declared and wired together.
Some of these modules have already been declared in order to wire up the
debugging logic for your test harness.
This file corresponds to the high-level overview in its entirety.
*This module is intended to be further fleshed out by you.*
As you work with this module, try keeping logic to a minimum to help readability.
If you end up with a lot of signal select logic, consider moving that to a separate
module.
+ [[./src/main/scala/IF.scala]]
This is the instruction fetch stage.
@@ -94,10 +111,11 @@
of these settings can be quite useful to alter.
The main attraction is the test options. By altering the verbosity settings you
may change what is output.
The settings are
The settings are:

+ printIfSuccessful
Enables logging on tests that succeed
Enables logging on tests that succeed.
You typically want this turned off, at least for the full test runner.

+ printErrors
Enables logging of errors. You obviously want this one on, at least on the single
@@ -147,6 +165,12 @@
In your sketch you will eventually add a box for registers, IMEM and DMEM, which
should make it clear how the already finished modules fit into the grander design,
making the skeleton-code less mysterious.
To give you an idea of how a drill down looks like, here is my sketch of the ID stage:
#+CAPTION: Instruction decode stage, showing the various signals.
[[./Images/IDstage.png]]
I would generally advice to do these on paper, but don't half-ass them.


** Adding numbers
@@ -174,11 +198,11 @@

**** Step ¾:
In your console, type ~testOnly FiveStage.SingleTest~ to run only the tests that you
have defined in the [[./src/test/scala/Manifest.scala][test manifest]] (currently set to ~"forward2.s"~).
have defined in the [[./src/test/scala/Manifest.scala][test manifest]] (currently set to ~forward2.s~).

As you will first implement addition you should change this to the [[./src/test/resources/tests/basic/immediate/addi.s][add immediate test]].
Luckily you do not have to deal with file paths, simply changing ~"forward2.s"~ to
~"addi.s"~ suffices.
Luckily you do not have to deal with file paths, simply changing ~forward2.s~ to
~addi.s~ suffices.

Ensure that the addi test is run by repeating the ~testOnly FiveStage.SingleTest~
command.
@@ -188,7 +212,7 @@
In [[./src/test/main/IF.scala]] you can see that the IMEM module is already set to fetch
the current program counter address (line 41), however since the current PC is stuck
at 0 it will fetch the same instruction over and over. Rectify this by commenting in
~// PC := PC + 4.U~ at line 43.
~// PC := PC + 4.U~ at line 48.
You can now verify that your design fetches new instructions each cycle by running
the test as in the previous step.

@@ -207,10 +231,10 @@
Next you need to ensure that the registers and decoder gets the relevant data from the
instruction.

This is made more convenient by the fact that `Instruction` is a class, allowing you
This is made more convenient by the fact that ~Instruction~ is a class, allowing you
to access methods defined on it.
Keep in mind that it is only a class at compile and synthesis time, it will be
indistinguishable from a regular ~UIint(32.W)~ in your finished circuit.
Keep in mind that it is only a class during compile and build time, it will be
indistinguishable from a regular ~UInt(32.W)~ in your finished circuit.
The methods can be accessed like this:
#+BEGIN_SRC scala
// Drive funct6 of myModule with the 26th to 31st bit of instruction
@@ -221,9 +245,27 @@
Your IF should now have an instruction as an OUTPUT, and your ID as an INPUT, however
they are not connected. This must be done in the CPU class where both the ID and IF are
instantiated.
In the overview sketch you probably noticed the barriers between IF and ID.
In accordance with the overview, it is incorrect to directly connect the two modules,
instead you must connect them using a *barrier*.
A barrier is responsible for keeping a value inbetween cycles, facilitating pipelining.
There is however one complicating matter: It takes a cycle to get the instruction from the
instruction memory, thus we don't want to delay it in the barrier!
In order to make code readable I suggest adding a new file for your barriers, containing
four different modules for the barriers your design will need.

Start with implementing your IF barrier module, which should contain the following:
+ An input and output for PC where the output is delayed by a single cycle.
+ An input and output for instruction where the output is wired directly to the input with
no delay.
The sketch for your barrier looks like this
#+CAPTION: The barrier between IF and ID. Note the passthrough for the instruction
[[./Images/IFID.png]]

**** Step 4½:
You should now verify that the correct control signals are produced. Using printf, ensure
You can now verify that the correct control signals are produced. Using printf, ensure
that:
+ The program counter is increasing in increments of 4
+ The instruction in ID is as expected
@@ -231,7 +273,8 @@
+ The correct operands are fetched from the registers

Keep in mind that printf might not always be cycle accurate, the point is to ensure that
your processor design at least does something!
your processor design at least does something! In general it is better to use debug signals
and println, but for quick and dirty debugging printf is passable.

*** Step 5:
You will now have to create the EX stage. Use the structure of the IF and ID modules to
@@ -247,12 +290,24 @@
...
)

io.aluResult := MuxLookup(0.U(32.W), io.aluOp, ALUopMap)
// MuxLookup API: https://github.com/freechipsproject/chisel3/wiki/Muxes-and-Input-Selection#muxlookup
io.aluResult := MuxLookup(io.aluOp, 0.U(32.W), ALUopMap)
#+END_SRC
As with the ID stage, you will need a barrier between ID and EX stage.
In this case, as the overview sketch indicates, all values should be delayed one cycle.
When you have finished the barrier, instantiate it and wire ID and EX together with the barrier in the
same fashion as IF and ID.
You don't need to add every single signal for your barrier, rather you should add them as they
become needed.

*** Step 6:
Your MEM stage does very little when an ADDI instruction is executed, so implementing it should
be easy. All you have to do is forward signals
be easy. All you have to do is forward signals.
From the overview sketch you can see that the same trick used in the IF/ID barrier is utilized
here, bypassing the data memory read value since it is already delayed by a cycle.

*** Step 7:
You now need to actually write the result back to your register bank.


+ 109
- 0
exercise2.org 파일 보기

@@ -0,0 +1,109 @@
* Exercise 2
Safety wheels are now officially off.
To verify this, set nopPadded to false in Manifest.scala and observe as all hell
breaks loose.
Let's break down what's going wrong and what we can do about it.

** RAW Hazards
Consider the following program:
#+begin_src asm
main:
add x1, x1, x2
add x1, x1, x1
add x1, x1, x2
#+end_src
In your implementation this will give you wrong results since the results
of the first add operation will not be available in the registers before
x1 is fetched for the second and third operation.
Your first task should therefore be to implement a forwarding unit
The forwarding unit is located in the EX stage and is responsible for selecting
the ALU input from three possible sources.
These sources are:
+ The value received from the register bank
+ The ALU result currently in MEM
+ The writeback result
The forwarder prioritizes as follows:
+ If the input register address is not the destination in either MEM or WB, select the
register.
+ If the input register address is the destination register in WB, but not in MEM, select
the writeback signal.
+ If the input register address is the destination register for the operation currently
in MEM, select that operation.
There is a special case you need take into account, namely load operations.
Considering the following program:
#+begin_src asm
main:
lw x1, 0(x2)
add x1, x1, x1
add x1, x1, x1
#+end_src
When the second operation (~add x1, x1, x1~) is in EX, the third clause in the forwarder
is triggered, however the result is not yet ready since fetching memory costs a cycle.
In order to fix this the forwarder must issue a signal that freezes the pipeline.
This is done by issuing a signal to the barrier registers, telling them to _not_ update
their contents, essentially repeating the last instruction.
There are many subtleties to consider here.
For instance: What should happen to the instruction currently
in MEM? If it too is repeated the hazard detector will trigger next cycle, effectively
deadlocking your processor.
What about when the write address and read address are similar in the ID stage?
Designing a forwarder can take very long, or it can be done very quickly, all depending
on how *methodical* you are. My advice is to design the algorithm first, then when you're
satisfied implement it on hardware.

** Control hazards

Consider the following code

#+begin_src asm
main:
beq zero, zero, target
add x1, x1, x1
add x1, x1, x1
j main
target:
sub x1, x2, x2
sub x2, x2, x2
#+end_src
Depending on your design the two add instructions will be fetched before the beq jump happens.
Whenever a branch happens it is necessary to flush the spurious instructions that were fetched
before the branch was noticed.
However, simply waiting until the branch has been decided is not acceptable since that guarantees
lost cycles.
In your first iteration, simply assume branches will not be taken, and if they are taken issue
a warning to the barriers that hold spurious instructions telling them to render them impotent
by setting the control signals to do nothing.
* Putting the pedal to the metal
Once you have a design that RAW and control hazards you're ready to up the ante and add some
improvements to your design.
Some suggestions:

** Branch predictor
Instead of assuming branch not taken, use a branch predictor. There are many different schemes,
but I advice you to stick to a simple one, such as 1-bit or 2-bit.

** Fast branch handling
Certaing branches like BEQ and BNE can be calculated very quickly, wheras size comparison branches
(BGE, BLE and friends) take longer. It is therefore feasible to do these checks in the ID stage.
** Adding a data cache
Unless you have already done the two suggested improvements, do not attempt to create a cache.
The first thing you need to do is to add a latency for memory fetching, if not you will have
nothing to improve upon.

If you still insist, start with the BTreeManyO3.s program and analyze the memory access pattern.
What sort of eviction policy and cache size would you choose for this pattern?
You should try writing additional benchmarking programs, it is important to have something measurable,
and the current programs are not made to test cache performance!!

+ 2
- 0
instructions.org 파일 보기

@@ -2,6 +2,8 @@
4.2. Register-Register Arithmetic Instructions
--------------------------------------------------------------------------

These do not render well on github, try using your text editor.

* ADD

- Summary : Addition with 3 GPRs, no overflow exception


+ 10
- 6
src/main/scala/IF.scala 파일 보기

@@ -8,13 +8,18 @@ class InstructionFetch extends MultiIOModule {
val testHarness = IO(
new Bundle {
val IMEMsetup = Input(new IMEMsetupSignals)
val PC = Output(UInt())
val PC = Output(UInt())
}
)


/**
* TODO: Add signals for handling events such as jumps
* TODO: Add input signals for handling events such as jumps

* TODO: Add output signal for the instruction.
* The instruction is of type Bundle, which means that you must
* use the same syntax used in the testHarness for IMEM setup signals
* further up.
*/
val io = IO(
new Bundle {
@@ -35,7 +40,7 @@ class InstructionFetch extends MultiIOModule {

/**
* TODO: Your code here.
*
*
* You should expand on or rewrite the code below.
*/
IMEM.io.instructionAddress := PC
@@ -47,11 +52,10 @@ class InstructionFetch extends MultiIOModule {


/**
* Setup. You should not change this code
* Setup. You should not change this code.
*/
when(testHarness.IMEMsetup.setup) {
PC := 0.U
// TODO: You must set the instruction to Instruction.NOP here.
// throw new Exception("Just making sure you're seeing the line above")
io.instruction := Instruction.NOP
}
}

+ 8
- 5
src/main/scala/ToplevelSignals.scala 파일 보기

@@ -22,14 +22,17 @@ class Instruction extends Bundle(){
def immediateJType = Cat(instruction(31), instruction(19, 12), instruction(20), instruction(30, 25), instruction(24, 21), 0.U(1.W)).asSInt
def immediateZType = instruction(19, 15).zext

def bubble(): Instruction = {
val bubbled = Wire(new Instruction)
bubbled.instruction := instruction
bubbled.instruction(6, 0) := BitPat.bitPatToUInt(BitPat("b0010011"))
bubbled
}
}
object Instruction {
def bubble(i: Instruction) =
i.opcode := BitPat.bitPatToUInt(BitPat("b0010011"))

def default: Instruction = {
def NOP: Instruction = {
val w = Wire(new Instruction)
w.instruction := 0.U
w.instruction := BitPat.bitPatToUInt(BitPat("b00000000000000000000000000010011"))
w
}
}


+ 192
- 192
src/test/resources/tests/basic/forward1.s 파일 보기

@@ -1,204 +1,204 @@
main:
ori gp, gp, 0xFFFFFE09
and gp, gp, ra
xor ra, ra, sp
sra ra, sp, sp
sltiu gp, ra, 0x01AE
srli sp, sp, 0x0005
addi ra, sp, 0x0177
srai sp, ra, 0x0003
sub sp, ra, sp
slli sp, ra, 0x000B
add sp, gp, ra
slli gp, sp, 0x0006
ori sp, ra, 0xFFFFFF64
and gp, gp, gp
andi gp, gp, 0x0084
xori ra, ra, 0xFFFFFEB4
or sp, ra, ra
xori ra, sp, 0x003D
srli sp, sp, 0xFFFFFFF2
addi ra, sp, 0x0012
add ra, gp, sp
ori gp, ra, 0xFFFFFFB8
sll ra, ra, ra
sll sp, gp, ra
slt ra, gp, ra
srai gp, gp, 0xFFFFFFFB
slli ra, ra, 0x0007
sub sp, gp, sp
andi ra, gp, 0x002D
sub gp, gp, sp
srai ra, gp, 0x0005
or sp, ra, sp
xori ra, gp, 0xFFFFFF54
sll ra, sp, ra
sub gp, gp, sp
add ra, sp, sp
sll ra, gp, ra
add gp, sp, sp
ori gp, sp, 0xFFFFFE68
srli sp, gp, 0xFFFFFFF1
sltui ra, ra, 0xFFFFFE5D
srli ra, gp, 0x0006
srai sp, sp, 0x0005
andi sp, sp, 0x0129
and sp, sp, sp
slli gp, ra, 0x0001
or gp, gp, gp
or sp, gp, gp
slli gp, gp, 0x0006
srl sp, ra, gp
sltui gp, ra, 0xFFFFFEC3
add sp, gp, sp
xori ra, ra, 0xFFFFFFA2
or gp, gp, sp
and sp, gp, gp
srai gp, sp, 0x0008
add sp, sp, ra
slti sp, ra, 0xFFFFFFF7
srli gp, ra, 0xFFFFFFFD
sll gp, ra, gp
sltu sp, sp, gp
srli gp, ra, 0x0002
ori gp, sp, 0xFFFFFF28
srl ra, gp, ra
slti gp, ra, 0x0054
or gp, ra, ra
ori sp, gp, 0x01D9
addi sp, ra, 0x0078
sltiu sp, sp, 0xFFFFFF1E
srli gp, sp, 0x0000
slti sp, ra, 0xFFFFFEF7
srai ra, ra, 0x0001
or sp, ra, gp
xor sp, sp, ra
sub sp, ra, sp
sub ra, gp, ra
sltiu gp, sp, 0xFFFFFE85
addi sp, gp, 0x017C
sltiu ra, gp, 0xFFFFFF64
xori sp, gp, 0x00A1
xor ra, sp, gp
ori gp, ra, 0x00B6
add ra, ra, sp
sltiu gp, ra, 0xFFFFFFEC
sltu gp, sp, ra
sll sp, ra, gp
add gp, ra, ra
or gp, ra, gp
xor sp, ra, sp
addi sp, gp, 0xFFFFFF4C
xor ra, sp, gp
xori ra, sp, 0xFFFFFF72
xori gp, sp, 0xFFFFFE95
or ra, ra, ra
slti ra, gp, 0xFFFFFE75
slli sp, sp, 0x0004
sltiu ra, ra, 0xFFFFFE25
add sp, ra, gp
sltiu gp, gp, 0xFFFFFFDB
addi sp, sp, 0x003D
sll ra, ra, sp
ori ra, ra, 0x012C
add gp, ra, gp
xori sp, sp, 0x0157
slti gp, sp, 0xFFFFFF2A
and sp, ra, ra
addi sp, gp, 0x0054
slli gp, ra, 0xFFFFFFF2
ori sp, sp, 0x0093
add gp, gp, gp
and gp, gp, gp
sltui gp, ra, 0x00DE
slli sp, gp, 0x000D
slli sp, ra, 0xFFFFFFF5
sltui sp, ra, 0xFFFFFF0E
and ra, gp, ra
add gp, sp, sp
slti ra, sp, 0x008C
srli ra, sp, 0x0000
addi sp, sp, 0x0168
slli ra, ra, 0xFFFFFFF3
addi ra, gp, 0x012A
or sp, gp, ra
add ra, sp, gp
and gp, ra, ra
slli ra, gp, 0xFFFFFFF6
or sp, gp, sp
or gp, ra, ra
ori gp, ra, 0x00EB
or sp, gp, ra
ori gp, sp, 0x01DA
andi ra, ra, 0xFFFFFFE9
addi gp, sp, 0x00C9
sltui ra, ra, 0xFFFFFF13
sltui ra, ra, 0xFFFFFF3A
sltui sp, gp, 0xFFFFFE5A
ori sp, sp, 0xFFFFFFFE
and gp, sp, gp
sltui sp, ra, 0x0034
srl gp, gp, ra
sll gp, sp, ra
ori ra, gp, 0xFFFFFEB6
sll ra, sp, ra
sra ra, gp, sp
sub ra, sp, gp
xor gp, gp, sp
sub ra, ra, sp
srl gp, gp, sp
andi ra, ra, 0xFFFFFFCB
ori ra, ra, 0xFFFFFE1B
andi ra, ra, 0xFFFFFEC8
sltui sp, gp, 0x0108
add gp, ra, ra
sltiu ra, gp, 0xFFFFFE56
sra gp, gp, ra
xori sp, gp, 0xFFFFFF0D
sub sp, gp, ra
slti ra, sp, 0x015D
slli sp, sp, 0x0004
xor gp, sp, ra
srl ra, gp, ra
sltui ra, ra, 0xFFFFFF3C
add sp, sp, sp
add gp, gp, ra
andi sp, sp, 0xFFFFFF3A
srli ra, sp, 0x0004
ori sp, gp, 0xFFFFFEAB
ori sp, ra, 0xFFFFFE95
slli sp, sp, 0xFFFFFFF2
xori gp, sp, 0x0040
slti gp, sp, 0xFFFFFED1
or sp, sp, sp
sltui sp, gp, 0x01B4
addi ra, gp, 0x002D
and sp, gp, gp
or ra, ra, ra
or ra, gp, ra
or ra, gp, ra
sra ra, ra, gp
sra gp, ra, sp
sub ra, sp, ra
slti ra, ra, 0x0154
slli ra, ra, 0x000A
ori ra, gp, 0xFFFFFEC2
ori ra, sp, 0x0075
addi gp, sp, 0x0079
xor gp, ra, sp
srli ra, sp, 0x0008
srai ra, ra, 0x000F
sltu sp, sp, ra
slli ra, gp, 0xFFFFFFF5
slti gp, gp, 0x00E0
addi gp, ra, 0xFFFFFF72
srl ra, ra, gp
sltui gp, sp, 0xFFFFFEAA
xor sp, ra, gp
and gp, sp, ra
srli gp, gp, 0x0003
xori ra, ra, 0x01BD
sub ra, gp, sp
slli gp, gp, 0x0006
sra sp, gp, gp
add sp, sp, sp
srai ra, sp, 0x0001
slli gp, ra, 0x0010
andi ra, ra, 0xFFFFFFA8
add sp, ra, sp
srai ra, gp, 0x000E
srai ra, sp, 0x0005
addi ra, gp, 0xFFFFFF83
xor gp, sp, ra
srai sp, gp, 0x0004
srli ra, ra, 0x0007
sll gp, ra, gp
xori ra, sp, 0x0065
or ra, sp, ra
slt sp, gp, ra
addi ra, sp, 0xFFFFFE34
slli gp, sp, 0x0007
sll ra, sp, gp
sltui gp, gp, 0xFFFFFE62
slti sp, sp, 0x0019
xori ra, gp, 0x0092
sltui gp, sp, 0xFFFFFF29
srl sp, ra, gp
xori sp, gp, 0xFFFFFF4C
add sp, ra, gp
add sp, gp, ra
xori gp, gp, 0x0163
add ra, gp, gp
srli gp, gp, 0x000B
add sp, ra, ra
sltu ra, ra, sp
sll sp, ra, ra
ori sp, sp, 0xFFFFFF6B
slli gp, gp, 0x0006
xori sp, ra, 0x00A7
add sp, ra, ra
add ra, gp, gp
addi gp, gp, 0xFFFFFFE9
sra sp, ra, gp
add gp, ra, ra
ori gp, gp, 0x0002
addi gp, gp, 0x002F
sll sp, sp, ra
srli sp, ra, 0x000E
ori gp, sp, 0x00EB
sra gp, ra, sp
sra sp, sp, gp
slli sp, ra, 0x0008
srl sp, sp, sp
and gp, ra, ra
sra ra, ra, gp
add sp, gp, ra
andi sp, sp, 0x0039
sll ra, gp, sp
andi gp, ra, 0xFFFFFECC
sll sp, sp, sp
sub sp, sp, ra
srai ra, sp, 0x0008
xor gp, ra, sp
add sp, sp, sp
sub gp, ra, gp
xori gp, sp, 0x01EE
and ra, ra, ra
ori gp, ra, 0xFFFFFE96
slli ra, gp, 0x0002
srli gp, ra, 0x000D
add ra, sp, sp
andi sp, gp, 0xFFFFFEC0
andi sp, gp, 0xFFFFFE7A
xori ra, sp, 0x0169
xori gp, sp, 0xFFFFFE02
andi ra, ra, 0xFFFFFFD1
xor ra, sp, gp
xori gp, gp, 0x00AB
srl ra, ra, gp
and ra, ra, sp
xori gp, sp, 0x005D
srai sp, sp, 0x000A
addi ra, sp, 0xFFFFFE19
srl gp, sp, gp
add ra, ra, sp
srai gp, ra, 0x000E
sltu gp, gp, sp
srli sp, ra, 0x0004
ori gp, sp, 0xFFFFFE6E
and gp, ra, ra
ori gp, ra, 0xFFFFFFAF
srl ra, ra, ra
or sp, ra, ra
addi ra, gp, 0x0084
ori sp, sp, 0xFFFFFF3D
xor gp, ra, gp
sra ra, ra, gp
xori ra, sp, 0x0040
srai gp, gp, 0x0002
xori ra, ra, 0xFFFFFE9A
sra ra, sp, sp
ori gp, sp, 0xFFFFFFB8
sll sp, ra, ra
sll sp, ra, gp
sll gp, sp, sp
sra gp, ra, ra
srli gp, gp, 0x0001
ori gp, sp, 0x0018
and gp, gp, gp
sll gp, sp, gp
srli gp, sp, 0x0006
add gp, ra, ra
add gp, ra, sp
sra sp, ra, ra
ori sp, ra, 0x0022
and gp, gp, gp
add ra, sp, ra
sll sp, gp, gp
ori gp, sp, 0x008E
add sp, ra, sp
and sp, gp, gp
addi ra, sp, 0x0145
and sp, gp, gp
sll gp, ra, sp
addi sp, sp, 0xFFFFFFAF
xori sp, ra, 0xFFFFFE2C
srl gp, ra, gp
sub ra, sp, gp
add sp, ra, ra
slli sp, sp, 0x0006
sltu gp, sp, ra
sub gp, ra, sp
xori ra, ra, 0xFFFFFF9A
addi sp, sp, 0xFFFFFE12
slli ra, ra, 0x0003
slli gp, ra, 0x0004
add gp, gp, gp
xori ra, ra, 0xFFFFFED7
andi gp, gp, 0xFFFFFE05
and gp, gp, sp
addi gp, gp, 0xFFFFFEE5
slli ra, gp, 0x000A
sll sp, gp, gp
and ra, gp, sp
ori ra, gp, 0xFFFFFE22
srl sp, sp, gp
srli ra, sp, 0x0005
slli ra, ra, 0x0005
srai ra, ra, 0x0007
srli ra, gp, 0x000F
andi gp, gp, 0xFFFFFF96
sra sp, gp, gp
srai gp, gp, 0x000F
sub sp, sp, gp
sltiu ra, ra, 0xFFFFFF41
and sp, sp, sp
xor gp, sp, ra
srai gp, sp, 0x000A
xori gp, gp, 0x00D3
or gp, sp, sp
sltu gp, ra, gp
slli ra, gp, 0x0002
or sp, gp, ra
addi ra, ra, 0x002B
addi gp, ra, 0x0035
slli sp, gp, 0x0008
addi gp, sp, 0x015E
xor ra, gp, sp
or ra, gp, ra
sll ra, gp, ra
sll gp, gp, ra
srli gp, ra, 0x000C
slt sp, ra, sp
sltiu sp, sp, 0xFFFFFE1C
ori sp, ra, 0xFFFFFE83
andi sp, sp, 0xFFFFFEFC
addi ra, ra, 0xFFFFFF85
ori gp, ra, 0x0084
sll gp, gp, ra
xori gp, sp, 0xFFFFFF6D
sll gp, sp, gp
sra ra, sp, ra
xor ra, gp, sp
srl ra, ra, sp
srl ra, ra, sp
andi gp, ra, 0xFFFFFE7B
srai ra, sp, 0x000F
sub sp, sp, ra
or sp, gp, gp
slt ra, ra, gp
or gp, gp, sp
srli ra, sp, 0x000B
andi ra, gp, 0xFFFFFFD4
slli ra, gp, 0x0009
done
#regset x1, 123
#regset x2, -40


+ 201
- 201
src/test/resources/tests/basic/forward2.s 파일 보기

@@ -1,205 +1,205 @@
main:
sltui gp, ra, 0x01AE
srli sp, sp, 0xFFFFFFFB
addi ra, sp, 0x0177
sub sp, ra, sp
slli sp, ra, 0x000B
add sp, gp, ra
slli gp, sp, 0x0006
ori sp, ra, 0xFFFFFF64
and gp, gp, gp
andi gp, gp, 0x0084
xori ra, ra, 0xFFFFFEB4
or sp, ra, ra
addi sp, ra, 0x0078
srli gp, sp, 0x0000
srl sp, gp, sp
andi ra, gp, 0xFFFFFFF4
srai ra, ra, 0xFFFFFFFF
sltu gp, sp, gp
or sp, ra, gp
sub ra, gp, ra
addi sp, gp, 0x017C
sltui ra, gp, 0xFFFFFF64
xori sp, gp, 0x00A1
xor ra, sp, gp
ori gp, ra, 0x00B6
add ra, ra, sp
sltui gp, ra, 0xFFFFFFEC
sltu gp, sp, ra
sll sp, ra, gp
add gp, ra, ra
or gp, ra, gp
xor sp, ra, sp
addi sp, gp, 0xFFFFFF4C
xor ra, sp, gp
xori ra, sp, 0xFFFFFF72
xori gp, sp, 0xFFFFFE95
or ra, ra, ra
slti ra, gp, 0xFFFFFE75
slli sp, sp, 0xFFFFFFFC
sltui ra, ra, 0xFFFFFE25
add sp, ra, gp
sltui gp, gp, 0xFFFFFFDB
addi sp, sp, 0x003D
sll ra, ra, sp
ori ra, ra, 0x012C
add gp, ra, gp
xori sp, sp, 0x0157
slti gp, sp, 0xFFFFFF2A
and sp, ra, ra
add gp, ra, ra
sltui ra, gp, 0xFFFFFE56
sra gp, gp, ra
xori sp, gp, 0xFFFFFF0D
sub sp, gp, ra
slti ra, ra, 0x0154
slli ra, ra, 0x000A
ori ra, gp, 0xFFFFFEC2
ori ra, sp, 0x0075
addi gp, sp, 0x0079
xor gp, ra, sp
srli ra, sp, 0xFFFFFFF8
slli gp, gp, 0x0006
sra sp, gp, gp
add sp, sp, sp
slli gp, ra, 0xFFFFFFF0
add sp, ra, sp
srai ra, sp, 0x0005
addi ra, gp, 0xFFFFFF83
xor gp, sp, ra
srli ra, ra, 0x0007
sll gp, ra, gp
xori gp, gp, 0x0163
add ra, gp, gp
add sp, ra, ra
sltu ra, ra, sp
sll sp, ra, ra
ori sp, sp, 0xFFFFFF6B
slli gp, gp, 0xFFFFFFFA
xori sp, ra, 0x00A7
add sp, ra, ra
add ra, gp, gp
addi gp, gp, 0xFFFFFFE9
sra sp, ra, gp
add gp, ra, ra
ori gp, gp, 0x0002
addi gp, gp, 0x002F
sll sp, sp, ra
srli sp, ra, 0xFFFFFFF2
ori gp, sp, 0x00EB
sra gp, ra, sp
sra sp, sp, gp
and gp, ra, ra
sra ra, ra, gp
add sp, gp, ra
srl gp, sp, gp
add ra, ra, sp
srai gp, ra, 0xFFFFFFF2
srli sp, ra, 0xFFFFFFFC
ori gp, sp, 0xFFFFFE6E
and gp, ra, ra
ori gp, ra, 0xFFFFFFAF
srl ra, ra, ra
or sp, ra, ra
ori gp, sp, 0x0018
and gp, gp, gp
slti gp, ra, 0x00C6
sll gp, sp, gp
srli gp, sp, 0xFFFFFFFA
add gp, ra, ra
add gp, ra, sp
sra sp, ra, ra
ori sp, ra, 0x0022
and gp, gp, gp
add ra, sp, ra
sll sp, gp, gp
ori gp, sp, 0x008E
slti ra, gp, 0x00B5
add sp, ra, sp
and sp, gp, gp
addi ra, sp, 0x0145
and sp, gp, gp
sll gp, ra, sp
addi sp, sp, 0xFFFFFFAF
xori sp, ra, 0xFFFFFE2C
srl gp, ra, gp
sub ra, sp, gp
add sp, ra, ra
slli sp, sp, 0x0006
sub gp, ra, sp
sltu sp, ra, gp
xori ra, ra, 0xFFFFFF9A
addi sp, sp, 0xFFFFFE12
slli ra, ra, 0xFFFFFFFD
add gp, gp, gp
xori ra, ra, 0xFFFFFED7
andi gp, gp, 0xFFFFFE05
and gp, gp, sp
addi gp, gp, 0xFFFFFEE5
slli ra, gp, 0xFFFFFFF6
sll sp, gp, gp
and ra, gp, sp
ori ra, gp, 0xFFFFFE22
srl sp, sp, gp
srli ra, sp, 0x0005
slli ra, ra, 0xFFFFFFFB
srai ra, ra, 0xFFFFFFF9
srli ra, gp, 0xFFFFFFF1
andi gp, gp, 0xFFFFFF96
sra sp, gp, gp
srai gp, gp, 0x000F
sub sp, sp, gp
sltui ra, ra, 0xFFFFFF41
and sp, sp, sp
xor gp, sp, ra
srai gp, sp, 0xFFFFFFF6
xori gp, gp, 0x00D3
or gp, sp, sp
sltu gp, ra, gp
slli ra, gp, 0x0002
or sp, gp, ra
addi ra, ra, 0x002B
addi gp, ra, 0x0035
slli sp, gp, 0x0008
addi gp, sp, 0x015E
xor ra, gp, sp
or ra, gp, ra
sll ra, gp, ra
sll gp, gp, ra
srli gp, ra, 0xFFFFFFF4
slt sp, ra, sp
sltui sp, sp, 0xFFFFFE1C
ori sp, ra, 0xFFFFFE83
andi sp, sp, 0xFFFFFEFC
addi ra, ra, 0xFFFFFF85
ori gp, ra, 0x0084
sll gp, gp, ra
xori gp, sp, 0xFFFFFF6D
sll gp, sp, gp
sra ra, sp, ra
xor ra, gp, sp
srl ra, ra, sp
srl ra, ra, sp
andi gp, ra, 0xFFFFFE7B
srai ra, sp, 0xFFFFFFF1
sub sp, sp, ra
or sp, gp, gp
slt ra, ra, gp
or gp, gp, sp
srli ra, sp, 0xFFFFFFF5
andi ra, gp, 0xFFFFFFD4
sra sp, sp, sp
add sp, ra, sp
sub gp, ra, sp
xori ra, gp, 0x0131
add sp, sp, ra
addi sp, gp, 0x0003
sll ra, ra, ra
slli gp, ra, 0x000E
andi ra, gp, 0xFFFFFE88
srai ra, gp, 0xFFFFFFFA
done
ori gp, gp, 0xFFFFFE09
and gp, gp, ra
srli sp, ra, 0x0002
xor ra, ra, sp
or sp, ra, ra
xori ra, sp, 0x003D
addi ra, sp, 0x0012
add ra, gp, sp
ori gp, ra, 0xFFFFFFB8
sll ra, ra, ra
sll sp, gp, ra
slt ra, gp, ra
srai gp, gp, 0x0005
slli ra, ra, 0x0007
sub sp, gp, sp
andi ra, gp, 0x002D
sub gp, gp, sp
srai ra, gp, 0x0005
or sp, ra, sp
xori ra, gp, 0xFFFFFF54
sll ra, sp, ra
sub gp, gp, sp
add ra, sp, sp
sll ra, gp, ra
add gp, sp, sp
ori gp, sp, 0xFFFFFE68
srli sp, gp, 0x000F
sltiu ra, ra, 0xFFFFFE5D
srli ra, gp, 0x0006
srai sp, sp, 0x0005
andi sp, sp, 0x0129
and sp, sp, sp
slli gp, ra, 0x0001
or gp, gp, gp
or sp, gp, gp
slli gp, gp, 0x0006
srl sp, ra, gp
sltiu gp, ra, 0xFFFFFEC3
add sp, gp, sp
srli ra, sp, 0x0001
xori ra, ra, 0xFFFFFFA2
or gp, gp, sp
and sp, gp, gp
srai gp, sp, 0x0008
add sp, sp, ra
slti sp, ra, 0xFFFFFFF7
srli gp, ra, 0x0003
sll gp, ra, gp
sltu sp, sp, gp
srli gp, ra, 0x0002
ori gp, sp, 0xFFFFFF28
srl ra, gp, ra
or gp, ra, ra
ori sp, gp, 0x01D9
and sp, ra, ra
addi sp, gp, 0x0054
slli gp, ra, 0x000E
ori sp, sp, 0x0093
srai sp, ra, 0x000F
slti ra, gp, 0xFFFFFFCB
add gp, gp, gp
and gp, gp, gp
sltiu gp, ra, 0x00DE
slli sp, gp, 0x000D
slli sp, ra, 0x000B
sltiu sp, ra, 0xFFFFFF0E
and ra, gp, ra
add gp, sp, sp
slti ra, sp, 0x008C
srli ra, sp, 0x0000
addi sp, sp, 0x0168
slli ra, ra, 0x000D
addi ra, gp, 0x012A
or sp, gp, ra
add ra, sp, gp
and gp, ra, ra
slli ra, gp, 0x000A
or sp, gp, sp
or gp, ra, ra
srli ra, sp, 0x0002
ori gp, ra, 0x00EB
or sp, gp, ra
ori gp, sp, 0x01DA
andi ra, ra, 0xFFFFFFE9
addi gp, sp, 0x00C9
sltiu ra, ra, 0xFFFFFF13
sltiu ra, ra, 0xFFFFFF3A
sltiu sp, gp, 0xFFFFFE5A
ori sp, sp, 0xFFFFFFFE
and gp, sp, gp
sltiu sp, ra, 0x0034
srl gp, gp, ra
sll gp, sp, ra
ori ra, gp, 0xFFFFFEB6
sll ra, sp, ra
sra ra, gp, sp
sub ra, sp, gp
xor gp, gp, sp
sub ra, ra, sp
srl gp, gp, sp
andi ra, ra, 0xFFFFFFCB
ori ra, ra, 0xFFFFFE1B
andi ra, ra, 0xFFFFFEC8
sltiu sp, gp, 0x0108
sub sp, gp, ra
slti ra, sp, 0x015D
slli sp, sp, 0x0004
xor gp, sp, ra
srl ra, gp, ra
sltiu ra, ra, 0xFFFFFF3C
add sp, sp, sp
add gp, gp, ra
slli gp, gp, 0x0001
andi sp, sp, 0xFFFFFF3A
slt gp, sp, gp
srli ra, sp, 0x0004
ori sp, gp, 0xFFFFFEAB
ori sp, ra, 0xFFFFFE95
slli sp, sp, 0x000E
xori gp, sp, 0x0040
slti gp, sp, 0xFFFFFED1
or sp, sp, sp
sltiu sp, gp, 0x01B4
addi ra, gp, 0x002D
and sp, gp, gp
or ra, ra, ra
or ra, gp, ra
srli ra, ra, 0x0004
or ra, gp, ra
sra ra, ra, gp
slli ra, gp, 0x000B
slti gp, gp, 0x00E0
addi gp, ra, 0xFFFFFF72
sltiu gp, sp, 0xFFFFFEAA
xor sp, ra, gp
and gp, sp, ra
srli gp, gp, 0x0003
xori ra, ra, 0x01BD
srl ra, ra, gp
srai ra, gp, 0x0006
sub ra, gp, sp
sll gp, ra, gp
xori ra, sp, 0x0065
and ra, gp, ra
or ra, sp, ra
slt sp, gp, ra
addi ra, sp, 0xFFFFFE34
slli gp, sp, 0x0007
sll ra, sp, gp
sltiu gp, gp, 0xFFFFFE62
slti sp, sp, 0x0019
xori ra, gp, 0x0092
sltiu gp, sp, 0xFFFFFF29
srl sp, ra, gp
xori sp, gp, 0xFFFFFF4C
add sp, ra, gp
add sp, gp, ra
sra sp, sp, gp
slli sp, ra, 0x0008
srl sp, sp, sp
add sp, gp, ra
andi sp, sp, 0x0039
sll ra, gp, sp
andi gp, ra, 0xFFFFFECC
sll sp, sp, sp
sub sp, sp, ra
srai ra, sp, 0x0008
xor gp, ra, sp
add sp, sp, sp
sub gp, ra, gp
xori gp, sp, 0x01EE
and ra, ra, ra
ori gp, ra, 0xFFFFFE96
slli ra, gp, 0x0002
srli gp, ra, 0x000D
srli sp, gp, 0x0005
add ra, sp, sp
andi sp, gp, 0xFFFFFEC0
andi sp, gp, 0xFFFFFE7A
xori ra, sp, 0x0169
xori gp, sp, 0xFFFFFE02
andi ra, ra, 0xFFFFFFD1
xor ra, sp, gp
xori gp, gp, 0x00AB
srl ra, ra, gp
and ra, ra, sp
xori gp, sp, 0x005D
srai sp, sp, 0x000A
addi ra, sp, 0xFFFFFE19
or sp, ra, ra
addi ra, gp, 0x0084
ori sp, sp, 0xFFFFFF3D
xor gp, ra, gp
sra ra, ra, gp
xori ra, sp, 0x0040
srai gp, gp, 0x0002
xori ra, ra, 0xFFFFFE9A
sra ra, sp, sp
ori gp, sp, 0xFFFFFFB8
sll sp, ra, ra
done
#regset x1, 123
#regset x2, -40
#regset x3, 0xFFEE

+ 7
- 6
src/test/scala/RISCV/DataTypes.scala 파일 보기

@@ -158,12 +158,13 @@ object Data {
rightShifted
}

def splitLoHi(loBits: Int): (Int, Int) = {
val hiBits = 32 - loBits
val sep = 31 - loBits
val lo = i.field(31, loBits)
val hi = i.field(sep, hiBits)
(lo, hi)
def splitHiLo(hiBits: Int): (Int, Int) = {
val loBits = 32 - hiBits
val sep = 31 - hiBits
val hi = i.field(31, hiBits)
val lo = i.field(sep, loBits)
say(s"split lo hi for $i with $hiBits high bits and got low: $lo, high: $hi")
(hi, lo)
}

def log2: Int = math.ceil(math.log(i.toDouble)/math.log(2.0)).toInt


+ 6
- 3
src/test/scala/RISCV/Ops.scala 파일 보기

@@ -93,14 +93,17 @@ object Ops {
def or( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), OR)
def xor( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), XOR)
def and( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), AND)
def sll( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLL)
def srl( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRL)
def sra( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRA)
def slt( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLT)
def sltu(rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLTU)
def nop = add(0, 0, 0)
}

case class ArithImmShift(rd: Reg, rs1: Reg, shamt: Imm, op: ArithOp) extends Op with IType
object ArithImmShift {
def sll( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Reg(rd), Reg(rs1), Imm(imm), SLL)
def srl( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Reg(rd), Reg(rs1), Imm(imm), SRL)
def sra( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Reg(rd), Reg(rs1), Imm(imm), SRA)
}

case class LUI(rd: Reg, imm: Imm) extends Op with UType
case class AUIPC(rd: Reg, imm: Imm) extends Op with UType


+ 27
- 25
src/test/scala/RISCV/Parser.scala 파일 보기

@@ -84,12 +84,12 @@ object Parser {
stringWs("xori") ~> arithImm.mapN{ArithImm.xor},
stringWs("andi") ~> arithImm.mapN{ArithImm.and},
stringWs("slli") ~> arithImm.mapN{ArithImm.sll},
stringWs("srli") ~> arithImm.mapN{ArithImm.srl},
stringWs("srai") ~> arithImm.mapN{ArithImm.sra},
stringWs("slli") ~> arithImm.mapN{ArithImmShift.sll},
stringWs("srli") ~> arithImm.mapN{ArithImmShift.srl},
stringWs("srai") ~> arithImm.mapN{ArithImmShift.sra},
stringWs("slti") ~> arithImm.mapN{ArithImm.slt},
stringWs("sltui") ~> arithImm.mapN{ArithImm.sltu},
stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu},

// pseudos
stringWs("not") ~> (reg <~ sep, reg, ok(-1)).mapN{ArithImm.xor},
@@ -98,8 +98,11 @@ object Parser {
// seqz rd, rs1 => sltiu rd, rs1, 1
stringWs("seqz") ~> (reg <~ sep, reg, ok(1)).mapN{ArithImm.sltu},

stringWs("li") ~> (reg ~ sep ~ int).collect{
case((a, b), c) if (c.nBitsS <= 12) => ArithImm.add(a, 0, c)
stringWs("li") ~> (reg ~ sep ~ (hex | int)).collect{
case((a, b), c) if (c.nBitsS <= 12) => {
say(s"for c: $c, nBitsS was ${c.nBitsS}")
ArithImm.add(a, 0, c)
}
},


@@ -122,16 +125,16 @@ object Parser {

////////////////////////////////////////////
//// load/store
stringWs("sw") ~> (reg <~ sep, int <~ char('('), reg <~ char(')')).mapN{case (rs2, offset, rs1) => SW(rs2, rs1, offset)},
stringWs("lw") ~> (reg <~ sep, int <~ char('('), reg <~ char(')')).mapN{case (rd, offset, rs1) => LW(rd, rs1, offset)},
stringWs("sw") ~> (reg <~ sep, (hex | int) <~ char('('), reg <~ char(')')).mapN{case (rs2, offset, rs1) => SW(rs2, rs1, offset)},
stringWs("lw") ~> (reg <~ sep, (hex | int) <~ char('('), reg <~ char(')')).mapN{case (rd, offset, rs1) => LW(rd, rs1, offset)},



////////////////////////////////////////////
//// others
stringWs("auipc") ~> (reg <~ sep, int).mapN{AUIPC.apply},
stringWs("lui") ~> (reg <~ sep, int).mapN{LUI.apply},
stringWs("auipc") ~> (reg <~ sep, (hex | int)).mapN{AUIPC.apply},
stringWs("lui") ~> (reg <~ sep, (hex | int)).mapN{LUI.apply},

many(whitespace) ~> string("nop") ~> ok(Arith.add(0, 0, 0)),
many(whitespace) ~> string("done") ~> ok(DONE),
@@ -140,19 +143,18 @@ object Parser {
).map(_.widen[Op]).reduce(_|_)


// def getShiftsHalfWord(offset: Int): (Int, Int) = (offset % 4) match {
// case 0 => (16, 16)
// case 1 => (
// }

val multipleInstructions: Parser[List[Op]] = List(
stringWs("li") ~> (reg <~ sep, int.map(_.splitLoHi(12))).mapN{ case(rd, (lo, hi)) => List(
// stringWs("li") ~> (reg <~ sep, (hex | int).map(_.splitLoHi(20))).mapN{ case(rd, (hi, lo)) => {
stringWs("li") ~> (reg <~ sep, (hex | int).map(_.splitHiLo(20))).mapN{ case(rd, (hi, lo)) => {
say("hello?")
List(
ArithImm.add(rd, rd, lo),
LUI(rd, hi),
ArithImm.add(rd, 0, lo)
)}.map(_.widen[Op]),
)}}.map(_.widen[Op]),

// NOTE: THESE ARE NOT PSEUDO-OPS IN RISV32I!
// NOTE: THESE ARE NOT PSEUDO-OPS IN RISC-V32I!
// NOTE: USES A SPECIAL REGISTER
// NOTE: PROBABLY BROKEN, NOT EXHAUSTIVELY TESTED!!!
stringWs("lh") ~> (reg <~ sep, int <~ char('('), reg <~ char(')')).mapN{
case (rd, offset, rs1) if (offset % 4 == 3) => {
val placeHolder = if(rd == Reg("a0").value) Reg("a1").value else Reg("a0").value
@@ -160,16 +162,16 @@ object Parser {
SW(placeHolder, 0, 2048),
LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)),
LW(rd.value, rs1.value, (offset & 0xFFFFFF1C) + 4),
ArithImm.sra(placeHolder, placeHolder, 24),
ArithImm.sll(rd.value, rd.value, 24),
ArithImm.sra(rd.value, rd.value, 16),
ArithImmShift.sra(placeHolder, placeHolder, 24),
ArithImmShift.sll(rd.value, rd.value, 24),
ArithImmShift.sra(rd.value, rd.value, 16),
Arith.add(rd, rd, placeHolder),
LW(placeHolder, 0, 2048)).reverse
}
case (rd, offset, rs1) if (offset % 4 == 2) => {
List(
LW(rd, rs1, (offset & 0xFFFFFF1C)),
ArithImm.sra(rd, rd, 16)
ArithImmShift.sra(rd, rd, 16)
).reverse
}

@@ -177,8 +179,8 @@ object Parser {
val leftShift = if((offset % 4) == 0) 16 else 8
List(
LW(rd, rs1, (offset & 0xFFFFFF1C)),
ArithImm.sll(rd, rd, leftShift),
ArithImm.sra(rd, rd, 16),
ArithImmShift.sll(rd, rd, leftShift),
ArithImmShift.sra(rd, rd, 16),
).reverse
}
}.map(_.widen[Op]),


+ 18
- 10
src/test/scala/RISCV/VM.scala 파일 보기

@@ -23,16 +23,17 @@ case class VM(
def stepInstruction: Either[Finished, ExecutionTrace[VM]] = {
if (pc.value == 0xEB1CEB1C) Left(Success)
else getOp flatMap {
case op: Branch => executeBranch(op)
case op: Arith => executeArith(op)
case op: ArithImm => executeArithImm(op)
case op: AUIPC => executeAUIPC(op)
case op: LUI => executeLUI(op)
case op: JALR => executeJALR(op)
case op: JAL => executeJAL(op)
case op: LW => executeLW(op)
case op: SW => executeSW(op)
case DONE => Left(Success)
case op: Branch => executeBranch(op)
case op: Arith => executeArith(op)
case op: ArithImm => executeArithImm(op)
case op: ArithImmShift => executeArithImmShift(op)
case op: AUIPC => executeAUIPC(op)
case op: LUI => executeLUI(op)
case op: JALR => executeJALR(op)
case op: JAL => executeJAL(op)
case op: LW => executeLW(op)
case op: SW => executeSW(op)
case DONE => Left(Success)
}
}

@@ -75,6 +76,13 @@ case class VM(
}


private def executeArithImmShift(op: ArithImmShift) = {
val (regUpdate, nextRegs) = regs.arithImm(op.rd, op.rs1, op.shamt, op.op.run)
val nextVM = this.copy(regs = nextRegs)
Right(step(nextVM, regUpdate.toList:_*))
}


private def executeLUI(op: LUI) = {
val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12))
val nextVM = this.copy(regs = nextRegs)


+ 37
- 33
src/test/scala/RISCV/assembler.scala 파일 보기

@@ -125,12 +125,11 @@ object assembler {
}

/**
* Currently not used, thus we allow too larg shifts.
* Used by SRI, SRAI, SLLI
*/
def setShiftTypeImmediate(instruction: Int, immediate: Int): Int = {
def setShiftTypeImmediate(shamt: Int, addr: Addr): Int => InstructionFragment = {
val points = List((24, 5))
val withField = applyImmediate(5, immediate, points)(instruction)
withField
applyImmediateU(shamt, points, addr)
}

def setOpCode(opcode: Int): Int => Int = setField(0, 7, opcode)
@@ -142,16 +141,17 @@ object assembler {


def setOpCode(op: Op): Int => Int = op match {
case x: Branch => setOpCode("1100011".binary)
case x: Arith => setOpCode("0110011".binary)
case x: ArithImm => setOpCode("0010011".binary)
case x: LW => setOpCode("0000011".binary)
case x: SW => setOpCode("0100011".binary)
case x: JALR => setOpCode("1100111".binary)
case x: JAL => setOpCode("1101111".binary)
case x: AUIPC => setOpCode("0110111".binary)
case x: LUI => setOpCode("0010111".binary)
case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler.
case x: Branch => setOpCode("1100011".binary)
case x: Arith => setOpCode("0110011".binary)
case x: ArithImm => setOpCode("0010011".binary)
case x: ArithImmShift => setOpCode("0010011".binary)
case x: LW => setOpCode("0000011".binary)
case x: SW => setOpCode("0100011".binary)
case x: JALR => setOpCode("1100111".binary)
case x: JAL => setOpCode("1101111".binary)
case x: AUIPC => setOpCode("0010111".binary)
case x: LUI => setOpCode("0110111".binary)
case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler.
}

def setComparisonFunct(cmp: Comparison): Int => Int = cmp match {
@@ -195,7 +195,6 @@ object assembler {
setRs1(op.rs1.value)

def assembleSType(op: SType): Int => Int = {
// say("stype")
instruction =>
(setRs1(op.rs1.value) andThen
setRs2(op.rs2.value))(instruction)
@@ -214,16 +213,17 @@ object assembler {


def assembleImmediate(op: Op, addr: Addr, labelMap: Map[Label, Addr]): Int => Either[(String, Addr), Int] = op match {
case DONE => instruction => Right(instruction)
case op: Arith => instruction => Right(instruction)
case op: ArithImm => setItypeImmediate(op.imm.value, addr)
case op: Branch => setBranchDestination(labelMap, op, addr)
case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction))
case op: AUIPC => setUtypeImmediate(op.imm.value, addr)
case op: LUI => setUtypeImmediate(op.imm.value, addr)
case op: LW => setItypeImmediate(op.offset.value, addr)
case op: SW => setStypeImmediate(op.offset.value, addr)
case op: JAL => instruction => {
case DONE => instruction => Right(instruction)
case op: Arith => instruction => Right(instruction)
case op: ArithImm => setItypeImmediate(op.imm.value, addr)
case op: ArithImmShift => setShiftTypeImmediate(op.shamt.value, addr)
case op: Branch => setBranchDestination(labelMap, op, addr)
case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction))
case op: AUIPC => setUtypeImmediate(op.imm.value, addr)
case op: LUI => setUtypeImmediate(op.imm.value, addr)
case op: LW => setItypeImmediate(op.offset.value, addr)
case op: SW => setStypeImmediate(op.offset.value, addr)
case op: JAL => instruction => {
val addressDistance = labelMap
.lift(op.dst).toRight(s"label ${op.dst} not found", addr)
.map(absoluteAddr => absoluteAddr - addr)
@@ -246,14 +246,18 @@ object assembler {
val opcode = setOpCode(op)

val extras: Int => Int = (instruction: Int) => op match {
case op: Branch => setComparisonFunct(op.comp)(instruction)
case op: ArithImm => setArithFunct(op.op)(instruction)
case op: Arith => setArithFunct(op.op)(instruction)
case op: JALR => setFunct3("000".binary)(instruction)
case op: LW => setFunct3("010".binary)(instruction)
case op: SW => setFunct3("010".binary)(instruction)
case DONE => (setFunct3("000".binary) andThen setFunct7("0000000".binary))(instruction)
case _ => instruction
case op: Branch => setComparisonFunct(op.comp)(instruction)
case op: ArithImm => setArithFunct(op.op)(instruction)
case op: ArithImmShift => setArithFunct(op.op)(instruction)
case op: Arith => setArithFunct(op.op)(instruction)
case op: JALR => setFunct3("000".binary)(instruction)
case op: LW => setFunct3("010".binary)(instruction)
case op: SW => setFunct3("010".binary)(instruction)
case DONE => (setFunct3("000".binary) andThen setFunct7("0000000".binary))(instruction)

case op: AUIPC => instruction
case op: JAL => instruction
case op: LUI => instruction
}

val withOp = opcode(0)


+ 0
- 178
src/test/scala/RISCV/deleteMe.scala 파일 보기

@@ -1,178 +0,0 @@
package FiveStage
import cats.data.Writer
import cats._
import cats.data.{ Op => _ }
import cats.implicits._

object DTree {

// opaques WHEN
type Feature = String
type Value = String
type Cls = String

case class TrainingData(values: Map[Feature, Value], cls: Cls)

type TestData = Map[Feature, Value]

// Base
// def predict(data: TestData): Cls = "Died"

// Gendered
def predictStatic(data: TestData): Cls =
if(data("gender") == "female")
"survived"
else "died"


sealed trait Tree
case class Node(feature: Feature, children: Map[Value, Tree]) extends Tree
case class Leaf(cls: Cls) extends Tree

val genderBased: Tree = Node(
"gender", Map(
"female" -> Leaf("survived"),
"male" -> Leaf("died"),
))


def predict(data: TestData)(tree: Tree): Cls =
tree match {
case Leaf(cls) => cls
case Node(feature, children) => predict(data)(children(data(feature)))
}

val data = Map("gender" -> "female", "family size" -> "0", "ticket" -> "1")

predict(data)(genderBased) // true


def entropy(classes: List[Cls]): Double = {
val total = classes.size
classes.groupBy(identity)
.mapValues { group =>
val prop = group.size / total
prop * math.log(1.0 / prop)
}.values.sum
}

def bucketedEntropy(data: List[TrainingData], feature: Feature): Double = {
val total = data.size
val bucketed = data.groupBy(_.values(feature))
.mapValues(_.map(_.cls))
.toMap
bucketed.values.map { classes =>
val prop = classes.size / total
prop * entropy(classes)
}.sum
}

def best(data: List[TrainingData], features: Set[Feature]): Feature = features.minBy(bucketedEntropy(data, _))

def mostCommonCls(data: List[TrainingData]): Cls = ???

def build(data: List[TrainingData], features: Set[Feature]): Tree = {
if(features.nonEmpty) {
val feature = best(data, features)
val buckets = data.groupBy(_.values(feature))
Node(feature, buckets.mapValues(build(_, features - feature)))
} else {
Leaf(mostCommonCls(data))
}
}

def withHKT {

sealed trait Tree[A]
case class Node[A](feature: Feature, children: Map[Value, A]) extends Tree[A]
case class Leaf[A](cls: Cls) extends Tree[A]

// import matryoshka._
// import matryoshka.data.Fix
// import matryoshka.implicits._

case class Fix[F[_]](unfix: F[Fix[F]])
case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]){
def counit: A = head
def map[B](f: A => B)(implicit ev: Functor[F]): Cofree[F, B] = Cofree(f(head), tail.map(_.map(f)))
/**
* Coflatmap alters the value of the node based on its context, then recursively
* alters its tail independently (which makes sense as it's the only thing Cofree[F, A] => B can do.
*/
def coflatMap[B](fa: Cofree[F, A] => B)(implicit ev: Functor[F]): Cofree[F, B] = {
val b = fa(this)
val fb = tail.map(_.coflatMap(fa))
Cofree(b, fb)
}
}

implicit val treeFunctor: Functor[Tree] = new Functor[Tree] {
def map[A, B](fa: Tree[A])(f: A => B): Tree[B] = fa match {
case Node(name, children) => Node(name, children.mapValues(f))
case Leaf(cls) => Leaf(cls)
}
}

val genderBased: Fix[Tree] =
Fix(Node(
"gender",
Map(
"female" -> Fix(Leaf[Fix[Tree]]("survived")),
"male" -> Fix(Leaf[Fix[Tree]]("died"))
)))

def build: ((List[TrainingData], Set[Feature])) => Tree[(List[TrainingData], Set[Feature])] = {
case (data, features) =>
if(features.nonEmpty) {
val feature = best(data, features)
val buckets = data.groupBy(_.values(feature))
val next = buckets.mapValues { subset => (subset, features - feature) }
Node(feature, next)
} else {
Leaf(mostCommonCls(data))
}
}

def explore(testData: TestData): Fix[Tree] => Cls Either Fix[Tree] =
fix => fix.unfix match {
case Leaf(cls) => Left(cls)
case Node(feature, children) => Right(children.get(testData(feature)).get)
}

// Anamorphism: Generalized unfold, builds structures
def ana[F[_]: Functor, A](f: A => F[A])(a: A): Fix[F] =
Fix( (f(a)).map(ana(f)) )

// Catamorphism: Generalized fold, tears structures down.
def cata[F[_]: Functor, A](fa: F[A] => A)(f: Fix[F]): A = {
fa(f.unfix.map(cata(fa)))
}

// def hyloSimple[F[_] : Functor, A, B](f: F[B] => B)(g: A => F[A]): A => B
def hyloSimple[F[_]: Functor, A, B](f: F[B] => B)(g: A => F[A])(a: A): B =
cata(f)(ana(g)(a))

// A more powerful cata
def para[F[_]: Functor, A](f: F[(Fix[F], A)] => A)(fa: Fix[F]): A =
f(fa.unfix.map(x => (x, para(f)(x))))

// A more powerful ana
def apo[F[_]: Functor, A](f: A => F[Either[Fix[F], A]])(a: A): Fix[F] = {
Fix(f(a).map{
case Right(a) => apo(f)(a)
case Left(fix) => fix
})
}

// When we have cofree
def histo[F[_]: Functor, A](f: F[Cofree[F, A]] => A)(fix: Fix[F]): A = {
def toCofree(fix: Fix[F]): Cofree[F, A] =
Cofree(histo(f)(fix), fix.unfix.map(toCofree))

f(fix.unfix.map(toCofree))
}


}
}

+ 0
- 164
src/test/scala/RISCV/deleteMe2.scala 파일 보기

@@ -1,164 +0,0 @@
package FiveStage
import cats.data.Writer
import cats._
import cats.data.{ Op => _ }
import cats.implicits._

import fileUtils.say

object DeletDis {

def delet = {

case class Fix[F[_]](unfix: F[Fix[F]])
case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]){
def counit: A = head
def map[B](f: A => B)(implicit ev: Functor[F]): Cofree[F, B] = Cofree(f(head), tail.map(_.map(f)))
/**
* Coflatmap alters the value of the node based on its context, then recursively
* alters its tail independently (which makes sense as it's the only thing Cofree[F, A] => B can do.
*/
def coflatMap[B](fa: Cofree[F, A] => B)(implicit ev: Functor[F]): Cofree[F, B] = {
val b = fa(this)
val fb = tail.map(_.coflatMap(fa))
Cofree(b, fb)
}
}
// Anamorphism: Generalized unfold, builds structures
def ana[F[_]: Functor, A](f: A => F[A])(a: A): Fix[F] =
Fix( (f(a)).map(ana(f)) )
// Catamorphism: Generalized fold, tears structures down.
def cata[F[_]: Functor, A](fa: F[A] => A)(f: Fix[F]): A = {
fa(f.unfix.map(cata(fa)))
}
// def hyloSimple[F[_] : Functor, A, B](f: F[B] => B)(g: A => F[A]): A => B
def hylo[F[_]: Functor, A, B](f: F[B] => B)(g: A => F[A])(a: A): B =
cata(f)(ana(g)(a))
// A more powerful cata
def para[F[_]: Functor, A](f: F[(Fix[F], A)] => A)(fa: Fix[F]): A =
f(fa.unfix.map(x => (x, para(f)(x))))
// A more powerful ana
def apo[F[_]: Functor, A](f: A => F[Either[Fix[F], A]])(a: A): Fix[F] = {
Fix(f(a).map{
case Right(a) => apo(f)(a)
case Left(fix) => fix
})
}
// When we have cofree
def histo[F[_]: Functor, A](f: F[Cofree[F, A]] => A)(fix: Fix[F]): A = {
def toCofree(fix: Fix[F]): Cofree[F, A] =
Cofree(histo(f)(fix), fix.unfix.map(toCofree))
f(fix.unfix.map(toCofree))
}
sealed trait StackR
final case class DoneR(result: Int = 1) extends StackR
final case class MoreR(stack: StackR, next: Int) extends StackR
def unfoldStackR(n: Int): StackR =
if(n > 0) MoreR(unfoldStackR(n-1), n) else DoneR()
say(unfoldStackR(5))

sealed trait Stack[A]
final case class Done[A](result: Int) extends Stack[A]
final case class More[A](a: A, next: Int) extends Stack[A]

object Stack {
implicit val stackFunctor: Functor[Stack] = new Functor[Stack] {
def map[A, B](fa: Stack[A])(f: A => B): Stack[B] = fa match {
case Done(result) => Done(result)
case More(a, next) => More(f(a), next)
}
}

def done[A](result: Int = 1): Stack[A] = Done(result)
def more[A](a: A, next: Int): Stack[A] = More(a, next)
}

import Stack._

val stackCoalgebra: Int => Stack[Int] =
n => if(n > 0) more(n - 1, n) else done()

say(ana(stackCoalgebra)(5))

val stackAlgebra: Stack[Int] => Int = {
case Done(result) => result
case More(acc, next) => acc * next
}

say(cata(stackAlgebra)(ana(stackCoalgebra)(5)))
say(hylo(stackAlgebra)(stackCoalgebra)(5))


sealed trait Nat[A]
final case class Zero[A]() extends Nat[A]
final case class Succ[A](prev: A) extends Nat[A]
object Nat {
implicit val natFunctor: Functor[Nat] = new Functor[Nat] {
override def map[A, B](na: Nat[A])(f: A => B): Nat[B] =
na match {
case Zero() => Zero()
case Succ(a) => Succ(f(a))
}
}
}

val natAlgebra: Nat[Int] => Int = {
case Zero() => 1
case Succ(n) => {
say(s"nat alg succ $n")
n + 1
}
}

val natAlgebraS: Nat[String] => String = {
case Zero() => "N"
case Succ(n) => n match {
case "N" => "NI"
case "NI" => "NIG"
case "NIG" => "NIGG"
case "NIGG" => "NIGGE"
case "NIGGE" => "NIGGER :-"
case s => s + "D"
}
}

val natCoalgebra: Int => Nat[Int] =
n => if (n == 0) Zero() else Succ(n - 1)

val b = ana(natCoalgebra)(9)
val c = cata(natAlgebraS)(b)
say(c)


val natAlgebraPara: Nat[(Fix[Nat], Int)] => Int = {
case Zero() => 1
case Succ((fix, acc)) => {
say(s"nat para alg succ $fix, $acc")
cata(natAlgebra)(fix) * acc
}
}

val build = ana(natCoalgebra)(_)
say("built")
val tear = para(natAlgebraPara)(_)
say(tear(build(5)))
// say(ana(natCoalgebra)(5))

val lastThreeSteps: Fix[Stack] = Fix(More(Fix(More(Fix(More(Fix(Done(1)),1)),2)),3))

val stackCoalgebraApo: Int => Stack[Either[Fix[Stack], Int]] =
n => if(n > 3) more(n - 1, n).map(_.asRight) else lastThreeSteps.unfix.map(_.asLeft)
}
}

+ 14
- 12
src/test/scala/RISCV/printUtils.scala 파일 보기

@@ -81,16 +81,17 @@ object PrintUtils {
val UNKNOWN = "UNKNOWN"

def printInstruction(op: Ops.Op, labelMap: Map[Label, Addr]): fansi.Str = op match {
case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}"
case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}"
case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})"
case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})"
case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}"
case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}"
case DONE => s"DONE"
case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}"
case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}"
case op: ArithImmShift => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.shamt.show}"
case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})"
case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})"
case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}"
case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}"
case DONE => s"DONE"
}


@@ -118,7 +119,7 @@ object PrintUtils {


def printBinary(bin: Map[Addr, Int]): String = {
bin.toList.sortBy(_._1.value).map{ case(addr, op) => s"$addr: ${op.hs}" }.mkString("\n","\n","\n")
bin.toList.sortBy(_._1.value).map{ case(addr, op) => s"$addr: ${op.hs}\t--\t${op.binary}" }.mkString("\n","\n","\n")
}


@@ -346,7 +347,8 @@ object PrintUtils {

def printLogSideBySide(trace: List[ExecutionTraceEvent], chiselTrace: List[CircuitTrace], program: Program): String = {
import LogParser._
val header = "ADDRESS -- VM UPDATES --- DEVICE UNDER TEST UPDATES --- CORRESPONDING SOURCE LINE\n"
val traces = mergeTraces(trace, chiselTrace).map(x => printMergedTraces((x), program))
traces.map(_.mkString("\n")).mkString("\n", "\n--------------------------------------------------------------------------+------------------------------------------------------+-------------------------------\n", "\n")
"\n" + header + (traces.map(_.mkString("\n")).mkString("\n", "\n--------------------------------------------------------------------------+------------------------------------------------------+-------------------------------\n", "\n"))
}
}

+ 6
- 6
src/test/scala/TestUtils.scala 파일 보기

@@ -75,7 +75,7 @@ object TestUtils {

val entry = hasLeft + (leftIndex << 1) + (hasRight << 8) + (rightIndex << 9) + (root.value << 16)

say(s"with leftIndex: ${leftIndex.hs}, rightIndex: ${rightIndex.hs}, value: ${root.value.hs} we got ${entry.hs}")
// say(s"with leftIndex: ${leftIndex.hs}, rightIndex: ${rightIndex.hs}, value: ${root.value.hs} we got ${entry.hs}")

entry :: foldAnno(root.left) ::: foldAnno(root.right)
}.getOrElse(Nil)
@@ -98,8 +98,8 @@ object TestUtils {
*/
def generateHazardsForward(steps: Int) : Unit = {

// val r = new scala.util.Random(0xF01D1EF7)
val r = new scala.util.Random(0xF01D1EF8)
val r = new scala.util.Random(0xF01D1EF7)
// val r = new scala.util.Random(0xF01D1EF8)
import Ops._

val active = List(1, 2, 3)
@@ -136,9 +136,9 @@ object TestUtils {
(s"ori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.or(rd, rs1, imm)),
(s"xori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.xor(rd, rs1, imm)),
(s"andi ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.and(rd, rs1, imm)),
(s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sll(rd, rs1, shift)),
(s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.srl(rd, rs1, shift)),
(s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sra(rd, rs1, shift)),
(s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(math.abs(shift).toInt % 32).show}", ArithImmShift.sll(rd, rs1, math.abs(shift).toInt % 32)),
(s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(math.abs(shift).toInt % 32).show}", ArithImmShift.srl(rd, rs1, math.abs(shift).toInt % 32)),
(s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(math.abs(shift).toInt % 32).show}", ArithImmShift.sra(rd, rs1, math.abs(shift).toInt % 32)),
(s"slti ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.slt(rd, rs1, imm)),
(s"sltiu ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.sltu(rd, rs1, imm)))
(rd, choices.shuffle(r).head)


+ 0
- 43
src/test/scala/testConf.scala 파일 보기

@@ -1,43 +0,0 @@
// package FiveStage
// import chisel3._
// import chisel3.iotesters._
// import org.scalatest.{Matchers, FlatSpec}
// import spire.math.{UInt => Uint}
// import fileUtils._
// import cats.implicits._

// import RISCVutils._
// import RISCVasm._
// import riscala._

// import utilz._

// class AllTests extends FlatSpec with Matchers {

// val results = fileUtils.getAllTests.map{f =>
// val result = TestRunner.runTest(f.getPath, false)
// (f.getName, result)
// }

// makeReport(results)
// }


// /**
// This is for you to run more verbose testing.
// */
// class SelectedTests extends FlatSpec with Matchers {

// val tests = List(
// "matMul.s"
// )

// if(!tests.isEmpty){
// val results = fileUtils.getAllTests.filter(f => tests.contains(f.getName)).map{ f =>
// val result = TestRunner.runTest(f.getPath, true)
// (f.getName, result)
// }

// makeReport(results)
// }
// }

불러오는 중...
취소
저장