Exemple #1
0
    def __init__(self, size=32, bus=None, debug_bus=None):
        self.irq = Signal()

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        if debug_bus is None:
            self.debug_bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.debug_bus = debug_bus

        # TODO ignore high bits instead of clipping actual value
        mem = Array(Signal(32, reset_less=True) for _ in range(size))

        # Main bus (read-only port)
        self.sync += [
            self.bus.ack.eq(0),
            self.bus.err.eq(0),
            self.bus.dat_r.eq(mem[(self.bus.adr >> 2)]),
            If(self.bus.stb & self.bus.cyc & ~self.bus.ack, self.bus.ack.eq(1))
        ]

        # Debug bus (read/write port)
        self.sync += [
            self.debug_bus.ack.eq(0),
            self.debug_bus.err.eq(0),
            self.debug_bus.dat_r.eq(mem[(self.debug_bus.adr >> 2)]),
            If(
                self.debug_bus.stb & self.debug_bus.cyc & ~self.debug_bus.ack,
                self.debug_bus.ack.eq(1),
                If(
                    self.debug_bus.we & self.debug_bus.sel[0],
                    mem[(self.debug_bus.adr >> 2)][0:8].eq(
                        self.debug_bus.dat_w[0:8])),
                If(
                    self.debug_bus.we & self.debug_bus.sel[1],
                    mem[(self.debug_bus.adr >> 2)][8:16].eq(
                        self.debug_bus.dat_w[8:16])),
                If(
                    self.debug_bus.we & self.debug_bus.sel[2],
                    mem[(self.debug_bus.adr >> 2)][16:24].eq(
                        self.debug_bus.dat_w[16:24])),
                If(
                    self.debug_bus.we & self.debug_bus.sel[3],
                    mem[(self.debug_bus.adr >> 2)][24:32].eq(
                        self.debug_bus.dat_w[24:32])),
            )
        ]
Exemple #2
0
    def __init__(self, data, bus=None, nullterm=True, endianness="little"):
        if bus is None:
            bus = wb.Interface(data_width=32, adr_width=32)

        self.bus = bus

        num_bytes = bus.data_width // 8
        data = list(data)

        for i in range(len(data)):
            if isinstance(data[i], str):
                data[i] = ord(data[i])

            data[i] = int(data[i])

        if nullterm:
            data = data + [0]

        # Add padding
        data = data + [0] * ((num_bytes - (len(data) % num_bytes)) % num_bytes)
        assert len(data) % num_bytes == 0

        # Group into words
        data = [data[i:i + num_bytes] for i in range(0, len(data), num_bytes)]
        assert all([len(x) == num_bytes for x in data])

        # Pack words
        data = [pack_list(x, endianness=endianness) for x in data]

        self.sync += [
            self.bus.ack.eq(self.bus.cyc & self.bus.stb & ~self.bus.ack),
            self.bus.dat_r.eq(Array(data)[self.bus.adr >> 2])
        ]
Exemple #3
0
    def __init__(self, pads, fifo_depth=4, bus=None):
        self.uart_tx = pads.tx
        self.uart_rx = pads.rx

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        addr_spacing = self.bus.dat_r.nbits // 8

        self.specials += Instance("wbuart",
                                  o_o_tx=self.uart_tx,
                                  i_i_rx=self.uart_rx,
                                  i_i_wb_cyc=self.bus.cyc,
                                  i_i_wb_stb=self.bus.stb,
                                  i_i_wb_we=self.bus.we & self.bus.sel[0],
                                  i_i_wb_addr=self.bus.adr,
                                  i_i_wb_data=self.bus.dat_w,
                                  o_o_wb_ack=self.bus.ack,
                                  o_o_wb_err=self.bus.err,
                                  o_o_wb_data=self.bus.dat_r,
                                  i_i_clk=ClockSignal(),
                                  i_i_rst=ResetSignal(),
                                  p_FIFO_DEPTH=fifo_depth,
                                  p_ADDR_STATUS=0 * addr_spacing,
                                  p_ADDR_CONFIG=1 * addr_spacing,
                                  p_ADDR_WRITE=2 * addr_spacing,
                                  p_ADDR_READ=3 * addr_spacing)
Exemple #4
0
    def __init__(self, bus=None, reset_less=False):

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        if reset_less:
            ctr = Signal(bits_sign=64, reset_less=True)
        else:
            ctr = Signal(bits_sign=64, reset=0)

        # Reads are not guaranteed to be atomic
        # Read-procedure:
        #   - Read high word
        #   - Read low word
        #   - Re-read high word
        #   - If high word has changed, re-read low word
        # Because the low word will only roll over after 4B clock cycles,
        # it is safe to read in this manner (with the last condition catching any rollovers)
        self.sync += [
            self.bus.ack.eq(0),
            self.bus.err.eq(0),
            self.bus.dat_r.eq(0),
            If(self.bus.stb & self.bus.cyc & ~self.bus.ack, self.bus.ack.eq(1),
               If((self.bus.adr >> 2) == 0, self.bus.dat_r.eq(ctr[0:32])),
               If((self.bus.adr >> 2) == 1, self.bus.dat_r.eq(ctr[32:64])))
        ]

        self.sync += ctr.eq(ctr + 1)
Exemple #5
0
    def __init__(self):
        self.instr_bus = wb.Interface(data_width=32, adr_width=32)
        self.data_bus = wb.Interface(data_width=32, adr_width=32)

        self.stall_in = Signal()
        self.stall_out = Signal()
        self.init_pc = Signal(32)

        self.pc_out = Signal(32)

        self.cpu_reset = Signal(reset=0)

        self.specials += Instance("cpu",
                                  o_instr_wb_cyc=self.instr_bus.cyc,
                                  o_instr_wb_stb=self.instr_bus.stb,
                                  o_instr_wb_we=self.instr_bus.we,
                                  o_instr_wb_sel=self.instr_bus.sel,
                                  o_instr_wb_addr=self.instr_bus.adr,
                                  o_instr_wb_data_wr=self.instr_bus.dat_w,
                                  i_instr_wb_ack=self.instr_bus.ack,
                                  i_instr_wb_err=self.instr_bus.err,
                                  i_instr_wb_data_rd=self.instr_bus.dat_r,
                                  o_data_wb_cyc=self.data_bus.cyc,
                                  o_data_wb_stb=self.data_bus.stb,
                                  o_data_wb_we=self.data_bus.we,
                                  o_data_wb_sel=self.data_bus.sel,
                                  o_data_wb_addr=self.data_bus.adr,
                                  o_data_wb_data_wr=self.data_bus.dat_w,
                                  i_data_wb_ack=self.data_bus.ack,
                                  i_data_wb_err=self.data_bus.err,
                                  i_data_wb_data_rd=self.data_bus.dat_r,
                                  i_i_stall_in=self.stall_in,
                                  i_i_init_pc=self.init_pc,
                                  o_o_stall_out=self.stall_out,
                                  o_o_pc_out=self.pc_out,
                                  i_i_clk=ClockSignal(),
                                  i_i_rst=ResetSignal() | self.cpu_reset,
                                  p_USE_BARREL_SHIFTER=True,
                                  p_WISHBONE_PIPELINED=0)
