Skip to content

Commit 79e99cd

Browse files
committed
Rewrite instruction cache to pack entire decoded instruction into one double
1 parent ef78540 commit 79e99cd

File tree

7 files changed

+441
-406
lines changed

7 files changed

+441
-406
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ RISC-V processor in Mindustry logic. Requires Mindustry build 149+.
66

77
## Architecture
88

9-
Physical memory consists of three sections. Two are directly accessible by code: ROM (rx) and RAM (rwx). The third section is an instruction cache which is 4x less dense than main memory.
9+
Physical memory consists of three sections. Two are directly accessible by code: ROM (rx) and RAM (rwx). The third section is an instruction cache, which sits directly after RAM and uses the same processor layout to store partially decoded instructions.
1010

1111
For maximum performance, the instruction cache for ROM can be initialized at boot using the MLOGSYS instruction. It is also updated whenever an instruction writes to RAM that is covered by the icache. If executing from memory not covered by the icache, the processor manually fetches and decodes the instruction from main memory.
1212

13+
Instructions are cached in the following format, utilizing the full 54 bits of `double` precision ([53 mantissa](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER), 1 sign).
14+
15+
| 53:47 | 46:42 | 41:37 | 36:32 | 31:0 |
16+
| ----------------- | ----- | ----- | ----- | ---- |
17+
| op_id (-64 to 63) | rs2 | rs1 | rd | imm |
18+
1319
The main CPU code is generated from `src/main.mlog.jinja` using a custom Jinja-based preprocessor (`python/src/mlogv32/preprocessor`).
1420

1521
## Memory

