#ifndef __CSRBASE_H
#define __CSRBASE_H
-#define UART_BASE 0xe0000000
-#define DFII_BASE 0xe0000800
-#define ID_BASE 0xe0001000
-#define TIMER0_BASE 0xe0001800
-#define MINIMAC_BASE 0xe0002000
-#define FB_BASE 0xe0002800
-#define ASMIPROBE_BASE 0xe0003000
+#define UART_BASE 0xe0000000
+#define DFII_BASE 0xe0000800
+#define IDENTIFIER_BASE 0xe0001000
+#define TIMER0_BASE 0xe0001800
+#define MINIMAC_BASE 0xe0002000
+#define FB_BASE 0xe0002800
+#define ASMIPROBE_BASE 0xe0003000
#endif /* __CSRBASE_H */
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bus import dfi, asmibus
from milkymist.asmicon.refresher import *
self.write_time = write_time
self.slot_time = slot_time
-class ASMIcon:
+class ASMIcon(Module):
def __init__(self, phy_settings, geom_settings, timing_settings, full_selector=False):
self.phy_settings = phy_settings
self.geom_settings = geom_settings
self.timing_settings = timing_settings
self.full_selector = full_selector
- self.finalized = False
self.dfi = dfi.Interface(self.geom_settings.mux_a,
self.geom_settings.bank_a,
self.address_align = log2_int(burst_length)
aw = self.geom_settings.bank_a + self.geom_settings.row_a + self.geom_settings.col_a - self.address_align
dw = self.phy_settings.dfi_d*self.phy_settings.nphases
- self.hub = asmibus.Hub(aw, dw, self.timing_settings.slot_time)
+ self.submodules.hub = asmibus.Hub(aw, dw, self.timing_settings.slot_time)
- def finalize(self):
- if self.finalized:
- raise FinalizeError
- self.finalized = True
- self.hub.finalize()
+ def do_finalize(self):
slots = self.hub.get_slots()
- self.refresher = Refresher(self.geom_settings.mux_a, self.geom_settings.bank_a,
+ self.submodules.refresher = Refresher(self.geom_settings.mux_a, self.geom_settings.bank_a,
self.timing_settings.tRP, self.timing_settings.tREFI, self.timing_settings.tRFC)
- self.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots, self.full_selector)
+ self.submodules.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots, self.full_selector)
for i in range(2**self.geom_settings.bank_a)]
- self.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings,
+ self.submodules.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings,
self.bank_machines, self.refresher,
self.dfi, self.hub)
-
- def get_fragment(self):
- if not self.finalized:
- raise FinalizeError
- return self.hub.get_fragment() + \
- self.refresher.get_fragment() + \
- sum([bm.get_fragment() for bm in self.bank_machines], Fragment()) + \
- self.multiplexer.get_fragment()
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bus.asmibus import *
from migen.genlib.roundrobin import *
from migen.genlib.fsm import FSM
else:
return Cat(Replicate(0, self.address_align), address[:self._b1])
-class _Selector:
+class _Selector(Module):
def __init__(self, slicer, bankn, slots):
- self.slicer = slicer
- self.bankn = bankn
- self.slots = slots
-
- self.nslots = len(self.slots)
+ nslots = len(slots)
self.stb = Signal()
self.ack = Signal()
- self.tag = Signal(max=self.nslots)
- self.adr = Signal(self.slots[0].adr.nbits)
+ self.tag = Signal(max=nslots)
+ self.adr = Signal(slots[0].adr.nbits)
self.we = Signal()
# derived classes should drive rr.request
- self.rr = RoundRobin(self.nslots, SP_CE)
+ self.submodules.rr = RoundRobin(nslots, SP_CE)
- def get_fragment(self):
- comb = []
- rr = self.rr
-
+ ###
+
# Multiplex
+ rr = self.rr
state = Signal(2)
- comb += [
- state.eq(Array(slot.state for slot in self.slots)[rr.grant]),
- self.adr.eq(Array(slot.adr for slot in self.slots)[rr.grant]),
- self.we.eq(Array(slot.we for slot in self.slots)[rr.grant]),
+ self.comb += [
+ state.eq(Array(slot.state for slot in slots)[rr.grant]),
+ self.adr.eq(Array(slot.adr for slot in slots)[rr.grant]),
+ self.we.eq(Array(slot.we for slot in slots)[rr.grant]),
self.stb.eq(
- (self.slicer.bank(self.adr) == self.bankn) \
+ (slicer.bank(self.adr) == bankn) \
& (state == SLOT_PENDING)),
rr.ce.eq(self.ack | ~self.stb),
self.tag.eq(rr.grant)
]
- comb += [If((rr.grant == i) & self.stb & self.ack, slot.process.eq(1))
- for i, slot in enumerate(self.slots)]
-
- return Fragment(comb) + rr.get_fragment()
+ self.comb += [If((rr.grant == i) & self.stb & self.ack, slot.process.eq(1))
+ for i, slot in enumerate(slots)]
+
+ self.complete_selector(slicer, bankn, slots)
class _SimpleSelector(_Selector):
- def get_fragment(self):
- comb = []
- for i, slot in enumerate(self.slots):
- comb.append(self.rr.request[i].eq(
- (self.slicer.bank(slot.adr) == self.bankn) & \
- (slot.state == SLOT_PENDING)
- ))
-
- return Fragment(comb) + _Selector.get_fragment(self)
+ def complete_selector(self, slicer, bankn, slots):
+ for i, slot in enumerate(slots):
+ self.comb += self.rr.request[i].eq(
+ (slicer.bank(slot.adr) == bankn) & \
+ (slot.state == SLOT_PENDING))
class _FullSelector(_Selector):
- def get_fragment(self):
- comb = []
- sync = []
+ def complete_selector(self, slicer, bankn, slots):
rr = self.rr
# List outstanding requests for our bank
outstandings = []
- for slot in self.slots:
+ for slot in slots:
outstanding = Signal()
- comb.append(outstanding.eq(
- (self.slicer.bank(slot.adr) == self.bankn) & \
- (slot.state == SLOT_PENDING)
- ))
+ self.comb += outstanding.eq(
+ (slicer.bank(slot.adr) == bankn) & \
+ (slot.state == SLOT_PENDING))
outstandings.append(outstanding)
# Row tracking
- openrow_r = Signal(self.slicer.geom_settings.row_a)
- openrow_n = Signal(self.slicer.geom_settings.row_a)
- openrow = Signal(self.slicer.geom_settings.row_a)
- comb += [
- openrow_n.eq(self.slicer.row(self.adr)),
+ openrow_r = Signal(slicer.geom_settings.row_a)
+ openrow_n = Signal(slicer.geom_settings.row_a)
+ openrow = Signal(slicer.geom_settings.row_a)
+ self.comb += [
+ openrow_n.eq(slicer.row(self.adr)),
If(self.stb,
openrow.eq(openrow_n)
).Else(
openrow.eq(openrow_r)
)
]
- sync += [
- If(self.stb & self.ack,
- openrow_r.eq(openrow_n)
- )
- ]
+ self.sync += If(self.stb & self.ack, openrow_r.eq(openrow_n))
hits = []
- for slot, os in zip(self.slots, outstandings):
+ for slot, os in zip(slots, outstandings):
hit = Signal()
- comb.append(hit.eq((self.slicer.row(slot.adr) == openrow) & os))
+ self.comb += hit.eq((slicer.row(slot.adr) == openrow) & os)
hits.append(hit)
# Determine best request
rr = RoundRobin(self.nslots, SP_CE)
has_hit = Signal()
- comb.append(has_hit.eq(optree("|", hits)))
+ self.comb += has_hit.eq(optree("|", hits))
best_hit = [rr.request[i].eq(hit)
for i, hit in enumerate(hits)]
*best_fallback
)
- if self.slots[0].time:
+ if slots[0].time:
# Implement anti-starvation timer
matures = []
- for slot, os in zip(self.slots, outstandings):
+ for slot, os in zip(slots, outstandings):
mature = Signal()
comb.append(mature.eq(slot.mature & os))
matures.append(mature)
has_mature = Signal()
- comb.append(has_mature.eq(optree("|", matures)))
+ self.comb += has_mature.eq(optree("|", matures))
best_mature = [rr.request[i].eq(mature)
for i, mature in enumerate(matures)]
select_stmt = If(has_mature, *best_mature).Else(select_stmt)
- comb.append(select_stmt)
-
- return Fragment(comb, sync) + _Selector.get_fragment(self)
+ self.comb += select_stmt
-class _Buffer:
+class _Buffer(Module):
def __init__(self, source):
- self.source = source
-
self.stb = Signal()
self.ack = Signal()
- self.tag = Signal(self.source.tag.bv)
- self.adr = Signal(self.source.adr.bv)
+ self.tag = Signal(source.tag.bv)
+ self.adr = Signal(source.adr.bv)
self.we = Signal()
- def get_fragment(self):
+ ###
+
en = Signal()
- comb = [
+ self.comb += [
en.eq(self.ack | ~self.stb),
- self.source.ack.eq(en)
+ source.ack.eq(en)
]
- sync = [
+ self.sync += [
If(en,
- self.stb.eq(self.source.stb),
- self.tag.eq(self.source.tag),
- self.adr.eq(self.source.adr),
- self.we.eq(self.source.we)
+ self.stb.eq(source.stb),
+ self.tag.eq(source.tag),
+ self.adr.eq(source.adr),
+ self.we.eq(source.we)
)
]
- return Fragment(comb, sync)
-class BankMachine:
+class BankMachine(Module):
def __init__(self, geom_settings, timing_settings, address_align, bankn, slots, full_selector):
- self.geom_settings = geom_settings
- self.timing_settings = timing_settings
- self.address_align = address_align
- self.bankn = bankn
- self.slots = slots
- self.full_selector = full_selector
-
self.refresh_req = Signal()
self.refresh_gnt = Signal()
self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a,
bits_for(len(slots)-1))
- def get_fragment(self):
- comb = []
- sync = []
-
+ ###
+
# Sub components
- slicer = _AddressSlicer(self.geom_settings, self.address_align)
- if self.full_selector:
- selector = _FullSelector(slicer, self.bankn, self.slots)
- buf = _Buffer(selector)
- cmdsource = buf
+ slicer = _AddressSlicer(geom_settings, address_align)
+ if full_selector:
+ selector = _FullSelector(slicer, bankn, slots)
+ self.submodules.buf = _Buffer(selector)
+ cmdsource = self.buf
else:
- selector = _SimpleSelector(slicer, self.bankn, self.slots)
+ selector = _SimpleSelector(slicer, bankn, slots)
cmdsource = selector
+ self.submodules += selector
# Row tracking
has_openrow = Signal()
- openrow = Signal(self.geom_settings.row_a)
+ openrow = Signal(geom_settings.row_a)
hit = Signal()
- comb.append(hit.eq(openrow == slicer.row(cmdsource.adr)))
+ self.comb += hit.eq(openrow == slicer.row(cmdsource.adr))
track_open = Signal()
track_close = Signal()
- sync += [
+ self.sync += [
If(track_open,
has_openrow.eq(1),
openrow.eq(slicer.row(cmdsource.adr))
# Address generation
s_row_adr = Signal()
- comb += [
- self.cmd.ba.eq(self.bankn),
+ self.comb += [
+ self.cmd.ba.eq(bankn),
If(s_row_adr,
self.cmd.a.eq(slicer.row(cmdsource.adr))
).Else(
)
]
- comb.append(self.cmd.tag.eq(cmdsource.tag))
+ self.comb += self.cmd.tag.eq(cmdsource.tag)
# Respect write-to-precharge specification
precharge_ok = Signal()
- t_unsafe_precharge = 2 + self.timing_settings.tWR - 1
+ t_unsafe_precharge = 2 + timing_settings.tWR - 1
unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
- comb.append(precharge_ok.eq(unsafe_precharge_count == 0))
- sync += [
+ self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
+ self.sync += [
If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
unsafe_precharge_count.eq(t_unsafe_precharge)
).Elif(~precharge_ok,
# Control and command generation FSM
fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[
- ("TRP", "ACTIVATE", self.timing_settings.tRP-1),
- ("TRCD", "REGULAR", self.timing_settings.tRCD-1)
+ ("TRP", "ACTIVATE", timing_settings.tRP-1),
+ ("TRCD", "REGULAR", timing_settings.tRCD-1)
])
+ self.submodules += fsm
fsm.act(fsm.REGULAR,
If(self.refresh_req,
fsm.next_state(fsm.REFRESH)
track_close.eq(1),
If(~self.refresh_req, fsm.next_state(fsm.REGULAR))
)
-
- if self.full_selector:
- buf_fragment = buf.get_fragment()
- else:
- buf_fragment = Fragment()
- return Fragment(comb, sync) + \
- selector.get_fragment() + \
- buf_fragment + \
- fsm.get_fragment()
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.genlib.roundrobin import *
from migen.genlib.misc import optree
from migen.genlib.fsm import FSM
self.is_write = Signal()
self.tag = Signal(tagbits)
-class _CommandChooser:
+class _CommandChooser(Module):
def __init__(self, requests, tagbits):
- self.requests = requests
-
self.want_reads = Signal()
self.want_writes = Signal()
# NB: cas_n/ras_n/we_n are 1 when stb is inactive
- self.cmd = CommandRequestRW(len(self.requests[0].a), len(self.requests[0].ba), tagbits)
+ self.cmd = CommandRequestRW(len(requests[0].a), len(requests[0].ba), tagbits)
- def get_fragment(self):
- comb = []
- sync = []
-
- rr = RoundRobin(len(self.requests), SP_CE)
+ ###
+
+ rr = RoundRobin(len(requests), SP_CE)
+ self.submodules += rr
- comb += [rr.request[i].eq(req.stb & ((req.is_read == self.want_reads) | (req.is_write == self.want_writes)))
- for i, req in enumerate(self.requests)]
+ self.comb += [rr.request[i].eq(req.stb & ((req.is_read == self.want_reads) | (req.is_write == self.want_writes)))
+ for i, req in enumerate(requests)]
stb = Signal()
- comb.append(stb.eq(Array(req.stb for req in self.requests)[rr.grant]))
+ self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
for name in ["a", "ba", "is_read", "is_write", "tag"]:
- choices = Array(getattr(req, name) for req in self.requests)
- comb.append(getattr(self.cmd, name).eq(choices[rr.grant]))
+ choices = Array(getattr(req, name) for req in requests)
+ self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
for name in ["cas_n", "ras_n", "we_n"]:
# we should only assert those signals when stb is 1
- choices = Array(getattr(req, name) for req in self.requests)
- comb.append(If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant])))
- comb.append(self.cmd.stb.eq(stb \
+ choices = Array(getattr(req, name) for req in requests)
+ self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
+ self.comb += self.cmd.stb.eq(stb \
& (self.cmd.is_read == self.want_reads) \
- & (self.cmd.is_write == self.want_writes)))
+ & (self.cmd.is_write == self.want_writes))
- comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
- for i, req in enumerate(self.requests)]
- comb.append(rr.ce.eq(self.cmd.ack))
-
- return Fragment(comb, sync) + rr.get_fragment()
+ self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
+ for i, req in enumerate(requests)]
+ self.comb += rr.ce.eq(self.cmd.ack)
-class _Steerer:
+class _Steerer(Module):
def __init__(self, commands, dfi):
- self.commands = commands
- self.dfi = dfi
-
- ncmd = len(self.commands)
- nph = len(self.dfi.phases)
+ ncmd = len(commands)
+ nph = len(dfi.phases)
self.sel = [Signal(max=ncmd) for i in range(nph)]
- def get_fragment(self):
- comb = []
- sync = []
+ ###
+
def stb_and(cmd, attr):
if not hasattr(cmd, "stb"):
return 0
else:
return cmd.stb & getattr(cmd, attr)
- for phase, sel in zip(self.dfi.phases, self.sel):
- comb += [
+ for phase, sel in zip(dfi.phases, self.sel):
+ self.comb += [
phase.cke.eq(1),
phase.cs_n.eq(0)
]
- sync += [
- phase.address.eq(Array(cmd.a for cmd in self.commands)[sel]),
- phase.bank.eq(Array(cmd.ba for cmd in self.commands)[sel]),
- phase.cas_n.eq(Array(cmd.cas_n for cmd in self.commands)[sel]),
- phase.ras_n.eq(Array(cmd.ras_n for cmd in self.commands)[sel]),
- phase.we_n.eq(Array(cmd.we_n for cmd in self.commands)[sel]),
- phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in self.commands)[sel]),
- phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in self.commands)[sel])
+ self.sync += [
+ phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
+ phase.bank.eq(Array(cmd.ba for cmd in commands)[sel]),
+ phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
+ phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
+ phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
+ phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
+ phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
]
- return Fragment(comb, sync)
-class _Datapath:
+class _Datapath(Module):
def __init__(self, timing_settings, command, dfi, hub):
- self.timing_settings = timing_settings
- self.command = command
- self.dfi = dfi
- self.hub = hub
-
- def get_fragment(self):
- comb = []
- sync = []
- tagbits = len(self.hub.tag_call)
+ tagbits = len(hub.tag_call)
rd_valid = Signal()
rd_tag = Signal(tagbits)
wr_valid = Signal()
wr_tag = Signal(tagbits)
- comb += [
- self.hub.call.eq(rd_valid | wr_valid),
+ self.comb += [
+ hub.call.eq(rd_valid | wr_valid),
If(wr_valid,
- self.hub.tag_call.eq(wr_tag)
+ hub.tag_call.eq(wr_tag)
).Else(
- self.hub.tag_call.eq(rd_tag)
+ hub.tag_call.eq(rd_tag)
)
]
- rd_delay = self.timing_settings.rd_delay + 1
+ rd_delay = timing_settings.rd_delay + 1
rd_valid_d = [Signal() for i in range(rd_delay)]
rd_tag_d = [Signal(tagbits) for i in range(rd_delay)]
for i in range(rd_delay):
if i:
- sync += [
+ self.sync += [
rd_valid_d[i].eq(rd_valid_d[i-1]),
rd_tag_d[i].eq(rd_tag_d[i-1])
]
else:
- sync += [
- rd_valid_d[i].eq(self.command.stb & self.command.ack & self.command.is_read),
- rd_tag_d[i].eq(self.command.tag)
+ self.sync += [
+ rd_valid_d[i].eq(command.stb & command.ack & command.is_read),
+ rd_tag_d[i].eq(command.tag)
]
- comb += [
+ self.comb += [
rd_valid.eq(rd_valid_d[-1]),
rd_tag.eq(rd_tag_d[-1]),
- wr_valid.eq(self.command.stb & self.command.ack & self.command.is_write),
- wr_tag.eq(self.command.tag),
+ wr_valid.eq(command.stb & command.ack & command.is_write),
+ wr_tag.eq(command.tag),
]
- all_rddata = [p.rddata for p in self.dfi.phases]
- all_wrdata = [p.wrdata for p in self.dfi.phases]
- all_wrdata_mask = [p.wrdata_mask for p in self.dfi.phases]
- comb += [
- self.hub.dat_r.eq(Cat(*all_rddata)),
- Cat(*all_wrdata).eq(self.hub.dat_w),
- Cat(*all_wrdata_mask).eq(self.hub.dat_wm)
+ all_rddata = [p.rddata for p in dfi.phases]
+ all_wrdata = [p.wrdata for p in dfi.phases]
+ all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
+ self.comb += [
+ hub.dat_r.eq(Cat(*all_rddata)),
+ Cat(*all_wrdata).eq(hub.dat_w),
+ Cat(*all_wrdata_mask).eq(hub.dat_wm)
]
-
- return Fragment(comb, sync)
-class Multiplexer:
+class Multiplexer(Module):
def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, hub):
- self.phy_settings = phy_settings
- self.geom_settings = geom_settings
- self.timing_settings = timing_settings
- self.bank_machines = bank_machines
- self.refresher = refresher
- self.dfi = dfi
- self.hub = hub
-
- assert(self.phy_settings.nphases == len(dfi.phases))
- if self.phy_settings.nphases != 2:
+ assert(phy_settings.nphases == len(dfi.phases))
+ if phy_settings.nphases != 2:
raise NotImplementedError("TODO: multiplexer only supports 2 phases")
- def get_fragment(self):
- comb = []
- sync = []
-
# Command choosing
- requests = [bm.cmd for bm in self.bank_machines]
- tagbits = len(self.hub.tag_call)
+ requests = [bm.cmd for bm in bank_machines]
+ tagbits = len(hub.tag_call)
choose_cmd = _CommandChooser(requests, tagbits)
choose_req = _CommandChooser(requests, tagbits)
- comb += [
+ self.comb += [
choose_cmd.want_reads.eq(0),
choose_cmd.want_writes.eq(0)
]
+ self.submodules += choose_cmd, choose_req
# Command steering
- nop = CommandRequest(self.geom_settings.mux_a, self.geom_settings.bank_a)
- commands = [nop, choose_cmd.cmd, choose_req.cmd, self.refresher.cmd] # nop must be 1st
+ nop = CommandRequest(geom_settings.mux_a, geom_settings.bank_a)
+ commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
(STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
- steerer = _Steerer(commands, self.dfi)
+ steerer = _Steerer(commands, dfi)
+ self.submodules += steerer
# Read/write turnaround
read_available = Signal()
write_available = Signal()
- comb += [
+ self.comb += [
read_available.eq(optree("|", [req.stb & req.is_read for req in requests])),
write_available.eq(optree("|", [req.stb & req.is_write for req in requests]))
]
if timeout:
t = timeout - 1
time = Signal(max=t+1)
- comb.append(max_time.eq(time == 0))
- sync.append(
- If(~en,
+ self.comb += max_time.eq(time == 0)
+ self.sync += If(~en,
time.eq(t)
).Elif(~max_time,
time.eq(time - 1)
)
- )
else:
- comb.append(max_time.eq(0))
+ self.comb += max_time.eq(0)
return en, max_time
- read_time_en, max_read_time = anti_starvation(self.timing_settings.read_time)
- write_time_en, max_write_time = anti_starvation(self.timing_settings.write_time)
+ read_time_en, max_read_time = anti_starvation(timing_settings.read_time)
+ write_time_en, max_write_time = anti_starvation(timing_settings.write_time)
# Refresh
- comb += [bm.refresh_req.eq(self.refresher.req)
- for bm in self.bank_machines]
+ self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
go_to_refresh = Signal()
- comb.append(go_to_refresh.eq(
- optree("&", [bm.refresh_gnt for bm in self.bank_machines])))
+ self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines]))
# Datapath
- datapath = _Datapath(self.timing_settings, choose_req.cmd, self.dfi, self.hub)
+ datapath = _Datapath(timing_settings, choose_req.cmd, dfi, hub)
+ self.submodules += datapath
# Control FSM
fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[
- ("RTW", "WRITE", self.timing_settings.rd_delay),
- ("WTR", "READ", self.timing_settings.tWR)
+ ("RTW", "WRITE", timing_settings.rd_delay),
+ ("WTR", "READ", timing_settings.tWR)
])
+ self.submodules += fsm
fsm.act(fsm.READ,
read_time_en.eq(1),
choose_req.want_reads.eq(1),
choose_cmd.cmd.ack.eq(1),
choose_req.cmd.ack.eq(1),
- steerer.sel[1-self.phy_settings.rdphase].eq(STEER_CMD),
- steerer.sel[self.phy_settings.rdphase].eq(STEER_REQ),
+ steerer.sel[1-phy_settings.rdphase].eq(STEER_CMD),
+ steerer.sel[phy_settings.rdphase].eq(STEER_REQ),
If(write_available,
# TODO: switch only after several cycles of ~read_available?
If(~read_available | max_read_time, fsm.next_state(fsm.RTW))
choose_req.want_writes.eq(1),
choose_cmd.cmd.ack.eq(1),
choose_req.cmd.ack.eq(1),
- steerer.sel[1-self.phy_settings.wrphase].eq(STEER_CMD),
- steerer.sel[self.phy_settings.wrphase].eq(STEER_REQ),
+ steerer.sel[1-phy_settings.wrphase].eq(STEER_CMD),
+ steerer.sel[phy_settings.wrphase].eq(STEER_REQ),
If(read_available,
If(~write_available | max_write_time, fsm.next_state(fsm.WTR))
),
)
fsm.act(fsm.REFRESH,
steerer.sel[0].eq(STEER_REFRESH),
- If(~self.refresher.req, fsm.next_state(fsm.READ))
+ If(~refresher.req, fsm.next_state(fsm.READ))
)
# FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
- comb.append(self.refresher.ack.eq(fsm._state == fsm.REFRESH))
-
- return Fragment(comb, sync) + \
- choose_cmd.get_fragment() + \
- choose_req.get_fragment() + \
- steerer.get_fragment() + \
- datapath.get_fragment() + \
- fsm.get_fragment()
+ self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH)
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.genlib.misc import timeline
from migen.genlib.fsm import FSM
from milkymist.asmicon.multiplexer import *
-class Refresher:
+class Refresher(Module):
def __init__(self, a, ba, tRP, tREFI, tRFC):
- self.tRP = tRP
- self.tREFI = tREFI
- self.tRFC = tRFC
-
self.req = Signal()
self.ack = Signal() # 1st command 1 cycle after assertion of ack
self.cmd = CommandRequest(a, ba)
- def get_fragment(self):
- comb = []
- sync = []
-
+ ###
+
# Refresh sequence generator:
# PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
seq_start = Signal()
seq_done = Signal()
- sync += [
+ self.sync += [
self.cmd.a.eq(2**10),
self.cmd.ba.eq(0),
self.cmd.cas_n.eq(1),
self.cmd.we_n.eq(1),
seq_done.eq(0)
]
- sync += timeline(seq_start, [
+ self.sync += timeline(seq_start, [
(1, [
self.cmd.ras_n.eq(0),
self.cmd.we_n.eq(0)
]),
- (1+self.tRP, [
+ (1+tRP, [
self.cmd.cas_n.eq(0),
self.cmd.ras_n.eq(0)
]),
- (1+self.tRP+self.tRFC, [
+ (1+tRP+tRFC, [
seq_done.eq(1)
])
])
# Periodic refresh counter
- counter = Signal(max=self.tREFI)
+ counter = Signal(max=tREFI)
start = Signal()
- sync += [
+ self.sync += [
start.eq(0),
If(counter == 0,
start.eq(1),
- counter.eq(self.tREFI - 1)
+ counter.eq(tREFI - 1)
).Else(
counter.eq(counter - 1)
)
# Control FSM
fsm = FSM("IDLE", "WAIT_GRANT", "WAIT_SEQ")
+ self.submodules += fsm
fsm.act(fsm.IDLE, If(start, fsm.next_state(fsm.WAIT_GRANT)))
fsm.act(fsm.WAIT_GRANT,
self.req.eq(1),
self.req.eq(1),
If(seq_done, fsm.next_state(fsm.IDLE))
)
-
- return Fragment(comb, sync) + fsm.get_fragment()
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bank.description import *
-from migen.bank import csrgen
-class ASMIprobe:
- def __init__(self, address, hub, trace_depth=16):
- self.hub = hub
- self.trace_depth = trace_depth
-
- slot_count = len(self.hub.get_slots())
- assert(self.trace_depth < 256)
+class ASMIprobe(Module):
+ def __init__(self, hub, trace_depth=16):
+ slots = hub.get_slots()
+ slot_count = len(slots)
+ assert(trace_depth < 256)
assert(slot_count < 256)
self._slot_count = RegisterField("slot_count", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._trace_depth = RegisterField("trace_depth", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
- self._slot_status = [RegisterField("slot_status", 2, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+ self._slot_status = [RegisterField("slot_status" + str(i), 2, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
for i in range(slot_count)]
- self._trace = [RegisterField("trace", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
- for i in range(self.trace_depth)]
+ self._trace = [RegisterField("trace" + str(i), 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+ for i in range(trace_depth)]
- self.bank = csrgen.Bank([self._slot_count, self._trace_depth]
- + self._slot_status + self._trace, address=address)
-
- def get_fragment(self):
- slots = self.hub.get_slots()
- comb = [
- self._slot_count.field.w.eq(len(slots)),
- self._trace_depth.field.w.eq(self.trace_depth)
+ ###
+
+ self.comb += [
+ self._slot_count.field.w.eq(slot_count),
+ self._trace_depth.field.w.eq(trace_depth)
]
for slot, status in zip(slots, self._slot_status):
- comb.append(status.field.w.eq(slot.state))
+ self.comb += status.field.w.eq(slot.state)
shift_tags = [self._trace[n].field.w.eq(self._trace[n+1].field.w)
for n in range(len(self._trace) - 1)]
- shift_tags.append(self._trace[-1].field.w.eq(self.hub.tag_call))
- sync = [If(self.hub.call, *shift_tags)]
- return Fragment(comb, sync) + self.bank.get_fragment()
+ shift_tags.append(self._trace[-1].field.w.eq(hub.tag_call))
+ self.sync += If(hub.call, *shift_tags)
+
+ def get_registers(self):
+ return [self._slot_count, self._trace_depth] + self._slot_status + self._trace
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bus import dfi
from migen.bank.description import *
-from migen.bank import csrgen
-class PhaseInjector:
+class PhaseInjector(Module, AutoReg):
def __init__(self, phase):
- self.phase = phase
-
self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
[self._cs, self._we, self._cas, self._ras, self._wren, self._rden])
self._command_issue = RegisterRaw("command_issue")
- self._address = RegisterField("address", len(self.phase.address))
- self._baddress = RegisterField("baddress", len(self.phase.bank))
+ self._address = RegisterField("address", len(phase.address))
+ self._baddress = RegisterField("baddress", len(phase.bank))
- self._wrdata = RegisterField("wrdata", len(self.phase.wrdata))
- self._rddata = RegisterField("rddata", len(self.phase.rddata), READ_ONLY, WRITE_ONLY)
+ self._wrdata = RegisterField("wrdata", len(phase.wrdata))
+ self._rddata = RegisterField("rddata", len(phase.rddata), READ_ONLY, WRITE_ONLY)
- def get_registers(self):
- return [self._command, self._command_issue,
- self._address, self._baddress,
- self._wrdata, self._rddata]
-
- def get_fragment(self):
- comb = [
+ ###
+
+ self.comb += [
If(self._command_issue.re,
- self.phase.cs_n.eq(~self._cs.r),
- self.phase.we_n.eq(~self._we.r),
- self.phase.cas_n.eq(~self._cas.r),
- self.phase.ras_n.eq(~self._ras.r)
+ phase.cs_n.eq(~self._cs.r),
+ phase.we_n.eq(~self._we.r),
+ phase.cas_n.eq(~self._cas.r),
+ phase.ras_n.eq(~self._ras.r)
).Else(
- self.phase.cs_n.eq(1),
- self.phase.we_n.eq(1),
- self.phase.cas_n.eq(1),
- self.phase.ras_n.eq(1)
+ phase.cs_n.eq(1),
+ phase.we_n.eq(1),
+ phase.cas_n.eq(1),
+ phase.ras_n.eq(1)
),
- self.phase.address.eq(self._address.field.r),
- self.phase.bank.eq(self._baddress.field.r),
- self.phase.wrdata_en.eq(self._command_issue.re & self._wren.r),
- self.phase.rddata_en.eq(self._command_issue.re & self._rden.r),
- self.phase.wrdata.eq(self._wrdata.field.r),
- self.phase.wrdata_mask.eq(0)
- ]
- sync = [
- If(self.phase.rddata_valid, self._rddata.field.w.eq(self.phase.rddata))
+ phase.address.eq(self._address.field.r),
+ phase.bank.eq(self._baddress.field.r),
+ phase.wrdata_en.eq(self._command_issue.re & self._wren.r),
+ phase.rddata_en.eq(self._command_issue.re & self._rden.r),
+ phase.wrdata.eq(self._wrdata.field.r),
+ phase.wrdata_mask.eq(0)
]
- return Fragment(comb, sync)
+ self.sync += If(phase.rddata_valid, self._rddata.field.w.eq(phase.rddata))
-class DFIInjector:
- def __init__(self, csr_address, a, ba, d, nphases=1):
- self._int = dfi.Interface(a, ba, d, nphases)
+class DFIInjector(Module, AutoReg):
+ def __init__(self, a, ba, d, nphases=1):
+ inti = dfi.Interface(a, ba, d, nphases)
self.slave = dfi.Interface(a, ba, d, nphases)
self.master = dfi.Interface(a, ba, d, nphases)
self._cke = Field("cke")
self._control = RegisterFields("control", [self._sel, self._cke])
- self._phase_injectors = [PhaseInjector(phase) for phase in self._int.phases]
-
- registers = sum([pi.get_registers() for pi in self._phase_injectors], [self._control])
- self.bank = csrgen.Bank(registers, address=csr_address)
+ for n, phase in enumerate(inti.phases):
+ setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
+
+ ###
- def get_fragment(self):
- connect_int = dfi.interconnect_stmts(self._int, self.master)
+ connect_inti = dfi.interconnect_stmts(inti, self.master)
connect_slave = dfi.interconnect_stmts(self.slave, self.master)
- comb = [
- If(self._sel.r, *connect_slave).Else(*connect_int)
- ]
- comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
-
- return Fragment(comb) \
- + sum([pi.get_fragment() for pi in self._phase_injectors], Fragment()) \
- + self.bank.get_fragment()
+ self.comb += If(self._sel.r, *connect_slave).Else(*connect_inti)
+ self.comb += [phase.cke.eq(self._cke.r) for phase in inti.phases]
from migen.fhdl.structure import *
from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
from migen.flow.actor import *
from migen.flow.network import *
from migen.flow.transactions import *
from migen.flow import plumbing
from migen.actorlib import misc, dma_asmi, structuring, sim, spi
from migen.bank.description import *
-from migen.bank import csrgen
_hbits = 11
_vbits = 11
]
spi.SingleGenerator.__init__(self, layout, spi.MODE_CONTINUOUS)
-class VTG(Actor):
+class VTG(Module, Actor):
def __init__(self):
Actor.__init__(self,
("timing", Sink, [
("pixels", Sink, _pixel_layout),
("dac", Source, _dac_layout)
)
-
- def get_fragment(self):
+
hactive = Signal()
vactive = Signal()
active = Signal()
vcounter = Signal(_vbits)
skip = _bpc - _bpc_dac
- comb = [
+ self.comb += [
active.eq(hactive & vactive),
If(active,
self.token("dac").r.eq(self.token("pixels").r[skip:]),
self.endpoints["dac"].stb.eq(generate_en)
]
tp = self.token("timing")
- sync = [
+ self.sync += [
self.endpoints["timing"].ack.eq(0),
If(generate_en & self.endpoints["dac"].ack,
hcounter.eq(hcounter + 1),
If(vcounter == tp.vsync_end, self.token("dac").vsync.eq(0))
)
]
-
- return Fragment(comb, sync)
-class FIFO(Actor):
+class FIFO(Module, Actor):
def __init__(self):
Actor.__init__(self, ("dac", Sink, _dac_layout))
self.vga_g = Signal(_bpc_dac)
self.vga_b = Signal(_bpc_dac)
- def get_fragment(self):
+ ###
+
data_width = 2+3*_bpc_dac
fifo_full = Signal()
fifo_write_en = Signal()
fifo_data_out = Signal(data_width)
fifo_data_in = Signal(data_width)
- asfifo = Instance("asfifo",
+ self.specials += Instance("asfifo",
Instance.Parameter("data_width", data_width),
Instance.Parameter("address_width", 8),
Instance.Input("rst", 0))
t = self.token("dac")
- return Fragment(
- [
- Cat(self.vga_hsync_n, self.vga_vsync_n, self.vga_r, self.vga_g, self.vga_b).eq(asfifo.get_io("data_out")),
-
- self.endpoints["dac"].ack.eq(~fifo_full),
- fifo_write_en.eq(self.endpoints["dac"].stb),
- fifo_data_in.eq(Cat(~t.hsync, ~t.vsync, t.r, t.g, t.b)),
-
- self.busy.eq(0)
- ],
- specials={asfifo})
+ self.comb += [
+ Cat(self.vga_hsync_n, self.vga_vsync_n, self.vga_r, self.vga_g, self.vga_b).eq(fifo_data_out),
+
+ self.endpoints["dac"].ack.eq(~fifo_full),
+ fifo_write_en.eq(self.endpoints["dac"].stb),
+ fifo_data_in.eq(Cat(~t.hsync, ~t.vsync, t.r, t.g, t.b)),
+
+ self.busy.eq(0)
+ ]
def sim_fifo_gen():
while True:
print("H/V:" + str(t.value["hsync"]) + str(t.value["vsync"])
+ " " + str(t.value["r"]) + " " + str(t.value["g"]) + " " + str(t.value["b"]))
-
-class Framebuffer:
- def __init__(self, address, asmiport, simulation=False):
+class Framebuffer(Module):
+ def __init__(self, asmiport, simulation=False):
asmi_bits = asmiport.hub.aw
alignment_bits = bits_for(asmiport.hub.dw//8) - 1
length_bits = _hbits + _vbits + 2 - alignment_bits
"hres", "hsync_start", "hsync_end", "hscan",
"vres", "vsync_start", "vsync_end", "vscan"])
g.add_connection(vtg, fifo)
- self._comp_actor = CompositeActor(g, debugger=False)
+ self.submodules._comp_actor = CompositeActor(g, debugger=False)
- self.bank = csrgen.Bank(fi.get_registers() + self._comp_actor.get_registers(),
- address=address)
+ self._registers = fi.get_registers() + self._comp_actor.get_registers()
# Pads
self.vga_psave_n = Signal()
self.vga_g = fifo.vga_g
self.vga_b = fifo.vga_b
- def get_fragment(self):
- comb = [
+ self.comb += [
self.vga_sync_n.eq(0),
self.vga_psave_n.eq(1),
self.vga_blank_n.eq(1)
]
- return self.bank.get_fragment() \
- + self._comp_actor.get_fragment() \
- + Fragment(comb)
+
+ def get_registers(self):
+ return self._registers
+import re
+
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bank.description import *
-from migen.bank import csrgen
-
-import re
def encode_version(version):
match = re.match("(\d+)\.(\d+)(\.(\d+))?(rc(\d+))?", version, re.IGNORECASE)
r |= int(rc)
return r
-class Identifier:
- def __init__(self, address, sysid, version, frequency):
- self.sysid = sysid
- self.version = encode_version(version)
- self.frequency = frequency
-
+class Identifier(Module, AutoReg):
+ def __init__(self, sysid, version, frequency):
self._r_sysid = RegisterField("sysid", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_version = RegisterField("version", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_frequency = RegisterField("frequency", 32, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
- regs = [self._r_sysid, self._r_version, self._r_frequency]
- self.bank = csrgen.Bank(regs, address=address)
- def get_fragment(self):
- comb = [
- self._r_sysid.field.w.eq(self.sysid),
- self._r_version.field.w.eq(self.version),
- self._r_frequency.field.w.eq(self.frequency)
+ ###
+
+ self.comb += [
+ self._r_sysid.field.w.eq(sysid),
+ self._r_version.field.w.eq(encode_version(version)),
+ self._r_frequency.field.w.eq(frequency)
]
- return self.bank.get_fragment() + Fragment(comb)
from migen.fhdl.structure import *
from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
from migen.bus import wishbone
-class LM32:
+class LM32(Module):
def __init__(self):
self.ibus = i = wishbone.Interface()
self.dbus = d = wishbone.Interface()
self.interrupt = Signal(32)
self.ext_break = Signal()
- self._i_adr_o = Signal(32)
- self._d_adr_o = Signal(32)
- self._inst = Instance("lm32_top",
+
+ ###
+
+ i_adr_o = Signal(32)
+ d_adr_o = Signal(32)
+ self.specials += Instance("lm32_top",
Instance.ClockPort("clk_i"),
Instance.ResetPort("rst_i"),
Instance.Input("interrupt", self.interrupt),
#Instance.Input("ext_break", self.ext_break),
- Instance.Output("I_ADR_O", self._i_adr_o),
+ Instance.Output("I_ADR_O", i_adr_o),
Instance.Output("I_DAT_O", i.dat_w),
Instance.Output("I_SEL_O", i.sel),
Instance.Output("I_CYC_O", i.cyc),
Instance.Input("I_ERR_I", i.err),
Instance.Input("I_RTY_I", 0),
- Instance.Output("D_ADR_O", self._d_adr_o),
+ Instance.Output("D_ADR_O", d_adr_o),
Instance.Output("D_DAT_O", d.dat_w),
Instance.Output("D_SEL_O", d.sel),
Instance.Output("D_CYC_O", d.cyc),
Instance.Input("D_ERR_I", d.err),
Instance.Input("D_RTY_I", 0))
- def get_fragment(self):
- comb = [
- self.ibus.adr.eq(self._i_adr_o[2:]),
- self.dbus.adr.eq(self._d_adr_o[2:])
+ self.comb += [
+ self.ibus.adr.eq(i_adr_o[2:]),
+ self.dbus.adr.eq(d_adr_o[2:])
]
- return Fragment(comb, specials={self._inst})
from migen.fhdl.structure import *
from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
from mibuild.crg import CRG
-class M1CRG(CRG):
+class M1CRG(Module, CRG):
def __init__(self, infreq, outfreq1x):
self.clk50_pad = Signal()
self.trigger_reset = Signal()
setattr(self, name, s)
inst_items.append(Instance.Output(name, s))
- self._inst = Instance("m1crg", *inst_items)
-
- def get_fragment(self):
- return Fragment(specials={self._inst})
+ self.specials += Instance("m1crg", *inst_items)
from migen.fhdl.structure import *
from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
from migen.bank.description import *
from migen.bank.eventmanager import *
-from migen.bank import csrgen
from migen.bus import wishbone
_count_width = 11
-class MiniMAC:
- def __init__(self, address):
+class MiniMAC(Module, AutoReg):
+ def __init__(self):
# PHY signals
self.phy_tx_clk = Signal()
self.phy_tx_data = Signal(4)
self._rx_count_1 = RegisterField("rx_count_1", _count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._tx_count = RegisterField("tx_count", _count_width, access_dev=READ_WRITE)
self._tx_start = RegisterRaw("tx_start")
- regs = [self._phy_reset, self._rx_count_0, self._rx_count_1, self._tx_count, self._tx_start]
- self._rx_event_0 = EventSourcePulse()
- self._rx_event_1 = EventSourcePulse()
- self._tx_event = EventSourcePulse()
- self.events = EventManager(self._rx_event_0, self._rx_event_1, self._tx_event)
+ self.submodules.ev = EventManager()
+ self.ev.rx0 = EventSourcePulse()
+ self.ev.rx1 = EventSourcePulse()
+ self.ev.tx = EventSourcePulse()
+ self.ev.finalize()
- self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
self.membus = wishbone.Interface()
- def get_fragment(self):
+ ###
+
init = Signal(reset=1)
+ self.sync += init.eq(0)
rx_ready_0 = Signal()
rx_ready_1 = Signal()
- rx_pending_0 = self._rx_event_0.pending
- rx_pending_1 = self._rx_event_1.pending
+ rx_pending_0 = self.ev.rx0.pending
+ rx_pending_1 = self.ev.rx1.pending
rx_pending_0_r = Signal()
rx_pending_1_r = Signal()
- comb = [
+ self.comb += [
self.phy_rst_n.eq(~self._phy_reset.field.r),
rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
self._tx_count.field.w.eq(0),
- self._tx_count.field.we.eq(self._tx_event.trigger)
+ self._tx_count.field.we.eq(self.ev.tx.trigger)
]
- sync = [
- init.eq(0),
+ self.sync += [
rx_pending_0_r.eq(rx_pending_0),
rx_pending_1_r.eq(rx_pending_1)
]
- inst = Instance("minimac3",
+ self.specials += Instance("minimac3",
Instance.ClockPort("sys_clk"),
Instance.ResetPort("sys_rst"),
- Instance.Output("rx_done_0", self._rx_event_0.trigger),
+ Instance.Output("rx_done_0", self.ev.rx0.trigger),
Instance.Output("rx_count_0", self._rx_count_0.field.w),
- Instance.Output("rx_done_1", self._rx_event_1.trigger),
+ Instance.Output("rx_done_1", self.ev.rx1.trigger),
Instance.Output("rx_count_1", self._rx_count_1.field.w),
Instance.Input("rx_ready_0", rx_ready_0),
Instance.Input("rx_ready_1", rx_ready_1),
Instance.Input("tx_start", self._tx_start.re),
Instance.Input("tx_count", self._tx_count.field.r),
- Instance.Output("tx_done", self._tx_event.trigger),
+ Instance.Output("tx_done", self.ev.tx.trigger),
Instance.Input("wb_adr_i", self.membus.adr),
Instance.Input("wb_dat_i", self.membus.dat_w),
Instance.Input("phy_rx_er", self.phy_rx_er),
Instance.Input("phy_col", self.phy_col),
Instance.Input("phy_crs", self.phy_crs))
- return Fragment(comb, sync, specials={inst}) \
- + self.events.get_fragment() \
- + self.bank.get_fragment()
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bus import wishbone
from migen.genlib.misc import timeline
-class NorFlash:
+class NorFlash(Module):
def __init__(self, adr_width, rd_timing):
- self.adr_width = adr_width
- self.rd_timing = rd_timing
-
self.bus = wishbone.Interface()
self.adr = Signal(adr_width-1)
self.d = Signal(16)
self.we_n = Signal()
self.ce_n = Signal()
- def get_fragment(self):
- comb = [self.oe_n.eq(0), self.we_n.eq(1),
+ ###
+
+ self.comb += [self.oe_n.eq(0), self.we_n.eq(1),
self.ce_n.eq(0)]
- sync = timeline(self.bus.cyc & self.bus.stb, [
- (0, [self.adr.eq(Cat(0, self.bus.adr[:self.adr_width-2]))]),
- (self.rd_timing, [
+ self.sync += timeline(self.bus.cyc & self.bus.stb, [
+ (0, [self.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
+ (rd_timing, [
self.bus.dat_r[16:].eq(self.d),
- self.adr.eq(Cat(1, self.bus.adr[:self.adr_width-2]))]),
- (2*self.rd_timing, [
+ self.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
+ (2*rd_timing, [
self.bus.dat_r[:16].eq(self.d),
self.bus.ack.eq(1)]),
- (2*self.rd_timing + 1, [
+ (2*rd_timing + 1, [
self.bus.ack.eq(0)])
])
- return Fragment(comb, sync)
from migen.fhdl.structure import *
from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
from migen.bus import dfi
-class S6DDRPHY:
+class S6DDRPHY(Module):
def __init__(self, a, ba, d):
inst_items = [
Instance.Parameter("NUM_AD", a),
inst_items += [Instance.Output(name, signal)
for name, signal in self.dfi.get_standard_names(False, True)]
- self._inst = Instance("s6ddrphy", *inst_items)
-
- def get_fragment(self):
- return Fragment(specials={self._inst})
+ self.specials += Instance("s6ddrphy", *inst_items)
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bank.description import *
from migen.bank.eventmanager import *
-from migen.bank import csrgen
-class Timer:
- def __init__(self, address, width=32):
+class Timer(Module, AutoReg):
+ def __init__(self, width=32):
self._en = RegisterField("en")
self._value = RegisterField("value", width, access_dev=READ_WRITE)
self._reload = RegisterField("reload", width)
- regs = [self._en, self._value, self._reload]
- self.event = EventSourceLevel()
- self.events = EventManager(self.event)
-
- self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
+ self.submodules.ev = EventManager()
+ self.ev.zero = EventSourceLevel()
+ self.ev.finalize()
+
+ ###
- def get_fragment(self):
- comb = [
+ self.comb += [
If(self._value.field.r == 0,
self._value.field.w.eq(self._reload.field.r)
).Else(
self._value.field.w.eq(self._value.field.r - 1)
),
self._value.field.we.eq(self._en.field.r),
- self.event.trigger.eq(self._value.field.r != 0)
+ self.ev.zero.trigger.eq(self._value.field.r != 0)
]
- return Fragment(comb) \
- + self.events.get_fragment() \
- + self.bank.get_fragment()
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.cdc import MultiReg
from migen.bank.description import *
from migen.bank.eventmanager import *
-from migen.bank import csrgen
-class UART:
- def __init__(self, address, clk_freq, baud=115200):
+class UART(Module, AutoReg):
+ def __init__(self, clk_freq, baud=115200):
self._rxtx = RegisterRaw("rxtx", 8)
self._divisor = RegisterField("divisor", 16, reset=int(clk_freq/baud/16))
- self._tx_event = EventSourceLevel()
- self._rx_event = EventSourcePulse()
- self.events = EventManager(self._tx_event, self._rx_event)
- self.bank = csrgen.Bank([self._rxtx, self._divisor] + self.events.get_registers(),
- address=address)
+ self.submodules.ev = EventManager()
+ self.ev.tx = EventSourceLevel()
+ self.ev.rx = EventSourcePulse()
+ self.ev.finalize()
self.tx = Signal(reset=1)
self.rx = Signal()
- def get_fragment(self):
+ ###
+
enable16 = Signal()
enable16_counter = Signal(16)
- comb = [
- enable16.eq(enable16_counter == 0)
- ]
- sync = [
+ self.comb += enable16.eq(enable16_counter == 0)
+ self.sync += [
enable16_counter.eq(enable16_counter - 1),
If(enable16,
enable16_counter.eq(self._divisor.field.r - 1))
tx_reg = Signal(8)
tx_bitcount = Signal(4)
tx_count16 = Signal(4)
- tx_busy = self._tx_event.trigger
- sync += [
+ tx_busy = self.ev.tx.trigger
+ self.sync += [
If(self._rxtx.re,
tx_reg.eq(self._rxtx.r),
tx_bitcount.eq(0),
]
# RX
- rx0 = Signal() # sychronize
rx = Signal()
- sync += [
- rx0.eq(self.rx),
- rx.eq(rx0)
- ]
+ self.specials += MultiReg(self.rx, "ext", rx, "sys")
rx_r = Signal()
rx_reg = Signal(8)
rx_bitcount = Signal(4)
rx_count16 = Signal(4)
rx_busy = Signal()
- rx_done = self._rx_event.trigger
+ rx_done = self.ev.rx.trigger
rx_data = self._rxtx.w
- sync += [
+ self.sync += [
rx_done.eq(0),
If(enable16,
rx_r.eq(rx),
)
)
]
-
- return self.bank.get_fragment() \
- + self.events.get_fragment() \
- + Fragment(comb, sync)
+++ /dev/null
-#ifndef __HW_ID_H
-#define __HW_ID_H
-
-#include <hw/common.h>
-#include <csrbase.h>
-
-#define ID_CSR(x) MMPTR(ID_BASE+(x))
-
-#define CSR_ID_SYSTEMH ID_CSR(0x00)
-#define CSR_ID_SYSTEML ID_CSR(0x04)
-#define CSR_ID_VERSIONH ID_CSR(0x08)
-#define CSR_ID_VERSIONL ID_CSR(0x0C)
-#define CSR_ID_FREQ3 ID_CSR(0x10)
-#define CSR_ID_FREQ2 ID_CSR(0x14)
-#define CSR_ID_FREQ1 ID_CSR(0x18)
-#define CSR_ID_FREQ0 ID_CSR(0x1C)
-
-#endif /* __HW_ID_H */
--- /dev/null
+#ifndef __HW_IDENTIFIER_H
+#define __HW_IDENTIFIER_H
+
+#include <hw/common.h>
+#include <csrbase.h>
+
+#define IDENTIFIER_CSR(x) MMPTR(IDENTIFIER_BASE+(x))
+
+#define CSR_IDENTIFIER_SYSTEMH IDENTIFIER_CSR(0x00)
+#define CSR_IDENTIFIER_SYSTEML IDENTIFIER_CSR(0x04)
+#define CSR_IDENTIFIER_VERSIONH IDENTIFIER_CSR(0x08)
+#define CSR_IDENTIFIER_VERSIONL IDENTIFIER_CSR(0x0C)
+#define CSR_IDENTIFIER_FREQ3 IDENTIFIER_CSR(0x10)
+#define CSR_IDENTIFIER_FREQ2 IDENTIFIER_CSR(0x14)
+#define CSR_IDENTIFIER_FREQ1 IDENTIFIER_CSR(0x18)
+#define CSR_IDENTIFIER_FREQ0 IDENTIFIER_CSR(0x1C)
+
+#endif /* __HW_IDENTIFIER_H */
-#include <hw/id.h>
+#include <hw/identifier.h>
#include <hw/gpio.h>
#include <stdio.h>
#include <stdlib.h>
static const struct board_desc *get_board_desc(void)
{
- return get_board_desc_id((CSR_ID_SYSTEMH << 8) | CSR_ID_SYSTEML);
+ return get_board_desc_id((CSR_IDENTIFIER_SYSTEMH << 8) | CSR_IDENTIFIER_SYSTEML);
}
int get_pcb_revision(void)
{
unsigned int id;
- id = CSR_ID_VERSIONH;
+ id = CSR_IDENTIFIER_VERSIONH;
*major = (id & 0xf0) >> 4;
*minor = id & 0x0f;
- id = CSR_ID_VERSIONL;
+ id = CSR_IDENTIFIER_VERSIONL;
*subminor = (id & 0xf0) >> 4;
*rc = id & 0x0f;
}
#include <hw/timer.h>
-#include <hw/id.h>
+#include <hw/identifier.h>
#include "timer.h"
unsigned int get_system_frequency(void)
{
- return (CSR_ID_FREQ3 << 24)
- |(CSR_ID_FREQ2 << 16)
- |(CSR_ID_FREQ1 << 8)
- |CSR_ID_FREQ0;
+ return (CSR_IDENTIFIER_FREQ3 << 24)
+ |(CSR_IDENTIFIER_FREQ2 << 16)
+ |(CSR_IDENTIFIER_FREQ1 << 8)
+ |CSR_IDENTIFIER_FREQ0;
}
void timer_enable(int en)
from math import ceil
from migen.fhdl.structure import *
-from migen.fhdl import verilog, autofragment
+from migen.fhdl.module import Module
from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi
+from migen.bank import csrgen
from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, asmicon, \
identifier, timer, minimac3, framebuffer, asmiprobe
version = get_macros("common/version.h")["VERSION"][1:-1]
-class SoC:
+def csr_address_map(name, memory):
+ if memory is not None:
+ name += "_" + memory.name_override
+ return csr_offset(name.upper())
+
+class SoC(Module):
def __init__(self):
#
# ASMI
#
- self.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
+ self.submodules.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
asmiport_wb = self.asmicon.hub.get_port()
asmiport_fb = self.asmicon.hub.get_port(2)
self.asmicon.finalize()
#
# DFI
#
- self.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
- self.dfii = dfii.DFIInjector(csr_offset("DFII"),
- sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
- self.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
- self.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
+ self.submodules.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
+ self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d,
+ sdram_phy.nphases)
+ self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
+ self.submodules.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
#
# WISHBONE
#
- self.cpu = lm32.LM32()
- self.norflash = norflash.NorFlash(25, 12)
- self.sram = wishbone.SRAM(sram_size)
- self.minimac = minimac3.MiniMAC(csr_offset("MINIMAC"))
- self.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
- self.wishbone2csr = wishbone2csr.WB2CSR()
+ self.submodules.cpu = lm32.LM32()
+ self.submodules.norflash = norflash.NorFlash(25, 12)
+ self.submodules.sram = wishbone.SRAM(sram_size)
+ self.submodules.minimac = minimac3.MiniMAC()
+ self.submodules.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
+ self.submodules.wishbone2csr = wishbone2csr.WB2CSR()
# norflash 0x00000000 (shadow @0x80000000)
# SRAM/debug 0x10000000 (shadow @0x90000000)
# Ethernet 0x30000000 (shadow @0xb0000000)
# SDRAM 0x40000000 (shadow @0xc0000000)
# CSR bridge 0x60000000 (shadow @0xe0000000)
- self.wishbonecon = wishbone.InterconnectShared(
+ self.submodules.wishbonecon = wishbone.InterconnectShared(
[
self.cpu.ibus,
self.cpu.dbus
#
# CSR
#
- self.uart = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
- self.identifier = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
- self.timer = timer.Timer(csr_offset("TIMER0"))
- self.fb = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
- self.asmiprobe = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), self.asmicon.hub)
- self.csrcon = csr.Interconnect(self.wishbone2csr.csr, [
- self.uart.bank.bus,
- self.dfii.bank.bus,
- self.identifier.bank.bus,
- self.timer.bank.bus,
- self.minimac.bank.bus,
- self.fb.bank.bus,
- self.asmiprobe.bank.bus
- ])
+ self.submodules.uart = uart.UART(clk_freq, baud=115200)
+ self.submodules.identifier = identifier.Identifier(0x4D31, version, int(clk_freq))
+ self.submodules.timer0 = timer.Timer()
+ self.submodules.fb = framebuffer.Framebuffer(asmiport_fb)
+ self.submodules.asmiprobe = asmiprobe.ASMIprobe(self.asmicon.hub)
+
+ self.submodules.csrbankarray = csrgen.BankArray(self, csr_address_map)
+ self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
+
+ #
+ # Interrupts
+ #
+ self.comb += [
+ self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.ev.irq),
+ self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer0.ev.irq),
+ self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.ev.irq)
+ ]
#
# Clocking
#
- self.crg = m1crg.M1CRG(50*MHz, clk_freq)
-
- def get_fragment(self):
- comb = [
- #
- # Interrupts
- #
- self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.events.irq),
- self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer.events.irq),
- self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.events.irq),
- #
- # DDR PHY strobes
- #
+ self.submodules.crg = m1crg.M1CRG(50*MHz, clk_freq)
+ self.comb += [
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
]
- glue = Fragment(comb)
- return glue + autofragment.from_attributes(self)