+++ /dev/null
-from .top import *
+++ /dev/null
-from nmigen import Elaboratable, Module, Signal, Array, Record
-from nmigen.lib.coding import PriorityEncoder
-
-from ...csr import AutoCSR, CSR
-from ...isa import dcsr_layout, flat_layout
-from ...wishbone import wishbone_layout
-from .dmi import DebugReg, Command, Error, Version, cmd_access_reg_layout
-
-
-__all__ = ["DebugController"]
-
-
-class HaltCause:
- EBREAK = 1
- TRIGGER = 0
- HALTREQ = 3
- STEP = 4
- RESET_HALTREQ = 2
-
-
-cause_map = [2, 1, 5, 3, 4]
-
-
-class DebugController(Elaboratable, AutoCSR):
- def __init__(self, debugrf):
- self.dcsr = CSR(0x7b0, dcsr_layout, name="dcsr")
- self.dpc = CSR(0x7b1, flat_layout, name="dpc")
-
- self.dmstatus = debugrf.reg_port(DebugReg.DMSTATUS)
- self.dmcontrol = debugrf.reg_port(DebugReg.DMCONTROL)
- self.hartinfo = debugrf.reg_port(DebugReg.HARTINFO)
- self.abstractcs = debugrf.reg_port(DebugReg.ABSTRACTCS)
- self.command = debugrf.reg_port(DebugReg.COMMAND)
- self.data0 = debugrf.reg_port(DebugReg.DATA0)
-
- self.trigger_haltreq = Signal()
-
- self.x_pc = Signal(32)
- self.x_ebreak = Signal()
- self.x_stall = Signal()
-
- self.m_branch_taken = Signal()
- self.m_branch_target = Signal(32)
- self.m_mret = Signal()
- self.m_exception = Signal()
- self.m_pc = Signal(32)
- self.m_valid = Signal()
- self.mepc_r_base = Signal(30)
- self.mtvec_r_base = Signal(30)
-
- self.halt = Signal()
- self.halted = Signal()
- self.killall = Signal()
- self.resumereq = Signal()
- self.resumeack = Signal()
-
- self.gprf_addr = Signal(5)
- self.gprf_re = Signal()
- self.gprf_dat_r = Signal(32)
- self.gprf_we = Signal()
- self.gprf_dat_w = Signal(32)
-
- self.csrf_addr = Signal(12)
- self.csrf_re = Signal()
- self.csrf_dat_r = Signal(32)
- self.csrf_we = Signal()
- self.csrf_dat_w = Signal(32)
-
- def elaborate(self, platform):
- m = Module()
-
- for csr in self.dcsr, self.dpc:
- with m.If(csr.we):
- m.d.sync += csr.r.eq(csr.w)
-
- with m.If(self.dmcontrol.update):
- m.d.sync += [
- self.dmcontrol.w.dmactive.eq(self.dmcontrol.r.dmactive),
- self.dmcontrol.w.ndmreset.eq(self.dmcontrol.r.ndmreset),
- self.dmcontrol.w.hartselhi.eq(self.dmcontrol.r.hartselhi),
- self.dmcontrol.w.hartsello.eq(self.dmcontrol.r.hartsello),
- self.dmcontrol.w.hasel.eq(self.dmcontrol.r.hasel),
- self.dmcontrol.w.hartreset.eq(self.dmcontrol.r.hartreset),
- self.dmcontrol.w.resumereq.eq(self.dmcontrol.r.resumereq)
- ]
-
- with m.If(self.abstractcs.update):
- m.d.sync += self.abstractcs.w.cmderr.eq(self.abstractcs.r.cmderr)
-
- m.d.comb += [
- self.dmstatus.w.version.eq(Version.V013),
- self.dmstatus.w.authenticated.eq(1),
- self.resumereq.eq(self.dmcontrol.w.resumereq)
- ]
-
- m_breakpoint = Signal()
- with m.If(~self.x_stall):
- m.d.comb += m_breakpoint.eq(self.x_ebreak & self.dcsr.r.ebreakm)
-
- halt_pe = m.submodules.halt_pe = PriorityEncoder(5)
- m.d.comb += [
- halt_pe.i[HaltCause.EBREAK].eq(m_breakpoint & self.m_valid),
- halt_pe.i[HaltCause.TRIGGER].eq(self.trigger_haltreq),
- halt_pe.i[HaltCause.HALTREQ].eq(self.dmcontrol.r.haltreq),
- halt_pe.i[HaltCause.STEP].eq(self.dcsr.r.step & self.m_valid),
- ]
-
- with m.FSM():
- with m.State("RUN"):
- m.d.comb += self.dmstatus.w.allrunning.eq(1)
- with m.If(~halt_pe.n):
- m.d.sync += [
- self.halt.eq(1),
- self.dcsr.r.cause.eq(Array(cause_map)[halt_pe.o]),
- self.dcsr.r.stepie.eq(1)
- ]
- with m.If(halt_pe.o == HaltCause.EBREAK):
- m.d.sync += self.dpc.r.eq(self.m_pc)
- with m.Elif(self.m_exception & self.m_valid):
- m.d.sync += self.dpc.r.eq(self.mtvec_r_base << 30)
- with m.Elif(self.m_mret & self.m_valid):
- m.d.sync += self.dpc.r.eq(self.mepc_r_base << 30)
- with m.Elif(self.m_branch_taken & self.m_valid):
- m.d.sync += self.dpc.r.eq(self.m_branch_target)
- with m.Else():
- m.d.sync += self.dpc.r.eq(self.x_pc)
- m.next = "HALTING"
-
- with m.State("HALTING"):
- with m.If(self.halted):
- m.d.comb += self.killall.eq(1)
- m.d.sync += self.dmstatus.w.allhalted.eq(1)
- m.next = "WAIT"
-
- with m.State("WAIT"):
- with m.If(self.dmcontrol.w.resumereq):
- m.next = "RESUME"
- with m.Elif(self.command.update):
- m.d.sync += self.abstractcs.w.busy.eq(1)
- m.next = "COMMAND:START"
-
- with m.State("RESUME"):
- with m.If(self.resumeack):
- m.d.sync += [
- self.dmcontrol.w.resumereq.eq(0),
- self.dmstatus.w.allresumeack.eq(1),
- self.halt.eq(0),
- self.dmstatus.w.allhalted.eq(0)
- ]
- m.next = "RUN"
-
- with m.State("COMMAND:START"):
- with m.Switch(self.command.r.cmdtype):
- with m.Case(Command.ACCESS_REG):
- control = Record(cmd_access_reg_layout)
- m.d.comb += control.eq(self.command.r.control)
- m.d.comb += self.gprf_addr.eq(control.regno)
- m.next = "COMMAND:ACCESS-REG"
- with m.Case():
- m.d.sync += self.abstractcs.w.cmderr.eq(Error.UNSUPPORTED)
- m.next = "COMMAND:DONE"
-
- with m.State("COMMAND:ACCESS-REG"):
- control = Record(cmd_access_reg_layout)
- m.d.comb += control.eq(self.command.r.control)
- with m.If(control.postexec | (control.aarsize != 2) | control.aarpostincrement):
- # Unsupported parameters.
- m.d.sync += self.abstractcs.w.cmderr.eq(Error.EXCEPTION)
- with m.Elif((control.regno >= 0x0000) & (control.regno < 0x1000)):
- with m.If(control.transfer):
- m.d.comb += self.csrf_addr.eq(control.regno)
- with m.If(control.write):
- m.d.comb += [
- self.csrf_we.eq(1),
- self.csrf_dat_w.eq(self.data0.r)
- ]
- with m.Else():
- m.d.comb += self.csrf_re.eq(1)
- m.d.sync += self.data0.w.eq(self.csrf_dat_r)
- m.d.sync += self.abstractcs.w.cmderr.eq(Error.NONE)
- with m.Elif((control.regno >= 0x1000) & (control.regno < 0x1020)):
- with m.If(control.transfer):
- m.d.comb += self.gprf_addr.eq(control.regno)
- with m.If(control.write):
- m.d.comb += [
- self.gprf_we.eq(1),
- self.gprf_dat_w.eq(self.data0.r)
- ]
- with m.Else():
- m.d.sync += self.data0.w.eq(self.gprf_dat_r)
- m.d.sync += self.abstractcs.w.cmderr.eq(Error.NONE)
- with m.Else():
- # Unknown register number.
- m.d.sync += self.abstractcs.w.cmderr.eq(Error.EXCEPTION)
- m.next = "COMMAND:DONE"
-
- with m.State("COMMAND:DONE"):
- m.d.sync += self.abstractcs.w.busy.eq(0)
- m.next = "WAIT"
-
- return m
+++ /dev/null
-from enum import Enum
-
-
-__all__ = [
- "Version", "Command", "Error", "RegMode", "DmiOp", "DebugReg", "dmstatus_layout",
- "dmcontrol_layout", "abstractcs_layout", "cmd_access_reg_layout", "command_layout",
- "sbcs_layout", "flat_layout"
-]
-
-
-class Version:
- NONE = 0
- V011 = 1
- V013 = 2
- OTHER = 15
-
-
-class Command:
- ACCESS_REG = 0
- QUICK_ACCESS = 1
- ACCESS_MEM = 2
-
-
-class Error:
- NONE = 0
- BUSY = 1
- UNSUPPORTED = 2
- EXCEPTION = 3
- HALT_RESUME = 4
-
-
-RegMode = Enum("RegMode", ("R", "W", "W1", "RW", "RW1C", "WARL"))
-
-
-class DmiOp:
- NOP = 0
- READ = 1
- WRITE = 2
-
-
-# Debug registers
-
-class DebugReg:
- DATA0 = 0x04
- DMCONTROL = 0x10
- DMSTATUS = 0x11
- HARTINFO = 0x12
- ABSTRACTCS = 0x16
- COMMAND = 0x17
- PROGBUF0 = 0x20
- SBCS = 0x38
- SBADDRESS0 = 0x39
- SBDATA0 = 0x3c
-
-
-dmstatus_layout = [
- ("version", 4, RegMode.R, Version.V013),
- ("confstrptrvalid", 1, RegMode.R, False),
- ("hasresethaltreq", 1, RegMode.R, False),
- ("authbusy", 1, RegMode.R, False),
- ("authenticated", 1, RegMode.R, True),
- ("anyhalted", 1, RegMode.R, False),
- ("allhalted", 1, RegMode.R, False),
- ("anyrunning", 1, RegMode.R, False),
- ("allrunning", 1, RegMode.R, False),
- ("anyunavail", 1, RegMode.R, False),
- ("allunavail", 1, RegMode.R, False),
- ("anynonexistent", 1, RegMode.R, False),
- ("allnonexistent", 1, RegMode.R, False),
- ("anyresumeack", 1, RegMode.R, False),
- ("allresumeack", 1, RegMode.R, False),
- ("anyhavereset", 1, RegMode.R, False),
- ("allhavereset", 1, RegMode.R, False),
- ("zero0", 2, RegMode.R, 0),
- ("impebreak", 1, RegMode.R, False),
- ("zero1", 9, RegMode.R, 0)
-]
-
-
-dmcontrol_layout = [
- ("dmactive", 1, RegMode.RW, False),
- ("ndmreset", 1, RegMode.RW, False),
- ("clrresethaltreq", 1, RegMode.W1, False),
- ("setresethaltreq", 1, RegMode.W1, False),
- ("zero0", 2, RegMode.R, 0),
- ("hartselhi", 10, RegMode.RW, 0),
- ("hartsello", 10, RegMode.RW, 0),
- ("hasel", 1, RegMode.RW, False),
- ("zero1", 1, RegMode.R, 0),
- ("ackhavereset", 1, RegMode.W1, False),
- ("hartreset", 1, RegMode.RW, False),
- ("resumereq", 1, RegMode.W1, False),
- ("haltreq", 1, RegMode.W, False)
-]
-
-
-abstractcs_layout = [
- ("datacount", 4, RegMode.R, 1),
- ("zero0", 4, RegMode.R, 0),
- ("cmderr", 3, RegMode.RW1C, 0),
- ("zero1", 1, RegMode.R, 0),
- ("busy", 1, RegMode.R, False),
- ("zero2", 11, RegMode.R, 0),
- ("progbufsize", 5, RegMode.R, 0),
- ("zero3", 3, RegMode.R, 0)
-]
-
-
-cmd_access_reg_layout = [
- ("regno", 16),
- ("write", 1),
- ("transfer", 1),
- ("postexec", 1),
- ("aarpostincrement", 1),
- ("aarsize", 3),
- ("zero0", 1),
-]
-
-
-command_layout = [
- ("control", 24, RegMode.W, 0),
- ("cmdtype", 8, RegMode.W, Command.ACCESS_REG)
-]
-
-
-sbcs_layout = [
- ("sbaccess8", 1, RegMode.R, True),
- ("sbaccess16", 1, RegMode.R, True),
- ("sbaccess32", 1, RegMode.R, True),
- ("sbaccess64", 1, RegMode.R, False),
- ("sbaccess128", 1, RegMode.R, False),
- ("sbasize", 7, RegMode.R, 32),
- ("sberror", 3, RegMode.RW1C, 0),
- ("sbreadondata", 1, RegMode.RW, False),
- ("sbautoincrement", 1, RegMode.RW, False),
- ("sbaccess", 3, RegMode.RW, 2),
- ("sbreadonaddr", 1, RegMode.RW, False),
- ("sbbusy", 1, RegMode.R, False),
- ("sbbusyerror", 1, RegMode.RW1C, False),
- ("zero0", 6, RegMode.R, 0),
- ("sbversion", 3, RegMode.R, 1)
-]
-
-
-flat_layout = [
- ("value", 32, RegMode.RW, 0)
-]
+++ /dev/null
-from nmigen.hdl.rec import DIR_FANIN, DIR_FANOUT
-
-
-__all__ = ["jtag_layout", "JTAGReg", "dtmcs_layout", "dmi_layout"]
-
-
-jtag_layout = [
- ("tck", 1, DIR_FANIN),
- ("tdi", 1, DIR_FANIN),
- ("tdo", 1, DIR_FANOUT),
- ("tms", 1, DIR_FANIN),
- ("trst", 1, DIR_FANIN) # TODO
-]
-
-
-class JTAGReg:
- BYPASS = 0x00
- IDCODE = 0x01
- DTMCS = 0x10
- DMI = 0x11
-
-
-# JTAG register layouts
-
-dtmcs_layout = [
- ("version", 4),
- ("abits", 6),
- ("dmistat", 2),
- ("idle", 3),
- ("zero0", 1),
- ("dmireset", 1),
- ("dmihardreset", 1),
- ("zero1", 14)
-]
-
-
-dmi_layout = [
- ("op", 2),
- ("data", 32),
- ("addr", 6)
-]
+++ /dev/null
-from nmigen import Elaboratable, Module, Record, Const
-
-from .dmi import (DebugReg, DmiOp, RegMode,
- abstractcs_layout, cmd_access_reg_layout, command_layout,
- dmcontrol_layout, dmstatus_layout, flat_layout, sbcs_layout)
-
-
-__all__ = ["DebugRegisterFile"]
-
-
-class DmiOp:
- NOP = 0
- READ = 1
- WRITE = 2
-
-
-class DmiResult:
- OK = 0
- FAIL = 2
- BUSY = 3
-
-
-reg_map = {
- DebugReg.DMSTATUS: dmstatus_layout,
- DebugReg.DMCONTROL: dmcontrol_layout,
- DebugReg.HARTINFO: flat_layout,
- DebugReg.ABSTRACTCS: abstractcs_layout,
- DebugReg.COMMAND: command_layout,
- DebugReg.SBCS: sbcs_layout,
- DebugReg.SBADDRESS0: flat_layout,
- DebugReg.SBDATA0: flat_layout,
- DebugReg.DATA0: flat_layout
-}
-
-
-class DebugRegisterFile(Elaboratable):
- def __init__(self, dmi):
- self.dmi = dmi
- self.ports = dict()
-
- def reg_port(self, addr):
- if addr not in reg_map:
- raise ValueError("Unknown register {:x}.".format(addr))
- if addr in self.ports:
- raise ValueError("Register {:x} has already been allocated.".format(addr))
- layout = [f[:2] for f in reg_map[addr]]
- port = Record([("r", layout), ("w", layout), ("update", 1), ("capture", 1)])
- for name, shape, mode, reset in reg_map[addr]:
- getattr(port.r, name).reset = reset
- getattr(port.w, name).reset = reset
- self.ports[addr] = port
- return port
-
- def elaborate(self, platform):
- m = Module()
-
- def do_read(addr, port):
- rec = Record(port.w.layout)
- m.d.sync += self.dmi.r.data.eq(rec)
- for name, shape, mode, reset in reg_map[addr]:
- dst = getattr(rec, name)
- src = getattr(port.w, name)
- if mode in {RegMode.R, RegMode.RW, RegMode.RW1C}:
- m.d.comb += dst.eq(src)
- else:
- m.d.comb += dst.eq(Const(0))
- m.d.sync += port.capture.eq(1)
-
- def do_write(addr, port):
- rec = Record(port.r.layout)
- m.d.comb += rec.eq(self.dmi.w.data)
- for name, shape, mode, reset in reg_map[addr]:
- dst = getattr(port.r, name)
- src = getattr(rec, name)
- if mode in {RegMode.W, RegMode.RW}:
- m.d.sync += dst.eq(src)
- elif mode is RegMode.W1:
- m.d.sync += dst.eq(getattr(port.w, name) | src)
- elif mode is RegMode.RW1C:
- m.d.sync += dst.eq(getattr(port.w, name) & ~src)
-
- m.d.sync += port.update.eq(1)
-
- with m.If(self.dmi.update):
- with m.Switch(self.dmi.w.addr):
- for addr, port in self.ports.items():
- with m.Case(addr):
- with m.If(self.dmi.w.op == DmiOp.READ):
- do_read(addr, port)
- with m.Elif(self.dmi.w.op == DmiOp.WRITE):
- do_write(addr, port)
- m.d.sync += self.dmi.r.op.eq(DmiResult.OK)
- with m.Case():
- # Invalid register.
- m.d.sync += self.dmi.r.op.eq(DmiResult.FAIL)
-
- for port in self.ports.values():
- with m.If(port.update):
- m.d.sync += port.update.eq(0)
- with m.If(port.capture):
- m.d.sync += port.capture.eq(0)
-
- return m
+++ /dev/null
-from nmigen import Elaboratable, Module, Signal, Record
-
-
-from ...wishbone import wishbone_layout
-from .controller import DebugController
-from .jtag import JTAGReg, dtmcs_layout, dmi_layout, jtag_layout
-from .regfile import DebugRegisterFile
-from .wbmaster import wishbone_layout, DebugWishboneMaster
-
-# FIXME: figure out where JTAGTap is
-# from jtagtap import JTAGTap
-
-
-class JTAGTap:
- def __init__(self):
- raise NotImplementedError(
- "jtagtap package not found: figure out where JTAGTap is")
-
-
-__all__ = ["DebugUnit"]
-
-
-jtag_regs = {
- JTAGReg.IDCODE: [("value", 32)],
- JTAGReg.DTMCS: dtmcs_layout,
- JTAGReg.DMI: dmi_layout
-}
-
-
-class DebugUnit(Elaboratable):
- def __init__(self):
- self.jtag = Record(jtag_layout)
- self.dbus = Record(wishbone_layout)
-
- self.trigger_haltreq = Signal()
-
- self.x_ebreak = Signal()
- self.x_pc = Signal(32)
- self.x_stall = Signal()
-
- self.m_branch_taken = Signal()
- self.m_branch_target = Signal(32)
- self.m_mret = Signal()
- self.m_exception = Signal()
- self.m_pc = Signal(32)
- self.m_valid = Signal()
- self.mepc_r_base = Signal(30)
- self.mtvec_r_base = Signal(30)
-
- self.dcsr_step = Signal()
- self.dcsr_ebreakm = Signal()
- self.dpc_value = Signal(32)
-
- self.halt = Signal()
- self.halted = Signal()
- self.killall = Signal()
- self.resumereq = Signal()
- self.resumeack = Signal()
-
- self.dbus_busy = Signal()
-
- self.csrf_addr = Signal(12)
- self.csrf_re = Signal()
- self.csrf_dat_r = Signal(32)
- self.csrf_we = Signal()
- self.csrf_dat_w = Signal(32)
-
- self.gprf_addr = Signal(5)
- self.gprf_re = Signal()
- self.gprf_dat_r = Signal(32)
- self.gprf_we = Signal()
- self.gprf_dat_w = Signal(32)
-
- def elaborate(self, platform):
- m = Module()
-
- tap = m.submodules.tap = JTAGTap(jtag_regs)
- regfile = m.submodules.regfile = DebugRegisterFile(
- tap.regs[JTAGReg.DMI])
- controller = m.submodules.controller = DebugController(regfile)
- wbmaster = m.submodules.wbmaster = DebugWishboneMaster(regfile)
-
- m.d.comb += [
- tap.port.connect(self.jtag),
- # Usurpate a Spike core for now.
- tap.regs[JTAGReg.IDCODE].r.eq(0x10e31913),
- tap.regs[JTAGReg.DTMCS].r.eq(0x61) # (abits=6, version=1) TODO
- ]
-
- m.d.comb += [
- controller.trigger_haltreq.eq(self.trigger_haltreq),
-
- controller.x_ebreak.eq(self.x_ebreak),
- controller.x_pc.eq(self.x_pc),
- controller.x_stall.eq(self.x_stall),
-
- controller.m_branch_taken.eq(self.m_branch_taken),
- controller.m_branch_target.eq(self.m_branch_target),
- controller.m_pc.eq(self.m_pc),
- controller.m_valid.eq(self.m_valid),
-
- self.halt.eq(controller.halt),
- controller.halted.eq(self.halted),
- self.killall.eq(controller.killall),
- self.resumereq.eq(controller.resumereq),
- controller.resumeack.eq(self.resumeack),
-
- self.dcsr_step.eq(controller.dcsr.r.step),
- self.dcsr_ebreakm.eq(controller.dcsr.r.ebreakm),
- self.dpc_value.eq(controller.dpc.r.value),
-
- self.csrf_addr.eq(controller.csrf_addr),
- self.csrf_re.eq(controller.csrf_re),
- controller.csrf_dat_r.eq(self.csrf_dat_r),
- self.csrf_we.eq(controller.csrf_we),
- self.csrf_dat_w.eq(controller.csrf_dat_w),
-
- self.gprf_addr.eq(controller.gprf_addr),
- self.gprf_re.eq(controller.gprf_re),
- controller.gprf_dat_r.eq(self.gprf_dat_r),
- self.gprf_we.eq(controller.gprf_we),
- self.gprf_dat_w.eq(controller.gprf_dat_w),
- ]
-
- m.d.comb += [
- wbmaster.bus.connect(self.dbus),
- self.dbus_busy.eq(wbmaster.dbus_busy)
- ]
-
- return m
+++ /dev/null
-from functools import reduce
-from operator import or_
-
-from nmigen import Elaboratable, Module, Signal, Record
-
-from ...wishbone import wishbone_layout
-from .dmi import DebugReg
-
-
-__all__ = ["BusError", "AccessSize", "DebugWishboneMaster"]
-
-
-class BusError:
- NONE = 0
- TIMEOUT = 1
- BAD_ADDRESS = 2
- MISALIGNED = 3
- BAD_SIZE = 4
- OTHER = 7
-
-
-class AccessSize:
- BYTE = 0
- HALF = 1
- WORD = 2
-
-
-class DebugWishboneMaster(Elaboratable):
- def __init__(self, debugrf):
- self.bus = Record(wishbone_layout)
-
- self.dbus_busy = Signal()
-
- self.sbcs = debugrf.reg_port(DebugReg.SBCS)
- self.sbaddress0 = debugrf.reg_port(DebugReg.SBADDRESS0)
- self.sbdata0 = debugrf.reg_port(DebugReg.SBDATA0)
-
- def elaborate(self, platform):
- m = Module()
-
- addr = self.sbaddress0.w.value
- size = self.sbcs.r.sbaccess
-
- width = Signal(6)
- m.d.comb += width.eq((1<<size)*8)
-
- sbbusyerror = self.sbcs.w.sbbusyerror
- sberror = self.sbcs.w.sberror
- m.d.comb += self.dbus_busy.eq(self.sbcs.w.sbbusy)
-
- m.d.comb += [
- self.sbcs.w.sbaccess8.eq(1),
- self.sbcs.w.sbaccess16.eq(1),
- self.sbcs.w.sbaccess32.eq(1),
- self.sbcs.w.sbasize.eq(32),
- self.sbcs.w.sbversion.eq(1)
- ]
-
- with m.If(self.sbcs.update):
- m.d.sync += [
- self.sbcs.w.sbbusyerror.eq(self.sbcs.r.sbbusyerror),
- self.sbcs.w.sberror.eq(self.sbcs.r.sberror)
- ]
-
- we = Signal()
- re = Signal()
-
- with m.If(self.sbdata0.update):
- with m.If(self.sbcs.w.sbbusy):
- m.d.sync += self.sbcs.w.sbbusyerror.eq(1)
- with m.Else():
- m.d.sync += we.eq(~sberror.bool())
-
- with m.If(self.sbdata0.capture):
- with m.If(self.sbcs.w.sbbusy):
- m.d.sync += self.sbcs.w.sbbusyerror.eq(1)
- with m.Else():
- m.d.sync += re.eq(self.sbcs.r.sbreadondata & ~sberror.bool())
-
- with m.If(self.sbaddress0.update):
- with m.If(self.sbcs.w.sbbusy):
- m.d.sync += self.sbcs.w.sbbusyerror.eq(1)
- with m.Else():
- m.d.sync += [
- re.eq(self.sbcs.r.sbreadonaddr & ~sberror.bool()),
- self.sbaddress0.w.value.eq(self.sbaddress0.r.value)
- ]
-
- with m.FSM():
- with m.State("IDLE"):
- with m.If(we | re):
- m.d.sync += we.eq(0), re.eq(0)
- with m.If(size > AccessSize.WORD):
- m.d.sync += sberror.eq(BusError.BAD_SIZE)
- with m.Elif((addr & (1<<size)-1) != 0):
- m.d.sync += sberror.eq(BusError.MISALIGNED)
- with m.Else():
- m.d.sync += [
- self.bus.cyc.eq(1),
- self.bus.stb.eq(1),
- self.bus.adr.eq(addr[2:]),
- self.bus.we.eq(we),
- self.bus.sel.eq((1<<(1<<size))-1 << addr[:2]),
- self.bus.dat_w.eq((self.sbdata0.r & (1<<width)-1) << addr[:2]*8)
- ]
- m.next = "BUSY"
-
- with m.State("BUSY"):
- m.d.comb += self.sbcs.w.sbbusy.eq(1)
- with m.If(self.bus.ack | self.bus.err):
- m.d.sync += [
- self.bus.cyc.eq(0),
- self.bus.stb.eq(0),
- self.bus.we.eq(0),
- ]
- with m.If(self.bus.err):
- m.d.sync += sberror.eq(BusError.OTHER)
- with m.Else():
- with m.If(~self.bus.we):
- m.d.sync += self.sbdata0.w.eq((self.bus.dat_r >> addr[:2]*8) & (1<<width)-1)
- with m.If(self.sbcs.r.sbautoincrement):
- m.d.sync += addr.eq(addr + (1<<size))
- m.next = "IDLE"
-
- return m