Skip to content

Commit 600326f

Browse files
committed
Start working on implementing M-mode and U-mode
1 parent f762187 commit 600326f

File tree

11 files changed

+314
-120
lines changed

11 files changed

+314
-120
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*.hex
66
/build/
77
/out/
8+
9+
/src/init.mlog
810
/src/main.mlog
911

1012
node_modules/

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@
2525
"ruff.organizeImports": true,
2626
"ruff.lint.ignore": ["I"],
2727
"python.languageServer": "Pylance",
28-
"python.analysis.diagnosticMode": "workspace"
28+
"python.analysis.diagnosticMode": "workspace",
29+
"python.analysis.packageIndexDepths": [{ "name": "jinja2", "depth": 2 }]
2930
}

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,26 @@ Code begins executing at address `0x4`. Address `0x0` must contain the size of t
1212

1313
The main CPU code is generated from `src/main.mlog.jinja` using a custom Jinja-based preprocessor (`python/src/mlogv32/preprocessor`).
1414

15-
## Extensions
15+
### MMIO
16+
17+
Addresses `0xf0000000` - `0xffffffff` are reserved for MMIO.
18+
19+
| Address | Value |
20+
| ------------ | ----------- |
21+
| `0xf0000000` | `mtime` |
22+
| `0xf0000004` | `mtimeh` |
23+
| `0xf0000008` | `mtimecmp` |
24+
| `0xf000000c` | `mtimecmph` |
25+
26+
## ISA
1627

1728
`RV32IMAZicntr_Zicsr_Zifencei_Zihintpause`
1829

30+
Supported privilege levels: M, U
31+
1932
| Extension | Version |
2033
| ----------- | ------- |
34+
| M-mode | 1.13 |
2135
| I | 2.1 |
2236
| M | 2.0 |
2337
| A | 2.1 |

nodemon.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"watch": ["src", "python"],
33
"ext": "jinja,py",
4-
"exec": "python -m mlogv32.preprocessor src/main.mlog.jinja -o src/main.mlog"
4+
"exec": "python -m mlogv32.preprocessor src/main.mlog.jinja -o src/main.mlog && python -m mlogv32.preprocessor src/init.mlog.jinja -o src/init.mlog"
55
}

python/src/mlogv32/preprocessor/app.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
from jinja2 import Environment, FileSystemLoader, StrictUndefined
55
from typer import Option, Typer
66

7+
from mlogv32.preprocessor.extensions import CommentStatement
8+
79
from . import filters
810

9-
app = Typer()
11+
app = Typer(
12+
pretty_exceptions_show_locals=False,
13+
)
1014

1115

1216
@app.command()
@@ -24,6 +28,9 @@ def main(
2428
lstrip_blocks=True,
2529
trim_blocks=True,
2630
undefined=StrictUndefined,
31+
extensions=[
32+
CommentStatement,
33+
],
2734
)
2835
env.filters |= { # pyright: ignore[reportAttributeAccessIssue]
2936
"ram_variable": filters.ram_variable,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from jinja2.ext import Extension
2+
3+
4+
class CommentStatement(Extension):
5+
"""Allows writing inline expressions without causing an mlogls error.
6+
7+
For example:
8+
```
9+
op add foo bar {{# 1 }}
10+
```
11+
"""
12+
13+
def preprocess(
14+
self,
15+
source: str,
16+
name: str | None,
17+
filename: str | None = None,
18+
) -> str:
19+
# hacky
20+
return source.replace("{{#", "{{")

python/src/mlogv32/preprocessor/filters.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,6 @@ def quote(value: Any):
5555
"timeh": 0xC81,
5656
"instreth": 0xC82,
5757
**{f"hpmcounter{i}h": 0xC80 + i for i in range(3, 32)},
58-
# supervisor
59-
"sstatus": 0x100,
60-
"sie": 0x104,
61-
"stvec": 0x105,
62-
"scounteren": 0x106,
63-
"senvcfg": 0x10A,
64-
"scountinhibit": 0x120,
65-
"sscratch": 0x140,
66-
"sepc": 0x141,
67-
"scause": 0x142,
68-
"stval": 0x143,
69-
"sip": 0x144,
70-
"scountovf": 0xDA0,
71-
"satp": 0x180,
72-
"scontext": 0x5A8,
73-
"sstateen0": 0x10C,
74-
"sstateen1": 0x10D,
75-
"sstateen2": 0x10E,
76-
"sstateen3": 0x10F,
7758
# machine
7859
"mvendorid": 0xF11,
7960
"marchid": 0xF12,
@@ -110,4 +91,17 @@ def quote(value: Any):
11091
"mstateen1h": 0x31D,
11192
"mstateen2h": 0x31E,
11293
"mstateen3h": 0x31F,
94+
"mnscratch": 0x740,
95+
"mnepc": 0x741,
96+
"mncause": 0x742,
97+
"mnstatus": 0x744,
98+
"mcycle": 0xB00,
99+
"minstret": 0xB02,
100+
**{f"mhpmcounter{i}": 0xB00 + i for i in range(3, 32)},
101+
"mcycleh": 0xB80,
102+
"minstreth": 0xB82,
103+
**{f"mhpmcounter{i}h": 0xB80 + i for i in range(3, 32)},
104+
"mcountinhibit": 0x320,
105+
**{f"mhpmevent{i}": 0x320 + i for i in range(3, 32)},
106+
**{f"mhpmevent{i}h": 0x720 + i for i in range(3, 32)},
113107
}
Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
# this processor initializes INCR using a lookup table
2-
# the lookup table must be linked first, and INCR must be linked last
1+
# this processor initializes INCR using a lookup table, and sets readonly CSR values
2+
# the lookup table must be linked first
33

