Skip to content

Commit 9e96931

Browse files
committed
Start setting up RISCOF / riscv-arch-test
1 parent 1647e2a commit 9e96931

File tree

20 files changed

+756
-23
lines changed

20 files changed

+756
-23
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "coremark/coremark"]
22
path = coremark/coremark
33
url = https://github.com/eembc/coremark
4+
[submodule "riscof/riscv-arch-test"]
5+
path = riscof/riscv-arch-test
6+
url = https://github.com/riscv-non-isa/riscv-arch-test

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,21 @@ Code begins executing at address `0x4`. Address `0x0` must contain the size of t
1414

1515
## Extensions
1616

17-
`rv32ima_Zicsr_Zicntr_Zihintpause`
17+
`RV32IMAZicntr_Zicsr_Zifencei_Zihintpause`
1818

1919
| Extension | Version |
2020
| ----------- | ------- |
2121
| I | 2.1 |
2222
| M | 2.0 |
2323
| A | 2.1 |
24-
| Zicsr | 2.0 |
2524
| Zicntr | 2.0 |
25+
| Zicsr | 2.0 |
26+
| Zifencei\* | 2.0 |
2627
| Zihintpause | 2.0 |
2728
| Xmlogsys | N/A |
2829

30+
\* Zifencei is currently just a stub - the instruction cache is already updated on every write to memory.
31+
2932
### Xmlogsys
3033

3134
This non-standard extension adds instructions to control the mlogv32 processor's hardware and access certain Mlog features.

mod/assets/scripts/main.js

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const loader = Vars.mods.getMod("mlogv32-utils").loader;
77
const ProcessorAccess = loader.loadClass("gay.object.mlogv32.ProcessorAccess");
88
const ProcessorAccess_Companion = ProcessorAccess.getField("Companion").get(null);
99

