diff --git a/src/gateware/aux_controller.py b/src/gateware/aux_controller.py index b0db389..a763703 100644 --- a/src/gateware/aux_controller.py +++ b/src/gateware/aux_controller.py @@ -21,7 +21,6 @@ class SRAM(Module): bus = axi.Interface() self.bus = bus bus_data_width = len(self.bus.r.data) - bus_addr_width = len(self.bus.ar.addr) if isinstance(mem_or_size, Memory): assert(mem_or_size.width <= bus_data_width) self.mem = mem_or_size @@ -34,21 +33,21 @@ class SRAM(Module): ### - # Dout : Data received from CPU, output by SRAM <- port.dat_r - # Din : Data driven into SRAM, written into CPU <- port.dat_w - self.dout_index = Signal(bus_addr_width) # is this legal? - self.din_index = Signal(bus_addr_width) - self.din_ready = Signal() - self.dout = Signal(64) - self.din = Signal(64) - ar, aw, w, r, b = attrgetter("ar", "aw", "w", "r", "b")(bus) + # Dout : Data received from CPU, output by SRAM <- port.dat_r + # Din : Data driven into SRAM, written into CPU <- port.dat_w + self.dout_index = Signal.like(ar.len) + self.r_addr_incr = axi.Incr(ar) + self.w_addr_incr = axi.Incr(aw) ### Read - self.comb += r.data.eq(port.dat_r) + self.comb += [ + r.data.eq(port.dat_r), + port.adr.eq(self.r_addr_incr.addr) + ] # read control self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE") @@ -60,15 +59,12 @@ class SRAM(Module): ) ) read_fsm.act("READ_START", - r.data.eq(port.dat_r), r.resp.eq(axi.Response.okay.value), r.valid.eq(1), If(r.ready, - r.data.eq(port.dat_r), # that should be always updated, right? NextState("READ")) ) read_fsm.act("READ", - r.data.eq(port.dat_r), If(r.last & r.ready, # that's a smart way of skipping "LAST" state NextState("IDLE") ) @@ -79,73 +75,67 @@ class SRAM(Module): self.dout_index.eq(0), r.valid.eq(0), # shall it be reset too on IDLE? ar.ready.eq(0), + r.last.eq(0) ).Else(If(r.ready & read_fsm.ongoing("READ"), self.dout_index.eq(self.dout_index+1), - port.adr.eq(self.r_addr_incr.addr), If(self.dout_index==ar.len, r.last.eq(1)) # and update last ) ) ] ### Write - self.comb += [ - port.dat_w.eq(w.data), - port.addr.eq(aw.addr), - # w.strb.eq(0xff), - # aw.burst.eq(axi.Burst.incr.value), - # aw.len.eq(IN_BURST_LEN-1), # Number of transfers in burst minus 1 - # aw.size.eq(3), # Width of burst: 3 = 8 bytes = 64 bits - # aw.cache.eq(0xf), - # b.ready.eq(1), - ] - self.submodules.write_fsm = write_fsm = FSM(reset_state="IDLE") - write_fsm.act("IDLE", - w.valid.eq(0), - aw.valid.eq(0), - If(self.trigger_stb, - aw.valid.eq(1), - If(aw.ready, # assumes aw.ready is not randomly deasserted - NextState("DATA_WAIT") - ).Else( - NextState("AW_READY_WAIT") + if not read_only: + self.comb += [ + port.dat_w.eq(w.data), + port.addr.eq(self.w_addr_incr.addr), + ] + + self.submodules.write_fsm = write_fsm = FSM(reset_state="IDLE") + write_fsm.act("IDLE", + w.ready.eq(0), + aw.ready.eq(0), + b.valid.eq(0), + If(aw.valid, + NextState("AW_VALID_WAIT") ) ) - ) - write_fsm.act("AW_READY_WAIT", - aw.valid.eq(1), - If(aw.ready, - NextState("DATA_WAIT"), + write_fsm.act("AW_VALID_WAIT", # wait for data + aw.ready.eq(1), + If(w.valid, + NextState("WRITE"), + ) ) - ) - write_fsm.act("DATA_WAIT", - aw.valid.eq(0), - If(self.din_ready, # probably unnecessary? - w.valid.eq(1), - NextState("WRITE") + # write_fsm.act("DATA_WAIT", + # aw.valid.eq(0), + # If(self.din_ready, + # w.valid.eq(1), + # NextState("WRITE") + # ) + # ) + write_fsm.act("WRITE", + w.ready.eq(1), + If(w.ready & w.last, + NextState("WRITE_RESP") + ) ) - ) - write_fsm.act("WRITE", - w.valid.eq(1), - If(w.ready & w.last, - NextState("IDLE") + + write_fsm.act("WRITE_RESP", + port.we.eq(0), + b.resp.eq(axi.Response.okay.value), + b.valid.eq(1), + If(b.ready, + NextState("IDLE") + ) ) - ) - # refer to port.we instead - self.sync += If(w.ready & w.valid, port.we.eq(1)) + self.sync += If(w.ready & w.valid, port.we.eq(1)) - self.sync += [ - If(write_fsm.ongoing("IDLE"), - self.din_index.eq(0) - ), # but need to synchronise the address too - If(w.ready & w.valid, self.din_index.eq(self.din_index+1), port.adr.eq(port.addr+self.din_index)) - ] - - self.comb += [ - w.last.eq(0), - If(self.din_index==aw.len, w.last.eq(1)) - ] + self.sync += [ + If(write_fsm.ongoing("IDLE"), + self.din_index.eq(0) + ), # but need to synchronise the address too) + ] # # generate write enable signal