1
0
mirror of synced 2026-03-10 04:11:01 +00:00

(optional) checksumming in SDRAM DMA, change clocking on Engine, ...

This commit is contained in:
Romain Dolbeau
2021-08-21 02:15:43 -04:00
parent d8914159b1
commit 67ad40c65e
4 changed files with 323 additions and 108 deletions

View File

@@ -1,5 +1,5 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (3ffd64c) & LiteX (8a644c90) on 2021-07-25 05:25:02
// Auto-generated by Migen (3ffd64c) & LiteX (8a644c90) on 2021-08-20 12:28:27
//--------------------------------------------------------------------------------
#ifndef __GENERATED_CSR_H
#define __GENERATED_CSR_H
@@ -592,6 +592,63 @@ static inline uint32_t exchange_with_mem_blk_cnt_read(struct sbusfpga_exchange_w
static inline void exchange_with_mem_blk_cnt_write(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x14L, v);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_BLK_CNT_OFFSET 0
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_BLK_CNT_SIZE 16
static inline uint32_t exchange_with_mem_blk_cnt_blk_cnt_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 16)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t exchange_with_mem_blk_cnt_blk_cnt_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_blk_cnt_read(sc);
return exchange_with_mem_blk_cnt_blk_cnt_extract(sc, word);
}
static inline uint32_t exchange_with_mem_blk_cnt_blk_cnt_replace(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 16)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void exchange_with_mem_blk_cnt_blk_cnt_write(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t plain_value) {
uint32_t oldword = exchange_with_mem_blk_cnt_read(sc);
uint32_t newword = exchange_with_mem_blk_cnt_blk_cnt_replace(sc, oldword, plain_value);
exchange_with_mem_blk_cnt_write(sc, newword);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_RSVD_OFFSET 16
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_RSVD_SIZE 15
static inline uint32_t exchange_with_mem_blk_cnt_rsvd_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 15)-1);
return ( (oldword >> 16) & mask );
}
static inline uint32_t exchange_with_mem_blk_cnt_rsvd_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_blk_cnt_read(sc);
return exchange_with_mem_blk_cnt_rsvd_extract(sc, word);
}
static inline uint32_t exchange_with_mem_blk_cnt_rsvd_replace(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 15)-1);
return (oldword & (~(mask << 16))) | (mask & plain_value)<< 16 ;
}
static inline void exchange_with_mem_blk_cnt_rsvd_write(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t plain_value) {
uint32_t oldword = exchange_with_mem_blk_cnt_read(sc);
uint32_t newword = exchange_with_mem_blk_cnt_rsvd_replace(sc, oldword, plain_value);
exchange_with_mem_blk_cnt_write(sc, newword);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_RD_WR_OFFSET 31
#define CSR_EXCHANGE_WITH_MEM_BLK_CNT_RD_WR_SIZE 1
static inline uint32_t exchange_with_mem_blk_cnt_rd_wr_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 31) & mask );
}
static inline uint32_t exchange_with_mem_blk_cnt_rd_wr_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_blk_cnt_read(sc);
return exchange_with_mem_blk_cnt_rd_wr_extract(sc, word);
}
static inline uint32_t exchange_with_mem_blk_cnt_rd_wr_replace(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 31))) | (mask & plain_value)<< 31 ;
}
static inline void exchange_with_mem_blk_cnt_rd_wr_write(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t plain_value) {
uint32_t oldword = exchange_with_mem_blk_cnt_read(sc);
uint32_t newword = exchange_with_mem_blk_cnt_rd_wr_replace(sc, oldword, plain_value);
exchange_with_mem_blk_cnt_write(sc, newword);
}
#define CSR_EXCHANGE_WITH_MEM_LAST_BLK_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x18L)
#define CSR_EXCHANGE_WITH_MEM_LAST_BLK_SIZE 1
static inline uint32_t exchange_with_mem_last_blk_read(struct sbusfpga_exchange_with_mem_softc *sc) {
@@ -602,21 +659,83 @@ static inline uint32_t exchange_with_mem_last_blk_read(struct sbusfpga_exchange_
static inline uint32_t exchange_with_mem_last_dma_read(struct sbusfpga_exchange_with_mem_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x1cL);
}
#define CSR_EXCHANGE_WITH_MEM_BLK_REM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x20L)
#define CSR_EXCHANGE_WITH_MEM_BLK_REM_SIZE 1
static inline uint32_t exchange_with_mem_blk_rem_read(struct sbusfpga_exchange_with_mem_softc *sc) {
#define CSR_EXCHANGE_WITH_MEM_DMA_WRDONE_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x20L)
#define CSR_EXCHANGE_WITH_MEM_DMA_WRDONE_SIZE 1
static inline uint32_t exchange_with_mem_dma_wrdone_read(struct sbusfpga_exchange_with_mem_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x20L);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x24L)
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_read(struct sbusfpga_exchange_with_mem_softc *sc) {
#define CSR_EXCHANGE_WITH_MEM_BLK_REM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x24L)
#define CSR_EXCHANGE_WITH_MEM_BLK_REM_SIZE 1
static inline uint32_t exchange_with_mem_blk_rem_read(struct sbusfpga_exchange_with_mem_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x24L);
}
#define CSR_EXCHANGE_WITH_MEM_WR_TOSDRAM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x28L)
#define CSR_EXCHANGE_WITH_MEM_WR_TOSDRAM_SIZE 1
static inline uint32_t exchange_with_mem_wr_tosdram_read(struct sbusfpga_exchange_with_mem_softc *sc) {
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x28L)
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_read(struct sbusfpga_exchange_with_mem_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x28L);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_RD_FSM_BUSY_OFFSET 0
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_RD_FSM_BUSY_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_rd_fsm_busy_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t exchange_with_mem_dma_status_rd_fsm_busy_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_dma_status_read(sc);
return exchange_with_mem_dma_status_rd_fsm_busy_extract(sc, word);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_WR_FSM_BUSY_OFFSET 1
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_WR_FSM_BUSY_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_wr_fsm_busy_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t exchange_with_mem_dma_status_wr_fsm_busy_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_dma_status_read(sc);
return exchange_with_mem_dma_status_wr_fsm_busy_extract(sc, word);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_HAS_WR_DATA_OFFSET 2
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_HAS_WR_DATA_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_has_wr_data_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 2) & mask );
}
static inline uint32_t exchange_with_mem_dma_status_has_wr_data_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_dma_status_read(sc);
return exchange_with_mem_dma_status_has_wr_data_extract(sc, word);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_HAS_REQUESTS_OFFSET 3
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_HAS_REQUESTS_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_has_requests_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 3) & mask );
}
static inline uint32_t exchange_with_mem_dma_status_has_requests_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_dma_status_read(sc);
return exchange_with_mem_dma_status_has_requests_extract(sc, word);
}
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_HAS_RD_DATA_OFFSET 4
#define CSR_EXCHANGE_WITH_MEM_DMA_STATUS_HAS_RD_DATA_SIZE 1
static inline uint32_t exchange_with_mem_dma_status_has_rd_data_extract(struct sbusfpga_exchange_with_mem_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 4) & mask );
}
static inline uint32_t exchange_with_mem_dma_status_has_rd_data_read(struct sbusfpga_exchange_with_mem_softc *sc) {
uint32_t word = exchange_with_mem_dma_status_read(sc);
return exchange_with_mem_dma_status_has_rd_data_extract(sc, word);
}
#define CSR_EXCHANGE_WITH_MEM_WR_TOSDRAM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x2cL)
#define CSR_EXCHANGE_WITH_MEM_WR_TOSDRAM_SIZE 1
static inline uint32_t exchange_with_mem_wr_tosdram_read(struct sbusfpga_exchange_with_mem_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x2cL);
}
#define CSR_EXCHANGE_WITH_MEM_SBUS_MASTER_ERROR_VIRTUAL_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x30L)
#define CSR_EXCHANGE_WITH_MEM_SBUS_MASTER_ERROR_VIRTUAL_SIZE 1
static inline uint32_t exchange_with_mem_sbus_master_error_virtual_read(struct sbusfpga_exchange_with_mem_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 0x30L);
}
#define CSR_EXCHANGE_WITH_MEM_CHECKSUM_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x34L)
#define CSR_EXCHANGE_WITH_MEM_CHECKSUM_SIZE 8
#endif // CSR_EXCHANGE_WITH_MEM_BASE
/* sdram */

