From: Sebastien Bourdeauducq Date: Tue, 11 Jun 2013 12:18:16 +0000 (+0200) Subject: Switch to LASMI, bug pandemonium X-Git-Tag: 24jan2021_ls180~2906 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91d7b656a9be99e0e7d3812f915f41af74c76440;p=litex.git Switch to LASMI, bug pandemonium --- diff --git a/milkymist/asmicon/__init__.py b/milkymist/asmicon/__init__.py deleted file mode 100644 index 5ea25c11..00000000 --- a/milkymist/asmicon/__init__.py +++ /dev/null @@ -1,62 +0,0 @@ -from migen.fhdl.std import * -from migen.bus import dfi, asmibus - -from milkymist.asmicon.refresher import * -from milkymist.asmicon.bankmachine import * -from milkymist.asmicon.multiplexer import * - -class PhySettings: - def __init__(self, dfi_d, nphases, rdphase, wrphase): - self.dfi_d = dfi_d - self.nphases = nphases - self.rdphase = rdphase - self.wrphase = wrphase - -class GeomSettings: - def __init__(self, bank_a, row_a, col_a): - self.bank_a = bank_a - self.row_a = row_a - self.col_a = col_a - self.mux_a = max(row_a, col_a) - -class TimingSettings: - def __init__(self, tRP, tRCD, tWR, tREFI, tRFC, CL, rd_delay, read_time, write_time, slot_time=0): - self.tRP = tRP - self.tRCD = tRCD - self.tWR = tWR - self.tREFI = tREFI - self.tRFC = tRFC - - self.CL = CL - self.rd_delay = rd_delay - - self.read_time = read_time - self.write_time = write_time - self.slot_time = slot_time - -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.dfi = dfi.Interface(self.geom_settings.mux_a, - self.geom_settings.bank_a, - self.phy_settings.dfi_d, - self.phy_settings.nphases) - burst_length = self.phy_settings.nphases*2 - 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.submodules.hub = asmibus.Hub(aw, dw, self.timing_settings.slot_time) - - def do_finalize(self): - slots = self.hub.get_slots() - 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.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.submodules.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings, - self.bank_machines, self.refresher, - self.dfi, self.hub) diff --git a/milkymist/asmicon/bankmachine.py b/milkymist/asmicon/bankmachine.py deleted file mode 100644 index 361631de..00000000 --- a/milkymist/asmicon/bankmachine.py +++ /dev/null @@ -1,273 +0,0 @@ -from migen.fhdl.std import * -from migen.bus.asmibus import * -from migen.genlib.roundrobin import * -from migen.genlib.fsm import FSM -from migen.genlib.misc import optree - -from milkymist.asmicon.multiplexer import * - -# Row:Bank:Col address mapping -class _AddressSlicer: - def __init__(self, geom_settings, address_align): - self.geom_settings = geom_settings - self.address_align = address_align - - self._b1 = self.geom_settings.col_a - self.address_align - self._b2 = self._b1 + self.geom_settings.bank_a - - def row(self, address): - if isinstance(address, int): - return address >> self._b2 - else: - return address[self._b2:] - - def bank(self, address): - if isinstance(address, int): - return (address & (2**self._b2 - 1)) >> self._b1 - else: - return address[self._b1:self._b2] - - def col(self, address): - if isinstance(address, int): - return (address & (2**self._b1 - 1)) << self.address_align - else: - return Cat(Replicate(0, self.address_align), address[:self._b1]) - -class _Selector(Module): - def __init__(self, slicer, bankn, slots): - nslots = len(slots) - self.stb = Signal() - self.ack = Signal() - self.tag = Signal(max=nslots) - self.adr = Signal(slots[0].adr.nbits) - self.we = Signal() - - # derived classes should drive rr.request - self.submodules.rr = RoundRobin(nslots, SP_CE) - - ### - - # Multiplex - rr = self.rr - state = Signal(2) - 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( - (slicer.bank(self.adr) == bankn) \ - & (state == SLOT_PENDING)), - rr.ce.eq(self.ack | ~self.stb), - self.tag.eq(rr.grant) - ] - 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 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 complete_selector(self, slicer, bankn, slots): - rr = self.rr - - # List outstanding requests for our bank - outstandings = [] - for slot in slots: - outstanding = Signal() - self.comb += outstanding.eq( - (slicer.bank(slot.adr) == bankn) & \ - (slot.state == SLOT_PENDING)) - outstandings.append(outstanding) - - # Row tracking - 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) - ) - ] - self.sync += If(self.stb & self.ack, openrow_r.eq(openrow_n)) - hits = [] - for slot, os in zip(slots, outstandings): - hit = Signal() - 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() - self.comb += has_hit.eq(optree("|", hits)) - - best_hit = [rr.request[i].eq(hit) - for i, hit in enumerate(hits)] - best_fallback = [rr.request[i].eq(os) - for i, os in enumerate(outstandings)] - select_stmt = If(has_hit, - *best_hit - ).Else( - *best_fallback - ) - - if slots[0].time: - # Implement anti-starvation timer - matures = [] - for slot, os in zip(slots, outstandings): - mature = Signal() - comb.append(mature.eq(slot.mature & os)) - matures.append(mature) - has_mature = Signal() - 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) - self.comb += select_stmt - -class _Buffer(Module): - def __init__(self, source): - self.stb = Signal() - self.ack = Signal() - self.tag = Signal(source.tag.bv) - self.adr = Signal(source.adr.bv) - self.we = Signal() - - ### - - en = Signal() - self.comb += [ - en.eq(self.ack | ~self.stb), - source.ack.eq(en) - ] - self.sync += [ - If(en, - self.stb.eq(source.stb), - self.tag.eq(source.tag), - self.adr.eq(source.adr), - self.we.eq(source.we) - ) - ] - -class BankMachine(Module): - def __init__(self, geom_settings, timing_settings, address_align, bankn, slots, 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)) - - ### - - # Sub components - 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, bankn, slots) - cmdsource = selector - self.submodules += selector - - # Row tracking - has_openrow = Signal() - openrow = Signal(geom_settings.row_a) - hit = Signal() - self.comb += hit.eq(openrow == slicer.row(cmdsource.adr)) - track_open = Signal() - track_close = Signal() - self.sync += [ - If(track_open, - has_openrow.eq(1), - openrow.eq(slicer.row(cmdsource.adr)) - ), - If(track_close, - has_openrow.eq(0) - ) - ] - - # Address generation - s_row_adr = Signal() - self.comb += [ - self.cmd.ba.eq(bankn), - If(s_row_adr, - self.cmd.a.eq(slicer.row(cmdsource.adr)) - ).Else( - self.cmd.a.eq(slicer.col(cmdsource.adr)) - ) - ] - - self.comb += self.cmd.tag.eq(cmdsource.tag) - - # Respect write-to-precharge specification - precharge_ok = Signal() - t_unsafe_precharge = 2 + timing_settings.tWR - 1 - unsafe_precharge_count = Signal(max=t_unsafe_precharge+1) - 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, - unsafe_precharge_count.eq(unsafe_precharge_count-1) - ) - ] - - # Control and command generation FSM - fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[ - ("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) - ).Elif(cmdsource.stb, - If(has_openrow, - If(hit, - # NB: write-to-read specification is enforced by multiplexer - self.cmd.stb.eq(1), - cmdsource.ack.eq(self.cmd.ack), - self.cmd.is_read.eq(~cmdsource.we), - self.cmd.is_write.eq(cmdsource.we), - self.cmd.cas_n.eq(0), - self.cmd.we_n.eq(~cmdsource.we) - ).Else( - fsm.next_state(fsm.PRECHARGE) - ) - ).Else( - fsm.next_state(fsm.ACTIVATE) - ) - ) - ) - fsm.act(fsm.PRECHARGE, - # Notes: - # 1. we are presenting the column address, A10 is always low - # 2. since we always go to the ACTIVATE state, we do not need - # to assert track_close. - If(precharge_ok, - self.cmd.stb.eq(1), - If(self.cmd.ack, fsm.next_state(fsm.TRP)), - self.cmd.ras_n.eq(0), - self.cmd.we_n.eq(0) - ) - ) - fsm.act(fsm.ACTIVATE, - s_row_adr.eq(1), - track_open.eq(1), - self.cmd.stb.eq(1), - If(self.cmd.ack, fsm.next_state(fsm.TRCD)), - self.cmd.ras_n.eq(0) - ) - fsm.act(fsm.REFRESH, - self.refresh_gnt.eq(precharge_ok), - track_close.eq(1), - If(~self.refresh_req, fsm.next_state(fsm.REGULAR)) - ) diff --git a/milkymist/asmicon/multiplexer.py b/milkymist/asmicon/multiplexer.py deleted file mode 100644 index 9793c551..00000000 --- a/milkymist/asmicon/multiplexer.py +++ /dev/null @@ -1,225 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.roundrobin import * -from migen.genlib.misc import optree -from migen.genlib.fsm import FSM - -class CommandRequest: - def __init__(self, a, ba): - self.a = Signal(a) - self.ba = Signal(ba) - self.cas_n = Signal(reset=1) - self.ras_n = Signal(reset=1) - self.we_n = Signal(reset=1) - -class CommandRequestRW(CommandRequest): - def __init__(self, a, ba, tagbits): - CommandRequest.__init__(self, a, ba) - self.stb = Signal() - self.ack = Signal() - self.is_read = Signal() - self.is_write = Signal() - self.tag = Signal(tagbits) - -class _CommandChooser(Module): - def __init__(self, requests, tagbits): - self.want_reads = Signal() - self.want_writes = Signal() - # NB: cas_n/ras_n/we_n are 1 when stb is inactive - self.cmd = CommandRequestRW(flen(requests[0].a), flen(requests[0].ba), tagbits) - - ### - - rr = RoundRobin(len(requests), SP_CE) - self.submodules += rr - - 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() - 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 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 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.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(Module): - def __init__(self, commands, dfi): - ncmd = len(commands) - nph = len(dfi.phases) - self.sel = [Signal(max=ncmd) for i in range(nph)] - - ### - - def stb_and(cmd, attr): - if not hasattr(cmd, "stb"): - return 0 - else: - return cmd.stb & getattr(cmd, attr) - for phase, sel in zip(dfi.phases, self.sel): - self.comb += [ - phase.cke.eq(1), - phase.cs_n.eq(0) - ] - 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]) - ] - -class _Datapath(Module): - def __init__(self, timing_settings, command, dfi, hub): - tagbits = flen(hub.tag_call) - - rd_valid = Signal() - rd_tag = Signal(tagbits) - wr_valid = Signal() - wr_tag = Signal(tagbits) - self.comb += [ - hub.call.eq(rd_valid | wr_valid), - If(wr_valid, - hub.tag_call.eq(wr_tag) - ).Else( - hub.tag_call.eq(rd_tag) - ) - ] - - 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: - self.sync += [ - rd_valid_d[i].eq(rd_valid_d[i-1]), - rd_tag_d[i].eq(rd_tag_d[i-1]) - ] - else: - self.sync += [ - rd_valid_d[i].eq(command.stb & command.ack & command.is_read), - rd_tag_d[i].eq(command.tag) - ] - self.comb += [ - rd_valid.eq(rd_valid_d[-1]), - rd_tag.eq(rd_tag_d[-1]), - wr_valid.eq(command.stb & command.ack & command.is_write), - wr_tag.eq(command.tag), - ] - - 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) - ] - -class Multiplexer(Module): - def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, hub): - assert(phy_settings.nphases == len(dfi.phases)) - if phy_settings.nphases != 2: - raise NotImplementedError("TODO: multiplexer only supports 2 phases") - - # Command choosing - requests = [bm.cmd for bm in bank_machines] - tagbits = flen(hub.tag_call) - choose_cmd = _CommandChooser(requests, tagbits) - choose_req = _CommandChooser(requests, tagbits) - self.comb += [ - choose_cmd.want_reads.eq(0), - choose_cmd.want_writes.eq(0) - ] - self.submodules += choose_cmd, choose_req - - # Command steering - 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, dfi) - self.submodules += steerer - - # Read/write turnaround - read_available = Signal() - write_available = Signal() - 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])) - ] - - def anti_starvation(timeout): - en = Signal() - max_time = Signal() - if timeout: - t = timeout - 1 - time = Signal(max=t+1) - self.comb += max_time.eq(time == 0) - self.sync += If(~en, - time.eq(t) - ).Elif(~max_time, - time.eq(time - 1) - ) - else: - self.comb += max_time.eq(0) - return en, max_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 - self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines] - go_to_refresh = Signal() - self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines])) - - # Datapath - datapath = _Datapath(timing_settings, choose_req.cmd, dfi, hub) - self.submodules += datapath - - # Control FSM - fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[ - ("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-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)) - ), - If(go_to_refresh, fsm.next_state(fsm.REFRESH)) - ) - fsm.act(fsm.WRITE, - write_time_en.eq(1), - choose_req.want_writes.eq(1), - choose_cmd.cmd.ack.eq(1), - choose_req.cmd.ack.eq(1), - 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)) - ), - If(go_to_refresh, fsm.next_state(fsm.REFRESH)) - ) - fsm.act(fsm.REFRESH, - steerer.sel[0].eq(STEER_REFRESH), - If(~refresher.req, fsm.next_state(fsm.READ)) - ) - # FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog - self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH) diff --git a/milkymist/asmicon/refresher.py b/milkymist/asmicon/refresher.py deleted file mode 100644 index cda70433..00000000 --- a/milkymist/asmicon/refresher.py +++ /dev/null @@ -1,68 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.misc import timeline -from migen.genlib.fsm import FSM - -from milkymist.asmicon.multiplexer import * - -class Refresher(Module): - def __init__(self, a, ba, tRP, tREFI, tRFC): - self.req = Signal() - self.ack = Signal() # 1st command 1 cycle after assertion of ack - self.cmd = CommandRequest(a, ba) - - ### - - # Refresh sequence generator: - # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done - seq_start = Signal() - seq_done = Signal() - self.sync += [ - self.cmd.a.eq(2**10), - self.cmd.ba.eq(0), - self.cmd.cas_n.eq(1), - self.cmd.ras_n.eq(1), - self.cmd.we_n.eq(1), - seq_done.eq(0) - ] - self.sync += timeline(seq_start, [ - (1, [ - self.cmd.ras_n.eq(0), - self.cmd.we_n.eq(0) - ]), - (1+tRP, [ - self.cmd.cas_n.eq(0), - self.cmd.ras_n.eq(0) - ]), - (1+tRP+tRFC, [ - seq_done.eq(1) - ]) - ]) - - # Periodic refresh counter - counter = Signal(max=tREFI) - start = Signal() - self.sync += [ - start.eq(0), - If(counter == 0, - start.eq(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), - If(self.ack, - seq_start.eq(1), - fsm.next_state(fsm.WAIT_SEQ) - ) - ) - fsm.act(fsm.WAIT_SEQ, - self.req.eq(1), - If(seq_done, fsm.next_state(fsm.IDLE)) - ) diff --git a/milkymist/asmiprobe/__init__.py b/milkymist/asmiprobe/__init__.py deleted file mode 100644 index ca9f9851..00000000 --- a/milkymist/asmiprobe/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * - -class ASMIprobe(Module): - def __init__(self, hub, trace_depth=16): - slots = hub.get_slots() - slot_count = len(slots) - - self._slot_count = CSRStatus(bits_for(slot_count)) - self._trace_depth = CSRStatus(bits_for(trace_depth)) - self._slot_status = [CSRStatus(2, name="slot_status" + str(i)) for i in range(slot_count)] - self._trace = [CSRStatus(bits_for(slot_count-1), name="trace" + str(i)) for i in range(trace_depth)] - - ### - - self.comb += [ - self._slot_count.status.eq(slot_count), - self._trace_depth.status.eq(trace_depth) - ] - for slot, status in zip(slots, self._slot_status): - self.sync += status.status.eq(slot.state) - shift_tags = [self._trace[n].status.eq(self._trace[n+1].status) - for n in range(len(self._trace) - 1)] - shift_tags.append(self._trace[-1].status.eq(hub.tag_call)) - self.sync += If(hub.call, *shift_tags) - - def get_csrs(self): - return [self._slot_count, self._trace_depth] + self._slot_status + self._trace diff --git a/milkymist/dfii/__init__.py b/milkymist/dfii/__init__.py index 22a5bcd5..c6fc834e 100644 --- a/milkymist/dfii/__init__.py +++ b/milkymist/dfii/__init__.py @@ -13,6 +13,7 @@ class PhaseInjector(Module, AutoCSR): ### + wrdata_en_adv = Signal() self.comb += [ If(self._command_issue.re, phase.cs_n.eq(~self._command.storage[0]), @@ -27,12 +28,15 @@ class PhaseInjector(Module, AutoCSR): ), phase.address.eq(self._address.storage), phase.bank.eq(self._baddress.storage), - phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]), + wrdata_en_adv.eq(self._command_issue.re & self._command.storage[4]), phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]), phase.wrdata.eq(self._wrdata.storage), phase.wrdata_mask.eq(0) ] - self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata)) + self.sync += [ + phase.wrdata_en.eq(wrdata_en_adv), + If(phase.rddata_valid, self._rddata.status.eq(phase.rddata)) + ] class DFIInjector(Module, AutoCSR): def __init__(self, a, ba, d, nphases=1): diff --git a/milkymist/dvisampler/debug.py b/milkymist/dvisampler/debug.py index 21d937ed..52df4e6d 100644 --- a/milkymist/dvisampler/debug.py +++ b/milkymist/dvisampler/debug.py @@ -2,7 +2,7 @@ from migen.fhdl.std import * from migen.genlib.fifo import AsyncFIFO from migen.genlib.record import layout_len from migen.bank.description import AutoCSR -from migen.actorlib import structuring, dma_asmi, spi +from migen.actorlib import structuring, dma_lasmi, spi from milkymist.dvisampler.edid import EDID from milkymist.dvisampler.clocking import Clocking @@ -35,7 +35,7 @@ class RawDVISampler(Module, AutoCSR): pack_factor = asmiport.hub.dw//16 self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor) self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw) - self.submodules.dma = spi.DMAWriteController(dma_asmi.Writer(asmiport), spi.MODE_SINGLE_SHOT, free_flow=True) + self.submodules.dma = spi.DMAWriteController(dma_lasmi.Writer(lasmim), spi.MODE_SINGLE_SHOT) self.comb += [ self.packer.sink.stb.eq(fifo.readable), fifo.re.eq(self.packer.sink.ack), diff --git a/milkymist/dvisampler/dma.py b/milkymist/dvisampler/dma.py index 1a361b17..48442bfe 100644 --- a/milkymist/dvisampler/dma.py +++ b/milkymist/dvisampler/dma.py @@ -3,7 +3,7 @@ from migen.genlib.fsm import FSM from migen.bank.description import * from migen.bank.eventmanager import * from migen.flow.actor import * -from migen.actorlib import dma_asmi +from migen.actorlib import dma_lasmi from milkymist.dvisampler.common import frame_layout @@ -55,9 +55,9 @@ class _SlotArray(Module, AutoCSR): self.comb += [slot.address_done.eq(self.address_done & (current_slot == n)) for n, slot in enumerate(slots)] class DMA(Module): - def __init__(self, asmiport, nslots): - bus_aw = asmiport.hub.aw - bus_dw = asmiport.hub.dw + def __init__(self, lasmim, nslots): + bus_aw = lasmim.aw + bus_dw = lasmim.dw alignment_bits = bits_for(bus_dw//8) - 1 self.frame = Sink(frame_layout) @@ -112,7 +112,7 @@ class DMA(Module): ) # bus accessor - self.submodules._bus_accessor = dma_asmi.Writer(asmiport) + self.submodules._bus_accessor = dma_lasmi.Writer(lasmim) self.comb += [ self._bus_accessor.address_data.payload.a.eq(current_address), self._bus_accessor.address_data.payload.d.eq(cur_memory_word) diff --git a/milkymist/framebuffer/__init__.py b/milkymist/framebuffer/__init__.py index 58ebfbc9..dff5817a 100644 --- a/milkymist/framebuffer/__init__.py +++ b/milkymist/framebuffer/__init__.py @@ -2,18 +2,18 @@ from migen.fhdl.std import * from migen.flow.actor import * from migen.flow.network import * from migen.bank.description import CSRStorage, AutoCSR -from migen.actorlib import dma_asmi, structuring, sim, spi +from migen.actorlib import dma_lasmi, structuring, sim, spi from milkymist.framebuffer.lib import bpp, pixel_layout, dac_layout, FrameInitiator, VTG, FIFO class Framebuffer(Module): - def __init__(self, pads, asmiport, simulation=False): - pack_factor = asmiport.hub.dw//(2*bpp) + def __init__(self, pads, lasmim, simulation=False): + pack_factor = lasmim.dw//(2*bpp) packed_pixels = structuring.pack_layout(pixel_layout, pack_factor) fi = FrameInitiator() - dma = spi.DMAReadController(dma_asmi.Reader(asmiport), spi.MODE_EXTERNAL, length_reset=640*480*4) - cast = structuring.Cast(asmiport.hub.dw, packed_pixels, reverse_to=True) + dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4) + cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True) unpack = structuring.Unpack(pack_factor, pixel_layout) vtg = VTG() if simulation: @@ -93,19 +93,19 @@ class Blender(PipelinedActor, AutoCSR): self.comb += self.source.payload.eq(outval) class MixFramebuffer(Module, AutoCSR): - def __init__(self, pads, *asmiports, blender_latency=5): - pack_factor = asmiports[0].hub.dw//(2*bpp) + def __init__(self, pads, *lasmims, blender_latency=5): + pack_factor = lasmims[0].dw//(2*bpp) packed_pixels = structuring.pack_layout(pixel_layout, pack_factor) self._enable = CSRStorage() self.fi = FrameInitiator() - self.blender = Blender(len(asmiports), blender_latency) + self.blender = Blender(len(lasmims), blender_latency) self.comb += self.fi.trigger.eq(self._enable.storage) g = DataFlowGraph() - for n, asmiport in enumerate(asmiports): - dma = spi.DMAReadController(dma_asmi.Reader(asmiport), spi.MODE_EXTERNAL, length_reset=640*480*4) - cast = structuring.Cast(asmiport.hub.dw, packed_pixels, reverse_to=True) + for n, lasmim in enumerate(lasmims): + dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4) + cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True) unpack = structuring.Unpack(pack_factor, pixel_layout) g.add_connection(dma, cast) diff --git a/milkymist/lasmicon/__init__.py b/milkymist/lasmicon/__init__.py new file mode 100644 index 00000000..bdc4dc74 --- /dev/null +++ b/milkymist/lasmicon/__init__.py @@ -0,0 +1,64 @@ +from migen.fhdl.std import * +from migen.bus import dfi, lasmibus + +from milkymist.lasmicon.refresher import * +from milkymist.lasmicon.bankmachine import * +from milkymist.lasmicon.multiplexer import * + +class PhySettings: + def __init__(self, dfi_d, nphases, rdphase, wrphase): + self.dfi_d = dfi_d + self.nphases = nphases + self.rdphase = rdphase + self.wrphase = wrphase + +class GeomSettings: + def __init__(self, bank_a, row_a, col_a): + self.bank_a = bank_a + self.row_a = row_a + self.col_a = col_a + self.mux_a = max(row_a, col_a) + +class TimingSettings: + def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, CL, read_latency, write_latency, read_time, write_time): + self.tRP = tRP + self.tRCD = tRCD + self.tWR = tWR + self.tWTR = tWTR + self.tREFI = tREFI + self.tRFC = tRFC + + self.CL = CL + self.read_latency = read_latency + self.write_latency = write_latency + + self.read_time = read_time + self.write_time = write_time + +class LASMIcon(Module): + def __init__(self, phy_settings, geom_settings, timing_settings): + burst_length = phy_settings.nphases*2 # command multiplication*DDR + address_align = log2_int(burst_length) + + self.dfi = dfi.Interface(geom_settings.mux_a, + geom_settings.bank_a, + phy_settings.dfi_d, + phy_settings.nphases) + self.lasmic = lasmibus.Interface( + aw=geom_settings.row_a + geom_settings.col_a - address_align, + dw=phy_settings.dfi_d*phy_settings.nphases, + nbanks=2**geom_settings.bank_a, + read_latency=timing_settings.read_latency, + write_latency=timing_settings.write_latency) + self.nrowbits = geom_settings.col_a - address_align + + ### + + self.submodules.refresher = Refresher(geom_settings.mux_a, geom_settings.bank_a, + timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC) + self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, address_align, i, + getattr(self.lasmic, "bank"+str(i))) + for i in range(2**geom_settings.bank_a)] + self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings, + self.bank_machines, self.refresher, + self.dfi, self.lasmic) diff --git a/milkymist/lasmicon/bankmachine.py b/milkymist/lasmicon/bankmachine.py new file mode 100644 index 00000000..ce0a2b3b --- /dev/null +++ b/milkymist/lasmicon/bankmachine.py @@ -0,0 +1,129 @@ +from migen.fhdl.std import * +from migen.bus.asmibus import * +from migen.genlib.roundrobin import * +from migen.genlib.fsm import FSM +from migen.genlib.misc import optree + +from milkymist.lasmicon.multiplexer import * + +class _AddressSlicer: + def __init__(self, col_a, address_align): + self.col_a = col_a + self.address_align = address_align + + def row(self, address): + split = self.col_a - self.address_align + if isinstance(address, int): + return address >> split + else: + return address[split:] + + def col(self, address): + split = self.col_a - self.address_align + if isinstance(address, int): + return (address & (2**split - 1)) << self.address_align + else: + return Cat(Replicate(0, self.address_align), address[:split]) + +class BankMachine(Module): + def __init__(self, geom_settings, timing_settings, address_align, bankn, req): + self.refresh_req = Signal() + self.refresh_gnt = Signal() + self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a) + + ### + + slicer = _AddressSlicer(geom_settings.col_a, address_align) + + # Row tracking + has_openrow = Signal() + openrow = Signal(geom_settings.row_a) + hit = Signal() + self.comb += hit.eq(openrow == slicer.row(req.adr)) + track_open = Signal() + track_close = Signal() + self.sync += [ + If(track_open, + has_openrow.eq(1), + openrow.eq(slicer.row(req.adr)) + ), + If(track_close, + has_openrow.eq(0) + ) + ] + + # Address generation + s_row_adr = Signal() + self.comb += [ + self.cmd.ba.eq(bankn), + If(s_row_adr, + self.cmd.a.eq(slicer.row(req.adr)) + ).Else( + self.cmd.a.eq(slicer.col(req.adr)) + ) + ] + + # Respect write-to-precharge specification + precharge_ok = Signal() + t_unsafe_precharge = 2 + timing_settings.tWR - 1 + unsafe_precharge_count = Signal(max=t_unsafe_precharge+1) + 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, + unsafe_precharge_count.eq(unsafe_precharge_count-1) + ) + ] + + # Control and command generation FSM + fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[ + ("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) + ).Elif(req.stb, + If(has_openrow, + If(hit, + # NB: write-to-read specification is enforced by multiplexer + self.cmd.stb.eq(1), + req.ack.eq(self.cmd.ack), + self.cmd.is_read.eq(~req.we), + self.cmd.is_write.eq(req.we), + self.cmd.cas_n.eq(0), + self.cmd.we_n.eq(~req.we) + ).Else( + fsm.next_state(fsm.PRECHARGE) + ) + ).Else( + fsm.next_state(fsm.ACTIVATE) + ) + ) + ) + fsm.act(fsm.PRECHARGE, + # Notes: + # 1. we are presenting the column address, A10 is always low + # 2. since we always go to the ACTIVATE state, we do not need + # to assert track_close. + If(precharge_ok, + self.cmd.stb.eq(1), + If(self.cmd.ack, fsm.next_state(fsm.TRP)), + self.cmd.ras_n.eq(0), + self.cmd.we_n.eq(0) + ) + ) + fsm.act(fsm.ACTIVATE, + s_row_adr.eq(1), + track_open.eq(1), + self.cmd.stb.eq(1), + If(self.cmd.ack, fsm.next_state(fsm.TRCD)), + self.cmd.ras_n.eq(0) + ) + fsm.act(fsm.REFRESH, + self.refresh_gnt.eq(precharge_ok), + track_close.eq(1), + If(~self.refresh_req, fsm.next_state(fsm.REGULAR)) + ) diff --git a/milkymist/lasmicon/multiplexer.py b/milkymist/lasmicon/multiplexer.py new file mode 100644 index 00000000..d1260b40 --- /dev/null +++ b/milkymist/lasmicon/multiplexer.py @@ -0,0 +1,184 @@ +from migen.fhdl.std import * +from migen.genlib.roundrobin import * +from migen.genlib.misc import optree +from migen.genlib.fsm import FSM + +class CommandRequest: + def __init__(self, a, ba): + self.a = Signal(a) + self.ba = Signal(ba) + self.cas_n = Signal(reset=1) + self.ras_n = Signal(reset=1) + self.we_n = Signal(reset=1) + +class CommandRequestRW(CommandRequest): + def __init__(self, a, ba): + CommandRequest.__init__(self, a, ba) + self.stb = Signal() + self.ack = Signal() + self.is_read = Signal() + self.is_write = Signal() + +class _CommandChooser(Module): + def __init__(self, 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(flen(requests[0].a), flen(requests[0].ba)) + + ### + + rr = RoundRobin(len(requests), SP_CE) + self.submodules += rr + + 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() + self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant]) + for name in ["a", "ba", "is_read", "is_write"]: + 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 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.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(Module): + def __init__(self, commands, dfi): + ncmd = len(commands) + nph = len(dfi.phases) + self.sel = [Signal(max=ncmd) for i in range(nph)] + + ### + + def stb_and(cmd, attr): + if not hasattr(cmd, "stb"): + return 0 + else: + return cmd.stb & getattr(cmd, attr) + for phase, sel in zip(dfi.phases, self.sel): + wrdata_en_adv = Signal() + self.comb += [ + phase.cke.eq(1), + phase.cs_n.eq(0) + ] + 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]), + wrdata_en_adv.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel]), + phase.wrdata_en.eq(wrdata_en_adv) + ] + +class Multiplexer(Module): + def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic): + assert(phy_settings.nphases == len(dfi.phases)) + if phy_settings.nphases != 2: + raise NotImplementedError("TODO: multiplexer only supports 2 phases") + + # Command choosing + requests = [bm.cmd for bm in bank_machines] + choose_cmd = _CommandChooser(requests) + choose_req = _CommandChooser(requests) + self.comb += [ + choose_cmd.want_reads.eq(0), + choose_cmd.want_writes.eq(0) + ] + self.submodules += choose_cmd, choose_req + + # Command steering + 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, dfi) + self.submodules += steerer + + # Read/write turnaround + read_available = Signal() + write_available = Signal() + 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])) + ] + + def anti_starvation(timeout): + en = Signal() + max_time = Signal() + if timeout: + t = timeout - 1 + time = Signal(max=t+1) + self.comb += max_time.eq(time == 0) + self.sync += If(~en, + time.eq(t) + ).Elif(~max_time, + time.eq(time - 1) + ) + else: + self.comb += max_time.eq(0) + return en, max_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 + self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines] + go_to_refresh = Signal() + self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines])) + + # Datapath + 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 += [ + lasmic.dat_r.eq(Cat(*all_rddata)), + Cat(*all_wrdata).eq(lasmic.dat_w), + Cat(*all_wrdata_mask).eq(~lasmic.dat_we) + ] + + # Control FSM + fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[ + ("RTW", "WRITE", timing_settings.read_latency), + ("WTR", "READ", timing_settings.tWTR) + ]) + 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-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)) + ), + If(go_to_refresh, fsm.next_state(fsm.REFRESH)) + ) + fsm.act(fsm.WRITE, + write_time_en.eq(1), + choose_req.want_writes.eq(1), + choose_cmd.cmd.ack.eq(1), + choose_req.cmd.ack.eq(1), + 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)) + ), + If(go_to_refresh, fsm.next_state(fsm.REFRESH)) + ) + fsm.act(fsm.REFRESH, + steerer.sel[0].eq(STEER_REFRESH), + If(~refresher.req, fsm.next_state(fsm.READ)) + ) + # FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog + self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH) diff --git a/milkymist/lasmicon/refresher.py b/milkymist/lasmicon/refresher.py new file mode 100644 index 00000000..190a93b3 --- /dev/null +++ b/milkymist/lasmicon/refresher.py @@ -0,0 +1,68 @@ +from migen.fhdl.std import * +from migen.genlib.misc import timeline +from migen.genlib.fsm import FSM + +from milkymist.lasmicon.multiplexer import * + +class Refresher(Module): + def __init__(self, a, ba, tRP, tREFI, tRFC): + self.req = Signal() + self.ack = Signal() # 1st command 1 cycle after assertion of ack + self.cmd = CommandRequest(a, ba) + + ### + + # Refresh sequence generator: + # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done + seq_start = Signal() + seq_done = Signal() + self.sync += [ + self.cmd.a.eq(2**10), + self.cmd.ba.eq(0), + self.cmd.cas_n.eq(1), + self.cmd.ras_n.eq(1), + self.cmd.we_n.eq(1), + seq_done.eq(0) + ] + self.sync += timeline(seq_start, [ + (1, [ + self.cmd.ras_n.eq(0), + self.cmd.we_n.eq(0) + ]), + (1+tRP, [ + self.cmd.cas_n.eq(0), + self.cmd.ras_n.eq(0) + ]), + (1+tRP+tRFC, [ + seq_done.eq(1) + ]) + ]) + + # Periodic refresh counter + counter = Signal(max=tREFI) + start = Signal() + self.sync += [ + start.eq(0), + If(counter == 0, + start.eq(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), + If(self.ack, + seq_start.eq(1), + fsm.next_state(fsm.WAIT_SEQ) + ) + ) + fsm.act(fsm.WAIT_SEQ, + self.req.eq(1), + If(seq_done, fsm.next_state(fsm.IDLE)) + ) diff --git a/software/bios/main.c b/software/bios/main.c index 618217e7..c3e9a9a4 100644 --- a/software/bios/main.c +++ b/software/bios/main.c @@ -367,7 +367,6 @@ static void do_command(char *c) else if(strcmp(token, "ddrwr") == 0) ddrwr(get_token(&c)); else if(strcmp(token, "memtest") == 0) memtest(); else if(strcmp(token, "ddrinit") == 0) ddrinit(); - else if(strcmp(token, "asmiprobe") == 0) asmiprobe(); else if(strcmp(token, "dfs") == 0) dfs(get_token(&c)); diff --git a/software/bios/sdram.c b/software/bios/sdram.c index 40196941..5604cc92 100644 --- a/software/bios/sdram.c +++ b/software/bios/sdram.c @@ -127,9 +127,9 @@ void ddrrd(char *startaddr) cdelay(15); for(i=0;i<8;i++) - printf("%02x", MMPTR(0xe0000834+4*i)); + printf("%02x", MMPTR(0xe0001038+4*i)); for(i=0;i<8;i++) - printf("%02x", MMPTR(0xe0000884+4*i)); + printf("%02x", MMPTR(0xe000108c+4*i)); printf("\n"); } @@ -150,8 +150,8 @@ void ddrwr(char *startaddr) } for(i=0;i<8;i++) { - MMPTR(0xe0000814+4*i) = i; - MMPTR(0xe0000864+4*i) = 0xf0 + i; + MMPTR(0xe0001018+4*i) = i; + MMPTR(0xe000106c+4*i) = 0xf0 + i; } dfii_pi1_address_write(addr); @@ -209,32 +209,3 @@ int ddrinit(void) return 1; } - -static const char *format_slot_state(int state) -{ - switch(state) { - case 0: return "Empty"; - case 1: return "Pending"; - case 2: return "Processing"; - default: return "UNEXPECTED VALUE"; - } -} - -void asmiprobe(void) -{ - volatile unsigned int *regs = (unsigned int *)ASMIPROBE_BASE; - int slot_count; - int trace_depth; - int i; - int offset; - - offset = 0; - slot_count = regs[offset++]; - trace_depth = regs[offset++]; - for(i=0;i