src/config/base.mlog.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
set ROM_SIZE {{# '%#0x'|format(ROM_ROWS * MEMORY_WIDTH * 16384) }} # ROM size in bytes (rx)
1313
set RAM_SIZE {{# '%#0x'|format(RAM_ROWS * MEMORY_WIDTH * 16384) }} # RAM size in bytes (rwx)
14-
set ICACHE_SIZE {{# '%#0x'|format(ICACHE_ROWS * MEMORY_WIDTH * 4096) }} # icache size in variables, or bytes of memory it can represent; 4x less dense than ROM/RAM
14+
set ICACHE_SIZE {{# '%#0x'|format(ICACHE_ROWS * MEMORY_WIDTH * 16384) }} # icache size in bytes
1515

1616
set UART_FIFO_CAPACITY {{#UART_FIFO_CAPACITY}} # UART TX/RX FIFO capacity in bytes (max 253)
1717

src/config/configs.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ configs:
1414
ICACHE_ROWS: 6
1515
UART_FIFO_CAPACITY: 253
1616
webserver:
17-
MEMORY_X_OFFSET: -11
18-
MEMORY_Y_OFFSET: -26
17+
MEMORY_X_OFFSET: -9
18+
MEMORY_Y_OFFSET: -23
1919
MEMORY_WIDTH: 32
2020
ROM_ROWS: 1
2121
RAM_ROWS: 19
22-
ICACHE_ROWS: 4
22+
ICACHE_ROWS: 1
2323
UART_FIFO_CAPACITY: 253

src/debugger.mlog.jinja

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ loop:
112112
read RAM_END CPU "RAM_END"
113113

114114
set ICACHE_START RAM_END
115-
op mul ICACHE_SIZE ICACHE_SIZE 4
116115
op add ICACHE_END ICACHE_START ICACHE_SIZE
117116

118117
read x0_zero REGISTERS 0
@@ -181,9 +180,10 @@ loop:
181180
read state CPU "STATE"
182181
read pc CPU "pc"
183182
read op_id CPU "op_id"
184-
read arg1 CPU "arg1"
185-
read arg2 CPU "arg2"
186-
read arg3 CPU "arg3"
183+
read rs1 CPU "rs1_id"
184+
read rs2 CPU "rs2_id"
185+
read rd CPU "rd_id"
186+
read imm CPU "imm"
187187

188188
set address pc
189189
op add ret @counter 1
@@ -380,14 +380,19 @@ loop__no_mark_icache:
380380
op add ret @counter 1
381381
jump format_op_id always
382382

383-
print "arg1 = {0}\n"
384-
format arg1
383+
print "rs1 = {0}\n"
384+
format rs1
385385

386-
print "arg2 = {0}\n"
387-
format arg2
386+
print "rs2 = {0}\n"
387+
format rs2
388388

389-
print "arg3 = {0}\n\n"
390-
format arg3
389+
print "rd = {0}\n"
390+
format rd
391+
392+
print "imm = {0}\n\n"
393+
set n imm
394+
op add ret @counter 1
395+
jump format_hex always
391396

392397
print "mscratch = {0}\n"
393398
set n mscratch
@@ -443,7 +448,7 @@ loop__no_mark_icache:
443448
print "instret = {0}\n\n"
444449
format instret
445450

446-
#{{'\n'}} {{ print(0, 33) }}
451+
#{{'\n'}} {{ print(0, 34) }}
447452

448453
# column 2
449454

@@ -653,39 +658,48 @@ format_bin__next:
653658
set @counter ret
654659

655660
format_op_id:
661+
op add n n 64
656662
jump format_null strictEqual n null
657663
jump format_op_id__unknown lessThan n 0
658664
jump format_op_id__unknown greaterThan n 66
659665
op mul n n 2
660666
op add @counter @counter n
661-
format "illegal_instruction"; set @counter ret
662-
format "LUI"; set @counter ret
663-
format "AUIPC"; set @counter ret
664-
format "JAL"; set @counter ret
665-
format "JALR"; set @counter ret
666667
format "BEQ"; set @counter ret
667668
format "BNE"; set @counter ret
669+
format "JAL"; set @counter ret
670+
format "JALR"; set @counter ret
668671
format "BLT"; set @counter ret
669672
format "BGE"; set @counter ret
670673
format "BLTU"; set @counter ret
671674
format "BGEU"; set @counter ret
672675
format "LB"; set @counter ret
673676
format "LH"; set @counter ret
674677
format "LW"; set @counter ret
678+
format "LUI"; set @counter ret
675679
format "LBU"; set @counter ret
676680
format "LHU"; set @counter ret
677681
format "SB"; set @counter ret
678682
format "SH"; set @counter ret
679683
format "SW"; set @counter ret
684+
format "AMOADD.W"; set @counter ret
685+
format "AMOSWAP.W"; set @counter ret
686+
format "LR.W"; set @counter ret
687+
format "SC.W"; set @counter ret
688+
format "AMOXOR.W"; set @counter ret
689+
format "AMOOR.W"; set @counter ret
690+
format "AMOAND.W"; set @counter ret
691+
format "AMOMIN.W"; set @counter ret
692+
format "AMOMAX.W"; set @counter ret
693+
format "AMOMINU.W"; set @counter ret
694+
format "AMOMAXU.W"; set @counter ret
680695
format "ADDI"; set @counter ret
696+
format "SUB"; set @counter ret
681697
format "SLTI"; set @counter ret
682698
format "SLTIU"; set @counter ret
683699
format "XORI"; set @counter ret
700+
format "SRA"; set @counter ret
684701
format "ORI"; set @counter ret
685702
format "ANDI"; set @counter ret
686-
format "SLLI"; set @counter ret
687-
format "SRLI"; set @counter ret
688-
format "SRAI"; set @counter ret
689703
format "ADD"; set @counter ret
690704
format "SLL"; set @counter ret
691705
format "SLT"; set @counter ret
@@ -694,16 +708,6 @@ format_op_id:
694708
format "SRL"; set @counter ret
695709
format "OR"; set @counter ret
696710
format "AND"; set @counter ret
697-
format "SUB"; set @counter ret
698-
format "SRA"; set @counter ret
699-
format "FENCE"; set @counter ret
700-
jump format_op_id__priv always; stop
701-
format "CSRRW"; set @counter ret
702-
format "CSRRS"; set @counter ret
703-
format "CSRRC"; set @counter ret
704-
format "CSRRWI"; set @counter ret
705-
format "CSRRSI"; set @counter ret
706-
format "CSRRCI"; set @counter ret
707711
format "MUL"; set @counter ret
708712
format "MULH"; set @counter ret
709713
format "MULHSU"; set @counter ret
@@ -712,17 +716,19 @@ format_op_id:
712716
format "DIVU"; set @counter ret
713717
format "REM"; set @counter ret
714718
format "REMU"; set @counter ret
715-
format "AMOADD.W"; set @counter ret
716-
format "AMOSWAP.W"; set @counter ret
717-
format "LR.W"; set @counter ret
718-
format "SC.W"; set @counter ret
719-
format "AMOXOR.W"; set @counter ret
720-
format "AMOOR.W"; set @counter ret
721-
format "AMOAND.W"; set @counter ret
722-
format "AMOMIN.W"; set @counter ret
723-
format "AMOMAX.W"; set @counter ret
724-
format "AMOMINU.W"; set @counter ret
725-
format "AMOMAXU.W"; set @counter ret
719+
jump format_op_id__priv always; stop
720+
format "CSRRW"; set @counter ret
721+
format "CSRRS"; set @counter ret
722+
format "CSRRC"; set @counter ret
723+
format "AUIPC"; set @counter ret
724+
format "CSRRWI"; set @counter ret
725+
format "CSRRSI"; set @counter ret
726+
format "CSRRCI"; set @counter ret
727+
format "FENCE"; set @counter ret
728+
format "SLLI"; set @counter ret
729+
format "SRLI"; set @counter ret
730+
format "SRAI"; set @counter ret
731+
format "illegal_instruction"; set @counter ret
726732
format "MLOGSYS"; set @counter ret
727733
format "MLOGDRAW"; set @counter ret
728734

@@ -731,13 +737,13 @@ format_op_id__unknown:
731737

732738
format_op_id__priv:
733739
set name "ECALL"
734-
jump format_op_id__priv__ok equal arg2 0
740+
jump format_op_id__priv__ok equal imm 0
735741
set name "EBREAK"
736-
jump format_op_id__priv__ok equal arg2 1
742+
jump format_op_id__priv__ok equal imm 1
737743
set name "MRET"
738-
jump format_op_id__priv__ok equal arg2 0b001100000010
744+
jump format_op_id__priv__ok equal imm 0b001100000010
739745
set name "WFI"
740-
jump format_op_id__priv__ok equal arg2 0b000100000101
746+
jump format_op_id__priv__ok equal imm 0b000100000101
741747
jump format_op_id__unknown always
742748
format_op_id__priv__ok:
743749
format name

src/init.mlog.jinja

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
# the lookup table must be linked first
1111

12-
set LOOKUP_START 0
1312
set EXPECTED_LINKS 21
1413

1514
# wait until ready
@@ -42,10 +41,8 @@ reset:
4241

4342
op idiv RAM_START_PROC ROM_SIZE {{ROM_PROC_BYTES}}
4443

45-
op idiv TOTAL_VARS RAM_SIZE 4
46-
op add TOTAL_VARS TOTAL_VARS ICACHE_SIZE
47-
48-
op idiv RAM_END_PROC TOTAL_VARS {{RAM_PROC_VARS}}
44+
op add RAM_END_PROC RAM_SIZE ICACHE_SIZE
45+
op idiv RAM_END_PROC RAM_END_PROC {{RAM_PROC_BYTES}}
4946
op add RAM_END_PROC RAM_END_PROC RAM_START_PROC
5047

5148
set i 0
@@ -126,7 +123,6 @@ init_incr:
126123
# address -> variable
127124
lookup_variable:
128125
op idiv _lookup address {{LOOKUP_PROC_SIZE}}
129-
op add _lookup _lookup LOOKUP_START
130126
getlink _lookup _lookup
131127

132128
op mod variable address {{LOOKUP_PROC_SIZE}}
@@ -142,6 +138,7 @@ lookup_variable:
142138
# preprocessor variable definitions
143139
set {{LOOKUP_PROC_SIZE}} null
144140
set {{ROM_PROC_BYTES}} null
141+
set {{RAM_PROC_BYTES}} null
145142
set {{RAM_PROC_VARS}} null
146143
set {{UART_RX_RPTR}} null
147144
set {{UART_RX_WPTR}} null

src/main.constants.jinja

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
{% set LOOKUP_PROC_SIZE = 260 %} {#- number of variables per lookup proc -#}
2020
{% set ROM_BYTE_OFFSET = 174 %} {#- start character for ROM string byte data -#}
2121
{% set ROM_PROC_BYTES = 16384 %} {#- number of bytes per ROM proc -#}
22+
{% set RAM_PROC_BYTES = 16384 %} {#- number of bytes per RAM proc -#}
2223
{% set RAM_PROC_VARS = 4096 %} {#- number of variables per RAM proc -#}
2324

2425
{#- ROM starts at 0x00000000, so we don't need a variable for it -#}

0 commit comments

Comments
 (0)