Exemple #6
0
    def __init__(self, controllers, peripherals, register=False):
        check_fns, periph_busses = zip(*peripherals)

        # TODO allow selectively blocking specific points in crossbar
        cross_points = [[
            wb.Interface(data_width=32, adr_width=32) for j in peripherals
        ] for i in controllers]

        for row, controller in zip(cross_points, controllers):
            self.submodules += wb.Decoder(controller,
                                          list(zip(check_fns, row)),
                                          register=register)
        for col, bus in zip(zip(*cross_points), periph_busses):
            self.submodules += wb.Arbiter(col, bus)
Exemple #7
0
    def __init__(self, pads, fifo_depth=4, bus=None):

        # Check if power of 2
        fifo_addr_width = int(math.log2(fifo_depth))
        if 2**(fifo_addr_width) != fifo_depth:
            raise ValueError("Invalid FIFO depth, must be a power of 2")

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        addr_spacing = self.bus.dat_r.nbits // 8
        print(addr_spacing)

        DEFAULT_PRESCALE = 32  # 400kHz @ 50Mhz

        last_stb = Signal()
        last_ack = Signal()
        self.sync += [last_stb.eq(self.bus.stb), last_ack.eq(self.bus.ack)]

        self.specials += Instance(
            "i2c_master_wbs_16",
            i_i2c_scl_i=pads.scl_i,
            o_i2c_scl_o=pads.scl_o,
            o_i2c_scl_t=pads.scl_oen,
            i_i2c_sda_i=pads.sda_i,
            o_i2c_sda_o=pads.sda_o,
            o_i2c_sda_t=pads.sda_oen,
            i_wbs_adr_i=self.bus.adr >> 1,
            i_wbs_dat_i=self.bus.dat_w,
            o_wbs_dat_o=self.bus.dat_r,
            i_wbs_we_i=self.bus.we & (self.bus.sel[1] | self.bus.sel[0]),
            i_wbs_sel_i=self.bus.sel,

            # Classic -> Pipelined
            i_wbs_stb_i=self.bus.stb & (~last_stb | last_ack),
            o_wbs_ack_o=self.bus.ack,
            i_wbs_cyc_i=self.bus.cyc,
            i_clk=ClockSignal(),
            i_rst=ResetSignal(),
            p_DEFAULT_PRESCALE=32,  # 400kHz @ 50Mhz
            p_FIXED_PRESCALE=0,
            p_CMD_FIFO=1,
            p_CMD_FIFO_ADDR_WIDTH=fifo_addr_width,
            p_WRITE_FIFO=1,
            p_WRITE_FIFO_ADDR_WIDTH=fifo_addr_width,
            p_READ_FIFO=1,
            p_READ_FIFO_ADDR_WIDTH=fifo_addr_width)
Exemple #8
0
    def __init__(self,
                 uart,
                 clk_freq,
                 baud=115200,
                 drop_clks=None,
                 fifo_depth=16):
        if drop_clks is None:
            # Default to 1s timeout
            drop_clks = clk_freq // 1

        self.uart_tx = uart.tx
        self.uart_rx = uart.rx

        self.bus = wb.Interface(data_width=32, adr_width=32)

        self.ctr = Signal(16)

        last_stb = Signal()
        self.sync += [
            last_stb.eq(self.bus.stb),
            If(self.bus.cyc & self.bus.stb,
               If(~last_stb, self.ctr.eq(0)).Else(self.ctr.eq(self.ctr + 1)))
        ]

        self.sync += [
            self.bus.sel.eq(Constant(0b1111)),
        ]

        self.specials += Instance("wbdbgbus",
                                  o_o_tx=self.uart_tx,
                                  i_i_rx=self.uart_rx,
                                  o_o_wb_cyc=self.bus.cyc,
                                  o_o_wb_stb=self.bus.stb,
                                  o_o_wb_we=self.bus.we,
                                  o_o_wb_addr=self.bus.adr,
                                  o_o_wb_data=self.bus.dat_w,
                                  i_i_wb_ack=self.bus.ack,
                                  i_i_wb_err=self.bus.err,
                                  i_i_wb_stall=0,
                                  i_i_wb_data=self.bus.dat_r,
                                  i_i_interrupt_1=0,
                                  i_i_interrupt_2=0,
                                  i_i_interrupt_3=0,
                                  i_i_interrupt_4=0,
                                  i_i_clk=ClockSignal(),
                                  p_CLK_FREQ=clk_freq,
                                  p_UART_BAUD=baud,
                                  p_DROP_CLKS=drop_clks,
                                  p_FIFO_DEPTH=fifo_depth)
Exemple #9
0
    def __init__(self, pads, bus=None):

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        self.comb += [
            self.bus.cyc.eq(pads.cyc),
            self.bus.stb.eq(pads.stb),
            self.bus.adr.eq(pads.addr),
            self.bus.dat_w.eq(pads.data_wr),
            pads.data_rd.eq(self.bus.dat_r),
            self.bus.sel.eq(pads.sel),
            self.bus.we.eq(pads.we),
            pads.ack.eq(self.bus.ack),
            pads.err.eq(self.bus.err),
        ]
Exemple #10
0
    def __init__(self,
                 platform,
                 debug_controller=None,
                 wishbone_delay_register=True):

        self.submodules.crg = SimpleCRG(platform.request("sys_clk"),
                                        platform.request("sys_rst"))

        self.controllers = {}
        self.mem_bus = {}
        self.periph_bus = {}

        if debug_controller is None:
            debug_controller = wb.Interface(data_width=32, adr_width=32)
        self.debug_controller = debug_controller
        self.debug_bus = {}

        self.wishbone_delay_register = wishbone_delay_register
