Skip to content

Commit f73d654

Browse files
committed
Use scalautils lib to generate machine code from assembly in tests
1 parent d5c698c commit f73d654

File tree

3 files changed

+200
-257
lines changed

3 files changed

+200
-257
lines changed

build.sbt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ Global / semanticdbVersion := "4.4.28" //scalafi
1616
Global / onChangedBuildSource := ReloadOnSourceChanges
1717

1818
Compile / run / mainClass := Some("chiselv.Toplevel")
19+
Test / logBuffered := false
1920

2021
lazy val chiselv = (project in file("."))
2122
.settings(
2223
name := "chiselv",
23-
version := "0.0.1",
24+
version := "1.0.0",
2425
scalaVersion := "2.13.6",
2526
)
2627

@@ -30,7 +31,7 @@ val defaultVersions = Map(
3031
"chiseltest" -> "0.5-SNAPSHOT",
3132
"scalatest" -> "3.2.10",
3233
"organize-imports" -> "0.5.0",
33-
"scalautils" -> "0.5.0",
34+
"scalautils" -> "0.7.0",
3435
)
3536

3637
// Import libraries

src/test/scala/CPUSingleCycleIOSpec.scala

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import chiseltest._
44
import chiseltest.experimental._
55
import org.scalatest._
66

7+
import com.carlosedp.scalautils.riscvassembler._
8+
79
import java.io.{File, PrintWriter}
10+
import java.nio.file.{Files, Paths, DirectoryNotEmptyException}
811

912
import flatspec._
1013
import matchers._
@@ -29,49 +32,64 @@ class CPUSingleCycleIOWrapper(
2932
val timerCounter = expose(core.timer0.counter)
3033
}
3134

