Skip to content

Commit

Permalink
Fix yet another bug in the instruction cache (#638)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Urbańczyk authored Apr 2, 2024
1 parent 5add626 commit 4f25673
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
6 changes: 4 additions & 2 deletions coreblocks/cache/icache.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,6 @@ def elaborate(self, platform):
with m.If(refill_finish):
m.next = "LOOKUP"

accepting_requests = fsm.ongoing("LOOKUP") & ~needs_refill

# Replacement policy
way_selector = Signal(self.params.num_of_ways, reset=1)
with m.If(refill_finish):
Expand All @@ -185,6 +183,9 @@ def elaborate(self, platform):
m.d.comb += assign(mem_read_addr, prev_mem_read_addr)

mem_read_output_valid = Signal()
forwarding_response_now = Signal()
accepting_requests = ~mem_read_output_valid | forwarding_response_now

with Transaction(name="MemRead").body(
m, request=fsm.ongoing("LOOKUP") & (mem_read_output_valid | refill_error_saved)
):
Expand All @@ -194,6 +195,7 @@ def elaborate(self, platform):
tag_hit_any = reduce(operator.or_, tag_hit)

with m.If(tag_hit_any | refill_error_saved):
m.d.comb += forwarding_response_now.eq(1)
self.perf_hits.incr(m, cond=tag_hit_any)
mem_out = Signal(self.params.fetch_block_bytes * 8)
for i in OneHotSwitchDynamic(m, Cat(tag_hit)):
Expand Down
31 changes: 27 additions & 4 deletions test/cache/test_icache.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ def setUp(self) -> None:
self.refill_requests = deque()
self.issued_requests = deque()

self.accept_refill_request = True

self.refill_in_fly = False
self.refill_word_cnt = 0
self.refill_addr = 0
Expand All @@ -347,7 +349,7 @@ def init_module(self, ways, sets) -> None:
self.cp = self.gen_params.icache_params
self.m = ICacheTestCircuit(self.gen_params)

@def_method_mock(lambda self: self.m.refiller.start_refill_mock)
@def_method_mock(lambda self: self.m.refiller.start_refill_mock, enable=lambda self: self.accept_refill_request)
def start_refill_mock(self, addr):
self.refill_requests.append(addr)
self.refill_block_cnt = 0
Expand Down Expand Up @@ -631,11 +633,21 @@ def cache_process():
# Schedule two requests and then flush
yield from self.send_req(0x00000000 + self.cp.line_size_bytes)
yield from self.send_req(0x00010000)
yield from self.m.flush_cache.call()
self.mem[0x00010000] = random.randrange(2**self.gen_params.isa.ilen)

# And accept the results
yield from self.m.flush_cache.call_init()
yield
# We cannot flush until there are two pending requests
self.assertFalse((yield from self.m.flush_cache.done()))
yield
yield from self.m.flush_cache.disable()
yield

# Accept the first response
self.assert_resp((yield from self.m.accept_res.call()))

yield from self.m.flush_cache.call()

# And accept the second response ensuring that we got old data
self.assert_resp((yield from self.m.accept_res.call()))
self.expect_refill(0x00000000 + self.cp.line_size_bytes)

Expand Down Expand Up @@ -753,6 +765,16 @@ def test_random(self):
if random.random() < 0.05:
self.add_bad_addr(i)

def refiller_ctrl():
yield Passive()

while True:
yield from self.random_wait_geom(0.4)
self.accept_refill_request = False

yield from self.random_wait_geom(0.7)
self.accept_refill_request = True

def sender():
for _ in range(iterations):
yield from self.send_req(random.randrange(0, max_addr, 4))
Expand All @@ -773,3 +795,4 @@ def receiver():
with self.run_simulation(self.m) as sim:
sim.add_sync_process(sender)
sim.add_sync_process(receiver)
sim.add_sync_process(refiller_ctrl)

0 comments on commit 4f25673

Please sign in to comment.