Exemple #11
0
    def __init__(self, pads, bus=None):

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        self.enable = Signal(reset=1)

        self.comb += [
            pads.cyc.eq(self.enable & self.bus.cyc),
            pads.stb.eq(self.enable & self.bus.stb),
            pads.addr.eq(self.bus.adr),
            pads.data_wr.eq(self.bus.dat_w),
            self.bus.dat_r.eq(pads.data_rd),
            pads.sel.eq(self.bus.sel),
            pads.we.eq(self.bus.we),
            self.bus.ack.eq(self.enable & pads.ack),
            self.bus.err.eq(self.enable & pads.err)
        ]
Exemple #12
0
    def __init__(self, bus=None, debug_bus=None, enable_code=0xABAB12):
        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        if debug_bus is None:
            self.debug_bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.debug_bus = debug_bus

        wb_rd_req = self.bus.cyc & self.bus.stb & ~self.bus.ack & ~self.bus.we
        wb_wr_req = self.bus.cyc & self.bus.stb & ~self.bus.ack & self.bus.we

        wb_rd_data = Signal(32)

        self.comb += self.bus.dat_r.eq(wb_rd_data)

        enable_entry = Signal(32, reset=0)
        enabled = enable_entry == Constant(enable_code)

        # 00 = Cfg/Status {22'b0, err, ack, sel[3:0], 2'b0, rd_req, wr_req}
        # 04 = Addr
        # 08 = Write Data
        # 0C = Read Data
        # 10 = Enable

        self.sync += [
            self.bus.ack.eq(0),
            self.bus.err.eq(0),

            self.debug_bus.ack.eq(0),
            self.debug_bus.err.eq(0),
            self.debug_bus.dat_r.eq(0),

            If(self.debug_bus.stb & self.debug_bus.cyc & ~self.debug_bus.ack,
               self.debug_bus.ack.eq(1),

               If((self.debug_bus.adr >> 2) == 0,
                  If(enabled & self.debug_bus.we & self.debug_bus.sel[1],
                     If(self.debug_bus.dat_w[8], self.bus.ack.eq(1)).
                     Elif(self.debug_bus.dat_w[9], self.bus.err.eq(1))),

                  self.debug_bus.dat_r.eq(Cat(wb_wr_req, wb_rd_req, Constant(0, bits_sign=2), self.bus.sel))),

               If((self.debug_bus.adr >> 2) == 1,
                  self.debug_bus.dat_r.eq(self.bus.adr)),

               If((self.debug_bus.adr >> 2) == 2,
                  self.debug_bus.dat_r.eq(self.bus.dat_w)),

               If((self.debug_bus.adr >> 2) == 3,
                  If(self.debug_bus.we & self.debug_bus.sel[0], wb_rd_data[0:8].eq(self.debug_bus.dat_w[0:8])),
                  If(self.debug_bus.we & self.debug_bus.sel[1], wb_rd_data[8:16].eq(self.debug_bus.dat_w[8:16])),
                  If(self.debug_bus.we & self.debug_bus.sel[2], wb_rd_data[16:24].eq(self.debug_bus.dat_w[16:24])),
                  If(self.debug_bus.we & self.debug_bus.sel[3], wb_rd_data[24:32].eq(self.debug_bus.dat_w[24:32])),
                  self.debug_bus.dat_r.eq(wb_rd_data)),

               If((self.debug_bus.adr >> 2) == 4,
                  If(self.debug_bus.we & self.debug_bus.sel[0], enable_entry[0:8].eq(self.debug_bus.dat_w[0:8])),
                  If(self.debug_bus.we & self.debug_bus.sel[1], enable_entry[8:16].eq(self.debug_bus.dat_w[8:16])),
                  If(self.debug_bus.we & self.debug_bus.sel[2], enable_entry[16:24].eq(self.debug_bus.dat_w[16:24])),
                  If(self.debug_bus.we & self.debug_bus.sel[3], enable_entry[24:32].eq(self.debug_bus.dat_w[24:32])),
                  self.debug_bus.dat_r.eq(enable_entry)),
              )
        ]
Exemple #13
0
    def __init__(self, bus=None):
        self.irq = Signal()

        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        ctr = Signal(bits_sign=32, reset=0)

        # When enabled, runs for `load` cycles, then repeatedly reloads to `reload` cycles
        # (Unless reload is zero)
        running = Signal(reset=0)
        triggered = Signal(reset=0)
        reload = Signal(bits_sign=32)
        load = Signal(bits_sign=32)

        # Address space:
        # 00 = ctr
        # 04 = reload
        # 08 = load
        # 0C = enable
        # 10 = triggered
        self.sync += [
            self.irq.eq(0),
            If(
                running, ctr.eq(ctr - 1),
                If((ctr == 1) | (ctr == 0), triggered.eq(1), self.irq.eq(1),
                   If(reload != 0, ctr.eq(reload)).Else(ctr.eq(0)))).Else(
                       ctr.eq(0), triggered.eq(0)),
            self.bus.ack.eq(0),
            self.bus.err.eq(0),
            self.bus.dat_r.eq(0),
            If(
                self.bus.stb & self.bus.cyc & ~self.bus.ack,
                self.bus.ack.eq(1),
                If((self.bus.adr >> 2) == 0, self.bus.dat_r.eq(ctr)),
                If((self.bus.adr >> 2) == 1,
                   If(self.bus.we & self.bus.sel[0],
                      reload[0:8].eq(self.bus.dat_w[0:8])),
                   If(self.bus.we & self.bus.sel[1],
                      reload[8:16].eq(self.bus.dat_w[8:16])),
                   If(self.bus.we & self.bus.sel[2],
                      reload[16:24].eq(self.bus.dat_w[16:24])),
                   If(self.bus.we & self.bus.sel[3],
                      reload[24:32].eq(self.bus.dat_w[24:32])),
                   self.bus.dat_r.eq(reload)),
                If((self.bus.adr >> 2) == 2,
                   If(self.bus.we & self.bus.sel[0],
                      load[0:8].eq(self.bus.dat_w[0:8])),
                   If(self.bus.we & self.bus.sel[1],
                      load[8:16].eq(self.bus.dat_w[8:16])),
                   If(self.bus.we & self.bus.sel[2],
                      load[16:24].eq(self.bus.dat_w[16:24])),
                   If(self.bus.we & self.bus.sel[3],
                      load[24:32].eq(self.bus.dat_w[24:32])),
                   self.bus.dat_r.eq(load)),
                If((self.bus.adr >> 2) == 3,
                   If(self.bus.we & self.bus.sel[0],
                      running.eq(self.bus.dat_w[0]),
                      If(self.bus.dat_w[0], ctr.eq(load))),
                   self.bus.dat_r.eq(running)),
                If((self.bus.adr >> 2) == 4,
                   If(self.bus.we & self.bus.sel[0] & self.bus.dat_w[0] == 0,
                      triggered.eq(0)), self.bus.dat_r.eq(triggered)),
            )
        ]
