Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: af6ef0a3b4d3
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1d33c61308df
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Jul 10, 2013

  1. bus/lasmibus: add separate req/data ack to target and initiator

    Sebastien Bourdeauducq committed Jul 10, 2013
    Copy the full SHA
    43fe16e View commit details
  2. examples/sim/abstract_transactions_lasmi: check data

    Sebastien Bourdeauducq committed Jul 10, 2013
    Copy the full SHA
    1d33c61 View commit details
Showing with 47 additions and 24 deletions.
  1. +12 −7 examples/sim/abstract_transactions_lasmi.py
  2. +35 −17 migen/bus/lasmibus.py
19 changes: 12 additions & 7 deletions examples/sim/abstract_transactions_lasmi.py
Original file line number Diff line number Diff line change
@@ -4,27 +4,32 @@
from migen.sim.generic import Simulator

def my_generator(n):
bank = n % 4
for x in range(4):
t = TWrite(4*n+x, 0x100+x)
t = TWrite(4*bank+x, 0x1000*bank + 0x100*x)
yield t
print("Wrote in {0} cycle(s)".format(t.latency))
print("{0}: Wrote in {1} cycle(s)".format(n, t.latency))

for x in range(4):
t = TRead(4*n+x)
t = TRead(4*bank+x)
yield t
print("Read {0:x} in {1:x} cycle(s)".format(t.data, t.latency))
print("{0}: Read {1:x} in {2} cycle(s)".format(n, t.data, t.latency))
assert(t.data == 0x1000*bank + 0x100*x)

class MyModel(lasmibus.TargetModel):
def read(self, bank, address):
#print("read from bank {0} address {1}".format(bank, address))
return 0x1000*bank + 0x200+address
r = 0x1000*bank + 0x100*address
#print("read from bank {0} address {1} -> {2:x}".format(bank, address, r))
return r

def write(self, bank, address, data, we):
print("write to bank {0} address {1:x} data {2:x}".format(bank, address, data))
assert(data == 0x1000*bank + 0x100*address)

class TB(Module):
def __init__(self):
self.submodules.controller = lasmibus.Target(MyModel(), aw=4, dw=32, nbanks=4, read_latency=4, write_latency=1)
self.submodules.controller = lasmibus.Target(MyModel(), aw=4, dw=32, nbanks=4, req_queue_size=4,
read_latency=4, write_latency=1)
self.submodules.xbar = lasmibus.Crossbar([self.controller.bus], 4, 2)
self.initiators = [lasmibus.Initiator(my_generator(n), bus) for n, bus in enumerate(self.xbar.masters)]
self.submodules += self.initiators
52 changes: 35 additions & 17 deletions migen/bus/lasmibus.py
Original file line number Diff line number Diff line change
@@ -174,12 +174,14 @@ def do_simulation(self, s):
s.wr(self.bus.dat_w, 0)
s.wr(self.bus.dat_we, 0)
if not self.done:
if self.transaction is not None and s.rd(self.bus.ack):
s.wr(self.bus.stb, 0)
if isinstance(self.transaction, TRead):
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 not None:
if s.rd(self.bus.req_ack):
s.wr(self.bus.stb, 0)
if s.rd(self.bus.dat_ack):
if isinstance(self.transaction, TRead):
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 not None:
@@ -224,38 +226,54 @@ def select_bank(self, pending_banks):
self.last_bank += 1
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):
def __init__(self, model, *ifargs, **ifkwargs):
self.model = model
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.wr_pipeline = [None]*(self.bus.write_latency + 1)

def do_simulation(self, s):
# determine banks with pending requests
pending_banks = set()
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)
pending_banks = set(nb for nb, rf in enumerate(self.req_fifos) if rf.contents)

# issue new transactions
selected_bank_n = self.model.select_bank(pending_banks)
selected_transaction = None
for nb in range(self.bus.nbanks):
bank = getattr(self.bus, "bank"+str(nb))
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:
s.wr(bank.ack, 0)
s.wr(bank.dat_ack, 0)

rd_transaction = None
wr_transaction = None
if selected_bank_n >= 0:
selected_bank = getattr(self.bus, "bank"+str(selected_bank_n))
if s.rd(selected_bank.we):
wr_transaction = selected_bank_n, s.rd(selected_bank.adr)
we, adr = selected_transaction
if we:
wr_transaction = selected_bank_n, adr
else:
rd_transaction = selected_bank_n, s.rd(selected_bank.adr)
rd_transaction = selected_bank_n, adr

# data pipeline
self.rd_pipeline.append(rd_transaction)