Skip to content

Commit 2a4b5be

Browse files
committed
Increment cycle at start of each worker instead of based on @tick and @ipt
1 parent 8729be0 commit 2a4b5be

File tree

4 files changed

+42
-41
lines changed

4 files changed

+42
-41
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ The `mlogsys.icache` M-mode instruction uses register _rs1_ as the number of byt
144144

145145
CSR values are stored either in a RAM processor (CSRS), in a variable in the CPU, or as an implicit read-only zero value, depending on the CSR. See [cpu.yaml](src/cpu/cpu.yaml) for the full list of implemented CSRs. Attempts to access a CSR that is not in this list will raise an illegal instruction exception.
146146

147+
### `cycle`
148+
149+
The `[m]cycle[h]` counter is incremented at the start of each worker's tick, just before it jumps back into code execution. The period should be something like `number of workers * 1/60 seconds`, but it will vary based on FPS.
150+
151+
### `time`
152+
153+
The `[m]time[h]` counter is based on the `@time` value in Mindustry. It has a period of 1 ms, and is incremented once per tick by the controller based on the time delta since the previous tick.
154+
147155
## riscv-arch-test
148156

149157
mlogv32 currently passes all compliance tests for the `RV32IMASUZicsr_Zifencei` ISA.

python/src/mlogv32/preprocessor/parser/mlog.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,13 @@ def check_unsaved_variables(ast: Iterable[ASTNode]):
176176
case Directive(name="end_fetch"):
177177
state = "check"
178178
continue
179-
case Directive(name="push_saved", args=[var]):
180-
saved_variables.add(var)
179+
case Directive(name="push_saved", args=args):
180+
for var in args:
181+
saved_variables.add(var)
181182
continue
182-
case Directive(name="pop_saved", args=[var]):
183-
saved_variables.remove(var)
183+
case Directive(name="pop_saved", args=args):
184+
for var in args:
185+
saved_variables.remove(var)
184186
continue
185187
case _:
186188
continue

src/cpu/controller.mlog.jinja

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,8 @@ end_slow_init:
247247
# align to tick
248248
wait 1e-5
249249

250-
# set mtime/mcycle reference points
250+
# set mtime reference point
251251
set last_mtime_update @time
252-
set last_mcycle_update @tick
253252

254253
# start the workers
255254
set prev_proc @this
@@ -282,7 +281,7 @@ end_breakpoint:
282281
# check which CSR we're currently updating, if any
283282

284283
# update mtime
285-
# TODO: handle mtimeh/mcycleh overflow
284+
# TODO: handle mtimeh overflow
286285

287286
op sub delta_ms @time last_mtime_update
288287

@@ -299,29 +298,6 @@ end_breakpoint:
299298

300299
set last_mtime_update @time
301300

302-
# update mcycle
303-
# we define the rate of increase of mcycle as "@ipt * ticks"
304-
# this should be a decent estimation of the number of mlog instructions executed
305-
306-
read csr_mcycle {{CSRS}} "{{ 'mcycle'|csr }}"
307-
read csr_mcycleh {{CSRS}} "{{ 'mcycleh'|csr }}"
308-
309-
op sub delta_cycles @tick last_mcycle_update
310-
op mul delta_cycles delta_cycles @ipt
311-
312-
op add csr_mcycle csr_mcycle delta_cycles
313-
op floor csr_mcycle csr_mcycle
314-
315-
op shr overflow csr_mcycle 32
316-
op add csr_mcycleh csr_mcycleh overflow
317-
318-
op mod csr_mcycle csr_mcycle 0x100000000
319-
320-
write csr_mcycle {{CSRS}} "{{ 'mcycle'|csr }}"
321-
write csr_mcycleh {{CSRS}} "{{ 'mcycleh'|csr }}"
322-
323-
set last_mcycle_update @tick
324-
325301
# tell the next worker to poll and fire interrupts
326302
op or csr_mip csr_mip 0b11000000000000000000000000000000
327303
write csr_mip prev_proc "csr_mip"
@@ -360,9 +336,8 @@ breakpoint__end_loop:
360336
set state "running"
361337
write state prev_proc "state"
362338

363-
# pause timers while at a breakpoint
339+
# pause timer while at a breakpoint
364340
set last_mtime_update @time
365-
set last_mcycle_update @tick
366341

367342
jump end_breakpoint always
368343

@@ -439,8 +414,6 @@ set _ csr_mtimecmp
439414
set _ csr_mtimecmph
440415
set _ csr_stimecmp
441416
set _ csr_stimecmph
442-
set _ csr_mcycle
443-
set _ csr_mcycleh
444417
set _ csr_minstret
445418
set _ csr_mstatus
446419
set _ csr_mip

src/cpu/worker.mlog.jinja

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494

9595
#% set labels.next_tick = 14
9696

97-
#% set labels.end_instruction_with_rd_and_poll_interrupts = 147
97+
#% set labels.end_instruction_with_rd_and_poll_interrupts = 155
9898
#% set labels.end_instruction_with_rd_and_fire_interrupts = _labels_vals|last + 1
9999
#% set labels.end_instruction_with_rd = _labels_vals|last + 1
100100
#% set labels.end_instruction = _labels_vals|last + 2
@@ -140,16 +140,34 @@ reset:
140140
# tell the next worker to fetch the hart state from us
141141
write @this {{CONTROLLER}} "prev_proc"
142142

143+
# these variables don't need to be saved because this should only ever run at the start of a tick
144+
145+
#directive push_saved __mcycle __mcycleh
146+
# increment mcycle
147+
read __mcycle {{CSRS}} "{{ 'mcycle'|csr }}"
148+
op add __mcycle __mcycle 1
149+
jump reset__no_overflow lessThan __mcycle 0x100000000
150+
151+
# overflow mcycle into mcycleh
152+
# TODO: handle mcycleh overflow
153+
set __mcycle 0
154+
read __mcycleh {{CSRS}} "{{ 'mcycleh'|csr }}"
155+
op add __mcycleh __mcycleh 1
156+
write __mcycleh {{CSRS}} "{{ 'mcycleh'|csr }}"
157+
158+
reset__no_overflow:
159+
write __mcycle {{CSRS}} "{{ 'mcycle'|csr }}"
160+
#directive pop_saved __mcycle __mcycleh
161+
143162
# if we just started executing, don't restore @counter
144163
jump poll_interrupts equal prev_proc {{CONTROLLER}}
145164

165+
#directive push_saved __counter
146166
# otherwise, jump to whatever instruction the previous worker would have executed next
147-
# _counter doesn't need to be saved because this should only ever run at the start of a tick
148-
#directive push_saved _counter
149-
read _counter prev_proc "@counter"
167+
read __counter prev_proc "@counter"
150168
write {{labels.next_tick}} prev_proc "@counter"
151-
set @counter _counter
152-
#directive pop_saved _counter
169+
set @counter __counter
170+
#directive pop_saved __counter
153171

154172
# check if software-manipulable interrupts should become pending
155173
# this runs at the start of the first worker each tick, and at the start of the next worker if certain CSRs/MMRs are modified
@@ -296,7 +314,7 @@ main__read_icache:
296314
op and rs2_id rs2_id 0b11111
297315

298316
# read rs1 and rs2
299-
# this wastes 1 cycle for I-type and 2 cycles for U-type and J-type, but it saves a huge amount of space
317+
# this wastes 1 instruction for I-type and 2 for U-type and J-type, but it saves a huge amount of space
300318
read rs1 {{REGISTERS}} rs1_id
301319
read rs2 {{REGISTERS}} rs2_id
302320

0 commit comments

Comments
 (0)