Exemple #14
0
    def generate_bus(self):
        if len(self.mem_bus) + len(self.periph_bus) < 1:
            raise ValueError(
                "Must have at least one peripheral or memory in order to generate bus"
            )

        if len(self.debug_bus) < 1:
            raise ValueError(
                "Must have at least one debug peripheral in order to generate bus"
            )

        if len(self.controllers) < 1:
            raise ValueError(
                "Must have at least one controller in order to generate bus")

        cpu_address_map = [
        ]  # (addr, name) or (addr, name, [(addr, name), ...]) - all addresses are absolute
        debug_address_map = []

        if len(self.periph_bus) != 0:
            periph_addr_base, periph_addr_top = self.wb_address("periphs")[0:2]
            periph_address_map = []
            peripherals = []

            for name, periph in self.periph_bus.items():
                controller_bus = wb.Interface(data_width=32, adr_width=32)
                periph_bus = periph[1]

                base_addr, top_addr, size, translate_fn, c_type, c_type_top = self.wb_address(
                    name)

                assert base_addr >= periph_addr_base and base_addr <= periph_addr_top
                assert top_addr >= periph_addr_base and top_addr <= periph_addr_top

                if translate_fn is None:
                    translate_fn = create_translate_fn(base_addr - 0, size)

                check_fn = create_check_fn(base_addr - 0, top_addr - 0)

                translator = WishboneAddressTranslator(controller_bus,
                                                       periph_bus,
                                                       translate_fn)
                setattr(self.submodules, name + "__translator", translator)

                peripherals.append((check_fn, controller_bus))
                periph_address_map.append((base_addr, name))

            cpu_address_map.append(
                (periph_addr_base, "Peripherals", periph_address_map))

            shared = wb.Interface(data_width=32, adr_width=32)
            periph_bridge = wb.Decoder(shared, peripherals, register=True)
            self.add_mem(periph_bridge, "periphs", bus=shared)

        assert len(self.mem_bus) >= 1

        controllers = [x[1] for x in self.controllers.values()]
        mems = []

        for name, periph in self.mem_bus.items():
            controller_bus = wb.Interface(data_width=32, adr_width=32)
            periph_bus = periph[1]
            base_addr, top_addr, size, translate_fn, c_type, c_type_top = self.wb_address(
                name)

            if translate_fn is None:
                if name == "periphs":
                    translate_fn = lambda x: x
                else:
                    translate_fn = create_translate_fn(base_addr, size)

            check_fn = create_check_fn(base_addr, top_addr)

            translator = WishboneAddressTranslator(controller_bus, periph_bus,
                                                   translate_fn)
            setattr(self.submodules, name + "__translator", translator)

            if name not in ["periphs"]:
                cpu_address_map.append((base_addr, name))

            mems.append((check_fn, controller_bus))

        self.submodules.crossbar = WishboneCrossbar(
            controllers, mems, register=self.wishbone_delay_register)

        debug_address_map = []
        debug_peripherals = []

        for name, periph in self.debug_bus.items():
            controller_bus = wb.Interface(data_width=32, adr_width=32)
            periph_bus = periph[1]

            base_addr, top_addr, size, translate_fn = self.debug_address(name)

            if translate_fn is None:
                translate_fn = create_translate_fn(base_addr, size)

            check_fn = create_check_fn(base_addr, top_addr)

            translator = WishboneAddressTranslator(controller_bus, periph_bus,
                                                   translate_fn)
            setattr(self.submodules, name + "__translator", translator)

            debug_peripherals.append((check_fn, controller_bus))
            debug_address_map.append((base_addr, name))

        self.submodules.debug_interconnect = wb.Decoder(self.debug_controller,
                                                        debug_peripherals,
                                                        register=True)

        return cpu_address_map, debug_address_map
