~charles/awk-riscv

f23e9c52c04ebd6291699bcaa9ccb2e59b4b3f9d — Charles Daniels 1 year, 2 months ago 4f833dd
implement and test slti
5 files changed, 67 insertions(+), 20 deletions(-)

M README.md
M riscv.awk
M run_tests.sh
D test1.text
A tests/simulation/slti.txt
M README.md => README.md +5 -0
@@ 7,3 7,8 @@ Tests can be run using the `.run_tests.sh` script.
Unit tests organized as a directory of TSV files in the `test/unit/` folder.
The first column of each file is an input to riscv.awk, and the second column
is the expected output. Each TSV file corresponds to one test case.

## Simulation tests

Files in `test/simulation/` are each used as input to the program, and it's
exit code is assumed to indicate a test failure in the event it is nonzero.

M riscv.awk => riscv.awk +20 -6
@@ 118,6 118,7 @@
#	Each line of input is treated as a 32-bit instruction literal and it's
#	disassembly is shown on standard out.
#
#
#                            MEMORY MODEL
#
# This simulator will allow reads and writes to any memory address addressable


@@ 127,6 128,14 @@
# memwrite() functions. Program execution starts by default at memory address
# 0x0.
#
#
#                               ASSERTIONS
#
# Assertions can cause an error message to be displayed on standard out.
# Additionally, each failed assertion increments a counter. This counter is
# used as the program's exist code. This can allow a RISC-V program (or the
# simulator) to be tested by monitoring the exit code.
#
###############################################################################

# sign extend at the given MSB


@@ 144,7 153,7 @@ function signextend(v, i,            temp) {

# return true if value is two's complement negative
function isneg(v) {
	return (and(immI(v), lshift(1, 31)) != 0)
	return (and(v, lshift(1, 31)) != 0)
}

# take the absolute value of a two's complement negative value


@@ 154,7 163,6 @@ function twoabs(v) {
	} else {
		return v
	}

}

# masks to pull relevant values out of an instruction


@@ 194,8 202,6 @@ function type(v) {
	if (opcode(v) == 0xf) { return "I" }
	if (opcode(v) == 0x73) { return "I" }

	printf("don't know type of opcode 0x%x of instruction 0x%x\n", opcode(v), v) > "/dev/stderr"

	return "E"
}



@@ 257,7 263,6 @@ function op2str(v) {
	if ((opcode(v) == 0x33) && (funct7(v) == 0x1) && (funct3(v) == 0x6)) {return "REM"}
	if ((opcode(v) == 0x33) && (funct7(v) == 0x1) && (funct3(v) == 0x7)) {return "REMU"}

	printf("don't know mnemonic of instruction 0x%x", v) > "/dev/stderr"
	return "ERROR"
}



@@ 363,6 368,15 @@ function two2dec(v) {
	}
}

# convert a decimal integer to two's complement
function dec2two(v) {
	if (v < 0) {
		return and(2^32 + v, 0xffffffff)
	} else {
		return and(v, 0xffffffff)
	}
}

# run the CPU for one tick
function nextstate(    inst) {
	inst = memread(PC)


@@ 396,7 410,7 @@ function nextstate(    inst) {
	}

	PC_NEXT = PC + 4
	if (op2str(inst) == "ADDI") { regwrite(rd(inst), two2dec(regread(rs1(inst))) + two2dec(immI(inst))) }
	if (op2str(inst) == "ADDI") { regwrite(rd(inst), dec2two(two2dec(regread(rs1(inst))) + two2dec(immI(inst)))) }

	if (op2str(inst) == "SLTI") { regwrite(rd(inst), two2dec(regread(rs1(inst))) < two2dec(immI(inst))) }


M run_tests.sh => run_tests.sh +14 -0
@@ 27,3 27,17 @@ for f in tests/unit/*.tsv ; do

	done < "$f"
done

echo '#### running simulation tests...'
for f in tests/simulation/*.txt; do
	echo "------ test case $(basename "$f" .txt)"

	if ! awk -f ./riscv.awk < "$f" > ./.testout.log ; then
		echo "test failed, log is shown below... "
		cat ./.testout.log
		rm -f ./.testout.log
		exit 1
	fi
	rm -f ./.testout.log

done

D test1.text => test1.text +0 -14
@@ 1,14 0,0 @@
traceregs 1
traceinst 1
tracemem 1

poke 0x0 0x00500093   # addi x1 x0 5
poke 0x4 0x0070a113   # slti x2 x1 7
poke 0x8 0x0030a193   # slti x3 x1 3

step 3
assert reg 1 5
assert reg 2 1
assert reg 3 0

showregs

A tests/simulation/slti.txt => tests/simulation/slti.txt +28 -0
@@ 0,0 1,28 @@
traceregs 1
traceinst 1
tracemem 1

poke 0x00 0x00500093   # addi x1 x0 5
poke 0x04 0xffb00113   # addi x2 x0 -5
poke 0x08 0x0070a193   # slti x3 x1 7
poke 0x0c 0x0030a213   # slti x4 x1 3
poke 0x10 0xfff0a293   # slti x5 x1 -1
poke 0x14 0x00012313   # slti x6 x2 0
poke 0x18 0xfff12393   # slti x7 x2 -1
poke 0x1c 0xffb12413   # slti x8 x2 -5
poke 0x20 0xff612493   # slti x9 x2 -10
poke 0x24 0x0050a513   # slti x10 x1 5

step 100
assert reg 1 5
assert reg 2 0xfffffffb
assert reg 3 1
assert reg 4 0
assert reg 5 0
assert reg 6 1
assert reg 7 1
assert reg 8 0
assert reg 9 0
assert reg 10 0

showregs