litesata: do some cleanup and prepare for RAID

This commit is contained in:
Florent Kermarrec 2015-05-23 14:08:56 +02:00
parent d9b15e6ef6
commit 5daba9af68
21 changed files with 241 additions and 178 deletions

View File

@ -1,21 +0,0 @@
from misoclib.mem.litesata.common import *
from misoclib.mem.litesata.phy import *
from misoclib.mem.litesata.core import *
from misoclib.mem.litesata.frontend import *
from migen.bank.description import *
class LiteSATA(Module, AutoCSR):
def __init__(self, phy, buffer_depth=2*fis_max_dwords,
with_bist=False, with_bist_csr=False):
# phy
self.phy = phy
# core
self.submodules.core = LiteSATACore(self.phy, buffer_depth)
# frontend
self.submodules.crossbar = LiteSATACrossbar(self.core)
if with_bist:
self.submodules.bist = LiteSATABIST(self.crossbar, with_bist_csr)

View File

@ -5,7 +5,7 @@ from misoclib.mem.litesata.core.command import LiteSATACommand
class LiteSATACore(Module):
def __init__(self, phy, buffer_depth):
def __init__(self, phy, buffer_depth=2*fis_max_dwords):
self.submodules.link = LiteSATALink(phy, buffer_depth)
self.submodules.transport = LiteSATATransport(self.link)
self.submodules.command = LiteSATACommand(self.transport)

View File