10+
let serverAddress = "localhost";
11+
let serverPort = 5000;
12+
1013
global.override.block(LogicBlock, {
1114
/**
1215
* @param {Table} table
@@ -60,8 +63,41 @@ global.override.block(LogicBlock, {
6063
processor.stopServer();
6164
Vars.ui.hudfrag.showToast("Stopped socket server.");
6265
} else {
63-
processor.startServer("localhost", 5000);
64-
Vars.ui.hudfrag.showToast("Started socket server at localhost:5000.");
66+
const dialog = new BaseDialog("Server address");
67+
dialog.addCloseButton();
68+
dialog.cont
69+
.field(serverAddress, (address) => {
70+
serverAddress = address;
71+
})
72+
.tooltip("Address");
73+
dialog.cont.row();
74+
dialog.cont
75+
.field(
76+
serverPort.toString(),
77+
TextField.TextFieldFilter.digitsOnly,
78+
(portStr) => {
79+
const port = parseInt(portStr);
80+
if (!isNaN(port)) {
81+
serverPort = port;
82+
}
83+
}
84+
)
85+
.tooltip("Port");
86+
dialog.cont.row();
87+
dialog.cont
88+
.button("Confirm", Styles.defaultt, () => {
89+
dialog.hide();
90+
processor.startServer(serverAddress, serverPort);
91+
Vars.ui.hudfrag.showToast(
92+
"Started socket server at " +
93+
serverAddress +
94+
":" +
95+
serverPort +
96+
"."
97+
);
98+
})
99+
.width(100);
100+
dialog.show();
65101
}
66102
})
67103
.tooltip("Start/stop mlogv32 socket server")

mod/src/main/kotlin/gay/object/mlogv32/ProcessorAccess.kt

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import kotlinx.serialization.json.Json
1414
import mindustry.Vars
1515
import mindustry.gen.Building
1616
import mindustry.world.blocks.logic.LogicBlock.LogicBuild
17+
import mindustry.world.blocks.logic.MessageBlock.MessageBuild
1718
import mindustry.world.blocks.logic.SwitchBlock.SwitchBuild
1819
import kotlin.concurrent.thread
1920
import kotlin.coroutines.resume
@@ -32,6 +33,7 @@ class ProcessorAccess(
3233
val ramStart: Int,
3334
val ramEnd: Int,
3435
val resetSwitch: SwitchBuild,
36+
val errorOutput: MessageBuild,
3537
) {
3638
val romSize = romEnd - romStart
3739
val ramSize = ramEnd - ramStart
@@ -228,6 +230,7 @@ class ProcessorAccess(
228230
ramStart = nonNegativeIntVar(build, "RAM_START") ?: return null,
229231
ramEnd = nonNegativeIntVar(build, "RAM_END") ?: return null,
230232
resetSwitch = buildVar<SwitchBuild>(build, "RESET_SWITCH") ?: return null,
233+
errorOutput = buildVar<MessageBuild>(build, "ERROR_OUTPUT") ?: return null,
231234
)
232235
}
233236

@@ -291,12 +294,19 @@ data class FlashRequest(val path: String) : Request() {
291294

292295
@Serializable
293296
@SerialName("dump")
294-
data class DumpRequest(val path: String) : Request() {
297+
data class DumpRequest(
298+
val path: String,
299+
val address: Int?,
300+
val bytes: Int?,
301+
) : Request() {
295302
override suspend fun handle(processor: ProcessorAccess) = runOnMainThread {
296303
val file = Core.files.absolute(path)
297304
file.parent().mkdirs()
298305

299-
val bytes = processor.dumpRam(file)
306+
val address = address ?: processor.ramStart
307+
val bytes = bytes ?: (processor.ramEnd - address)
308+
309+
processor.dumpRam(file, address, bytes)
300310
SuccessResponse("Successfully dumped $bytes bytes from RAM to $file.")
301311
}
302312
}
@@ -316,7 +326,7 @@ data class StartRequest(val wait: Boolean) : Request() {
316326
delay(500)
317327
val stopped = runOnMainThread { processor.resetSwitch.enabled }
318328
if (stopped) {
319-
return SuccessResponse("Processor has halted.")
329+
return SuccessResponse("Processor started and finished executing.")
320330
}
321331
}
322332
}
@@ -331,13 +341,33 @@ data object StopRequest : Request() {
331341
}
332342
}
333343

344+
@Serializable
345+
@SerialName("status")
346+
data object StatusRequest : Request() {
347+
override suspend fun handle(processor: ProcessorAccess) = runOnMainThread {
348+
StatusResponse(
349+
running = !processor.resetSwitch.enabled,
350+
pc = processor.build.executor.optionalVar("pc")?.numi(),
351+
errorOutput = processor.errorOutput.message?.toString() ?: "",
352+
)
353+
}
354+
}
355+
334356
@Serializable
335357
sealed class Response
336358

337359
@Serializable
338360
@SerialName("success")
339361
data class SuccessResponse(val message: String) : Response()
340362

363+
@Serializable
364+
@SerialName("status")
365+
data class StatusResponse(
366+
val running: Boolean,
367+
val pc: Int?,
368+
val errorOutput: String,
369+
) : Response()
370+
341371
@Serializable
342372
@SerialName("error")
343373
data class ErrorResponse(val message: String) : Response() {

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ extraPaths = [
6161
]
6262
include = [
6363
"python/*",
64+
"riscof/mlogv32",
6465
]
6566
exclude = [
6667
"**/venv",
@@ -104,7 +105,6 @@ reportWildcardImportFromLibrary = "error"
104105
reportMissingTypeArgument = "warning"
105106
reportPrivateUsage = "warning"
106107
reportUnknownLambdaType = "warning"
107-
reportUnknownMemberType = "warning"
108108
reportUnnecessaryComparison = "warning"
109109
reportUnnecessaryIsInstance = "warning"
110110
reportUnusedClass = "warning"
@@ -114,6 +114,7 @@ reportUnusedImport = "warning"
114114
reportUnusedVariable = "warning"
115115

116116
reportUnknownArgumentType = "information"
117+
reportUnknownMemberType = "information"
117118
reportUnknownVariableType = "information"
118119

119120
reportMissingTypeStubs = "none"

python/src/mlogv32/processor_access.py

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import logging
34
import socket
45
from pathlib import Path
56
from typing import Annotated, Any, Literal
@@ -12,11 +13,20 @@
1213
alias_generators,
1314
)
1415

16+
logger = logging.getLogger(__name__)
17+
1518

1619
class ProcessorAccess:
17-
def __init__(self, hostname: str, port: int):
20+
def __init__(
21+
self,
22+
hostname: str,
23+
port: int,
24+
*,
25+
log_level: int = logging.DEBUG,
26+
):
1827
self.hostname = hostname
1928
self.port = port
29+
self.log_level = log_level
2030
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2131

2232
def connect(self):
@@ -31,32 +41,47 @@ def flash(self, path: str | Path):
3141
raise ValueError("Path must be absolute.")
3242

3343
self._send_request(FlashRequest(path=path))
34-
return self._recv_response()
35-
36-
def dump(self, path: str | Path):
44+
return self._recv_response(SuccessResponse)
45+
46+
def dump(
47+
self,
48+
path: str | Path,
49+
address: int | None = None,
50+
bytes: int | None = None,
51+
):
3752
path = Path(path)
3853
if not path.is_absolute():
3954
raise ValueError("Path must be absolute.")
4055

41-
self._send_request(DumpRequest(path=path))
42-
return self._recv_response()
56+
self._send_request(DumpRequest(path=path, address=address, bytes=bytes))
57+
return self._recv_response(SuccessResponse)
4358

4459
def start(self, wait: bool):
4560
self._send_request(StartRequest(wait=wait))
46-
return self._recv_response()
61+
return self._recv_response(SuccessResponse)
4762

4863
def stop(self):
4964
self._send_request(StopRequest())
50-
return self._recv_response()
65+
return self._recv_response(SuccessResponse)
66+
67+
def status(self):
68+
self._send_request(StatusRequest())
69+
return self._recv_response(StatusResponse)
5170

5271
def _send_request(self, request: Request) -> None:
5372
message = request.model_dump_json() + "\n"
73+
logger.log(self.log_level, f"Sending request: {message.rstrip()}")
5474
self.socket.sendall(message.encode("utf-8"))
5575

56-
def _recv_response(self) -> Response:
76+
def _recv_response[T](self, response_type: type[T]) -> T:
5777
with self.socket.makefile("r", encoding="utf-8") as f:
5878
line = f.readline()
59-
return response_ta.validate_json(line)
79+
logger.log(self.log_level, f"Received response: {line.rstrip()}")
80+
match TypeAdapter(response_type | ErrorResponse).validate_json(line):
81+
case ErrorResponse() as e:
82+
raise ProcessorError(e)
83+
case response:
84+
return response
6085

6186
def __enter__(self):
6287
self.connect()
@@ -81,6 +106,8 @@ class FlashRequest(BaseModel):
81106
class DumpRequest(BaseModel):
82107
type: Literal["dump"] = "dump"
83108
path: Path
109+
address: int | None
110+
bytes: int | None
84111

85112

86113
class StartRequest(BaseModel):
@@ -92,8 +119,12 @@ class StopRequest(BaseModel):
92119
type: Literal["stop"] = "stop"
93120

94121

122+
class StatusRequest(BaseModel):
123+
type: Literal["status"] = "status"
124+
125+
95126
type Request = Annotated[
96-
FlashRequest | DumpRequest | StartRequest | StopRequest,
127+
FlashRequest | DumpRequest | StartRequest | StopRequest | StatusRequest,
97128
Field(discriminator="type"),
98129
]
99130

@@ -103,14 +134,25 @@ class SuccessResponse(BaseModel):
103134
message: str
104135

105136

137+
class StatusResponse(BaseModel):
138+
type: Literal["status"]
139+
running: bool
140+
pc: int | None
141+
error_output: str
142+
143+
106144
class ErrorResponse(BaseModel):
107145
type: Literal["error"]
108146
message: str
109147

110148

111149
type Response = Annotated[
112-
SuccessResponse | ErrorResponse,
150+
SuccessResponse | StatusResponse | ErrorResponse,
113151
Field(discriminator="type"),
114152
]
115153

116-
response_ta = TypeAdapter[Response](Response)
154+
155+
class ProcessorError(RuntimeError):
156+
def __init__(self, response: ErrorResponse):
157+
super().__init__(response.message)
158+
self.response = response

riscof/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
!env/
2+
riscof_work/

riscof/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
validate:
2+
riscof validateyaml --config=config.ini
3+
4+
testlist:
5+
riscof testlist --config=config.ini --suite=riscv-arch-test/riscv-test-suite/ --env=riscv-arch-test/riscv-test-suite/env
6+
7+
run:
8+
riscof run --config=config.ini --suite=riscv-arch-test/riscv-test-suite/ --env=riscv-arch-test/riscv-test-suite/env
9+
10+
run-dut:
11+
riscof run --config=config.ini --suite=riscv-arch-test/riscv-test-suite/ --env=riscv-arch-test/riscv-test-suite/env --no-ref-run

riscof/config.ini

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[RISCOF]
2+
ReferencePlugin=sail_cSim
3+
ReferencePluginPath=./sail_cSim
4+
DUTPlugin=mlogv32
5+
DUTPluginPath=./mlogv32
6+
7+
[mlogv32]
8+
pluginpath=./mlogv32
9+
ispec=./mlogv32/mlogv32_isa.yaml
10+
pspec=./mlogv32/mlogv32_platform.yaml
11+
target_run=1
12+
13+
[sail_cSim]
14+
pluginpath=./sail_cSim
15+
docker=True
16+
image=registry.gitlab.com/incoresemi/docker-images/compliance

0 commit comments

Comments
 (0)