variants = ("std", "std_debug", "lite", "lite_debug", "min", "min_debug")
assert variant in variants, "Unsupported variant %s" % variant
self.reset = Signal()
- self.ibus = i = wishbone.Interface()
- self.dbus = d = wishbone.Interface()
- i_err = Signal()
- d_err = Signal()
+ self.ibus = ibus = wishbone.Interface()
+ self.dbus = dbus = wishbone.Interface()
self.interrupt = Signal(32)
- # Output reset signal -- set to 1 when CPU reset is asserted
- self.debug_reset = Signal()
-
verilog_variants = {
"std": "VexRiscv.v",
"std_debug": "VexRiscv_Debug.v",
"min": "VexRiscv_Lite.v",
"min_debug": "VexRiscv_LiteDebug.v",
}
-
- cpu_reset = ResetSignal()
- cpu_args = {}
cpu_filename = verilog_variants[variant]
- if "debug" in variant:
- cpu_reset = Signal()
- cpu_args = {}
-
- self.i_cmd_valid = Signal()
- self.i_cmd_payload_wr = Signal()
- self.i_cmd_payload_address = Signal(8)
- self.i_cmd_payload_data = Signal(32)
- self.o_cmd_ready = Signal()
- self.o_rsp_data = Signal(32)
- self.o_resetOut = Signal()
-
- reset_debug_logic = Signal()
-
- self.transfer_complete = Signal()
- self.transfer_in_progress = Signal()
- self.transfer_wait_for_ack = Signal()
-
- self.debug_bus = wishbone.Interface()
-
- self.sync += [
- self.debug_bus.dat_r.eq(self.o_rsp_data),
- cpu_reset.eq(reset_debug_logic | ResetSignal()),
- ]
-
- self.sync += [
- # CYC is held high for the duration of the transfer.
- # STB is kept high when the transfer finishes (write)
- # or the master is waiting for data (read), and stays
- # there until ACK, ERR, or RTY are asserted.
- If((self.debug_bus.stb & self.debug_bus.cyc)
- & (~self.transfer_in_progress)
- & (~self.transfer_complete)
- & (~self.transfer_wait_for_ack),
- self.i_cmd_payload_data.eq(self.debug_bus.dat_w),
- self.i_cmd_payload_address.eq((self.debug_bus.adr[0:6] << 2) | 0),
- self.i_cmd_payload_wr.eq(self.debug_bus.we),
- self.i_cmd_valid.eq(1),
- self.transfer_in_progress.eq(1),
- self.transfer_complete.eq(0),
- self.debug_bus.ack.eq(0)
- ).Elif(self.transfer_in_progress,
- If(self.o_cmd_ready,
- self.i_cmd_valid.eq(0),
- self.i_cmd_payload_wr.eq(0),
- self.transfer_complete.eq(1),
- self.transfer_in_progress.eq(0)
- )
- ).Elif(self.transfer_complete,
- self.transfer_complete.eq(0),
- self.debug_bus.ack.eq(1),
- self.transfer_wait_for_ack.eq(1)
- ).Elif(self.transfer_wait_for_ack & ~(self.debug_bus.stb & self.debug_bus.cyc),
- self.transfer_wait_for_ack.eq(0),
- self.debug_bus.ack.eq(0)
- ),
- # Force a Wishbone error if transferring during a reset sequence.
- # Because o_resetOut is multiple cycles and i.stb/d.stb should
- # deassert one cycle after i_err/i_ack/d_err/d_ack are asserted,
- # this will give i_err and o_err enough time to be reset to 0
- # once the reset cycle finishes.
- If(self.o_resetOut,
- If(i.cyc & i.stb, i_err.eq(1)).Else(i_err.eq(0)),
- If(d.cyc & d.stb, d_err.eq(1)).Else(d_err.eq(0)),
- reset_debug_logic.eq(1))
- .Else(
- reset_debug_logic.eq(0)
- )
- ]
-
- cpu_args.update({
- "i_debugReset": ResetSignal(),
- "i_debug_bus_cmd_valid": self.i_cmd_valid,
- "i_debug_bus_cmd_payload_wr": self.i_cmd_payload_wr,
- "i_debug_bus_cmd_payload_address": self.i_cmd_payload_address,
- "i_debug_bus_cmd_payload_data": self.i_cmd_payload_data,
- "o_debug_bus_cmd_ready": self.o_cmd_ready,
- "o_debug_bus_rsp_data": self.o_rsp_data,
- "o_debug_resetOut": self.o_resetOut
- })
-
- self.comb += [
- i.err.eq(i_err),
- d.err.eq(d_err),
- ]
- self.specials += Instance("VexRiscv",
- **cpu_args,
-
+ self.cpu_params = dict(
i_clk=ClockSignal(),
- i_reset=cpu_reset | self.reset,
+ i_reset=ResetSignal() | self.reset,
i_externalResetVector=cpu_reset_address,
i_externalInterruptArray=self.interrupt,
i_timerInterrupt=0,
- o_iBusWishbone_ADR=i.adr,
- o_iBusWishbone_DAT_MOSI=i.dat_w,
- o_iBusWishbone_SEL=i.sel,
- o_iBusWishbone_CYC=i.cyc,
- o_iBusWishbone_STB=i.stb,
- o_iBusWishbone_WE=i.we,
- o_iBusWishbone_CTI=i.cti,
- o_iBusWishbone_BTE=i.bte,
- i_iBusWishbone_DAT_MISO=i.dat_r,
- i_iBusWishbone_ACK=i.ack,
- i_iBusWishbone_ERR=i_err,
-
- o_dBusWishbone_ADR=d.adr,
- o_dBusWishbone_DAT_MOSI=d.dat_w,
- o_dBusWishbone_SEL=d.sel,
- o_dBusWishbone_CYC=d.cyc,
- o_dBusWishbone_STB=d.stb,
- o_dBusWishbone_WE=d.we,
- o_dBusWishbone_CTI=d.cti,
- o_dBusWishbone_BTE=d.bte,
- i_dBusWishbone_DAT_MISO=d.dat_r,
- i_dBusWishbone_ACK=d.ack,
- i_dBusWishbone_ERR=d_err)
+ o_iBusWishbone_ADR=ibus.adr,
+ o_iBusWishbone_DAT_MOSI=ibus.dat_w,
+ o_iBusWishbone_SEL=ibus.sel,
+ o_iBusWishbone_CYC=ibus.cyc,
+ o_iBusWishbone_STB=ibus.stb,
+ o_iBusWishbone_WE=ibus.we,
+ o_iBusWishbone_CTI=ibus.cti,
+ o_iBusWishbone_BTE=ibus.bte,
+ i_iBusWishbone_DAT_MISO=ibus.dat_r,
+ i_iBusWishbone_ACK=ibus.ack,
+ i_iBusWishbone_ERR=ibus.err,
+
+ o_dBusWishbone_ADR=dbus.adr,
+ o_dBusWishbone_DAT_MOSI=dbus.dat_w,
+ o_dBusWishbone_SEL=dbus.sel,
+ o_dBusWishbone_CYC=dbus.cyc,
+ o_dBusWishbone_STB=dbus.stb,
+ o_dBusWishbone_WE=dbus.we,
+ o_dBusWishbone_CTI=dbus.cti,
+ o_dBusWishbone_BTE=dbus.bte,
+ i_dBusWishbone_DAT_MISO=dbus.dat_r,
+ i_dBusWishbone_ACK=dbus.ack,
+ i_dBusWishbone_ERR=dbus.err)
+
+ if "debug" in variant:
+ self.add_debug()
# add verilog sources
self.add_sources(platform, cpu_filename)
+ def add_debug(self):
+ debug_reset = Signal()
+
+ ibus_err = Signal()
+ dbus_err = Signal()
+
+ self.i_cmd_valid = Signal()
+ self.i_cmd_payload_wr = Signal()
+ self.i_cmd_payload_address = Signal(8)
+ self.i_cmd_payload_data = Signal(32)
+ self.o_cmd_ready = Signal()
+ self.o_rsp_data = Signal(32)
+ self.o_resetOut = Signal()
+
+ reset_debug_logic = Signal()
+
+ self.transfer_complete = Signal()
+ self.transfer_in_progress = Signal()
+ self.transfer_wait_for_ack = Signal()
+
+ self.debug_bus = wishbone.Interface()
+
+ self.sync += [
+ self.debug_bus.dat_r.eq(self.o_rsp_data),
+ debug_reset.eq(reset_debug_logic | ResetSignal()),
+ ]
+
+ self.sync += [
+ # CYC is held high for the duration of the transfer.
+ # STB is kept high when the transfer finishes (write)
+ # or the master is waiting for data (read), and stays
+ # there until ACK, ERR, or RTY are asserted.
+ If((self.debug_bus.stb & self.debug_bus.cyc)
+ & (~self.transfer_in_progress)
+ & (~self.transfer_complete)
+ & (~self.transfer_wait_for_ack),
+ self.i_cmd_payload_data.eq(self.debug_bus.dat_w),
+ self.i_cmd_payload_address.eq((self.debug_bus.adr[0:6] << 2) | 0),
+ self.i_cmd_payload_wr.eq(self.debug_bus.we),
+ self.i_cmd_valid.eq(1),
+ self.transfer_in_progress.eq(1),
+ self.transfer_complete.eq(0),
+ self.debug_bus.ack.eq(0)
+ ).Elif(self.transfer_in_progress,
+ If(self.o_cmd_ready,
+ self.i_cmd_valid.eq(0),
+ self.i_cmd_payload_wr.eq(0),
+ self.transfer_complete.eq(1),
+ self.transfer_in_progress.eq(0)
+ )
+ ).Elif(self.transfer_complete,
+ self.transfer_complete.eq(0),
+ self.debug_bus.ack.eq(1),
+ self.transfer_wait_for_ack.eq(1)
+ ).Elif(self.transfer_wait_for_ack & ~(self.debug_bus.stb & self.debug_bus.cyc),
+ self.transfer_wait_for_ack.eq(0),
+ self.debug_bus.ack.eq(0)
+ ),
+ # Force a Wishbone error if transferring during a reset sequence.
+ # Because o_resetOut is multiple cycles and i.stb/d.stb should
+ # deassert one cycle after i_err/i_ack/d_err/d_ack are asserted,
+ # this will give i_err and o_err enough time to be reset to 0
+ # once the reset cycle finishes.
+ If(self.o_resetOut,
+ If(self.ibus.cyc & self.ibus.stb, ibus_err.eq(1)).Else(ibus_err.eq(0)),
+ If(self.dbus.cyc & self.dbus.stb, dbus_err.eq(1)).Else(dbus_err.eq(0)),
+ reset_debug_logic.eq(1))
+ .Else(
+ reset_debug_logic.eq(0)
+ )
+ ]
+
+ self.cpu_params.update(
+ i_reset=ResetSignal() | self.reset | debug_reset,
+ i_iBusWishbone_ERR=self.ibus.err | ibus_err,
+ i_dBusWishbone_ERR=self.dbus.err | dbus_err,
+ i_debugReset=ResetSignal(),
+ i_debug_bus_cmd_valid=self.i_cmd_valid,
+ i_debug_bus_cmd_payload_wr=self.i_cmd_payload_wr,
+ i_debug_bus_cmd_payload_address=self.i_cmd_payload_address,
+ i_debug_bus_cmd_payload_data=self.i_cmd_payload_data,
+ o_debug_bus_cmd_ready=self.o_cmd_ready,
+ o_debug_bus_rsp_data=self.o_rsp_data,
+ o_debug_resetOut=self.o_resetOut
+ )
+
@staticmethod
def add_sources(platform, cpu_filename):
vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog")
platform.add_source(os.path.join(vdir, cpu_filename))
+
+ def do_finalize(self):
+ self.specials += Instance("VexRiscv", **self.cpu_params)