sram: redesigned write FSM. removed unused signals

This commit is contained in:
mwojcik 2021-08-17 11:10:08 +02:00
parent 3e1d14ff38
commit 61f81cec47
1 changed files with 54 additions and 64 deletions

View File

@ -21,7 +21,6 @@ class SRAM(Module):
bus = axi.Interface() bus = axi.Interface()
self.bus = bus self.bus = bus
bus_data_width = len(self.bus.r.data) bus_data_width = len(self.bus.r.data)
bus_addr_width = len(self.bus.ar.addr)
if isinstance(mem_or_size, Memory): if isinstance(mem_or_size, Memory):
assert(mem_or_size.width <= bus_data_width) assert(mem_or_size.width <= bus_data_width)
self.mem = mem_or_size 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) 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.r_addr_incr = axi.Incr(ar)
self.w_addr_incr = axi.Incr(aw)
### Read ### 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 # read control
self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE") self.submodules.read_fsm = read_fsm = FSM(reset_state="IDLE")
@ -60,15 +59,12 @@ class SRAM(Module):
) )
) )
read_fsm.act("READ_START", read_fsm.act("READ_START",
r.data.eq(port.dat_r),
r.resp.eq(axi.Response.okay.value), r.resp.eq(axi.Response.okay.value),
r.valid.eq(1), r.valid.eq(1),
If(r.ready, If(r.ready,
r.data.eq(port.dat_r), # that should be always updated, right?
NextState("READ")) NextState("READ"))
) )
read_fsm.act("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 If(r.last & r.ready, # that's a smart way of skipping "LAST" state
NextState("IDLE") NextState("IDLE")
) )
@ -79,73 +75,67 @@ class SRAM(Module):
self.dout_index.eq(0), self.dout_index.eq(0),
r.valid.eq(0), # shall it be reset too on IDLE? r.valid.eq(0), # shall it be reset too on IDLE?
ar.ready.eq(0), ar.ready.eq(0),
r.last.eq(0)
).Else(If(r.ready & read_fsm.ongoing("READ"), ).Else(If(r.ready & read_fsm.ongoing("READ"),
self.dout_index.eq(self.dout_index+1), 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 If(self.dout_index==ar.len, r.last.eq(1)) # and update last
) )
) )
] ]
### Write ### 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") if not read_only:
write_fsm.act("IDLE", self.comb += [
w.valid.eq(0), port.dat_w.eq(w.data),
aw.valid.eq(0), port.addr.eq(self.w_addr_incr.addr),
If(self.trigger_stb, ]
aw.valid.eq(1),
If(aw.ready, # assumes aw.ready is not randomly deasserted self.submodules.write_fsm = write_fsm = FSM(reset_state="IDLE")
NextState("DATA_WAIT") write_fsm.act("IDLE",
).Else( w.ready.eq(0),
NextState("AW_READY_WAIT") aw.ready.eq(0),
b.valid.eq(0),
If(aw.valid,
NextState("AW_VALID_WAIT")
) )
) )
) write_fsm.act("AW_VALID_WAIT", # wait for data
write_fsm.act("AW_READY_WAIT", aw.ready.eq(1),
aw.valid.eq(1), If(w.valid,
If(aw.ready, NextState("WRITE"),
NextState("DATA_WAIT"), )
) )
) # write_fsm.act("DATA_WAIT",
write_fsm.act("DATA_WAIT", # aw.valid.eq(0),
aw.valid.eq(0), # If(self.din_ready,
If(self.din_ready, # probably unnecessary? # w.valid.eq(1),
w.valid.eq(1), # NextState("WRITE")
NextState("WRITE") # )
# )
write_fsm.act("WRITE",
w.ready.eq(1),
If(w.ready & w.last,
NextState("WRITE_RESP")
)
) )
)
write_fsm.act("WRITE", write_fsm.act("WRITE_RESP",
w.valid.eq(1), port.we.eq(0),
If(w.ready & w.last, b.resp.eq(axi.Response.okay.value),
NextState("IDLE") 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 += [ self.sync += [
If(write_fsm.ongoing("IDLE"), If(write_fsm.ongoing("IDLE"),
self.din_index.eq(0) self.din_index.eq(0)
), # but need to synchronise the address too ), # 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))
]
# # generate write enable signal # # generate write enable signal