Skip to content

Commit ed62900

Browse files
committed
spec: Inline PC memory access into CPU
1 parent caa053c commit ed62900

2 files changed

Lines changed: 45 additions & 3 deletions

File tree

spec/cpu.typ

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ The ALU functionality is then obtained through judicious dispatching to the corr
6060

6161
The interactions with the memory, both for register loading and storing, as for `LOAD` and `STORE` instructions are handled.
6262
Note that since registers need no byte-addressing, we store them in the memory argument with `Word` limbs.
63+
The `pc` register behaves very predictably with respect to its timestamps and when it is being read,
64+
so for performance reasons, we inline its memory interactions directly into the #cpu chip.
6365
The timestamps are ensured to be disjoint for disjoint memory locations.
6466
One consequence of that is that `next_pc` is written at `timestamp + 1`
6567
to ensure the access is disjoint with the `pc` read into `rv1` as part of the `AUIPC` instruction.
68+
#rj[We can try to do a bit more, and move `double_pc_read` into decoding, so that `AUIPC` could set `read_register1 = 0`.]
6669

6770
#render_constraint_table(chip, config, groups: "mem")
6871

spec/src/cpu.toml

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,18 @@ desc = "The value to (maybe) be written back to rvd"
221221
pad = 0
222222

223223
# Auxiliary
224+
[[variables.auxiliary]]
225+
name = "prev_pc_timestamp_borrow"
226+
type = "Bit"
227+
desc = "The borrow bit for computing the previous timestamp the PC was accessed"
228+
pad = 0
229+
230+
[[variables.auxiliary]]
231+
name = "pc_double_read"
232+
type = "Bit"
233+
desc = "Whether the PC is being read as a general purpose register (rs1) this cycle"
234+
pad = 0
235+
224236
[[variables.auxiliary]]
225237
name = "rv1"
226238
type = "DWordWHH"
@@ -691,12 +703,39 @@ tag = "MEMW"
691703
input = [0, ["cast", "res", "DWordWL"], ["cast", "arg2", ["Byte", 8]], ["+", "timestamp", ["cast", 1, "DWordWL"]], "memory_2bytes", "memory_4bytes", "memory_8bytes"]
692704
multiplicity = "STORE"
693705

706+
[[constraints.mem]]
707+
kind = "arith"
708+
constraint = "$#`pc_double_read` => #`rs1` = 255$"
709+
poly = ["*", ["-", 1, "pc_double_read"], ["-", "rs1", 255]]
710+
711+
[[constraints.mem]]
712+
kind = "template"
713+
tag = "IS_BIT"
714+
input = ["pc_double_read"]
715+
716+
[[constraints.mem]]
717+
kind = "template"
718+
tag = "IS_BIT"
719+
input = ["prev_pc_timestamp_borrow"]
720+
721+
[[constraints.mem]]
722+
kind = "arith"
723+
constraint = "$#`pc_double_read` => #`prev_pc_timestamp_borrow` = 0$"
724+
poly = ["*", ["-", 1, "pc_double_read"], "prev_pc_timestamp_borrow"]
725+
694726
[[constraints.mem]]
695727
kind = "interaction"
696-
tag = "MEMW"
697-
input = [1, ["cast", ["*", 2, 255], "DWordWL"], ["arr", ["idx", "next_pc", 0], ["idx", "next_pc", 1], 0, 0, 0, 0, 0, 0], ["+", "timestamp", ["cast", 1, "DWordWL"]], 1, 0, 0]
698-
output = ["arr", ["idx", "pc", 0], ["idx", "pc", 1], 0, 0, 0, 0, 0, 0]
728+
tag = "memory"
729+
input = [1, ["arr", ["+", ["*", 2, 255], "i"], 0], ["arr", ["+", ["-", ["idx", "timestamp", 0], ["*", 3, ["not", "pc_double_read"]]], ["*", ["^", 2, 32], "prev_pc_timestamp_borrow"]], ["-", ["idx", "timestamp", 1], "prev_pc_timestamp_borrow"]], ["idx", "pc", "i"]]
699730
multiplicity = ["not", "pad"]
731+
iter = ["i", 0, 1]
732+
733+
[[constraints.mem]]
734+
kind = "interaction"
735+
tag = "memory"
736+
input = [1, ["arr", ["+", ["*", 2, 255], "i"], 0], ["+", "timestamp", ["cast", 1, "DWordWL"]], ["idx", "next_pc", "i"]]
737+
multiplicity = ["-", ["not", "pad"]]
738+
iter = ["i", 0, 1]
700739

701740

702741
[[constraint_groups]]

0 commit comments

Comments
 (0)