32-
class CPUSingleCycleIOSpec extends AnyFlatSpec with ChiselScalatestTester with should.Matchers {
35+
class CPUSingleCycleIOSpec
36+
extends AnyFlatSpec
37+
with ChiselScalatestTester
38+
with BeforeAndAfterEach
39+
with BeforeAndAfter
40+
with should.Matchers {
3341
behavior of "GPIO"
3442

3543
val cpuFrequency = 25000000
3644
val bitWidth = 32
3745
val instructionMemorySize = 1 * 1024
3846
val memorySize = 1 * 1024
3947
val ms = cpuFrequency / 1000
48+
var memoryfile = ""
49+
val tmpdir = "tmphex"
50+
51+
before {
52+
Files.createDirectories(Paths.get(tmpdir));
53+
}
54+
after {
55+
try {
56+
Files.deleteIfExists(Paths.get(tmpdir));
57+
} catch {
58+
case _: DirectoryNotEmptyException =>
59+
// println("Directory not empty")
60+
}
61+
}
62+
override def beforeEach(): Unit =
63+
memoryfile =
64+
Paths.get(tmpdir, scala.util.Random.alphanumeric.filter(_.isLetter).take(15).mkString + ".hex").toString()
65+
override def afterEach(): Unit = {
66+
val _ = new File(memoryfile).delete()
67+
}
4068

41-
def defaultDut(memoryfile: String) =
69+
def defaultDut(prog: String) = {
70+
val hex = RISCVAssembler.fromString(prog)
71+
new PrintWriter(new File(memoryfile)) { write(hex); close }
4272
test(new CPUSingleCycleIOWrapper(cpuFrequency, bitWidth, instructionMemorySize, memorySize, memoryfile))
4373
.withAnnotations(
4474
Seq(
4575
WriteVcdAnnotation,
4676
VerilatorBackendAnnotation,
4777
)
4878
)
79+
}
4980

5081
it should "write to GPIO0" in {
51-
val filename = "CPUSpecMemoryTestFileGPIO0.hex"
52-
/*
53-
lui x1, %hi(0x30001000)
54-
addi x5, x0, -1
55-
addi x3, x3, 1
56-
addi x4, x0, 7
57-
sw x5, 0(x1)
58-
loop: add x2, x2, x3
59-
sw x2, 4(x1)
60-
jal x0, loop
61-
*/
62-
new PrintWriter(new File(filename)) {
63-
write("""
64-
300010b7
65-
fff00293
66-
00118193
67-
00700213
68-
0050a023
69-
00310133
70-
0020a223
71-
ff9ff06f
72-
""".stripMargin); close
73-
}
74-
defaultDut(filename) { c =>
82+
val prog = """
83+
lui x1, 0x30001000
84+
addi x5, x0, -1
85+
addi x3, x3, 1
86+
addi x4, x0, 7
87+
sw x5, 0(x1)
88+
add x2, x2, x3
89+
sw x2, 4(x1)
90+
jal x0, -8
91+
"""
92+
defaultDut(prog) { c =>
7593
c.clock.setTimeout(0)
7694
c.registers(1).peek().litValue should be(0)
7795
c.registers(2).peek().litValue should be(0)
@@ -104,29 +122,18 @@ class CPUSingleCycleIOSpec extends AnyFlatSpec with ChiselScalatestTester with s
104122
c.clock.step(1) // sw
105123
c.GPIO0_value.peek().litValue should be(2)
106124
}
107-
new File(filename).delete()
108125
}
109126

110127
behavior of "Timer"
111128
it should "read timer and wait for 2 ms" in {
112-
val filename = "CPUSpecMemoryTestFileTimer0_1.hex"
113-
/*
114-
main: lui x1, %hi(0x30003000)
129+
val prog = """
130+
main: lui x1, 0x30003000
115131
addi x2, x0, 2
116132
wait: lw x3, 0(x1)
117-
bne x2, x3, wait
133+
bne x2, x3, -4
118134
cont: addi x4, x0, 1
119-
*/
120-
new PrintWriter(new File(filename)) {
121-
write("""
122-
300030b7
123-
00200113
124-
0000a183
125-
fe311ee3
126-
00100213
127-
""".stripMargin); close
128-
}
129-
defaultDut(filename) { c =>
135+
"""
136+
defaultDut(prog) { c =>
130137
c.clock.setTimeout(0)
131138
c.registers(1).peek().litValue should be(0)
132139
c.registers(2).peek().litValue should be(0)
@@ -148,34 +155,20 @@ class CPUSingleCycleIOSpec extends AnyFlatSpec with ChiselScalatestTester with s
148155
c.clock.step(1) // addi
149156
c.registers(4).peek().litValue should be(1)
150157
}
151-
new File(filename).delete()
152158
}
153159

154160
it should "reset timer after 1ms and wait for 1 ms" in {
155-
val filename = "CPUSpecMemoryTestFileTimer0_2.hex"
156-
/*
157-
main: lui x1, %hi(0x30003000)
161+
val prog = """
162+
main: lui x1, 0x30003000
158163
addi x2, x0, 1
159164
wait: lw x3, 0(x1)
160-
bne x2, x3, wait
165+
bne x2, x3, -4
161166
cont: sw x0, 0(x1)
162167
wait2: lw x3, 0(x1)
163-
bne x2, x3, wait2
168+
bne x2, x3, -4
164169
cont2: addi x3, x0, 2
165-
*/
166-
new PrintWriter(new File(filename)) {
167-
write("""
168-
300030b7
169-
00100113
170-
0000a183
171-
fe311ee3
172-
0000a023
173-
0000a183
174-
fe311ee3
175-
00200193
176-
""".stripMargin); close
177-
}
178-
defaultDut(filename) { c =>
170+
"""
171+
defaultDut(prog) { c =>
179172
c.clock.setTimeout(0)
180173
c.registers(1).peek().litValue should be(0)
181174
c.registers(2).peek().litValue should be(0)
@@ -207,6 +200,5 @@ class CPUSingleCycleIOSpec extends AnyFlatSpec with ChiselScalatestTester with s
207200
c.clock.step(1) // addi
208201
c.registers(3).peek().litValue should be(2)
209202
}
210-
new File(filename).delete()
211203
}
212204
}

0 commit comments

Comments
 (0)