View File

@@ -10,7 +10,7 @@ from litex.soc.interconnect import wishbone
# width of fromsbus_fifo is 'blk_addr_width' + 'burst_size * 32' (blk_addr + data)
# the blk_addr does the round-trip to accompany the data
class ExchangeWithMem(Module, AutoCSR):
def __init__(self, soc, tosbus_fifo, fromsbus_fifo, fromsbus_req_fifo, dram_dma_writer, dram_dma_reader, burst_size = 8):
def __init__(self, soc, tosbus_fifo, fromsbus_fifo, fromsbus_req_fifo, dram_dma_writer, dram_dma_reader, burst_size = 8, do_checksum = False):
#self.wishbone_r_slave = wishbone.Interface(data_width=soc.bus.data_width)
#self.wishbone_w_slave = wishbone.Interface(data_width=soc.bus.data_width)
self.tosbus_fifo = tosbus_fifo
@@ -61,34 +61,59 @@ class ExchangeWithMem(Module, AutoCSR):
self.blk_addr = CSRStorage(32, description = "SDRAM Block address to read/write from Wishbone memory (block of size {})".format(data_width))
self.dma_addr = CSRStorage(32, description = "Host Base address where to write/read data (i.e. SPARC Virtual addr)")
self.blk_cnt = CSRStorage(32, write_from_dev=True, description = "How many blk to read/write (max 2^{}-1); bit 31 is RD".format(max_block_bits), reset = 0)
#self.blk_cnt = CSRStorage(32, write_from_dev=True, description = "How many blk to read/write (max 2^{}-1); bit 31 is RD".format(max_block_bits), reset = 0)
self.blk_cnt = CSRStorage(write_from_dev=True, fields = [CSRField("blk_cnt", max_block_bits, description = "How many blk to read/write (max 2^{}-1)".format(max_block_bits)),
CSRField("rsvd", 32 - (max_block_bits + 1), description = "Reserved"),
CSRField("rd_wr", 1, description = "Read/Write selector"),
])
self.last_blk = CSRStatus(32, description = "Last Blk addr finished on WB side")
self.last_dma = CSRStatus(32, description = "Last DMA addr finished on WB side")
self.dma_wrdone = CSRStatus(32, description = "DMA Block written to SDRAM", reset = 0)
self.blk_rem = CSRStatus(32, description = "How many block remaining; bit 31 is RD", reset = 0)
self.dma_status = CSRStatus(32, description = "Status register")
self.dma_status = CSRStatus(fields = [CSRField("rd_fsm_busy", 1, description = "Read FSM is doing some work"),
CSRField("wr_fsm_busy", 1, description = "Write FSM is doing some work"),
CSRField("has_wr_data", 1, description = "Data available to write to SDRAM"),
CSRField("has_requests", 1, description = "There's outstanding requests to the SBus"),
CSRField("has_rd_data", 1, description = "Data available to write to SBus"),
])
self.wr_tosdram = CSRStatus(32, description = "Last address written to SDRAM")
self.sbus_master_error_virtual = CSRStatus(32, description = "Virtual address that failed translation phase")
if (do_checksum):
self.checksum = CSRStorage(data_width_bits, write_from_dev=True, description = "checksum (XOR)");
self.submodules.req_r_fsm = req_r_fsm = FSM(reset_state="Reset")
self.submodules.req_w_fsm = req_w_fsm = FSM(reset_state="Reset")
# this could use CSRFields...
self.comb += self.dma_status.status[0:1].eq(~req_r_fsm.ongoing("Idle")) # Read FSM Busy
self.comb += self.dma_status.status[1:2].eq(~req_w_fsm.ongoing("Idle")) # Write FSM Busy
self.comb += self.dma_status.status[2:3].eq(self.fromsbus_fifo.readable) # Some data available to write to memory
self.comb += self.dma_status.fields.rd_fsm_busy.eq(~req_r_fsm.ongoing("Idle")) # Read FSM Busy
self.comb += self.dma_status.fields.wr_fsm_busy.eq(~req_w_fsm.ongoing("Idle")) # Write FSM Busy
self.comb += self.dma_status.fields.has_wr_data.eq(self.fromsbus_fifo.readable) # Some data available to write to memory
# The next two status bits reflect stats in the SBus clock domain
self.submodules.fromsbus_req_fifo_readable_sync = PulseSynchronizer("sbus", "sys")
fromsbus_req_fifo_readable_in_sys = Signal()
self.comb += self.fromsbus_req_fifo_readable_sync.i.eq(self.fromsbus_req_fifo.readable)
self.comb += fromsbus_req_fifo_readable_in_sys.eq(self.fromsbus_req_fifo_readable_sync.o)
self.comb += self.dma_status.status[3:4].eq(fromsbus_req_fifo_readable_in_sys) # we still have outstanding requests
# w/o this extra delay, the driver sees an outdated checksum for some reason...
# there's probably a more fundamental issue :-(
fromsbus_req_fifo_readable_in_sys_cnt = Signal(5)
self.sync += If(fromsbus_req_fifo_readable_in_sys,
fromsbus_req_fifo_readable_in_sys_cnt.eq(0x1F)
).Else(
If(fromsbus_req_fifo_readable_in_sys_cnt > 0,
fromsbus_req_fifo_readable_in_sys_cnt.eq(fromsbus_req_fifo_readable_in_sys_cnt - 1)
)
)
#self.comb += self.dma_status.fields.has_requests.eq(fromsbus_req_fifo_readable_in_sys) # we still have outstanding requests
self.comb += self.dma_status.fields.has_requests.eq(fromsbus_req_fifo_readable_in_sys | (fromsbus_req_fifo_readable_in_sys_cnt != 0)) # we still have outstanding requests, or had recently
self.submodules.tosbus_fifo_readable_sync = PulseSynchronizer("sbus", "sys")
tosbus_fifo_readable_in_sys = Signal()
self.comb += self.tosbus_fifo_readable_sync.i.eq(self.tosbus_fifo.readable)
self.comb += tosbus_fifo_readable_in_sys.eq(self.tosbus_fifo_readable_sync.o)
self.comb += self.dma_status.status[4:5].eq(tosbus_fifo_readable_in_sys) # there's still data to be sent to memory; this will drop before the last SBus Master Cycle is finished, but then the SBus is busy so the host won't be able to read the status before the cycle is finished so we're good
self.comb += self.dma_status.status[8:9].eq(req_r_fsm.ongoing("ReqFromMemory"))
self.comb += self.dma_status.status[9:10].eq(req_r_fsm.ongoing("WaitForData"))
self.comb += self.dma_status.status[10:11].eq(req_r_fsm.ongoing("QueueReqToMemory"))
self.comb += self.dma_status.fields.has_rd_data.eq(tosbus_fifo_readable_in_sys) # there's still data to be sent to memory; this will drop before the last SBus Master Cycle is finished, but then the SBus is busy so the host won't be able to read the status before the cycle is finished so we're good
#self.comb += self.dma_status.status[16:17].eq(self.wishbone_w_master.cyc) # show the WB iface status (W)
#self.comb += self.dma_status.status[17:18].eq(self.wishbone_w_master.stb)
@@ -106,17 +131,17 @@ class ExchangeWithMem(Module, AutoCSR):
NextState("Idle")
)
req_r_fsm.act("Idle",
If(((self.blk_cnt.storage[0:max_block_bits] != 0) & # checking self.blk_cnt.re might be too transient ? -> need to auto-reset
(~self.blk_cnt.storage[31:32])), # !read -> write
If(((self.blk_cnt.fields.blk_cnt != 0) & # checking self.blk_cnt.re might be too transient ? -> need to auto-reset
(~self.blk_cnt.fields.rd_wr)), # !read -> write
NextValue(local_r_addr, self.blk_addr.storage),
NextValue(dma_r_addr, self.dma_addr.storage),
NextValue(self.blk_rem.status, Cat(self.blk_cnt.storage[0:max_block_bits], Signal(32-max_block_bits, reset = 0))),
NextValue(self.blk_rem.status, Cat(self.blk_cnt.fields.blk_cnt, Signal(32-max_block_bits, reset = 0))),
NextState("ReqFromMemory")
).Elif(((self.blk_cnt.storage[0:max_block_bits] != 0) & # checking self.blk_cnt.re might be too transient ? -> need to auto-reset
(self.blk_cnt.storage[31:32])), # read
).Elif(((self.blk_cnt.fields.blk_cnt != 0) & # checking self.blk_cnt.re might be too transient ? -> need to auto-reset
(self.blk_cnt.fields.rd_wr)), # read
NextValue(local_r_addr, self.blk_addr.storage),
NextValue(dma_r_addr, self.dma_addr.storage),
NextValue(self.blk_rem.status, Cat(self.blk_cnt.storage[0:max_block_bits], Signal(32-max_block_bits, reset = 0))),
NextValue(self.blk_rem.status, Cat(self.blk_cnt.fields.blk_cnt, Signal(32-max_block_bits, reset = 0))),
NextState("QueueReqToMemory")
)
)
@@ -128,10 +153,13 @@ class ExchangeWithMem(Module, AutoCSR):
)
)
req_r_fsm.act("WaitForData",
If(self.dram_dma_reader.source.valid &
self.tosbus_fifo.writable,
If(self.dram_dma_reader.source.valid & self.tosbus_fifo.writable,
self.tosbus_fifo.we.eq(1),
self.tosbus_fifo.din.eq(Cat(dma_r_addr, self.dram_dma_reader.source.data)),
If(do_checksum,
self.checksum.we.eq(1),
self.checksum.dat_w.eq(self.checksum.storage ^ self.dram_dma_reader.source.data),
),
self.dram_dma_reader.source.ready.eq(1),
NextValue(self.last_blk.status, local_r_addr),
NextValue(self.last_dma.status, dma_r_addr),
@@ -203,7 +231,12 @@ class ExchangeWithMem(Module, AutoCSR):
self.dram_dma_writer.sink.valid.eq(1),
NextValue(self.wr_tosdram.status, self.fromsbus_fifo.dout[0:blk_addr_width]),
If(self.dram_dma_writer.sink.ready,
self.fromsbus_fifo.re.eq(1)
self.fromsbus_fifo.re.eq(1),
NextValue(self.dma_wrdone.status, self.dma_wrdone.status + 1),
If(do_checksum,
self.checksum.we.eq(1),
self.checksum.dat_w.eq(self.checksum.storage ^ self.fromsbus_fifo.dout[blk_addr_width:(blk_addr_width + data_width_bits)]),
)
)
)
)

View File

@@ -274,15 +274,16 @@ class SBusFPGABus(Module):
SBUS_3V3_PA_i = Signal(28)
self.comb += SBUS_3V3_PA_i.eq(pad_SBUS_3V3_PA)
p_data = Signal(32) # data to read/write
data_read_addr = Signal(30) # first addr of req. when reading from WB
data_read_enable = Signal() # start enqueuing req. to read from WB
p_data = Signal(32) # data to read/write in Slave mode
# buffers when someone inside issues a DMA write request to go over SBus
master_data = Signal(32) # could be merged with p_data
master_data_src_tosbus_fifo = Signal()
master_data_src_fromsbus_fifo = Signal()
master_addr = Signal(30) # could be meged with data_read_addr
# FIXME, ugly
# we're handling a request from the FIFO (not wishbone) - write to host
master_data_src_tosbus_fifo = Signal()
# we're handling a request from the FIFO (not wishbone) - read from host
master_data_src_fromsbus_fifo = Signal()
master_size = Signal(4)
master_idx = Signal(2)
@@ -298,10 +299,10 @@ class SBusFPGABus(Module):
#self.submodules.led_display = LedDisplay(platform.request_all("user_led"))
self.sync += platform.request("user_led", 4).eq(self.wishbone_slave.cyc)
self.sync += platform.request("user_led", 5).eq(self.wishbone_slave.stb)
self.sync += platform.request("user_led", 6).eq(self.wishbone_slave.we)
self.sync += platform.request("user_led", 7).eq(self.wishbone_slave.ack)
#self.sync += platform.request("user_led", 4).eq(self.wishbone_slave.cyc)
#self.sync += platform.request("user_led", 5).eq(self.wishbone_slave.stb)
#self.sync += platform.request("user_led", 6).eq(self.wishbone_slave.we)
#self.sync += platform.request("user_led", 7).eq(self.wishbone_slave.ack)
#self.sync += platform.request("user_led", 0).eq(self.wishbone_slave.err)
#led4 = platform.request("user_led", 4)
#led5 = platform.request("user_led", 5)
@@ -342,11 +343,12 @@ class SBusFPGABus(Module):
# platform.request("user_led", 2).eq(cycle_busmaster[6]),
# platform.request("user_led", 3).eq(cycle_busmaster[7]))
# Read buffering when a DMA read request is issued by Wishbone
self.master_read_buffer_data = Array(Signal(32) for a in range(4))
self.master_read_buffer_addr = Signal(28)
self.master_read_buffer_done = Array(Signal() for a in range(4))
self.master_read_buffer_read = Array(Signal() for a in range(4))
self.master_read_buffer_start = Signal()
self.master_read_buffer_start = Signal(reset = 0)
#self.sync += platform.request("user_led", 1).eq(self.master_read_buffer_start)
@@ -363,23 +365,37 @@ class SBusFPGABus(Module):
# slave_fsm.ongoing("Master_Read_Finish") |
# slave_fsm.ongoing("Master_Write") |
# slave_fsm.ongoing("Master_Write_Final"))
self.sync += platform.request("user_led", 2).eq(slave_fsm.ongoing("Slave_Do_Read") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_Burst") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_Burst_Wait_For_Data") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_Burst_Wait_For_Wishbone") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_HWord") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_HWord_Wait_For_Data") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_HWord_Wait_For_Wishbone") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_Byte") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_Byte_Wait_For_Data") |
slave_fsm.ongoing("Slave_Ack_Read_Reg_Byte_Wait_For_Wishbone"))
self.sync += platform.request("user_led", 3).eq(slave_fsm.ongoing("Slave_Ack_Reg_Write_Burst") |
slave_fsm.ongoing("Slave_Ack_Reg_Write_Final") |
slave_fsm.ongoing("Slave_Ack_Reg_Write_Burst_Wait_For_Wishbone") |
slave_fsm.ongoing("Slave_Ack_Reg_Write_HWord") |
slave_fsm.ongoing("Slave_Ack_Reg_Write_HWord_Wait_For_Wishbone") |
slave_fsm.ongoing("Slave_Ack_Reg_Write_Byte") |
slave_fsm.ongoing("Slave_Ack_Reg_Write_Byte_Wait_For_Wishbone"))
#self.sync += platform.request("user_led", 2).eq(slave_fsm.ongoing("Slave_Do_Read") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_Burst") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_Burst_Wait_For_Data") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_Burst_Wait_For_Wishbone") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_HWord") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_HWord_Wait_For_Data") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_HWord_Wait_For_Wishbone") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_Byte") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_Byte_Wait_For_Data") |
# slave_fsm.ongoing("Slave_Ack_Read_Reg_Byte_Wait_For_Wishbone"))
#self.sync += platform.request("user_led", 3).eq(slave_fsm.ongoing("Slave_Ack_Reg_Write_Burst") |
# slave_fsm.ongoing("Slave_Ack_Reg_Write_Final") |
# slave_fsm.ongoing("Slave_Ack_Reg_Write_Burst_Wait_For_Wishbone") |
# slave_fsm.ongoing("Slave_Ack_Reg_Write_HWord") |
# slave_fsm.ongoing("Slave_Ack_Reg_Write_HWord_Wait_For_Wishbone") |
# slave_fsm.ongoing("Slave_Ack_Reg_Write_Byte") |
# slave_fsm.ongoing("Slave_Ack_Reg_Write_Byte_Wait_For_Wishbone"))
master_error_seen = Signal(4, reset = 0)
self.sync += platform.request("user_led", 0).eq(master_error_seen[0:1])
self.sync += platform.request("user_led", 1).eq(master_error_seen[1:2])
self.sync += platform.request("user_led", 2).eq(master_error_seen[2:3])
self.sync += platform.request("user_led", 3).eq(master_error_seen[3:4])
master_error_details = Signal(4, reset = 0)
self.sync += platform.request("user_led", 4).eq(master_error_details[0:1])
self.sync += platform.request("user_led", 5).eq(master_error_details[1:2])
self.sync += platform.request("user_led", 6).eq(master_error_details[2:3])
self.sync += platform.request("user_led", 7).eq(master_error_details[3:4])
self.sbus_master_last_virtual = Signal(32) # last VDMA address put on the bus in master mode
self.sbus_master_error_virtual = Signal(32) # this gets exported to a Wishbone CSR in exchange_with_mem
#self.sync += platform.request("user_led", 5).eq(~slave_fsm.ongoing("Idle"))
#self.sync += platform.request("user_led", 6).eq(master_data_src_tosbus_fifo)
@@ -665,40 +681,47 @@ class SBusFPGABus(Module):
self.wishbone_slave.dat_w[ 0: 8])),
Case(self.wishbone_slave.sel, {
0xf: [NextValue(burst_counter, 0),
NextValue(burst_limit_m1, 0), ## only single word for now
NextValue(master_size, SIZ_WORD),
NextValue(SBUS_3V3_SIZ_o, SIZ_WORD),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
NextValue(burst_limit_m1, 0), ## only single word for now
NextValue(master_size, SIZ_WORD),
NextValue(SBUS_3V3_SIZ_o, SIZ_WORD),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
],
0x1: [NextValue(master_idx, 3),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
],
0x2: [NextValue(master_idx, 2),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 1), self.wishbone_slave.adr)),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 1), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 1), self.wishbone_slave.adr)),
],
0x4: [NextValue(master_idx, 1),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 2), self.wishbone_slave.adr)),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 2), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 2), self.wishbone_slave.adr)),
],
0x8: [NextValue(master_idx, 0),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 3), self.wishbone_slave.adr)),
NextValue(master_size, SIZ_BYTE),
NextValue(SBUS_3V3_SIZ_o, SIZ_BYTE),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 3), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 3), self.wishbone_slave.adr)),
],
0x3: [NextValue(master_idx, 2),
NextValue(master_size, SIZ_HWORD),
NextValue(SBUS_3V3_SIZ_o, SIZ_HWORD),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
NextValue(master_size, SIZ_HWORD),
NextValue(SBUS_3V3_SIZ_o, SIZ_HWORD),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 0), self.wishbone_slave.adr)),
],
0xc: [NextValue(master_idx, 0),
NextValue(master_size, SIZ_HWORD),
NextValue(SBUS_3V3_SIZ_o, SIZ_HWORD),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 2), self.wishbone_slave.adr)),
NextValue(master_size, SIZ_HWORD),
NextValue(SBUS_3V3_SIZ_o, SIZ_HWORD),
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 2), self.wishbone_slave.adr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(2, reset = 2), self.wishbone_slave.adr)),
],
"default":[NextValue(burst_counter, 0), # FIXME if it happens!
NextValue(burst_limit_m1, 0), ## only single word for now
@@ -730,6 +753,7 @@ class SBusFPGABus(Module):
NextValue(burst_counter, 0),
NextValue(burst_limit_m1, 3), ## only quadword word for now
NextValue(SBUS_3V3_D_o, Cat(Signal(4, reset = 0), self.master_read_buffer_addr)),
NextValue(self.sbus_master_last_virtual, Cat(Signal(4, reset = 0), self.master_read_buffer_addr)),
NextValue(SBUS_3V3_PPRD_o, 1),
NextValue(SBUS_3V3_SIZ_o, SIZ_BURST4),
NextValue(master_we, 0),
@@ -750,6 +774,7 @@ class SBusFPGABus(Module):
NextValue(burst_counter, 0),
NextValue(burst_limit_m1, burst_size - 1),
NextValue(SBUS_3V3_D_o, self.tosbus_fifo.dout[0:32]),
NextValue(self.sbus_master_last_virtual, self.tosbus_fifo.dout[0:32]),
NextValue(master_addr, self.tosbus_fifo.dout[2:32]),
NextValue(master_data, self.tosbus_fifo.dout[32:64]),
NextValue(fifo_buffer, self.tosbus_fifo.dout[32:]),
@@ -784,6 +809,7 @@ class SBusFPGABus(Module):
NextValue(burst_counter, 0),
NextValue(burst_limit_m1, burst_size - 1),
NextValue(SBUS_3V3_D_o, self.fromsbus_req_fifo.dout[blk_addr_width:blk_addr_width+32]),
NextValue(self.sbus_master_last_virtual, self.fromsbus_req_fifo.dout[blk_addr_width:blk_addr_width+32]),
NextValue(fifo_blk_addr, self.fromsbus_req_fifo.dout[0:blk_addr_width]),
NextValue(master_data_src_fromsbus_fifo, 1),
self.fromsbus_req_fifo.re.eq(1),
@@ -1199,15 +1225,20 @@ class SBusFPGABus(Module):
),
Case(SBUS_3V3_ACKs_i, {
ACK_ERR: ## ouch
[NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
[If(~master_data_src_tosbus_fifo & ~master_data_src_fromsbus_fifo,
NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
),
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextValue(master_error_seen, 1),
NextState("Idle")],
ACK_RERUN: ### dunno how to handle that yet,
[NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
[If(~master_data_src_tosbus_fifo & ~master_data_src_fromsbus_fifo,
NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
),
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
@@ -1240,19 +1271,38 @@ class SBusFPGABus(Module):
[NextState("Master_Read") ## redundant
],
ACK_RERUN: ### burst not handled
[NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
[If(~master_data_src_tosbus_fifo & ~master_data_src_fromsbus_fifo,
NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
),
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextState("Idle")
],
"default": ## ACK_ERRS or other ### burst not handled
[NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
ACK_ERR: ## ### burst not handled
[If(~master_data_src_tosbus_fifo & ~master_data_src_fromsbus_fifo,
NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
),
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextValue(master_error_seen, 8),
NextValue(master_error_details, burst_counter),
NextValue(self.sbus_master_error_virtual, self.sbus_master_last_virtual),
NextState("Idle")
],
"default": ## other ### burst not handled
[If(~master_data_src_tosbus_fifo & ~master_data_src_fromsbus_fifo,
NextValue(wishbone_slave_timeout, wishbone_default_timeout),
NextValue(self.wishbone_slave.err, 1),
),
NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextValue(master_error_seen, 4),
NextValue(master_error_details, Cat(SBUS_3V3_ACKs_i, Signal(1, reset = 0))),
NextState("Idle")
],
})
@@ -1302,6 +1352,7 @@ class SBusFPGABus(Module):
[NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextValue(master_error_seen, 1),
NextState("Idle")
],
}),
@@ -1372,7 +1423,8 @@ class SBusFPGABus(Module):
[NextValue(sbus_oe_data, 0),
NextValue(sbus_oe_slave_in, 0),
NextValue(sbus_oe_master_in, 0),
NextState("Idle")
NextValue(master_error_seen, 1),
NextState("Idle"),
],
})
)
@@ -1463,8 +1515,8 @@ class SBusFPGABus(Module):
# ##### Slave read buffering FSM ####
last_read_word_idx = Signal(2)
self.submodules.wishbone_slave_read_buffering_fsm = wishbone_slave_read_buffering_fsm = FSM(reset_state="Reset")
self.sync += platform.request("user_led", 0).eq(~wishbone_slave_read_buffering_fsm.ongoing("Idle"))
self.sync += platform.request("user_led", 1).eq(self.master_read_buffer_done[last_read_word_idx])
#self.sync += platform.request("user_led", 0).eq(~wishbone_slave_read_buffering_fsm.ongoing("Idle"))
#self.sync += platform.request("user_led", 1).eq(self.master_read_buffer_done[last_read_word_idx])
wishbone_slave_read_buffering_fsm.act("Reset",
NextState("Idle")
)

