stb/req_ack becomes valid/ready + others small cleanup

This commit is contained in:
Florent Kermarrec 2016-05-02 09:13:09 +02:00
parent 19e84975f6
commit 52a0f4e617
9 changed files with 80 additions and 74 deletions

View file

@ -49,10 +49,10 @@ class Interface(Record):
self.write_latency = write_latency
bank_layout = [
("adr", aw, DIR_M_TO_S),
("valid", 1, DIR_M_TO_S),
("ready", 1, DIR_S_TO_M),
("we", 1, DIR_M_TO_S),
("stb", 1, DIR_M_TO_S),
("req_ack", 1, DIR_S_TO_M),
("adr", aw, DIR_M_TO_S),
("dat_w_ack", 1, DIR_S_TO_M),
("dat_r_ack", 1, DIR_S_TO_M),
("lock", 1, DIR_S_TO_M)
@ -67,3 +67,22 @@ class Interface(Record):
("dat_r", dw, DIR_S_TO_M)
]
Record.__init__(self, layout)
class CommandRequest:
def __init__(self, a, ba):
self.a = Signal(a)
self.ba = Signal(ba)
self.cas_n = Signal(reset=1)
self.ras_n = Signal(reset=1)
self.we_n = Signal(reset=1)
class CommandRequestRW(CommandRequest):
def __init__(self, a, ba):
CommandRequest.__init__(self, a, ba)
self.valid = Signal()
self.ack = Signal()
self.is_cmd = Signal()
self.is_read = Signal()
self.is_write = Signal()

View file