@ -41,6 +41,7 @@ class LiteSATALinkTX(Module):
# datas / primitives mux
insert = Signal(32)
copy = Signal()
self.comb += [
If(self.from_rx.insert,
cont.sink.stb.eq(1),
@ -51,7 +52,7 @@ class LiteSATALinkTX(Module):
cont.sink.stb.eq(1),
cont.sink.data.eq(insert),
cont.sink.charisk.eq(0x0001),
).Elif(fsm.ongoing("COPY"),
).Elif(copy,
cont.sink.stb.eq(scrambler.source.stb),
cont.sink.data.eq(scrambler.source.d),
scrambler.source.ack.eq(cont.sink.ack),
@ -87,6 +88,7 @@ class LiteSATALinkTX(Module):
)
)
fsm.act("COPY",
copy.eq(1),
If(self.from_rx.det == primitives["HOLD"],
insert.eq(primitives["HOLDA"]),
).Elif(~scrambler.source.stb,
@ -145,12 +147,15 @@ class LiteSATALinkRX(Module):
crc = LiteSATACRCChecker(link_description(32))
self.submodules += crc
idle = Signal()
copy = Signal()
sop = Signal()
eop = Signal()
self.sync += \
If(fsm.ongoing("IDLE"),
If(idle,
sop.eq(1),
).Elif(fsm.ongoing("COPY"),
).Elif(copy,
If(scrambler.sink.stb & scrambler.sink.ack,
sop.eq(0)
)
@ -177,6 +182,7 @@ class LiteSATALinkRX(Module):
# FSM
fsm.act("IDLE",
idle.eq(1),
scrambler.reset.eq(1),
If(det == primitives["X_RDY"],
NextState("RDY")
@ -199,6 +205,7 @@ class LiteSATALinkRX(Module):
scrambler.sink.eop.eq(eop)
]
fsm.act("COPY",
copy.eq(1),
scrambler.sink.stb.eq(cont.source.stb & ((det == 0) | eop)),
insert.eq(primitives["R_IP"]),
If(det == primitives["HOLD"],

View File

@ -94,10 +94,10 @@ if __name__ == "__main__":
print(" "+a)
sys.exit(1)
revision = soc.sata_phy.revision
has_bist = hasattr(soc.sata, "bist")
user_ports = len(soc.sata.crossbar.users)
try:
revision = soc.sata_phy.revision
except:
revision = soc.sata_phy0.revision
print("""
__ _ __ _______ _________
@ -111,13 +111,9 @@ A small footprint and configurable SATA core
====== Building options: ======
{} / {} Gbps
System Clk: {} MHz (min: {} MHz)
User ports: {}
BIST: {}
===============================""".format(
revision.replace("sata_", "SATA "), bitrates[revision],
soc.clk_freq/1000000, frequencies[revision],
user_ports,
has_bist
soc.clk_freq/1000000, frequencies[revision]
)
)
@ -145,9 +141,9 @@ BIST: {}
soc = soc.get_fragment()
platform.finalize(soc)
so = {
NoRetiming: XilinxNoRetiming,
MultiReg: XilinxMultiReg,
AsyncResetSynchronizer: XilinxAsyncResetSynchronizer
NoRetiming: XilinxNoRetiming,
MultiReg: XilinxMultiReg,
AsyncResetSynchronizer: XilinxAsyncResetSynchronizer
}
v_output = verilog.convert(soc, ios, special_overrides=so)
v_output.write("build/litesata.v")

View File

@ -2,13 +2,33 @@ from mibuild.generic_platform import *
from mibuild.platforms import kc705
_sata_io = [
("sata", 0,
("sata_clocks", 0,
Subsignal("refclk_p", Pins("HPC:GBTCLK0_M2C_P")),
Subsignal("refclk_n", Pins("HPC:GBTCLK0_M2C_N")),
Subsignal("refclk_n", Pins("HPC:GBTCLK0_M2C_N"))
),
("sata", 0,
Subsignal("txp", Pins("HPC:DP0_C2M_P")),
Subsignal("txn", Pins("HPC:DP0_C2M_N")),
Subsignal("rxp", Pins("HPC:DP0_M2C_P")),
Subsignal("rxn", Pins("HPC:DP0_M2C_N")),
Subsignal("rxn", Pins("HPC:DP0_M2C_N"))
),
("sata", 1,
Subsignal("txp", Pins("HPC:DP1_C2M_P")),
Subsignal("txn", Pins("HPC:DP1_C2M_N")),
Subsignal("rxp", Pins("HPC:DP1_M2C_P")),
Subsignal("rxn", Pins("HPC:DP1_M2C_N"))
),
("sata", 2,
Subsignal("txp", Pins("HPC:DP2_C2M_P")),
Subsignal("txn", Pins("HPC:DP2_C2M_N")),
Subsignal("rxp", Pins("HPC:DP2_M2C_P")),
Subsignal("rxn", Pins("HPC:DP2_M2C_N"))
),
("sata", 3,
Subsignal("txp", Pins("HPC:DP3_C2M_P")),
Subsignal("txn", Pins("HPC:DP3_C2M_N")),
Subsignal("rxp", Pins("HPC:DP3_M2C_P")),
Subsignal("rxn", Pins("HPC:DP3_M2C_N"))
)
]
@ -28,15 +48,6 @@ class Platform(kc705.Platform):
except ConstraintError:
pass
self.add_platform_command("""
create_clock -name sys_clk -period 6 [get_nets sys_clk]
create_clock -name sata_rx_clk -period 3.33 [get_nets sata_rx_clk]
create_clock -name sata_tx_clk -period 3.33 [get_nets sata_tx_clk]
set_false_path -from [get_clocks sys_clk] -to [get_clocks sata_rx_clk]
set_false_path -from [get_clocks sys_clk] -to [get_clocks sata_tx_clk]
set_false_path -from [get_clocks sata_rx_clk] -to [get_clocks sys_clk]
set_false_path -from [get_clocks sata_tx_clk] -to [get_clocks sys_clk]
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 2.5 [current_design]
""")

View File

@ -13,7 +13,9 @@ from misoclib.com.uart.bridge import UARTWishboneBridge
from misoclib.mem.litesata.common import *
from misoclib.mem.litesata.phy import LiteSATAPHY
from misoclib.mem.litesata import LiteSATA
from misoclib.mem.litesata.core import LiteSATACore
from misoclib.mem.litesata.frontend.crossbar import LiteSATACrossbar
from misoclib.mem.litesata.frontend.bist import LiteSATABIST
class _CRG(Module):
@ -53,41 +55,31 @@ class _CRG(Module):
class BISTLeds(Module):
def __init__(self, platform, sata_phy):
# 1Hz blinking leds (sata_rx and sata_tx clocks)
sata_rx_led = platform.request("user_led", 0)
sata_tx_led = platform.request("user_led", 1)
def __init__(self, platform, sata_phys):
for i, sata_phy in enumerate(sata_phys):
# 1Hz blinking leds (sata_rx and sata_tx clocks)
rx_led = platform.request("user_led", 2*i)
sata_rx_cnt = Signal(32)
sata_tx_cnt = Signal(32)
rx_cnt = Signal(32)
sata_freq = int(frequencies[sata_phy.revision]*1000*1000)
freq = int(frequencies[sata_phy.revision]*1000*1000)
self.sync.sata_rx += \
If(sata_rx_cnt == 0,
sata_rx_led.eq(~sata_rx_led),
sata_rx_cnt.eq(sata_freq//2)
).Else(
sata_rx_cnt.eq(sata_rx_cnt-1)
)
self.sync.sata_rx += \
If(rx_cnt == 0,
rx_led.eq(~rx_led),
rx_cnt.eq(freq//2)
).Else(
rx_cnt.eq(rx_cnt-1)
)
self.sync.sata_tx += \
If(sata_tx_cnt == 0,
sata_tx_led.eq(~sata_tx_led),
sata_tx_cnt.eq(sata_freq//2)
).Else(
sata_tx_cnt.eq(sata_tx_cnt-1)
)
# ready leds (crg and ctrl)
self.comb += platform.request("user_led", 2).eq(sata_phy.crg.ready)
self.comb += platform.request("user_led", 3).eq(sata_phy.ctrl.ready)
# ready leds
self.comb += platform.request("user_led", 2*i+1).eq(sata_phy.ctrl.ready)
class BISTSoC(SoC, AutoCSR):
default_platform = "kc705"
csr_map = {
"sata": 10,
"sata_bist": 16
}
csr_map.update(SoC.csr_map)
def __init__(self, platform):
@ -104,16 +96,29 @@ class BISTSoC(SoC, AutoCSR):
self.submodules.crg = _CRG(platform)
# SATA PHY/Core/Frontend
self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "sata_gen2", clk_freq)
self.submodules.sata = LiteSATA(self.sata_phy, with_bist=True, with_bist_csr=True)
self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata_clocks"), platform.request("sata", 0), "sata_gen2", clk_freq)
self.submodules.sata_core = LiteSATACore(self.sata_phy)
self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core)
self.submodules.sata_bist = LiteSATABIST(self.sata_crossbar, with_csr=True)
# Status Leds
self.submodules.leds = BISTLeds(platform, self.sata_phy)
self.submodules.leds = BISTLeds(platform, [self.sata_phy])
platform.add_platform_command("""
create_clock -name sys_clk -period 6 [get_nets sys_clk]
create_clock -name sata_rx_clk -period 6.66 [get_nets sata_rx_clk]
create_clock -name sata_tx_clk -period 6.66 [get_nets sata_tx_clk]
set_false_path -from [get_clocks sys_clk] -to [get_clocks sata_rx_clk]
set_false_path -from [get_clocks sys_clk] -to [get_clocks sata_tx_clk]
set_false_path -from [get_clocks sata_rx_clk] -to [get_clocks sys_clk]
set_false_path -from [get_clocks sata_tx_clk] -to [get_clocks sys_clk]
""")
class BISTSoCDevel(BISTSoC, AutoCSR):
csr_map = {
"la": 20
"la": 17
}
csr_map.update(BISTSoC.csr_map)
def __init__(self, platform):

View File

@ -2,22 +2,31 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
from targets import *
from misoclib.soc import SoC
from misoclib.mem.litesata.common import *
from misoclib.mem.litesata.phy import LiteSATAPHY
from misoclib.mem.litesata import LiteSATA
from misoclib.mem.litesata.core import LiteSATACore
from misoclib.mem.litesata.frontend.crossbar import LiteSATACrossbar
from misoclib.mem.litesata.frontend.bist import LiteSATABIST
class LiteSATACore(Module):
class Core(Module):
default_platform = "verilog_backend"
def __init__(self, platform, clk_freq=166*1000000, nports=4):
def __init__(self, platform, clk_freq=166*1000000, with_bist=True, nports=4):
self.clk_freq = clk_freq
# SATA PHY/Core/Frontend
self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "sata_gen2", clk_freq)
self.submodules.sata = LiteSATA(self.sata_phy, with_bist=True)
self.submodules.sata_core = LiteSATACore(self.sata_phy)
self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core)
# BIST
if with_bist:
self.submodules.sata_bist = LiteSATABIST(self.sata_crossbar)
# Get user ports from crossbar
self.user_ports = self.sata.crossbar.get_ports(nports)
self.user_ports = self.sata_crossbar.get_ports(nports)
def get_ios(self):
ios = set()
@ -35,16 +44,16 @@ class LiteSATACore(Module):
})
# BIST
if hasattr(self.sata, "bist"):
if hasattr(self, "sata_bist"):
for bist_unit in ["generator", "checker"]:
for signal in ["start", "sector", "count", "random", "done", "aborted", "errors"]:
ios = ios.union({getattr(getattr(self.sata.bist, bist_unit), signal)})
ios = ios.union({getattr(getattr(self.sata_bist, bist_unit), signal)})
ios = ios.union({
self.sata.bist.identify.start,
self.sata.bist.identify.done,
self.sata.bist.identify.source.stb,
self.sata.bist.identify.source.data,
self.sata.bist.identify.source.ack
self.sata_bist.identify.start,
self.sata_bist.identify.done,
self.sata_bist.identify.source.stb,
self.sata_bist.identify.source.data,
self.sata_bist.identify.source.ack
})
# User ports
@ -62,4 +71,4 @@ class LiteSATACore(Module):
ios = ios.union({obj})
return ios
default_subtarget = LiteSATACore
default_subtarget = Core

View File

@ -72,7 +72,7 @@ class LiteSATABISTIdentifyDriver:
def __init__(self, regs, name):
self.regs = regs
self.name = name
for s in ["start", "done", "source_stb", "source_ack", "source_data"]:
for s in ["start", "done", "data_width", "source_stb", "source_ack", "source_data"]:
setattr(self, s, getattr(regs, name + "_identify_" + s))
self.data = []
@ -189,11 +189,12 @@ if __name__ == "__main__":
if not read_done:
retry += 1
ratio = identify.data_width.read()//32
print("sector={:d}({:d}MB) wr_speed={:4.2f}MB/s rd_speed={:4.2f}MB/s errors={:d} retry={:d}".format(
sector,
int(run_sectors*logical_sector_size/MB),
write_speed/MB,
read_speed/MB,
int(run_sectors*logical_sector_size/MB)*ratio,
write_speed/MB*ratio,
read_speed/MB*ratio,
write_errors + read_errors,
retry))
if random_addressing:

View File

@ -1,11 +1,11 @@
import sys
from tools import *
from test_bist import *
from litescope.software.driver.la import LiteScopeLADriver
from bist import *
from misoclib.tools.litescope.software.driver.la import LiteScopeLADriver
def main(wb):
la = LiteScopeLADriver(wb.regs, "la")
la = LiteScopeLADriver(wb.regs, "la", debug=True)
identify = LiteSATABISTIdentifyDriver(wb.regs, "sata_bist")
generator = LiteSATABISTGeneratorDriver(wb.regs, "sata_bist")
checker = LiteSATABISTCheckerDriver(wb.regs, "sata_bist")

View File

@ -1,4 +1,4 @@
from litescope.software.dump import *
from misoclib.tools.litescope.software.dump import *
primitives = {
"ALIGN": 0x7B4A4ABC,
@ -25,10 +25,10 @@ def decode_primitive(dword):
return ""
def link_trace(mila, tx_data_name, rx_data_name):
def link_trace(la, tx_data_name, rx_data_name):
r = ""
dump = Dump()
dump.add_from_layout(mila.layout, mila.dat)
dump.add_from_layout(la.layout, la.data)
for var in dump.vars:
if var.name == tx_data_name:

View File

@ -17,6 +17,8 @@ class LiteSATABISTGenerator(Module):
# # #
n = flen(user_port.sink.data)//32
source, sink = user_port.sink, user_port.source
counter = Counter(32)
@ -45,9 +47,9 @@ class LiteSATABISTGenerator(Module):
source.sector.eq(self.sector),
source.count.eq(self.count),
If(self.random,
source.data.eq(scrambler.value)
source.data.eq(Replicate(scrambler.value, n))
).Else(
source.data.eq(counter.value)
source.data.eq(Replicate(counter.value, n))
)
]
fsm.act("SEND_CMD_AND_DATA",
@ -81,6 +83,8 @@ class LiteSATABISTChecker(Module):
# # #
n = flen(user_port.sink.data)//32
source, sink = user_port.sink, user_port.source
counter = Counter(32)
@ -124,12 +128,12 @@ class LiteSATABISTChecker(Module):
NextState("RECEIVE_DATA")
)
)
expected_data = Signal(32)
expected_data = Signal(n*32)
self.comb += \
If(self.random,
expected_data.eq(scrambler.value)
expected_data.eq(Replicate(scrambler.value, n))
).Else(
expected_data.eq(counter.value)
expected_data.eq(Replicate(counter.value, n))
)
fsm.act("RECEIVE_DATA",
sink.ack.eq(1),
@ -221,6 +225,7 @@ class LiteSATABISTIdentify(Module):
def __init__(self, user_port):
self.start = Signal()
self.done = Signal()
self.data_width = flen(user_port.sink.data)
fifo = SyncFIFO([("data", 32)], 512, buffered=True)
self.submodules += fifo
@ -270,6 +275,7 @@ class LiteSATABISTIdentifyCSR(Module, AutoCSR):
def __init__(self, bist_identify):
self._start = CSR()
self._done = CSRStatus()
self._data_width = CSRStatus(16, reset=bist_identify.data_width)
self._source_stb = CSRStatus()
self._source_ack = CSR()
self._source_data = CSRStatus(32)

View File

@ -4,16 +4,17 @@ from misoclib.mem.litesata.frontend.arbiter import LiteSATAArbiter
class LiteSATACrossbar(Module):
def __init__(self, core):
def __init__(self, controller):
self.dw = flen(controller.sink.data)
self.users = []
self.master = LiteSATAMasterPort(32)
self.master = LiteSATAMasterPort(self.dw)
self.comb += [
self.master.source.connect(core.sink),
core.source.connect(self.master.sink)
self.master.source.connect(controller.sink),
controller.source.connect(self.master.sink)
]
def get_port(self):
port = LiteSATAUserPort(32)
port = LiteSATAUserPort(self.dw)
self.users += [port]
return port

View File

@ -4,7 +4,7 @@ from misoclib.mem.litesata.phy.datapath import *
class LiteSATAPHY(Module):
def __init__(self, device, pads, revision, clk_freq):
def __init__(self, device, clock_pads_or_refclk, pads, revision, clk_freq):
self.pads = pads
self.revision = revision
@ -13,7 +13,7 @@ class LiteSATAPHY(Module):
from misoclib.mem.litesata.phy.k7.trx import K7LiteSATAPHYTRX
from misoclib.mem.litesata.phy.k7.crg import K7LiteSATAPHYCRG
self.submodules.trx = K7LiteSATAPHYTRX(pads, revision)
self.submodules.crg = K7LiteSATAPHYCRG(pads, self.trx, revision, clk_freq)
self.submodules.crg = K7LiteSATAPHYCRG(clock_pads_or_refclk, pads, self.trx, revision, clk_freq)
else:
raise NotImplementedError

View File

@ -19,11 +19,19 @@ class LiteSATAPHYCtrl(Module):
align_timer = WaitTimer(self.us(873))
self.submodules += align_timer, retry_timer
align_detect = Signal()
non_align_cnt = Signal(4)
align_det = Signal()
misalign_det = Signal()
non_align_counter = Counter(4)
self.submodules += non_align_counter
self.comb += [
If(sink.stb,
align_det.eq((self.sink.charisk == 0b0001) &
(self.sink.data == primitives["ALIGN"])),
misalign_det.eq((self.sink.charisk & 0b1010) != 0)
)
]
self.fsm = fsm = InsertReset(FSM(reset_state="RESET"))
self.submodules += fsm
self.comb += fsm.reset.eq(retry_timer.done | align_timer.done)
@ -96,7 +104,7 @@ class LiteSATAPHYCtrl(Module):
source.charisk.eq(0b0000),
trx.rx_align.eq(1),
align_timer.wait.eq(1),
If(align_detect & ~trx.rx_idle,
If(align_det & ~trx.rx_idle,
NextState("SEND_ALIGN")
)
)
@ -117,19 +125,33 @@ class LiteSATAPHYCtrl(Module):
NextState("READY")
)
)
# wait alignement stability for 100ms before declaring ctrl is ready,
# reset the RX part of the transceiver when misalignment is detected.
stability_timer = WaitTimer(100*clk_freq//1000)
self.submodules += stability_timer
fsm.act("READY",
trx.tx_idle.eq(0),
trx.rx_align.eq(1),
source.data.eq(primitives["SYNC"]),
source.charisk.eq(0b0001),
self.ready.eq(1),
stability_timer.wait.eq(1),
self.ready.eq(stability_timer.done),
If(trx.rx_idle,
NextState("RESET"),
)
NextState("RESET"),
).Elif(misalign_det,
crg.rx_reset.eq(1),
NextState("REALIGN")
)
)
fsm.act("REALIGN",
If(crg.ready,
NextState("READY")
)
)
self.comb += align_detect.eq(self.sink.stb &
(self.sink.data == primitives["ALIGN"]))
def us(self, t):
clk_period_us = 1000000/self.clk_freq

View File

@ -2,7 +2,7 @@ from misoclib.mem.litesata.common import *
class K7LiteSATAPHYCRG(Module):
def __init__(self, pads, gtx, revision, clk_freq):
def __init__(self, clock_pads_or_refclk, pads, gtx, revision, clk_freq):
self.tx_reset = Signal()
self.rx_reset = Signal()
self.ready = Signal()
@ -14,14 +14,19 @@ class K7LiteSATAPHYCRG(Module):
# (sata_gen3) 150MHz / VCO @ 3GHz / Line rate @ 6Gbps
# (sata_gen2 & sata_gen1) VCO still @ 3 GHz, Line rate is
# decreased with output dividers.
refclk = Signal()
self.specials += Instance("IBUFDS_GTE2",
i_CEB=0,
i_I=pads.refclk_p,
i_IB=pads.refclk_n,
o_O=refclk
)
self.comb += gtx.gtrefclk0.eq(refclk)
if isinstance(clock_pads_or_refclk, Signal):
self.refclk = clock_pads_or_refclk
else:
self.refclk = Signal()
clock_pads = clock_pads_or_refclk
self.specials += Instance("IBUFDS_GTE2",
i_CEB=0,
i_I=clock_pads.refclk_p,
i_IB=clock_pads.refclk_n,
o_O=self.refclk
)
self.comb += gtx.gtrefclk0.eq(self.refclk)
# TX clocking
# (sata_gen3) 150MHz from CPLL TXOUTCLK, sata_tx clk @ 300MHz (16-bits)

View File

@ -127,7 +127,7 @@ class K7LiteSATAPHYTRX(Module):
cdr_config = {
"sata_gen1": 0x0380008BFF40100008,
"sata_gen2": 0x0388008BFF40200008,
"sata_gen3": 0X0380008BFF10200010
"sata_gen3": 0x0380008BFF10200010
}
rxcdr_cfg = cdr_config[revision]
@ -352,7 +352,7 @@ class K7LiteSATAPHYTRX(Module):
"p_RXDLY_LCFG": 0x30,
"p_RXDLY_TAP_CFG": 0,
"p_RXPH_CFG": 0,
"p_RXPHDLY_CFG": 0x084820,
"p_RXPHDLY_CFG": 0x084020,
"p_RXPH_MONITOR_SEL": 0,
"p_RX_XCLK_SEL": "RXUSR",
"p_RX_DDI_SEL": 0,
@ -405,7 +405,7 @@ class K7LiteSATAPHYTRX(Module):
# TX Buffer Attributes
"p_TXBUF_EN": "FALSE",
"p_TXBUF_RESET_ON_RATE_CHANGE": "TRUE",
"p_TXBUF_RESET_ON_RATE_CHANGE": "FALSE",
"p_TXDLY_CFG": 0x1f,
"p_TXDLY_LCFG": 0x030,
"p_TXDLY_TAP_CFG": 0,
@ -471,7 +471,7 @@ class K7LiteSATAPHYTRX(Module):
"p_RX_DFE_H5_CFG": 0b00011100000,
"p_RX_DFE_KL_CFG": 0b0000011111110,
"p_RX_DFE_LPM_CFG": 0x0954,
"p_RX_DFE_LPM_HOLD_DURING_EIDLE": 0,
"p_RX_DFE_LPM_HOLD_DURING_EIDLE": 1,
"p_RX_DFE_UT_CFG": 0b10001111000000000,
"p_RX_DFE_VP_CFG": 0b00011111100000011,

View File

@ -1,5 +1,6 @@
from misoclib.mem.litesata.common import *
from misoclib.mem.litesata import LiteSATA
from misoclib.mem.litesata.core import LiteSATACore
from misoclib.mem.litesata.frontend.crossbar import LiteSATACrossbar
from misoclib.mem.litesata.frontend.bist import LiteSATABISTGenerator, LiteSATABISTChecker
from misoclib.mem.litesata.test.common import *
@ -12,35 +13,43 @@ class TB(Module):
link_debug=False, link_random_level=0,
transport_debug=False, transport_loopback=False,
hdd_debug=True)
self.submodules.controller = LiteSATA(self.hdd.phy)
self.submodules.generator = LiteSATABISTGenerator(self.controller.crossbar.get_port())
self.submodules.checker = LiteSATABISTChecker(self.controller.crossbar.get_port())
self.submodules.core = LiteSATACore(self.hdd.phy)
self.submodules.crossbar = LiteSATACrossbar(self.core)
self.submodules.generator = LiteSATABISTGenerator(self.crossbar.get_port())
self.submodules.checker = LiteSATABISTChecker(self.crossbar.get_port())
def gen_simulation(self, selfp):
hdd = self.hdd
hdd.malloc(0, 64)
selfp.generator.sector = 0
selfp.generator.count = 17
selfp.checker.sector = 0
selfp.checker.count = 17
sector = 0
count = 17
generator = selfp.generator
checker = selfp.checker
while True:
selfp.generator.start = 1
# write data
generator.sector = sector
generator.count = count
generator.start = 1
yield
selfp.generator.start = 0
generator.start = 0
yield
while selfp.generator.done == 0:
while generator.done == 0:
yield
selfp.checker.start = 1
# verify data
checker.sector = sector
checker.count = count
checker.start = 1
yield
selfp.checker.start = 0
checker.start = 0
yield
while selfp.checker.done == 0:
while checker.done == 0:
yield
print("errors {}".format(selfp.checker.errors))
selfp.generator.sector += 1
selfp.generator.count = max((selfp.generator.count + 1)%8, 1)
selfp.checker.sector += 1
selfp.checker.count = max((selfp.checker.count + 1)%8, 1)
print("errors {}".format(checker.errors))
# prepare next iteration
sector += 1
count = max((count + 1)%8, 1)
if __name__ == "__main__":
run_simulation(TB(), ncycles=8192*2, vcd_name="my.vcd", keep_files=True)

View File

@ -3,15 +3,19 @@ from misoclib.mem.litesata.test.common import *
from misoclib.mem.litesata.test.model.transport import FIS_REG_H2D, FIS_DATA
class CommandLayer(Module):
def __init__(self, transport):
self.transport = transport
self.transport.set_command_callback(self.callback)
self.transport.set_command(self)
self.hdd = None
self.n = None
def set_hdd(self, hdd):
self.hdd = hdd
self.transport.n = hdd.n
self.transport.link.n = hdd.n
def callback(self, fis):
resp = None

View File

@ -8,8 +8,9 @@ from misoclib.mem.litesata.test.model.link import *
from misoclib.mem.litesata.test.model.transport import *
from misoclib.mem.litesata.test.model.command import *
def print_hdd(s):
print_with_prefix(s, "[HDD]: ")
def print_hdd(s, n=None):
print_with_prefix(s, "[HDD{}]: ".format("" if n is None else str(n)))
class HDDMemRegion:
@ -20,11 +21,12 @@ class HDDMemRegion:
class HDD(Module):
def __init__(self,
def __init__(self, n=None,
link_debug=False, link_random_level=0,
transport_debug=False, transport_loopback=False,
hdd_debug=False,
):
self.n = n
self.submodules.phy = PHYLayer()
self.submodules.link = LinkLayer(self.phy, link_debug, link_random_level)
self.submodules.transport = TransportLayer(self.link, transport_debug, transport_loopback)
@ -43,7 +45,7 @@ class HDD(Module):
if self.debug:
s = "Allocating {n} sectors: {s} to {e}".format(n=count, s=sector, e=sector+count-1)
s += " ({} KB)".format(count*logical_sector_size//1024)
print_hdd(s)
print_hdd(s, self.n)
self.mem = HDDMemRegion(sector, count, logical_sector_size)
def write(self, sector, data):
@ -53,7 +55,7 @@ class HDD(Module):
s = "{}".format(sector)
else:
s = "{s} to {e}".format(s=sector, e=sector+n-1)
print_hdd("Writing sector " + s)
print_hdd("Writing sector " + s, self.n)
for i in range(len(data)):
offset = sectors2dwords(sector)
self.mem.data[offset+i] = data[i]
@ -64,7 +66,7 @@ class HDD(Module):
s = "{}".format(sector)
else:
s = "{s} to {e}".format(s=sector, e=sector+count-1)
print_hdd("Reading sector " + s)
print_hdd("Reading sector " + s, self.n)
data = []
for i in range(sectors2dwords(count)):
data.append(self.mem.data[sectors2dwords(sector)+i])

View File

@ -4,8 +4,9 @@ import math
from misoclib.mem.litesata.common import *
from misoclib.mem.litesata.test.common import *
def print_link(s):
print_with_prefix(s, "[LNK]: ")
def print_link(s, n=None):
print_with_prefix(s, "[LNK{}]: ".format("" if n is None else str(n)))
def import_scrambler_datas():
@ -91,13 +92,14 @@ class LinkLayer(Module):
self.scrambled_datas = import_scrambler_datas()
self.transport_callback = None
self.transport = None
self.n = None
self.send_state = ""
self.send_states = ["RDY", "SOF", "DATA", "EOF", "WTRM"]
def set_transport_callback(self, callback):
self.transport_callback = callback
def set_transport(self, transport):
self.transport = transport
def send(self, dword):
if self.send_state == "RDY":
@ -164,8 +166,8 @@ class LinkLayer(Module):
self.phy.send(primitives["R_OK"])
if self.rx_packet.ongoing:
self.rx_packet.decode()
if self.transport_callback is not None:
self.transport_callback(self.rx_packet)
if self.transport is not None:
self.transport.callback(self.rx_packet)
self.rx_packet.ongoing = False
elif dword == primitives["HOLD"]:
self.phy.send(primitives["HOLDA"])
@ -190,7 +192,7 @@ class LinkLayer(Module):
while True:
yield from self.phy.receive()
if self.debug:
print_link(self.phy)
print_link(self.phy, self.n)
self.phy.send(primitives["SYNC"])
rx_dword = self.phy.rx.dword.dat
rx_dword = self.remove_cont(rx_dword)

View File

@ -3,8 +3,9 @@ from misoclib.mem.litesata.test.common import *
from misoclib.mem.litesata.test.model.link import LinkTXPacket
def print_transport(s):
print_with_prefix(s, "[TRN]: ")
def print_transport(s, n=None):
print_with_prefix(s, "[TRN{}]: ".format("" if n is None else str(n)))
def get_field_data(field, packet):
@ -105,17 +106,20 @@ class TransportLayer(Module):
self.link = link
self.debug = debug
self.loopback = loopback
self.link.set_transport_callback(self.callback)
self.link.set_transport(self)
def set_command_callback(self, callback):
self.command_callback = callback
self.command = None
self.n = None
def set_command(self, command):
self.command = command
def send(self, fis):
fis.encode()
packet = LinkTXPacket(fis.packet)
self.link.tx_packets.append(packet)
if self.debug and not self.loopback:
print_transport(fis)
print_transport(fis, self.n)
def callback(self, packet):
fis_type = packet[0] & 0xff
@ -130,8 +134,8 @@ class TransportLayer(Module):
else:
fis = FIS_UNKNOWN(packet, direction="H2D")
if self.debug:
print_transport(fis)
print_transport(fis, self.n)
if self.loopback:
self.send(fis)
else:
self.command_callback(fis)
self.command.callback(fis)