def __init__(self, endianness="big"): self.source = source = stream.Endpoint(spi_core2phy_layout) self.sink = sink = stream.Endpoint(spi_phy2core_layout) self.bus = bus = wishbone.Interface() self.cs = cs = Signal() # # # # Burst Control. burst_cs = Signal() burst_adr = Signal(len(bus.adr), reset_less=True) burst_timeout = WaitTimer(MMAP_DEFAULT_TIMEOUT) self.submodules += burst_timeout # FSM. self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", # Keep CS active after Burst for Timeout. burst_timeout.wait.eq(1), NextValue(burst_cs, burst_cs & ~burst_timeout.done), cs.eq(burst_cs), # On Bus Read access... If( bus.cyc & bus.stb & ~bus.we, # If CS is still active and Bus address matches previous Burst address: # Just continue the current Burst. If(burst_cs & (bus.adr == burst_adr), NextState("BURST-REQ") # Otherwise initialize a new Burst. ).Else(cs.eq(0), NextState("BURST-CMD")))) fsm.act( "BURST-CMD", cs.eq(1), source.valid.eq(1), source.cmd.eq(CMD), source.data.eq(Cat(Signal(2), bus.adr)), # Words to Bytes. NextValue(burst_cs, 1), NextValue(burst_adr, bus.adr), If( source.ready, NextState("BURST-REQ"), )) fsm.act("BURST-REQ", cs.eq(1), source.valid.eq(1), source.cmd.eq(READ), source.last.eq(1), If( source.ready, NextState("BURST-DAT"), )) fsm.act( "BURST-DAT", cs.eq(1), sink.ready.eq(1), bus.dat_r.eq({ "big": sink.data, "little": reverse_bytes(sink.data) }[endianness]), If( sink.valid, bus.ack.eq(1), NextValue(burst_adr, burst_adr + 1), NextState("IDLE"), ))
def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), endianness="big", variant="standard"): self.variant = variant self.icp_bus = icp_bus = wishbone.Interface(data_width=32, adr_width=12) self.ics_bus = ics_bus = wishbone.Interface(data_width=32, adr_width=12) # Bus endianness handlers self.icp_dat_w = Signal(32) self.icp_dat_r = Signal(32) self.comb += self.icp_dat_w.eq(icp_bus.dat_w if endianness == "big" else reverse_bytes(icp_bus.dat_w)) self.comb += icp_bus.dat_r.eq(self.icp_dat_r if endianness == "big" else reverse_bytes(self.icp_dat_r)) self.ics_dat_w = Signal(32) self.ics_dat_r = Signal(32) self.comb += self.ics_dat_w.eq(ics_bus.dat_w if endianness == "big" else reverse_bytes(ics_bus.dat_w)) self.comb += ics_bus.dat_r.eq(self.ics_dat_r if endianness == "big" else reverse_bytes(self.ics_dat_r)) # XICS signals self.ics_icp_xfer_src = Signal(4) self.ics_icp_xfer_pri = Signal(8) self.icp_params = dict( # Clock / Reset i_clk=ClockSignal(), i_rst=ResetSignal(), # Wishbone bus o_wishbone_dat_r=self.icp_dat_r, o_wishbone_ack=icp_bus.ack, i_wishbone_adr=icp_bus.adr, i_wishbone_dat_w=self.icp_dat_w, i_wishbone_cyc=icp_bus.cyc, i_wishbone_stb=icp_bus.stb, i_wishbone_sel=icp_bus.sel, i_wishbone_we=icp_bus.we, i_ics_in_src=self.ics_icp_xfer_src, i_ics_in_pri=self.ics_icp_xfer_pri, o_core_irq_out=core_irq_out, ) self.ics_params = dict( # Clock / Reset i_clk=ClockSignal(), i_rst=ResetSignal(), # Wishbone bus o_wishbone_dat_r=self.ics_dat_r, o_wishbone_ack=ics_bus.ack, i_wishbone_adr=ics_bus.adr, i_wishbone_dat_w=self.ics_dat_w, i_wishbone_cyc=ics_bus.cyc, i_wishbone_stb=ics_bus.stb, i_wishbone_sel=ics_bus.sel, i_wishbone_we=ics_bus.we, i_int_level_in=int_level_in, o_icp_out_src=self.ics_icp_xfer_src, o_icp_out_pri=self.ics_icp_xfer_pri, ) # add vhdl sources self.add_sources(platform, use_ghdl_yosys_plugin="ghdl" in self.variant)
def format_bytes(s, endianness): return {"big": s, "little": reverse_bytes(s)}[endianness]
def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True): self.source = source = stream.Endpoint(spi_core2phy_layout) self.sink = sink = stream.Endpoint(spi_phy2core_layout) self.bus = bus = wishbone.Interface() self.cs = cs = Signal() # Burst Control. burst_cs = Signal() burst_adr = Signal(len(bus.adr), reset_less=True) burst_timeout = WaitTimer(MMAP_DEFAULT_TIMEOUT) self.submodules += burst_timeout cmd_bits = 8 data_bits = 32 if flash.cmd_width == 1: self._default_dummy_bits = flash.dummy_bits if flash.fast_mode else 0 elif flash.cmd_width == 4: self._default_dummy_bits = flash.dummy_bits * 3 if flash.fast_mode else 0 else: raise NotImplementedError( f'Command width of {flash.cmd_width} bits is currently not supported!' ) self._spi_dummy_bits = spi_dummy_bits = Signal(8) if with_csr: self.dummy_bits = dummy_bits = CSRStorage( 8, reset=self._default_dummy_bits) if clock_domain != "sys": self.specials += MultiReg(dummy_bits.storage, spi_dummy_bits, clock_domain) else: self.comb += spi_dummy_bits.eq(dummy_bits.storage) else: self.comb += spi_dummy_bits.eq(self._default_dummy_bits) dummy = Signal(data_bits, reset=0xdead) # FSM. self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", # Keep CS active after Burst for Timeout. burst_timeout.wait.eq(1), NextValue(burst_cs, burst_cs & ~burst_timeout.done), cs.eq(burst_cs), # On Bus Read access... If( bus.cyc & bus.stb & ~bus.we, # If CS is still active and Bus address matches previous Burst address: # Just continue the current Burst. If(burst_cs & (bus.adr == burst_adr), NextState("BURST-REQ") # Otherwise initialize a new Burst. ).Else(cs.eq(0), NextState("BURST-CMD")))) fsm.act( "BURST-CMD", cs.eq(1), source.valid.eq(1), source.data.eq(flash.read_opcode.code), # send command. source.len.eq(cmd_bits), source.width.eq(flash.cmd_width), source.mask.eq(cmd_oe_mask[flash.cmd_width]), NextValue(burst_adr, bus.adr), If( source.ready, NextState("CMD-RET"), )) fsm.act("CMD-RET", cs.eq(1), sink.ready.eq(1), If( sink.valid, NextState("BURST-ADDR"), )) fsm.act( "BURST-ADDR", cs.eq(1), source.valid.eq(1), source.width.eq(flash.addr_width), source.mask.eq(addr_oe_mask[flash.addr_width]), source.data.eq(Cat(Signal(2), bus.adr)), # send address. source.len.eq(flash.addr_bits), NextValue(burst_cs, 1), NextValue(burst_adr, bus.adr), If( source.ready, NextState("ADDR-RET"), )) fsm.act( "ADDR-RET", cs.eq(1), sink.ready.eq(1), If( sink.valid, If( spi_dummy_bits == 0, NextState("BURST-REQ"), ).Else(NextState("DUMMY"), ))) fsm.act("DUMMY", cs.eq(1), source.valid.eq(1), source.width.eq(flash.addr_width), source.mask.eq(addr_oe_mask[flash.addr_width]), source.data.eq(dummy), source.len.eq(spi_dummy_bits), If( source.ready, NextState("DUMMY-RET"), )) fsm.act("DUMMY-RET", cs.eq(1), sink.ready.eq(1), If( sink.valid, NextState("BURST-REQ"), )) fsm.act("BURST-REQ", cs.eq(1), source.valid.eq(1), source.last.eq(1), source.width.eq(flash.bus_width), source.len.eq(data_bits), source.mask.eq(0), If( source.ready, NextState("BURST-DAT"), )) fsm.act( "BURST-DAT", cs.eq(1), sink.ready.eq(1), bus.dat_r.eq({ "big": sink.data, "little": reverse_bytes(sink.data) }[endianness]), If( sink.valid, bus.ack.eq(1), NextValue(burst_adr, burst_adr + 1), NextState("IDLE"), ))