View File

@@ -23,6 +23,7 @@ from sbus_to_fpga_trng import *
from litedram.frontend.dma import *
from engine import Engine;
from migen.genlib.cdc import PulseSynchronizer, BusSynchronizer
from migen.genlib.resetsync import AsyncResetSynchronizer;
import sbus_to_fpga_export;
@@ -40,9 +41,10 @@ class _CRG(Module):
self.clock_domains.cd_sbus = ClockDomain() # 16.67-25 MHz SBus, reset'ed by SBus, native SBus clock domain
# self.clock_domains.cd_por = ClockDomain() # 48 MHz native, reset'ed by SBus, power-on-reset timer
self.clock_domains.cd_usb = ClockDomain() # 48 MHZ PLL, reset'ed by SBus (via pll), for USB controller
self.clock_domains.cd_clk50 = ClockDomain() # 50 MHz for curve25519engine -> eng_clk
self.clock_domains.cd_clk100 = ClockDomain() # 100 MHz for curve25519engine -> mul_clk
self.clock_domains.cd_clk200 = ClockDomain() # 200 MHz for curve25519engine -> rf_clk
self.clock_domains.cd_clk50 = ClockDomain() # 50 MHz (gated) for curve25519engine -> eng_clk
self.clock_domains.cd_clk100 = ClockDomain() # 100 MHz for curve25519engine -> sys_clk
self.clock_domains.cd_clk100_gated = ClockDomain() # 100 MHz (gated) for curve25519engine -> mul_clk
self.clock_domains.cd_clk200 = ClockDomain() # 200 MHz (gated) for curve25519engine -> rf_clk
# # #
clk48 = platform.request("clk48")
@@ -76,21 +78,22 @@ class _CRG(Module):
platform.add_platform_command("create_generated_clock -name sys4x90clk [get_pins {{MMCME2_ADV/CLKOUT2}}]")
self.comb += pll.reset.eq(~rst_sbus) # | ~por_done
platform.add_false_path_constraints(self.cd_native.clk, self.cd_sbus.clk)
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_sbus.clk)
platform.add_false_path_constraints(self.cd_sbus.clk, self.cd_native.clk)
platform.add_false_path_constraints(self.cd_sbus.clk, self.cd_sys.clk)
#platform.add_false_path_constraints(self.cd_sys.clk, self.cd_sbus.clk)
#platform.add_false_path_constraints(self.cd_sbus.clk, self.cd_sys.clk)
##platform.add_false_path_constraints(self.cd_native.clk, self.cd_sys.clk)
self.submodules.curve25519_pll = curve25519_pll = S7MMCM(speedgrade=-1)
curve25519_clk_freq = 80e6
self.curve25519_on = Signal()
#curve25519_pll.register_clkin(clk48, 48e6)
curve25519_pll.register_clkin(self.clk48_bufg, 48e6)
curve25519_pll.create_clkout(self.cd_clk50, curve25519_clk_freq/2, margin=0)
curve25519_pll.create_clkout(self.cd_clk50, curve25519_clk_freq/2, margin=0, ce=curve25519_pll.locked & self.curve25519_on)
platform.add_platform_command("create_generated_clock -name clk50 [get_pins {{MMCME2_ADV_1/CLKOUT0}}]")
curve25519_pll.create_clkout(self.cd_clk100, curve25519_clk_freq, margin=0)
curve25519_pll.create_clkout(self.cd_clk100, curve25519_clk_freq, margin=0, ce=curve25519_pll.locked,
gated_replicas={self.cd_clk100_gated : curve25519_pll.locked & self.curve25519_on})
platform.add_platform_command("create_generated_clock -name clk100 [get_pins {{MMCME2_ADV_1/CLKOUT1}}]")
curve25519_pll.create_clkout(self.cd_clk200, curve25519_clk_freq*2, margin=0)
curve25519_pll.create_clkout(self.cd_clk200, curve25519_clk_freq*2, margin=0, ce=curve25519_pll.locked & self.curve25519_on)
platform.add_platform_command("create_generated_clock -name clk200 [get_pins {{MMCME2_ADV_1/CLKOUT2}}]")
#self.comb += curve25519_pll.reset.eq(~rst_sbus) # | ~por_done
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_clk50.clk)
@@ -234,9 +237,9 @@ class SBusFPGA(SoCCore):
# burst_size=16 should work on Ultra systems, but then they probably should go for 64-bits ET as well...
# Older systems are probably limited to burst_size=4, (it should always be available)
burst_size=8
self.submodules.tosbus_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=(32+burst_size*32), depth=4))
self.submodules.fromsbus_fifo = ClockDomainsRenamer({"write": "sbus", "read": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+burst_size*32), depth=4))
self.submodules.fromsbus_req_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+32), depth=16))
self.submodules.tosbus_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=(32+burst_size*32), depth=burst_size))
self.submodules.fromsbus_fifo = ClockDomainsRenamer({"write": "sbus", "read": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+burst_size*32), depth=burst_size))
self.submodules.fromsbus_req_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+32), depth=burst_size))
self.submodules.dram_dma_writer = LiteDRAMDMAWriter(port=self.sdram.crossbar.get_port(mode="write", data_width=burst_size*32),
fifo_depth=4,
@@ -252,7 +255,8 @@ class SBusFPGA(SoCCore):
fromsbus_req_fifo=self.fromsbus_req_fifo,
dram_dma_writer=self.dram_dma_writer,
dram_dma_reader=self.dram_dma_reader,
burst_size=burst_size)
burst_size=burst_size,
do_checksum = True)
_sbus_bus = SBusFPGABus(platform=self.platform,
hold_reset=hold_reset,
@@ -269,6 +273,10 @@ class SBusFPGA(SoCCore):
self.bus.add_slave(name="usb_fake_dma", slave=self.wishbone_slave_sys, region=SoCRegion(origin=self.mem_map.get("usb_fake_dma", None), size=0x03ffffff, cached=False))
#self.bus.add_master(name="mem_read_master", master=self.exchange_with_mem.wishbone_r_slave)
#self.bus.add_master(name="mem_write_master", master=self.exchange_with_mem.wishbone_w_slave)
self.submodules.sbus_master_error_virtual_sync = BusSynchronizer(width=32, idomain="sbus", odomain="sys")
self.comb += self.sbus_master_error_virtual_sync.i.eq(self.sbus_bus.sbus_master_error_virtual)
self.comb += self.exchange_with_mem.sbus_master_error_virtual.status.eq(self.sbus_master_error_virtual_sync.o)
#self.add_sdcard()
@@ -277,10 +285,13 @@ class SBusFPGA(SoCCore):
# beware the naming, as 'clk50' 'sysclk' 'clk200' are used in the original platform constraints
# the local engine.py was slightly modified to have configurable names, so we can have 'clk50', 'clk100', 'clk200'
# Beware that Engine implicitely runs in 'sys' by default, need to rename that one as well
self.submodules.curve25519engine = ClockDomainsRenamer({"eng_clk":"clk50", "rf_clk":"clk200", "mul_clk":"clk100", "sys":"clk100"})(Engine(platform=platform,prefix=self.mem_map.get("curve25519engine", None)))
self.submodules.curve25519engine = ClockDomainsRenamer({"eng_clk":"clk50", "rf_clk":"clk200", "mul_clk":"clk100_gated", "sys":"clk100"})(Engine(platform=platform,prefix=self.mem_map.get("curve25519engine", None)))
self.submodules.curve25519engine_wishbone_cdc = wishbone.WishboneDomainCrossingMaster(platform=self.platform, slave=self.curve25519engine.bus, cd_master="sys", cd_slave="clk100")
self.bus.add_slave("curve25519engine", self.curve25519engine_wishbone_cdc, SoCRegion(origin=self.mem_map.get("curve25519engine", None), size=0x20000, cached=False))
#self.bus.add_slave("curve25519engine", self.curve25519engine.bus, SoCRegion(origin=self.mem_map.get("curve25519engine", None), size=0x20000, cached=False))
self.submodules.curve25519_on_sync = PulseSynchronizer("clk100", "sys")
self.comb += self.curve25519_on_sync.i.eq(self.curve25519engine.power.fields.on)
self.comb += self.crg.curve25519_on.eq(self.curve25519_on_sync.o)
def main():
parser = argparse.ArgumentParser(description="SbusFPGA")