mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
bus/lasmibus: add separate req/data ack to target and initiator
This commit is contained in:
parent
af6ef0a3b4
commit
43fe16ef73
1 changed files with 35 additions and 17 deletions
|
@ -174,12 +174,14 @@ class Initiator(Module):
|
||||||
s.wr(self.bus.dat_w, 0)
|
s.wr(self.bus.dat_w, 0)
|
||||||
s.wr(self.bus.dat_we, 0)
|
s.wr(self.bus.dat_we, 0)
|
||||||
if not self.done:
|
if not self.done:
|
||||||
if self.transaction is not None and s.rd(self.bus.ack):
|
if self.transaction is not None:
|
||||||
s.wr(self.bus.stb, 0)
|
if s.rd(self.bus.req_ack):
|
||||||
if isinstance(self.transaction, TRead):
|
s.wr(self.bus.stb, 0)
|
||||||
self.transaction_end = s.cycle_counter + self.bus.read_latency
|
if s.rd(self.bus.dat_ack):
|
||||||
else:
|
if isinstance(self.transaction, TRead):
|
||||||
self.transaction_end = s.cycle_counter + self.bus.write_latency - 1
|
self.transaction_end = s.cycle_counter + self.bus.read_latency
|
||||||
|
else:
|
||||||
|
self.transaction_end = s.cycle_counter + self.bus.write_latency - 1
|
||||||
|
|
||||||
if self.transaction is None or s.cycle_counter == self.transaction_end:
|
if self.transaction is None or s.cycle_counter == self.transaction_end:
|
||||||
if self.transaction is not None:
|
if self.transaction is not None:
|
||||||
|
@ -224,38 +226,54 @@ class TargetModel:
|
||||||
self.last_bank += 1
|
self.last_bank += 1
|
||||||
return self.last_bank
|
return self.last_bank
|
||||||
|
|
||||||
|
class _ReqFIFO(Module):
|
||||||
|
def __init__(self, req_queue_size, bank):
|
||||||
|
self.req_queue_size = req_queue_size
|
||||||
|
self.bank = bank
|
||||||
|
self.contents = []
|
||||||
|
|
||||||
|
def do_simulation(self, s):
|
||||||
|
if len(self.contents) < self.req_queue_size:
|
||||||
|
if s.rd(self.bank.stb):
|
||||||
|
self.contents.append((s.rd(self.bank.we), s.rd(self.bank.adr)))
|
||||||
|
s.wr(self.bank.req_ack, 1)
|
||||||
|
else:
|
||||||
|
s.wr(self.bank.req_ack, 0)
|
||||||
|
s.wr(self.bank.lock, bool(self.contents))
|
||||||
|
|
||||||
class Target(Module):
|
class Target(Module):
|
||||||
def __init__(self, model, *ifargs, **ifkwargs):
|
def __init__(self, model, *ifargs, **ifkwargs):
|
||||||
self.model = model
|
self.model = model
|
||||||
self.bus = Interface(*ifargs, **ifkwargs)
|
self.bus = Interface(*ifargs, **ifkwargs)
|
||||||
|
self.req_fifos = [_ReqFIFO(self.bus.req_queue_size, getattr(self.bus, "bank"+str(nb)))
|
||||||
|
for nb in range(self.bus.nbanks)]
|
||||||
|
self.submodules += self.req_fifos
|
||||||
self.rd_pipeline = [None]*self.bus.read_latency
|
self.rd_pipeline = [None]*self.bus.read_latency
|
||||||
self.wr_pipeline = [None]*(self.bus.write_latency + 1)
|
self.wr_pipeline = [None]*(self.bus.write_latency + 1)
|
||||||
|
|
||||||
def do_simulation(self, s):
|
def do_simulation(self, s):
|
||||||
# determine banks with pending requests
|
# determine banks with pending requests
|
||||||
pending_banks = set()
|
pending_banks = set(nb for nb, rf in enumerate(self.req_fifos) if rf.contents)
|
||||||
for nb in range(self.bus.nbanks):
|
|
||||||
bank = getattr(self.bus, "bank"+str(nb))
|
|
||||||
if s.rd(bank.stb) and not s.rd(bank.ack):
|
|
||||||
pending_banks.add(nb)
|
|
||||||
|
|
||||||
# issue new transactions
|
# issue new transactions
|
||||||
selected_bank_n = self.model.select_bank(pending_banks)
|
selected_bank_n = self.model.select_bank(pending_banks)
|
||||||
|
selected_transaction = None
|
||||||
for nb in range(self.bus.nbanks):
|
for nb in range(self.bus.nbanks):
|
||||||
bank = getattr(self.bus, "bank"+str(nb))
|
bank = getattr(self.bus, "bank"+str(nb))
|
||||||
if nb == selected_bank_n:
|
if nb == selected_bank_n:
|
||||||
s.wr(bank.ack, 1)
|
s.wr(bank.dat_ack, 1)
|
||||||
|
selected_transaction = self.req_fifos[nb].contents.pop(0)
|
||||||
else:
|
else:
|
||||||
s.wr(bank.ack, 0)
|
s.wr(bank.dat_ack, 0)
|
||||||
|
|
||||||
rd_transaction = None
|
rd_transaction = None
|
||||||
wr_transaction = None
|
wr_transaction = None
|
||||||
if selected_bank_n >= 0:
|
if selected_bank_n >= 0:
|
||||||
selected_bank = getattr(self.bus, "bank"+str(selected_bank_n))
|
we, adr = selected_transaction
|
||||||
if s.rd(selected_bank.we):
|
if we:
|
||||||
wr_transaction = selected_bank_n, s.rd(selected_bank.adr)
|
wr_transaction = selected_bank_n, adr
|
||||||
else:
|
else:
|
||||||
rd_transaction = selected_bank_n, s.rd(selected_bank.adr)
|
rd_transaction = selected_bank_n, adr
|
||||||
|
|
||||||
# data pipeline
|
# data pipeline
|
||||||
self.rd_pipeline.append(rd_transaction)
|
self.rd_pipeline.append(rd_transaction)
|
||||||
|
|
Loading…
Reference in a new issue