@ -40,10 +40,10 @@ class BankMachine(Module):
fifo = stream.SyncFIFO(layout, controller_settings.req_queue_size)
self.submodules += fifo
self.comb += [
fifo.sink.valid.eq(req.stb),
fifo.sink.valid.eq(req.valid),
fifo.sink.we.eq(req.we),
fifo.sink.adr.eq(req.adr),
req.req_ack.eq(fifo.sink.ready),
req.ready.eq(fifo.sink.ready),
fifo.source.ready.eq(req.dat_w_ack | req.dat_r_ack),
req.lock.eq(fifo.source.valid),
@ -81,7 +81,7 @@ class BankMachine(Module):
# Respect write-to-precharge specification
self.submodules.precharge_timer = WaitTimer(2 + timing_settings.tWR - 1 + 1)
self.comb += self.precharge_timer.wait.eq(~(self.cmd.stb &
self.comb += self.precharge_timer.wait.eq(~(self.cmd.valid &
self.cmd.ack &
self.cmd.is_write))
@ -94,7 +94,7 @@ class BankMachine(Module):
If(has_openrow,
If(hit,
# NB: write-to-read specification is enforced by multiplexer
self.cmd.stb.eq(1),
self.cmd.valid.eq(1),
If(fifo.source.we,
req.dat_w_ack.eq(self.cmd.ack),
self.cmd.is_write.eq(1)
@ -118,7 +118,7 @@ class BankMachine(Module):
# 2. since we always go to the ACTIVATE state, we do not need
# to assert track_close.
If(self.precharge_timer.done,
self.cmd.stb.eq(1),
self.cmd.valid.eq(1),
If(self.cmd.ack,
NextState("TRP")
),
@ -130,7 +130,7 @@ class BankMachine(Module):
fsm.act("ACTIVATE",
s_row_adr.eq(1),
track_open.eq(1),
self.cmd.stb.eq(1),
self.cmd.valid.eq(1),
self.cmd.is_cmd.eq(1),
If(self.cmd.ack, NextState("TRCD")),
self.cmd.ras_n.eq(0)

View file

@ -52,19 +52,22 @@ class LiteDRAMController(Module):
timing_settings.tREFI,timing_settings.tRFC,
controller_settings.with_refresh)
self.submodules.bank_machines = [BankMachine(geom_settings,
timing_settings,
controller_settings,
address_align,
i,
getattr(self.lasmic, "bank"+str(i)))
for i in range(2**geom_settings.bankbits)]
bank_machines = []
for i in range(2**geom_settings.bankbits):
bank_machine = BankMachine(geom_settings,
timing_settings,
controller_settings,
address_align,
i,
getattr(self.lasmic, "bank"+str(i)))
bank_machines.append(bank_machine)
self.submodules += bank_machine
self.submodules.multiplexer = Multiplexer(phy_settings,
geom_settings,
timing_settings,
controller_settings,
self.bank_machines,
bank_machines,
self.refresher,
self.dfi,
self.lasmic)

View file

@ -3,29 +3,11 @@ from operator import or_, and_
from litex.gen import *
from litex.gen.genlib.roundrobin import *
from litex.gen.genlib.fsm import FSM, NextState
from litedram.core.perf import Bandwidth
from litex.soc.interconnect.csr import AutoCSR
class CommandRequest:
def __init__(self, a, ba):
self.a = Signal(a)
self.ba = Signal(ba)
self.cas_n = Signal(reset=1)
self.ras_n = Signal(reset=1)
self.we_n = Signal(reset=1)
class CommandRequestRW(CommandRequest):
def __init__(self, a, ba):
CommandRequest.__init__(self, a, ba)
self.stb = Signal()
self.ack = Signal()
self.is_cmd = Signal()
self.is_read = Signal()
self.is_write = Signal()
from litedram.common import *
from litedram.core.perf import Bandwidth
class _CommandChooser(Module):
@ -33,7 +15,7 @@ class _CommandChooser(Module):
self.want_reads = Signal()
self.want_writes = Signal()
self.want_cmds = Signal()
# NB: cas_n/ras_n/we_n are 1 when stb is inactive
# NB: cas_n/ras_n/we_n are 1 when valid is inactive
self.cmd = CommandRequestRW(len(requests[0].a), len(requests[0].ba))
# # #
@ -41,23 +23,25 @@ class _CommandChooser(Module):
rr = RoundRobin(len(requests), SP_CE)
self.submodules += rr
self.comb += [rr.request[i].eq(req.stb & ((req.is_cmd & self.want_cmds) | ((req.is_read == self.want_reads) | (req.is_write == self.want_writes))))
for i, req in enumerate(requests)]
for i, req in enumerate(requests):
self.comb += rr.request[i].eq(req.valid & ((req.is_cmd & self.want_cmds) |
((req.is_read == self.want_reads) |
(req.is_write == self.want_writes))))
stb = Signal()
self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
valid = Signal()
self.comb += valid.eq(Array(req.valid for req in requests)[rr.grant])
for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
choices = Array(getattr(req, name) for req in requests)
self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
for name in ["cas_n", "ras_n", "we_n"]:
# we should only assert those signals when stb is 1
# we should only assert those signals when valid is 1
choices = Array(getattr(req, name) for req in requests)
self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
self.comb += self.cmd.stb.eq(stb \
self.comb += If(self.cmd.valid, getattr(self.cmd, name).eq(choices[rr.grant]))
self.comb += self.cmd.valid.eq(valid \
& ((self.cmd.is_cmd & self.want_cmds) | ((self.cmd.is_read == self.want_reads) \
& (self.cmd.is_write == self.want_writes))))
self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
self.comb += [If(self.cmd.valid & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
for i, req in enumerate(requests)]
self.comb += rr.ce.eq(self.cmd.ack)
@ -70,11 +54,11 @@ class _Steerer(Module):
###
def stb_and(cmd, attr):
if not hasattr(cmd, "stb"):
def valid_and(cmd, attr):
if not hasattr(cmd, "valid"):
return 0
else:
return cmd.stb & getattr(cmd, attr)
return cmd.valid & getattr(cmd, attr)
for phase, sel in zip(dfi.phases, self.sel):
self.comb += [
phase.cke.eq(1),
@ -90,8 +74,8 @@ class _Steerer(Module):
phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
phase.rddata_en.eq(Array(valid_and(cmd, "is_read") for cmd in commands)[sel]),
phase.wrdata_en.eq(Array(valid_and(cmd, "is_write") for cmd in commands)[sel])
]
@ -126,8 +110,8 @@ class Multiplexer(Module, AutoCSR):
read_available = Signal()
write_available = Signal()
self.comb += [
read_available.eq(reduce(or_, [req.stb & req.is_read for req in requests])),
write_available.eq(reduce(or_, [req.stb & req.is_write for req in requests]))
read_available.eq(reduce(or_, [req.valid & req.is_read for req in requests])),
write_available.eq(reduce(or_, [req.valid & req.is_write for req in requests]))
]
def anti_starvation(timeout):

View file

@ -12,12 +12,12 @@ class Bandwidth(Module, AutoCSR):
# # #
cmd_stb = Signal()
cmd_valid = Signal()
cmd_ack = Signal()
cmd_is_read = Signal()
cmd_is_write = Signal()
self.sync += [
cmd_stb.eq(cmd.stb),
cmd_valid.eq(cmd.valid),
cmd_ack.eq(cmd.ack),
cmd_is_read.eq(cmd.is_read),
cmd_is_write.eq(cmd.is_write)
@ -36,7 +36,7 @@ class Bandwidth(Module, AutoCSR):
nwrites_r.eq(nwrites),
nreads.eq(0),
nwrites.eq(0)
).Elif(cmd_stb & cmd_ack,
).Elif(cmd_valid & cmd_ack,
If(cmd_is_read, nreads.eq(nreads + 1)),
If(cmd_is_write, nwrites.eq(nwrites + 1)),
),

View file

@ -64,7 +64,7 @@ class LiteDRAMBISTGenerator(Module):
self.comb += [
self._dma.trigger.eq(self._shoot.re),
self._dma.data.stb.eq(en),
self._dma.data.valid.eq(en),
lfsr.ce.eq(en & self._dma.data.ack),
self._dma.data.d.eq(lfsr.o)
]
@ -90,14 +90,14 @@ class LiteDRAMBISTChecker(Module):
self.comb += lfsr.reset.eq(self._reset.re)
self.comb += [
lfsr.ce.eq(self._dma.data.stb),
lfsr.ce.eq(self._dma.data.valid),
self._dma.data.ack.eq(1)
]
err_cnt = self._error_count.status
self.sync += [
If(self._reset.re,
err_cnt.eq(0)
).Elif(self._dma.data.stb,
).Elif(self._dma.data.valid,
If(self._dma.data.d != lfsr.o, err_cnt.eq(err_cnt + 1))
)
]

View file

@ -14,9 +14,9 @@ class LiteDRAMWishboneBridge(Module):
)
)
fsm.act("REQUEST",
port.stb.eq(1),
port.valid.eq(1),
port.we.eq(wishbone.we),
If(port.req_ack,
If(port.ready,
If(wishbone.we,
NextState("WRITE_DATA")
).Else(

View file

@ -40,7 +40,7 @@ class LiteDRAMCrossbar(Module):
controller = self.controller
controller_selected = [1]*nmasters
master_req_acks = [0]*nmasters
master_readys = [0]*nmasters
master_dat_w_acks = [0]*nmasters
master_dat_r_acks = [0]*nmasters
@ -61,20 +61,20 @@ class LiteDRAMCrossbar(Module):
# arbitrate
bank_selected = [cs & (ba == nb) & ~locked for cs, ba, locked in zip(controller_selected, m_ba, master_locked)]
bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self.masters)]
bank_requested = [bs & master.valid for bs, master in zip(bank_selected, self.masters)]
self.comb += [
rr.request.eq(Cat(*bank_requested)),
rr.ce.eq(~bank.stb & ~bank.lock)
rr.ce.eq(~bank.valid & ~bank.lock)
]
# route requests
self.comb += [
bank.adr.eq(Array(m_rca)[rr.grant]),
bank.we.eq(Array(self.masters)[rr.grant].we),
bank.stb.eq(Array(bank_requested)[rr.grant])
bank.valid.eq(Array(bank_requested)[rr.grant])
]
master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & bank.req_ack)
for nm, master_req_ack in enumerate(master_req_acks)]
master_readys = [master_ready | ((rr.grant == nm) & bank_selected[nm] & bank.ready)
for nm, master_ready in enumerate(master_readys)]
master_dat_w_acks = [master_dat_w_ack | ((rr.grant == nm) & bank.dat_w_ack)
for nm, master_dat_w_ack in enumerate(master_dat_w_acks)]
master_dat_r_acks = [master_dat_r_ack | ((rr.grant == nm) & bank.dat_r_ack)
@ -94,7 +94,7 @@ class LiteDRAMCrossbar(Module):
master_dat_r_ack = new_master_dat_r_ack
master_dat_r_acks[nm] = master_dat_r_ack
self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self.masters, master_req_acks)]
self.comb += [master.ready.eq(master_ready) for master, master_ready in zip(self.masters, master_readys)]
self.comb += [master.dat_w_ack.eq(master_dat_w_ack) for master, master_dat_w_ack in zip(self.masters, master_dat_w_acks)]
self.comb += [master.dat_r_ack.eq(master_dat_r_ack) for master, master_dat_r_ack in zip(self.masters, master_dat_r_acks)]

View file

@ -20,10 +20,10 @@ class LiteDRAMDMAReader(Module):
self.comb += [
port.we.eq(0),
port.stb.eq(sink.valid & request_enable),
port.valid.eq(sink.valid & request_enable),
port.adr.eq(sink.address),
sink.ready.eq(port.req_ack & request_enable),
request_issued.eq(port.stb & port.req_ack)
sink.ready.eq(port.ready & request_enable),
request_issued.eq(port.valid & port.ready)
]
# FIFO reservation level counter
@ -74,10 +74,10 @@ class LiteDRAMDMAWriter(Module):
self.comb += [
port.we.eq(1),
port.stb.eq(fifo.writable & source.valid),
port.valid.eq(fifo.writable & source.valid),
port.adr.eq(source.address),
source.ready.eq(fifo.writable & port.req_ack),
fifo.we.eq(source.valid & port.req_ack),
source.ready.eq(fifo.writable & port.ready),
fifo.we.eq(source.valid & port.ready),
fifo.din.eq(source.data)
]