Exemple #15
0
    def __init__(self, platform):
        debug_bus = wb.Interface(data_width=32, adr_width=32)
        CLK = int(25e6)

        super().__init__(
            platform, debug_controller=debug_bus,
            wishbone_delay_register=False
        )

        spi0_pads = make_pads_obj({
            "mosi": Signal(1),
            "miso": Signal(1),
            "clk":  Signal(1),
        })

        spi1_pads = make_pads_obj({
            "mosi": Signal(1),
            "miso": Signal(1),
            "clk":  Signal(1),
        })

        uart0_pads = make_pads_obj({
            "rx": Signal(1),
            "tx": Signal(1),
        })

        uart1_pads = make_pads_obj({
            "rx": Signal(1),
            "tx": Signal(1),
        })

        i2c0_pads = make_pads_obj({
            "sda_i":   Signal(1),
            "sda_o":   Signal(1),
            "sda_oen": Signal(1),
            "scl_i":   Signal(1),
            "scl_o":   Signal(1),
            "scl_oen": Signal(1),
        })

        pwm0_pad = Signal(1)
        pwm1_pad = Signal(1)
        pwm2_pad = Signal(1)
        pwm3_pad = Signal(1)
        pwm4_pad = Signal(1)
        pwm5_pad = Signal(1)

        # IO control setup
        # Input-only  = (input_wire, Signal(), Constant(0))
        # Output-only = (Signal(), output_wire, Constant(1))
        io_in  = lambda a, b, c: (a, b, c, Signal(), Constant(0))
        io_out = lambda a, b, c: (a, b, Signal(), c, Constant(1))

        UART_IO_IND = 1
        UART_RX_PORT = 0
        UART_TX_PORT = 1
        LED_PORT = 13

        io_config = [
            {
                "index": 0, "name": "GPIO0 / RX0", "mode": "standard", "sync": True,
                "options": [
                    io_in(UART_IO_IND, "uart", uart0_pads.rx),
                ],
            },
            {
                "index": 1, "name": "GPIO1 / TX0", "mode": "standard", "sync": True,
                "options": [
                    io_out(UART_IO_IND, "uart", uart0_pads.tx),
                ],
            },
            {
                "index": 2, "name": "GPIO2 / RX1", "mode": "standard", "sync": True,
                "options": [
                    io_in(UART_IO_IND, "uart", uart1_pads.rx),
                ],
            },
            {
                "index": 3, "name": "GPIO3 / TX1", "mode": "standard", "sync": True,
                "options": [
                    io_out(UART_IO_IND, "uart", uart1_pads.tx),
                ],
            },
            {
                "index": 4, "name": "GPIO4 / PWM0", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "pwm", pwm0_pad),
                ],
            },
            {
                "index": 5, "name": "GPIO5 / PWM1", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "pwm", pwm1_pad),
                ],
            },
            {
                "index": 6, "name": "GPIO6 / PWM2", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "pwm", pwm2_pad),
                ],
            },
            {
                "index": 7, "name": "GPIO7 / PWM3", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "pwm", pwm3_pad),
                ],
            },
            {
                "index": 8, "name": "GPIO8 / PWM4", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "pwm", pwm4_pad),
                ],
            },
            {
                "index": 9, "name": "GPIO9 / PWM5", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "pwm", pwm5_pad),
                ],
            },
            {
                "index": 10, "name": "GPIO10", "mode": "standard", "sync": True,
                "options": [],
            },
            {
                "index": 11, "name": "GPIO11 / SPI0-MOSI", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "spi", spi0_pads.mosi),
                ],
            },
            {
                "index": 12, "name": "GPIO12 / SPI0-MISO", "mode": "standard", "sync": True,
                "options": [
                    io_in(1, "spi", spi0_pads.miso),
                ],
            },
            {
                "index": 13, "name": "GPIO13 / SPI0-SCK", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "spi", spi0_pads.clk),
                ],
            },
            {
                "index": 14, "name": "GPIO14 / SPI1-MOSI", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "spi", spi1_pads.mosi),
                ],
            },
            {
                "index": 15, "name": "GPIO15 / SPI1-MISO", "mode": "standard", "sync": True,
                "options": [
                    io_in(1, "spi", spi1_pads.miso),
                ],
            },
            {
                "index": 16, "name": "GPIO16 / SPI0-SCK", "mode": "standard", "sync": True,
                "options": [
                    io_out(1, "spi", spi1_pads.clk),
                ],
            },
            {
                "index": 17, "name": "GPIO17", "mode": "standard", "sync": True,
                "options": [],
            },

            # I2C is open-collector, only output-enable when low
            {
                "index": 18, "name": "GPIO18 / I2C0-SDA", "mode": "standard", "sync": True,
                "options": [
                    (1, "i2c", i2c0_pads.sda_i, Constant(0), i2c0_pads.sda_o == 0),
                ],
            },
            {
                "index": 19, "name": "GPIO19 / I2C0-SCL", "mode": "standard", "sync": True,
                "options": [
                    (1, "i2c", i2c0_pads.scl_i, Constant(0), i2c0_pads.scl_o == 0),
                ],
            },

        ]

        assert len(io_config) == NUM_IO

        """I/O controller setup"""
        io_pins = {"io{}".format(i): platform.request("io{}".format(i)) for i in range(NUM_IO)}
        self.add_periph(IOControl(io_pins, io_config), "ioctrl")
        self.add_debug_periph(None, "ioctrl_debug", bus=self.ioctrl.debug_bus)

        """I/O peripherals"""
        self.add_periph(spi.SPI(spi0_pads), "spi0")
        self.add_periph(spi.SPI(spi1_pads), "spi1")

        self.add_periph(uart.UART(uart0_pads, fifo_depth=8), "uart0")
        self.add_periph(uart.UART(uart1_pads, fifo_depth=8), "uart1")

        self.add_periph(i2c.I2C(i2c0_pads, fifo_depth=8), "i2c0")

        self.add_periph(pwm.PWM(pwm0_pad), "pwm0")
        self.add_periph(pwm.PWM(pwm1_pad), "pwm1")
        self.add_periph(pwm.PWM(pwm2_pad), "pwm2")
        self.add_periph(pwm.PWM(pwm3_pad), "pwm3")
        self.add_periph(pwm.PWM(pwm4_pad), "pwm4")
        self.add_periph(pwm.PWM(pwm5_pad), "pwm5")

        """External memories"""
        # Disabled in this build - can be added as needed
        # Cached bus is read-only (designed to be used as an instruction-cache)
        # Uncached is read-write
        #self.submodules.ram = RAMSubsystem(platform.request("hyperram"), platform.request("cache_mem"))
        #self.add_mem(None, "hyperram0", bus=self.ram.bus_cached)
        #self.add_mem(None, "hyperram1", bus=self.ram.bus_uncached)

        """Internal memories"""
        self.add_periph(ROM(bootrom(
            ioctrl_addr = wb_address_map["ioctrl"][0],
            uptime_timer_addr = wb_address_map["uptime"][0],
            uart_addr = wb_address_map["uart0"][0],
            uart_io_ind = UART_IO_IND,
            rx_port = UART_RX_PORT,
            tx_port = UART_TX_PORT,
            led_port = LED_PORT,
            imem_base = wb_address_map["imem"][0],
            dmem_base = wb_address_map["dmem"][0],
            clk = CLK
        ), nullterm=False, endianness="little"), "bootrom")

        self.add_mem(wb.SRAM(IMEM_SIZE, bus=wb.Interface(data_width=32, adr_width=32)), "imem")
        self.add_mem(wb.SRAM(DMEM_SIZE, bus=wb.Interface(data_width=32, adr_width=32)), "dmem")

        """Misc non-I/O peripherals"""
        self.add_periph(ROM(IDENT), "ident")
        self.add_periph(timer.UptimeTimer(), "uptime")
        self.add_periph(timer.Timer(), "timer0")
        self.add_periph(timer.Timer(), "timer1")
        #self.add_periph(timer.Timer(), "timer2")
        #self.add_periph(timer.Timer(), "timer3")

        """Debug-related peripherals"""
        # Debug region is not necessary in final builds - it is primarily intended for inspecting and debugging CPU internals when the main system bus is congested or blocked

        #self.add_controller(wishbone_bridge.WishboneBridge(), "wb_bridge")
        #self.add_debug_periph(None, "wb_bridge_debug", bus=self.wb_bridge.debug_bus)
        #self.add_debug_periph(debug_probe.DebugProbe(probe_width=64, output_width=64), "debug_probe_debug")
        #self.add_controller(wishbone_debug_bus.WishboneDebugBus(platform.request("uart_debug_bus"), CLK, baud=115200), "wbdbgbus_debug")

        """External debug utilities"""
        self.add_controller(wishbone_debug_bus.WishboneDebugBus(platform.request("uart_main_dbg"), CLK, baud=115200), "wbdbgbus_main")

        """CPU Instantiation"""
        self.submodules.cpu = CPUWrapper()
        self.add_controller(None, "cpu_ibus", bus=self.cpu.instr_bus)
        self.add_controller(None, "cpu_dbus", bus=self.cpu.data_bus)

        # Fixed init PC
        self.comb += self.cpu.init_pc.eq(self.wb_address("bootrom")[0])

        # Only needed for debugging the CPU and busses on hardware
        #self.comb += self.cpu.stall_in.eq(self.debug_probe_debug.stall_out)
        #self.comb += self.debug_probe_debug.stall_in.eq(self.cpu.stall_out)
        #self.comb += self.cpu.cpu_reset.eq(self.debug_probe_debug.reset_out)
        #self.comb += self.debug_probe_debug.probe.eq(self.cpu.pc_out)

        self.comb += self.cpu.cpu_reset.eq(0)

        """Generate the bus"""
        main_mem_map, debug_mem_map = self.generate_bus()

        with open("build/mem_map.txt", "w+") as f:
            def println_both(x):
                print(x)
                f.write(x+"\n")

            println_both("Main Memory Map:")
            print_mem_map(main_mem_map, print_fn = println_both)
            println_both("")
            println_both("Debug Memory Map:")
            print_mem_map(debug_mem_map, print_fn = println_both)
            print()

        with open("build/platform.h", "w+") as f:
            def println_file(x):
                f.write(x+"\n")

            println_file("// THIS FILE IS AUTO-GENERATED AND SHOULD NOT BE EDITED BY HAND")
            println_file("#include <stdint.h>")
            println_file("")
            println_file("#ifndef PLATFORM_H")
            println_file("#define PLATFORM_H 1")
            println_file("")
            print_mem_map_defines(wb_address_map, print_fn = println_file)
            println_file("")
            print_io_map_defines(io_config, wb_address_map["ioctrl"][0], print_fn = println_file)
            println_file("#define CLK_FREQ        {}".format(CLK))
            println_file("#define CLKS_PER_MILLIS {}".format(CLK // 1000))
            println_file("")
            println_file("#endif")

        with open("build/platform_init.h", "w+") as f:
            def println_file(x):
                f.write(x+"\n")

            println_file("// THIS FILE IS AUTO-GENERATED AND SHOULD NOT BE EDITED BY HAND")
            println_file("")
            println_file("#ifndef PLATFORM_INIT_H")
            println_file("#define PLATFORM_INIT_H 1")
            println_file("")
            print_mem_map_defines(wb_address_map, print_fn = println_file, raw_only = True)
            println_file("#endif")

        with open("build/platform.ld", "w+") as f:
            def println_file(x):
                f.write(x+"\n")

            println_file("/* THIS FILE IS AUTO-GENERATED AND SHOULD NOT BE EDITED BY HAND */")
            println_file("")
            print_mem_map_ld(wb_address_map, print_fn = println_file)
Exemple #16
0
    def __init__(self, pads, bus=None):
        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        self.irq = Signal()

        wb_req = self.bus.cyc & self.bus.stb & ~self.bus.ack

        data_out_reg = Signal(8)
        data_out = Signal(8)
        data_out_valid = Signal()
        self.sync += If(data_out_valid, data_out_reg.eq(data_out))

        data_write = Signal(8)
        start_write = Signal()

        ready = Signal()
        mode = Signal(2)
        divider = Signal(16, reset=25)  # 1Mhz at 50Mhz clk
        last_out_valid = Signal()

        # Address 0 = Config / Status = {13'b0, ready[0:0], mode[1:0], divider[15:0]}
        # Address 4 = Data Write (lowest 8 bits)
        # Address 8 = Data Read (lowest 8 bits)
        self.sync += [
            self.bus.ack.eq(0),
            self.bus.err.eq(0),
            self.irq.eq(0),
            start_write.eq(0),
            last_out_valid.eq(data_out_valid),
            If(data_out_valid & ~last_out_valid, self.irq.eq(1)),
            If(
                wb_req,
                self.bus.ack.eq(1),
                If((self.bus.adr >> 2) == 0,
                   If(self.bus.we & self.bus.sel[0],
                      divider[0:8].eq(self.bus.dat_w[0:8])),
                   If(self.bus.we & self.bus.sel[1],
                      divider[8:16].eq(self.bus.dat_w[8:16])),
                   If(self.bus.we & self.bus.sel[2],
                      mode.eq(self.bus.dat_w[16:18])),
                   self.bus.dat_r.eq(Cat(divider, mode, ready))),
            ),
            If((self.bus.adr >> 2) == 1,
               If(self.bus.we & self.bus.sel[0],
                  data_write.eq(self.bus.dat_w[0:8]), start_write.eq(1)),
               self.bus.dat_r.eq(data_write)),
            If(
                (self.bus.adr >> 2) == 2,
                self.bus.dat_r.eq(data_out_reg),
            ),
        ]

        self.specials += Instance("spi_controller",
                                  i_i_TX_Byte=data_write,
                                  i_i_TX_DV=start_write,
                                  o_o_TX_Ready=ready,
                                  o_o_RX_Byte=data_out,
                                  o_o_RX_DV=data_out_valid,
                                  o_o_SPI_Clk=pads.clk,
                                  i_i_SPI_MISO=pads.miso,
                                  o_o_SPI_MOSI=pads.mosi,
                                  i_i_CPHA=mode[0],
                                  i_i_CPOL=mode[1],
                                  i_i_divider=divider,
                                  i_i_Clk=ClockSignal(),
                                  i_i_Rst=ResetSignal())
Exemple #17
0
 def __init__(self, controllers, peripherals, shared=None, register=False):
     if shared is None:
         shared = wb.Interface(data_width=32, adr_width=32)
     self.submodules.arbiter = wb.Arbiter(controllers, shared)
     self.submodules.decoder = wb.Decoder(shared, peripherals, register)
Exemple #18
0
    def __init__(self, pins, config, bus=None, debug_bus=None):
        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        if debug_bus is None:
            self.debug_bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.debug_bus = debug_bus

        self.irq = Signal()
        self.sync += self.irq.eq(0)

        io = []

        assert 0 < len(config) and len(config) < 256
        """
            Pad naming: io0, io1, io2, ...

            Config:
            [
                {
                    index: 0, # must match index of pin in array
                    name: "", # optional
                    mode: "standard/passthrough/passthrough-direct",
                    sync: True/False,
                    options: [ # Only for standard-mode
                        (ind, name, i, o, oe), # ind must not be zero
                        (ind, name, i, o, oe),
                        (ind, name, i, o, oe),
                        ... up to 16
                    ],
                    passthrough: (i, o, oe) # Only for passthrough-mode
                }
            ]

            state = {4'b0, type[1:0], actual_enable, actual_select[3:0], actual_irqmode[1:0], actual_oe, actual_out, actual_in}
            Dbg reg: {15'b0, 1'b0, state[15:0]}
            CPU reg: {state[15:0], 1'b0, enable, select[3:0], irqmode[1:0], 5'b0, gpio_oe, gpio_out, gpio_in}

            Data:
            - GPIO in
            - GPIO out
            - GPIO oe
            - enable
            - select[3:0]
            - IRQ mode[1:0] - 0 = none, 1 = rising, 2 = falling

            State:
            - Actual out
            - Actual in
            - Actual oe
            - Actual enable
            - Actual select[3:0]
            - Actual irq mode[1:0]

            - type[1:0] - 0 = standard, 1 = passthrough, 2 = passthrough-silent

        """
        # Set up I/O
        for pin_ind, pin in enumerate(config):
            assert pin["index"] == pin_ind
            mode = pin["mode"]
            assert mode in ["standard", "passthrough", "passthrough-direct"]

            if mode != "standard":
                assert "options" not in pin or len(pin["options"]) == 0
                assert "passthrough" in pin

            pad = pins["io{}".format(pin_ind)]
            ind = Constant(pin_ind, bits_sign=8)

            if pin["sync"]:
                ff1 = Signal(reset_less=True)
                ff2 = Signal(reset_less=True)
                pad_i = Signal(reset_less=True)

                self.sync += [
                    ff1.eq(pad.i),
                    ff2.eq(ff1),
                    pad_i.eq(ff2),
                ]
            else:
                pad_i = pad.i

            pad_o = pad.o
            pad_oe = pad.oe

            if mode == "standard":
                typ = Constant(0, bits_sign=2)
            elif mode == "passthrough":
                typ = Constant(1, bits_sign=2)
            elif mode == "passthrough-direct":
                typ = Constant(2, bits_sign=2)

            last = Signal(reset=0)
            self.sync += last.eq(pad_i)

            rising = ~pad_oe & pad_i & ~last
            falling = ~pad_oe & last & ~pad_i

            gpio_in = Signal(reset=0)
            gpio_out = Signal(reset=0)
            gpio_oe = Signal(reset=0)

            irqmode = Signal(2, reset=0)
            select = Signal(4, reset=0)
            enable = Signal(reset=0)

            if mode == "passthrough-direct":
                state = Cat(Constant(0, bits_sign=3), irqmode, select, enable,
                            typ, Constant(0, bits_sign=4))
            else:
                state = Cat(pad_i, pad_o, pad_oe, irqmode, select, enable, typ,
                            Constant(0, bits_sign=4))

            assert len(state) == 16

            dbg_reg = Cat(state, Constant(0, bits_sign=16))
            assert len(dbg_reg) == 32

            cpu_reg = Cat(gpio_in, gpio_out, gpio_oe,
                          Constant(0, bits_sign=5), irqmode, select, enable,
                          Constant(0, bits_sign=1), state)
            assert len(cpu_reg) == 32

            if mode == "passthrough-direct" or mode == "passthrough":
                self.comb += [
                    pin["passthrough"][0].eq(pad_i),
                    pad_o.eq(pin["passthrough"][1]),
                    pad_oe.eq(pin["passthrough"][2]),
                ]
            else:
                # Set up standard I/O multiplexing
                options = [x for x in pin["options"]]
                assert not any([x[0] == 0 for x in options])
                #options.append((0, "gpio", gpio_in, gpio_out, gpio_oe))

                cases = {}
                cases["default"] = [
                    pad_o.eq(gpio_out),
                    pad_oe.eq(gpio_oe),
                ]

                self.comb += gpio_in.eq(pad_i)
                for opt_ind, name, i, o, oe in options:
                    self.comb += i.eq(pad_i)
                    cases[opt_ind] = [
                        pad_o.eq(o),
                        pad_oe.eq(oe),
                    ]

                self.comb += [
                    If(~enable, pad_oe.eq(0),
                       pad_o.eq(0)).Else(Case(select, cases))
                ]

                self.sync += [
                    If(rising & irqmode == 1, self.irq.eq(1)),
                    If(falling & irqmode == 2, self.irq.eq(1))
                ]

            assert pin_ind == len(io)
            io.append({
                "index": pin_ind,
                "gpio_in": gpio_in,
                "gpio_out": gpio_out,
                "gpio_oe": gpio_oe,
                "enable": enable,
                "select": select,
                "irqmode": irqmode,
                "cpu_reg": cpu_reg,
                "dbg_reg": dbg_reg,
            })

        # Main bus access
        # CPU reg: {state[15:0], 1'b0, enable, select[3:0], irqmode[1:0], 5'b0, gpio_oe, gpio_out, gpio_in}
        self.sync += [
            self.bus.ack.eq(0),
            self.bus.err.eq(0),
            If(
                self.bus.stb & self.bus.cyc & ~self.bus.ack,
                self.bus.ack.eq(1), *[
                    If((self.bus.adr >> 2) == port["index"],
                       self.bus.dat_r.eq(port["cpu_reg"]),
                       If(self.bus.we & self.bus.sel[0],
                          port["gpio_out"].eq(self.bus.dat_w[1]),
                          port["gpio_oe"].eq(self.bus.dat_w[2])),
                       If(self.bus.we & self.bus.sel[1],
                          port["irqmode"].eq(self.bus.dat_w[8:10]),
                          port["select"].eq(self.bus.dat_w[10:14]),
                          port["enable"].eq(self.bus.dat_w[14])))
                    for port in io
                ])
        ]

        # Debug bus access
        self.sync += [
            self.debug_bus.ack.eq(0),
            self.debug_bus.err.eq(0),
            If(
                self.debug_bus.stb & self.debug_bus.cyc & ~self.debug_bus.ack,
                self.debug_bus.ack.eq(1), *[
                    If(
                        (self.debug_bus.adr >> 2) == port["index"],
                        self.debug_bus.dat_r.eq(port["dbg_reg"]),
                    ) for port in io
                ])
        ]
Exemple #19
0
    def __init__(self, bus=None, debug_bus=None, enable_code=0xABAB12):
        if bus is None:
            self.bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.bus = bus

        if debug_bus is None:
            self.debug_bus = wb.Interface(data_width=32, adr_width=32)
        else:
            self.debug_bus = debug_bus

        wb_sel = Signal(4, reset=0b1111)
        wb_addr = Signal(32)
        wb_wr_data = Signal(32)
        wb_rd_data = Signal(32)
        wb_rd_data_valid = Signal()
        wb_error = Signal()
        wb_in_progress = Signal()

        enable_entry = Signal(32, reset=0)
        enabled = enable_entry == Constant(enable_code)

        # 00 = Cfg/Status {19'b0, sel_valid, sel[3:0], 2'b0, error, in_progress, rd_valid, halt, rd_req, wr_req}
        # 04 = Addr
        # 08 = Write Data
        # 0C = Read Data
        # 10 = Enable

        # Main bus
        self.comb += [
            self.bus.stb.eq(wb_in_progress),
            self.bus.cyc.eq(wb_in_progress),
            self.bus.adr.eq(wb_addr),
            self.bus.dat_w.eq(wb_wr_data),
            self.bus.sel.eq(wb_sel)
        ]

        self.sync += [
            If(self.bus.ack, wb_in_progress.eq(0),
               wb_rd_data.eq(self.bus.dat_r), wb_rd_data_valid.eq(1),
               wb_error.eq(0)),
            If(self.bus.err, wb_in_progress.eq(0), wb_rd_data_valid.eq(0),
               wb_error.eq(1))
        ]

        # Debug bus
        self.sync += [
            self.debug_bus.ack.eq(0),
            self.debug_bus.err.eq(0),
            self.debug_bus.dat_r.eq(0),
            If(
                self.debug_bus.stb & self.debug_bus.cyc & ~self.debug_bus.ack,
                self.debug_bus.ack.eq(1),
                If((self.debug_bus.adr >> 2) == 0,
                   If(
                       self.debug_bus.we & self.debug_bus.sel[0],
                       If(enabled & ~wb_in_progress & self.debug_bus.dat_w[0],
                          wb_in_progress.eq(1), wb_error.eq(0),
                          wb_rd_data.eq(0), wb_rd_data_valid.eq(0),
                          self.bus.we.eq(1)).Elif(
                              enabled
                              & ~wb_in_progress & self.debug_bus.dat_w[1],
                              wb_in_progress.eq(1), wb_error.eq(0),
                              wb_rd_data.eq(0), wb_rd_data_valid.eq(0),
                              self.bus.we.eq(0)).Elif(self.debug_bus.dat_w[2],
                                                      wb_in_progress.eq(0))),
                   If(
                       self.debug_bus.we & self.debug_bus.sel[1],
                       If(self.debug_bus.dat_w[12] == 1,
                          wb_sel.eq(self.debug_bus.dat_w[8:12]))),
                   self.debug_bus.dat_r.eq(
                       Cat(Constant(0, bits_sign=3),
                           wb_rd_data_valid, wb_in_progress, wb_error,
                           Constant(0, bits_sign=2), wb_sel,
                           Constant(0, bits_sign=1)))),
                If((self.debug_bus.adr >> 2) == 1,
                   If(self.debug_bus.we & self.debug_bus.sel[0],
                      wb_addr[0:8].eq(self.debug_bus.dat_w[0:8])),
                   If(self.debug_bus.we & self.debug_bus.sel[1],
                      wb_addr[8:16].eq(self.debug_bus.dat_w[8:16])),
                   If(self.debug_bus.we & self.debug_bus.sel[2],
                      wb_addr[16:24].eq(self.debug_bus.dat_w[16:24])),
                   If(self.debug_bus.we & self.debug_bus.sel[3],
                      wb_addr[24:32].eq(self.debug_bus.dat_w[24:32])),
                   self.debug_bus.dat_r.eq(wb_addr)),
                If((self.debug_bus.adr >> 2) == 2,
                   If(self.debug_bus.we & self.debug_bus.sel[0],
                      wb_wr_data[0:8].eq(self.debug_bus.dat_w[0:8])),
                   If(self.debug_bus.we & self.debug_bus.sel[1],
                      wb_wr_data[8:16].eq(self.debug_bus.dat_w[8:16])),
                   If(self.debug_bus.we & self.debug_bus.sel[2],
                      wb_wr_data[16:24].eq(self.debug_bus.dat_w[16:24])),
                   If(self.debug_bus.we & self.debug_bus.sel[3],
                      wb_wr_data[24:32].eq(self.debug_bus.dat_w[24:32])),
                   self.debug_bus.dat_r.eq(wb_wr_data)),
                If((self.debug_bus.adr >> 2) == 3,
                   self.debug_bus.dat_r.eq(wb_rd_data)),
                If((self.debug_bus.adr >> 2) == 4,
                   If(self.debug_bus.we & self.debug_bus.sel[0],
                      enable_entry[0:8].eq(self.debug_bus.dat_w[0:8])),
                   If(self.debug_bus.we & self.debug_bus.sel[1],
                      enable_entry[8:16].eq(self.debug_bus.dat_w[8:16])),
                   If(self.debug_bus.we & self.debug_bus.sel[2],
                      enable_entry[16:24].eq(self.debug_bus.dat_w[16:24])),
                   If(self.debug_bus.we & self.debug_bus.sel[3],
                      enable_entry[24:32].eq(self.debug_bus.dat_w[24:32])),
                   self.debug_bus.dat_r.eq(enable_entry)),
            )
        ]