44
set LOOKUP_START 0
5-
set LOOKUP_LINKS 16
5+
set EXPECTED_LINKS 17
66
set LOOKUP_PROC_SIZE 260
77
set RAM_PROC_SIZE 4096
88

99
# wait until ready
1010
reset:
11-
jump reset lessThanEq @links LOOKUP_LINKS # 16 lookup procs + 1 incr proc
12-
op sub i @links 1
13-
getlink INCR i
11+
jump reset lessThan @links EXPECTED_LINKS
12+
13+
set INCR processor17
1414
read type INCR "_type"
1515
jump reset equal type "lookup" # sanity check
1616

17+
set CSRS processor18
18+
1719
op div wait LOOKUP_PROC_SIZE 120 # micro proc instructions/sec
1820
op ceil wait wait
1921
wait wait
@@ -38,6 +40,28 @@ loop:
3840
op add address address 1
3941
jump loop lessThanEq address RAM_PROC_SIZE
4042

43+
# initialize CSRS
44+
45+
# misa
46+
# XLEN=32 --
47+
# 0 ----
48+
# IMAX ZYXWVUTSRQPONMLKJIHGFEDCBA
49+
write 0b01000000100000000001000100000001 CSRS "{{ 'misa'|csr }}"
50+
51+
# mstatush
52+
# WPRI -------------------------- ----
53+
# MBE -
54+
# SBE -
55+
write 0b00000000000000000000000000000000 CSRS "{{ 'mstatush'|csr }}"
56+
57+
# mlogv32 only has one hart, so mhartid is required to be zero
58+
write 0 CSRS "{{ 'mhartid'|csr }}"
59+
60+
# unimplemented fields
61+
write 0 CSRS "{{ 'mvendorid'|csr }}"
62+
write 0 CSRS "{{ 'marchid'|csr }}"
63+
write 0 CSRS "{{ 'mimpid'|csr }}"
64+
4165
stop
4266

4367
# given a value 0 <= address < RAM_PROC_SIZE, resolve that variable in the lookup table

src/macros/bits.jinja

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#%# usage: op or value value {{# set_bits(high, low) }}
2+
{% macro set_bits(high, low=none) -%}
3+
{%- if low == none -%}
4+
{%- set low = high -%}
5+
{%- elif high < low -%}
6+
{%- set high, low = low, high -%}
7+
{%- endif -%}
8+
0b
9+
{{- '0' * (31 - high) -}}
10+
{{- '1' * (high - low + 1) -}}
11+
{{- '0' * low -}}
12+
{%- endmacro %}
13+
14+
#%# usage: op and value value {{# clear_bits(high, low) }}
15+
{% macro clear_bits(high, low=none) -%}
16+
{%- if low == none -%}
17+
{%- set low = high -%}
18+
{%- elif high < low -%}
19+
{%- set high, low = low, high -%}
20+
{%- endif -%}
21+
0b
22+
{{- '1' * (31 - high) -}}
23+
{{- '0' * (high - low + 1) -}}
24+
{{- '1' * low -}}
25+
{%- endmacro %}

src/main.constants.jinja

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414
{% set KBCONV_DATA = 'cell2' %}
1515
{% set DISPLAY = 'display1' %}
1616

17+
{% set MMIO_START = '0xf0000000' %}
18+
1719
{% block contents %}{% endblock %}

0 commit comments

Comments
 (0)