mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
improve BIST and clean up (remove support of identify command and debug code)
This commit is contained in:
parent
38d3f3697b
commit
678ee33af4
14 changed files with 176 additions and 448 deletions
|
@ -5,6 +5,11 @@ from lib.sata.command import SATACommand
|
|||
|
||||
class SATACON(Module):
|
||||
def __init__(self, phy, sector_size=512, max_count=8):
|
||||
self.sector_size = sector_size
|
||||
self.max_count = max_count
|
||||
|
||||
###
|
||||
|
||||
self.link = SATALink(phy)
|
||||
self.transport = SATATransport(self.link)
|
||||
self.command = SATACommand(self.transport, sector_size=sector_size, max_count=max_count)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from lib.sata.common import *
|
||||
from lib.sata.link.scrambler import Scrambler
|
||||
from migen.bank.description import *
|
||||
|
||||
class SATABIST(Module):
|
||||
def __init__(self, sector_size=512):
|
||||
self.sink = sink = Sink(command_rx_description(32))
|
||||
self.source = source = Source(command_tx_description(32))
|
||||
class SATABISTUnit(Module):
|
||||
def __init__(self, sata_con):
|
||||
sink = sata_con.source
|
||||
source = sata_con.sink
|
||||
|
||||
self.start = Signal()
|
||||
self.sector = Signal(48)
|
||||
|
@ -36,7 +37,7 @@ class SATABIST(Module):
|
|||
fsm.act("SEND_WRITE_CMD_AND_DATA",
|
||||
source.stb.eq(1),
|
||||
source.sop.eq((counter.value == 0)),
|
||||
source.eop.eq((counter.value == (sector_size//4*self.count)-1)),
|
||||
source.eop.eq((counter.value == (sata_con.sector_size//4*self.count)-1)),
|
||||
source.write.eq(1),
|
||||
source.sector.eq(self.sector),
|
||||
source.count.eq(self.count),
|
||||
|
@ -87,3 +88,65 @@ class SATABIST(Module):
|
|||
)
|
||||
)
|
||||
)
|
||||
|
||||
class SATABIST(Module, AutoCSR):
|
||||
def __init__(self, sata_con):
|
||||
self._start = CSR()
|
||||
self._start_sector = CSRStorage(48)
|
||||
self._count = CSRStorage(4)
|
||||
self._stop = CSRStorage()
|
||||
|
||||
self._sector = CSRStatus(48)
|
||||
self._errors = CSRStatus(32)
|
||||
|
||||
start = self._start.r & self._start.re
|
||||
start_sector = self._start_sector.storage
|
||||
count = self._count.storage
|
||||
stop = self._stop.storage
|
||||
|
||||
update = Signal()
|
||||
|
||||
sector = self._sector.status
|
||||
errors = self._errors.status
|
||||
|
||||
###
|
||||
|
||||
self.unit = SATABISTUnit(sata_con)
|
||||
self.comb += [
|
||||
self.unit.sector.eq(sector),
|
||||
self.unit.count.eq(count)
|
||||
]
|
||||
|
||||
self.fsm = fsm = FSM(reset_state="IDLE")
|
||||
|
||||
# FSM
|
||||
fsm.act("IDLE",
|
||||
If(start,
|
||||
NextState("START")
|
||||
)
|
||||
)
|
||||
fsm.act("START",
|
||||
self.unit.start.eq(1),
|
||||
NextState("WAIT_DONE")
|
||||
)
|
||||
fsm.act("WAIT_DONE",
|
||||
If(self.unit.done,
|
||||
NextState("CHECK_PREPARE")
|
||||
).Elif(stop,
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("CHECK_PREPARE",
|
||||
update.eq(1),
|
||||
NextState("START")
|
||||
)
|
||||
|
||||
self.sync += [
|
||||
If(start,
|
||||
errors.eq(0),
|
||||
sector.eq(start_sector)
|
||||
).Elif(update,
|
||||
errors.eq(errors + self.unit.data_errors),
|
||||
sector.eq(sector + count)
|
||||
)
|
||||
]
|
||||
|
|
|
@ -3,7 +3,6 @@ from lib.sata.common import *
|
|||
tx_to_rx = [
|
||||
("write", 1),
|
||||
("read", 1),
|
||||
("identify", 1),
|
||||
("count", 4)
|
||||
]
|
||||
|
||||
|
@ -39,8 +38,6 @@ class SATACommandTX(Module):
|
|||
NextState("SEND_WRITE_DMA_CMD")
|
||||
).Elif(sink.read,
|
||||
NextState("SEND_READ_DMA_CMD")
|
||||
).Elif(sink.identify,
|
||||
NextState("SEND_IDENTIFY_CMD")
|
||||
).Else(
|
||||
sink.ack.eq(1)
|
||||
)
|
||||
|
@ -87,24 +84,11 @@ class SATACommandTX(Module):
|
|||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("SEND_IDENTIFY_CMD",
|
||||
transport.sink.stb.eq(sink.stb),
|
||||
transport.sink.sop.eq(1),
|
||||
transport.sink.eop.eq(1),
|
||||
transport.sink.type.eq(fis_types["REG_H2D"]),
|
||||
transport.sink.c.eq(1),
|
||||
transport.sink.command.eq(regs["IDENTIFY_DEVICE_DMA"]),
|
||||
sink.ack.eq(transport.sink.ack),
|
||||
If(sink.stb & sink.ack,
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
|
||||
self.comb += [
|
||||
If(sink.stb,
|
||||
to_rx.write.eq(sink.write),
|
||||
to_rx.read.eq(sink.read),
|
||||
to_rx.identify.eq(sink.identify),
|
||||
to_rx.count.eq(sink.count)
|
||||
)
|
||||
]
|
||||
|
@ -131,15 +115,10 @@ class SATACommandRX(Module):
|
|||
transport.source.ack.eq(1),
|
||||
If(from_tx.write,
|
||||
NextState("WAIT_WRITE_ACTIVATE")
|
||||
).Elif(from_tx.read | from_tx.identify,
|
||||
).Elif(from_tx.read,
|
||||
NextState("WAIT_READ_DATA")
|
||||
)
|
||||
)
|
||||
identify = Signal()
|
||||
self.sync += \
|
||||
If(fsm.ongoing("IDLE"),
|
||||
identify.eq(from_tx.identify)
|
||||
)
|
||||
fsm.act("WAIT_WRITE_ACTIVATE",
|
||||
transport.source.ack.eq(1),
|
||||
If(transport.source.stb,
|
||||
|
@ -202,11 +181,10 @@ class SATACommandRX(Module):
|
|||
)
|
||||
fsm.act("PRESENT_READ_RESPONSE",
|
||||
cmd_fifo.sink.stb.eq(1),
|
||||
cmd_fifo.sink.read.eq(~identify),
|
||||
cmd_fifo.sink.identify.eq(identify),
|
||||
cmd_fifo.sink.read.eq(1),
|
||||
cmd_fifo.sink.success.eq(1),
|
||||
cmd_fifo.sink.failed.eq(0),
|
||||
If(~cmd_fifo.fifo.readable, # Note: simulate a depth=1 fifo
|
||||
If(~cmd_fifo.fifo.readable, # Note: simulate a fifo with depth=1
|
||||
If(cmd_fifo.sink.stb & cmd_fifo.sink.ack,
|
||||
If(cmd_fifo.sink.failed,
|
||||
data_fifo.reset.eq(1)
|
||||
|
@ -220,7 +198,7 @@ class SATACommandRX(Module):
|
|||
out_fsm.act("IDLE",
|
||||
If(cmd_fifo.source.stb & cmd_fifo.source.write,
|
||||
NextState("PRESENT_WRITE_RESPONSE"),
|
||||
).Elif(cmd_fifo.source.stb & (cmd_fifo.source.read | cmd_fifo.source.identify),
|
||||
).Elif(cmd_fifo.source.stb & (cmd_fifo.source.read),
|
||||
If(cmd_fifo.source.success,
|
||||
NextState("PRESENT_READ_RESPONSE_SUCCESS"),
|
||||
).Else(
|
||||
|
@ -242,7 +220,6 @@ class SATACommandRX(Module):
|
|||
out_fsm.act("PRESENT_READ_RESPONSE_SUCCESS",
|
||||
source.stb.eq(data_fifo.source.stb),
|
||||
source.read.eq(cmd_fifo.source.read),
|
||||
source.identify.eq(cmd_fifo.source.identify),
|
||||
source.success.eq(1),
|
||||
source.sop.eq(data_fifo.source.sop),
|
||||
source.eop.eq(data_fifo.source.eop),
|
||||
|
@ -258,7 +235,6 @@ class SATACommandRX(Module):
|
|||
source.sop.eq(1),
|
||||
source.eop.eq(1),
|
||||
source.read.eq(cmd_fifo.source.read),
|
||||
source.identify.eq(cmd_fifo.source.identify),
|
||||
source.failed.eq(1),
|
||||
If(source.stb & source.ack,
|
||||
cmd_fifo.source.ack.eq(1),
|
||||
|
|
|
@ -143,15 +143,13 @@ def transport_rx_description(dw):
|
|||
# Command Layer
|
||||
regs = {
|
||||
"WRITE_DMA_EXT" : 0x35,
|
||||
"READ_DMA_EXT" : 0x25,
|
||||
"IDENTIFY_DEVICE_DMA" : 0xEE
|
||||
"READ_DMA_EXT" : 0x25
|
||||
}
|
||||
|
||||
def command_tx_description(dw):
|
||||
layout = [
|
||||
("write", 1),
|
||||
("read", 1),
|
||||
("identify", 1),
|
||||
("sector", 48),
|
||||
("count", 4),
|
||||
("data", dw)
|
||||
|
@ -162,7 +160,6 @@ def command_rx_description(dw):
|
|||
layout = [
|
||||
("write", 1),
|
||||
("read", 1),
|
||||
("identify", 1),
|
||||
("success", 1),
|
||||
("failed", 1),
|
||||
("data", dw)
|
||||
|
@ -173,7 +170,6 @@ def command_rx_cmd_description(dw):
|
|||
layout = [
|
||||
("write", 1),
|
||||
("read", 1),
|
||||
("identify", 1),
|
||||
("success", 1),
|
||||
("failed", 1)
|
||||
]
|
||||
|
|
|
@ -10,7 +10,7 @@ from_rx = [
|
|||
]
|
||||
|
||||
class SATALinkTX(Module):
|
||||
def __init__(self, phy, disable_cont=False):
|
||||
def __init__(self, phy):
|
||||
self.sink = Sink(link_description(32))
|
||||
self.from_rx = Sink(from_rx)
|
||||
|
||||
|
@ -34,7 +34,7 @@ class SATALinkTX(Module):
|
|||
|
||||
# inserter CONT and scrambled data between
|
||||
# CONT and next primitive
|
||||
self.cont = cont = SATACONTInserter(phy_description(32), disable=False)
|
||||
self.cont = cont = SATACONTInserter(phy_description(32))
|
||||
|
||||
# datas / primitives mux
|
||||
insert = Signal(32)
|
||||
|
@ -200,7 +200,7 @@ class SATALinkRX(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("WTRM",
|
||||
# XXX: check CRC resutlt to return R_ERR or R_OK
|
||||
# XXX: check CRC result to return R_ERR or R_OK
|
||||
insert.eq(primitives["R_OK"]),
|
||||
If(det == primitives["SYNC"],
|
||||
NextState("IDLE")
|
||||
|
@ -215,8 +215,8 @@ class SATALinkRX(Module):
|
|||
]
|
||||
|
||||
class SATALink(Module):
|
||||
def __init__(self, phy, disable_tx_cont=False):
|
||||
self.tx = SATALinkTX(phy, disable_tx_cont)
|
||||
def __init__(self, phy):
|
||||
self.tx = SATALinkTX(phy)
|
||||
self.rx = SATALinkRX(phy)
|
||||
self.comb += Record.connect(self.rx.to_tx, self.tx.from_rx)
|
||||
self.sink, self.source = self.tx.sink, self.rx.source
|
||||
|
|
|
@ -4,15 +4,12 @@ from lib.sata.link.scrambler import Scrambler
|
|||
from migen.genlib.misc import optree
|
||||
|
||||
class SATACONTInserter(Module):
|
||||
def __init__(self, description, disable=False):
|
||||
def __init__(self, description):
|
||||
self.sink = sink = Sink(description)
|
||||
self.source = source = Source(description)
|
||||
|
||||
###
|
||||
|
||||
if disable:
|
||||
self.comb += Record.connect(self.sink, self.source)
|
||||
else:
|
||||
self.counter = counter = Counter(max=4)
|
||||
|
||||
is_data = Signal()
|
||||
|
|
|
@ -7,12 +7,11 @@ from lib.sata.test.hdd import *
|
|||
from lib.sata.test.common import *
|
||||
|
||||
class CommandTXPacket(list):
|
||||
def __init__(self, write=0, read=0, identify=0, sector=0, count=0, data=[]):
|
||||
def __init__(self, write=0, read=0, sector=0, count=0, data=[]):
|
||||
self.ongoing = False
|
||||
self.done = False
|
||||
self.write = write
|
||||
self.read = read
|
||||
self.identify = identify
|
||||
self.sector = sector
|
||||
self.count = count
|
||||
for d in data:
|
||||
|
@ -26,7 +25,6 @@ class CommandStreamer(PacketStreamer):
|
|||
PacketStreamer.do_simulation(self, selfp)
|
||||
selfp.source.write = self.packet.write
|
||||
selfp.source.read = self.packet.read
|
||||
selfp.source.identify = self.packet.identify
|
||||
selfp.source.sector = self.packet.sector
|
||||
selfp.source.count = self.packet.count
|
||||
|
||||
|
@ -36,7 +34,6 @@ class CommandRXPacket(list):
|
|||
self.done = False
|
||||
self.write = 0
|
||||
self.read = 0
|
||||
self.identify = 0
|
||||
self.success = 0
|
||||
self.failed = 0
|
||||
|
||||
|
@ -50,7 +47,6 @@ class CommandLogger(PacketLogger):
|
|||
self.packet = CommandRXPacket()
|
||||
self.packet.write = selfp.sink.write
|
||||
self.packet.read = selfp.sink.read
|
||||
self.packet.identify = selfp.sink.identify
|
||||
self.packet.sucess = selfp.sink.success
|
||||
self.packet.failed = selfp.sink.failed
|
||||
self.packet.append(selfp.sink.data)
|
||||
|
@ -100,8 +96,5 @@ class TB(Module):
|
|||
s, l, e = check(write_data, read_data)
|
||||
print("shift "+ str(s) + " / length " + str(l) + " / errors " + str(e))
|
||||
|
||||
identify_packet = CommandTXPacket(identify=1)
|
||||
yield from self.streamer.send(identify_packet)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_simulation(TB(), ncycles=2048, vcd_name="my.vcd", keep_files=True)
|
||||
|
|
|
@ -421,8 +421,6 @@ class CommandLayer(Module):
|
|||
resp = self.hdd.write_dma_callback(fis)
|
||||
elif fis.command == regs["READ_DMA_EXT"]:
|
||||
resp = self.hdd.read_dma_callback(fis)
|
||||
elif fis.command == regs["IDENTIFY_DEVICE_DMA"]:
|
||||
resp = self.hdd.identify_device_dma_callback(fis)
|
||||
elif isinstance(fis, FIS_DATA):
|
||||
resp = self.hdd.data_callback(fis)
|
||||
|
||||
|
@ -508,12 +506,6 @@ class HDD(Module):
|
|||
packet.insert(0, 0)
|
||||
return [FIS_DATA(packet, direction="D2H"), FIS_REG_D2H()]
|
||||
|
||||
def identify_device_dma_callback(self, fis):
|
||||
print_hdd("Identify device request")
|
||||
packet = [i for i in range(256)]
|
||||
packet.insert(0, 0)
|
||||
return [FIS_DATA(packet, direction="D2H"), FIS_REG_D2H()]
|
||||
|
||||
def data_callback(self, fis):
|
||||
self.write(self.wr_sector, fis.packet[1:])
|
||||
self.wr_sector += self.dwords2sectors(len(fis.packet[1:]))
|
||||
|
|
178
targets/test.py
178
targets/test.py
|
@ -152,179 +152,6 @@ class ClockLeds(Module):
|
|||
sata_tx_cnt.eq(sata_tx_cnt-1)
|
||||
)
|
||||
|
||||
|
||||
class CommandGenerator(Module, AutoCSR):
|
||||
def __init__(self, sata_con, sector_size):
|
||||
self._write = CSR()
|
||||
self._read = CSR()
|
||||
self._identify = CSR()
|
||||
self._sector = CSRStorage(48)
|
||||
self._count = CSRStorage(4)
|
||||
self._data = CSRStorage(32) # Note: fixed data, add a fifo later
|
||||
|
||||
self._sucess = CSRStatus()
|
||||
self._failed = CSRStatus()
|
||||
|
||||
self.fsm = fsm = FSM(reset_state="IDLE")
|
||||
|
||||
def new_command(csr):
|
||||
return csr.r & csr.re
|
||||
|
||||
cnt = Signal(16)
|
||||
sector = self._sector.storage
|
||||
count = self._count.storage
|
||||
data = self._data.storage
|
||||
|
||||
success = self._sucess.status
|
||||
failed = self._failed.status
|
||||
clr_status = Signal()
|
||||
set_success = Signal()
|
||||
set_failed = Signal()
|
||||
self.sync += [
|
||||
If(clr_status,
|
||||
success.eq(0),
|
||||
failed.eq(0),
|
||||
).Elif(set_success,
|
||||
success.eq(1)
|
||||
).Elif(set_failed,
|
||||
failed.eq(1)
|
||||
)
|
||||
]
|
||||
|
||||
self.comb += sata_con.source.ack.eq(1)
|
||||
|
||||
# FSM
|
||||
fsm.act("IDLE",
|
||||
clr_status.eq(1),
|
||||
If(new_command(self._write),
|
||||
NextState("SEND_WRITE_CMD")
|
||||
).Elif(new_command(self._read),
|
||||
NextState("SEND_READ_CMD")
|
||||
).Elif(new_command(self._identify),
|
||||
NextState("SEND_IDENTIFY_CMD")
|
||||
)
|
||||
)
|
||||
fsm.act("SEND_WRITE_CMD",
|
||||
sata_con.sink.stb.eq(1),
|
||||
sata_con.sink.sop.eq(cnt == 0),
|
||||
sata_con.sink.eop.eq(cnt == (count*sector_size-1)),
|
||||
sata_con.sink.write.eq(1),
|
||||
sata_con.sink.sector.eq(sector),
|
||||
sata_con.sink.count.eq(count),
|
||||
sata_con.sink.data.eq(data),
|
||||
If(sata_con.sink.eop & sata_con.sink.ack,
|
||||
NextState("WAIT_WRITE_ACK")
|
||||
)
|
||||
)
|
||||
self.sync += [
|
||||
If(fsm.ongoing("IDLE"),
|
||||
cnt.eq(0)
|
||||
).Elif(sata_con.sink.stb & sata_con.sink.stb,
|
||||
cnt.eq(cnt+1)
|
||||
)
|
||||
]
|
||||
fsm.act("WAIT_WRITE_ACK",
|
||||
# XXX: add check of success / failed
|
||||
If(sata_con.source.stb & sata_con.source.eop,
|
||||
set_success.eq(1),
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("SEND_READ_CMD",
|
||||
sata_con.sink.stb.eq(1),
|
||||
sata_con.sink.sop.eq(1),
|
||||
sata_con.sink.eop.eq(1),
|
||||
sata_con.sink.read.eq(1),
|
||||
sata_con.sink.sector.eq(sector),
|
||||
sata_con.sink.count.eq(count),
|
||||
If(sata_con.sink.ack,
|
||||
NextState("WAIT_READ_ACK_AND_DATA")
|
||||
)
|
||||
)
|
||||
fsm.act("WAIT_READ_ACK_AND_DATA",
|
||||
# XXX: add check of success / failed and receive data
|
||||
If(sata_con.source.stb & sata_con.source.eop,
|
||||
set_success.eq(1),
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("SEND_IDENTIFY_CMD",
|
||||
sata_con.sink.stb.eq(1),
|
||||
sata_con.sink.sop.eq(1),
|
||||
sata_con.sink.eop.eq(1),
|
||||
sata_con.sink.identify.eq(1),
|
||||
If(sata_con.sink.ack,
|
||||
NextState("WAIT_IDENTIFY_ACK_AND_DATA")
|
||||
)
|
||||
)
|
||||
fsm.act("WAIT_IDENTIFY_ACK_AND_DATA",
|
||||
# XXX: add check of success / failed and receive data
|
||||
If(sata_con.source.stb & sata_con.source.eop,
|
||||
set_success.eq(1),
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
|
||||
class BIST(Module, AutoCSR):
|
||||
def __init__(self, sata_con, sector_size):
|
||||
self._start = CSR()
|
||||
self._stop = CSR()
|
||||
|
||||
self._sector = CSRStatus(48)
|
||||
self._ctrl_errors = CSRStatus(32)
|
||||
self._data_errors = CSRStatus(32)
|
||||
|
||||
check_prepare = Signal()
|
||||
sector = self._sector.status
|
||||
ctrl_errors = self._ctrl_errors.status
|
||||
data_errors = self._data_errors.status
|
||||
|
||||
###
|
||||
|
||||
self.sata_bist = SATABIST(sector_size)
|
||||
self.comb += [
|
||||
Record.connect(sata_con.source, self.sata_bist.sink),
|
||||
Record.connect(self.sata_bist.source, sata_con.sink)
|
||||
]
|
||||
|
||||
self.fsm = fsm = FSM(reset_state="IDLE")
|
||||
|
||||
self.comb += [
|
||||
self.sata_bist.sector.eq(sector),
|
||||
self.sata_bist.count.eq(4)
|
||||
]
|
||||
|
||||
# FSM
|
||||
fsm.act("IDLE",
|
||||
If(self._start.r & self._start.re,
|
||||
NextState("START")
|
||||
)
|
||||
)
|
||||
fsm.act("START",
|
||||
self.sata_bist.start.eq(1),
|
||||
NextState("WAIT_DONE")
|
||||
)
|
||||
fsm.act("WAIT_DONE",
|
||||
If(self.sata_bist.done,
|
||||
NextState("CHECK_PREPARE")
|
||||
).Elif(self._stop.r & self._stop.re,
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("CHECK_PREPARE",
|
||||
check_prepare.eq(1),
|
||||
NextState("START")
|
||||
)
|
||||
|
||||
self.sync += [
|
||||
If(check_prepare,
|
||||
ctrl_errors.eq(ctrl_errors + self.sata_bist.ctrl_errors),
|
||||
data_errors.eq(data_errors + self.sata_bist.data_errors),
|
||||
sector.eq(sector+4)
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class TestDesign(UART2WB, AutoCSR):
|
||||
default_platform = "kc705"
|
||||
csr_map = {
|
||||
|
@ -342,8 +169,7 @@ class TestDesign(UART2WB, AutoCSR):
|
|||
self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, host=True, speed="SATA2")
|
||||
self.sata_con = SATACON(self.sata_phy, sector_size=512, max_count=8)
|
||||
|
||||
#self.command_generator = CommandGenerator(self.sata_con, sector_size=512)
|
||||
self.bist = BIST(self.sata_con, sector_size=512)
|
||||
self.bist = SATABIST(self.sata_con)
|
||||
|
||||
self.clock_leds = ClockLeds(platform)
|
||||
|
||||
|
@ -380,7 +206,6 @@ class TestDesign(UART2WB, AutoCSR):
|
|||
self.sata_con.sink.ack,
|
||||
self.sata_con.sink.write,
|
||||
self.sata_con.sink.read,
|
||||
self.sata_con.sink.identify,
|
||||
|
||||
self.sata_con.source.stb,
|
||||
self.sata_con.source.sop,
|
||||
|
@ -388,7 +213,6 @@ class TestDesign(UART2WB, AutoCSR):
|
|||
self.sata_con.source.ack,
|
||||
self.sata_con.source.write,
|
||||
self.sata_con.source.read,
|
||||
self.sata_con.source.identify,
|
||||
self.sata_con.source.success,
|
||||
self.sata_con.source.failed,
|
||||
self.sata_con.source.data
|
||||
|
|
|
@ -5,18 +5,44 @@ from tools import *
|
|||
sector_size = 512
|
||||
|
||||
wb.open()
|
||||
regs = wb.regs
|
||||
###
|
||||
regs.bist_start.write(1)
|
||||
last_sector = 0
|
||||
while True:
|
||||
class SATABISTDriver:
|
||||
def __init__(self, regs):
|
||||
self.regs = regs
|
||||
self.last_sector = 0
|
||||
self.last_time = time.time()
|
||||
self.last_errors = 0
|
||||
|
||||
def start_loopback(self, sector, count):
|
||||
self.regs.bist_start_sector.write(sector)
|
||||
self.regs.bist_count.write(count)
|
||||
self.regs.bist_stop.write(0)
|
||||
self.regs.bist_start.write(1)
|
||||
|
||||
def stop(self):
|
||||
self.regs.bist_stop.write(1)
|
||||
|
||||
def show_status(self):
|
||||
errors = self.regs.bist_errors.read() - self.last_errors
|
||||
self.last_errors += errors
|
||||
|
||||
sector = self.regs.bist_sector.read()
|
||||
n = sector - self.last_sector
|
||||
self.last_sector = sector
|
||||
|
||||
t = self.last_time - time.time()
|
||||
self.last_time = time.time()
|
||||
|
||||
print("%4.2f Mb/sec errors=%d sector=%d" %(n*512*8*2/(1024*1024), errors, sector))
|
||||
|
||||
bist = SATABISTDriver(wb.regs)
|
||||
try:
|
||||
bist.start_loopback(0, 4)
|
||||
while True:
|
||||
bist.show_status()
|
||||
time.sleep(1)
|
||||
sector = regs.bist_sector.read()
|
||||
n_sectors = sector - last_sector
|
||||
last_sector = sector
|
||||
n_bytes = n_sectors*sector_size*4*2
|
||||
ctrl_errors = regs.bist_ctrl_errors.read()
|
||||
data_errors = regs.bist_data_errors.read()
|
||||
print("%04d MB/s / data_errors %08d / ctrl_errors %08d " %(n_bytes/(1024*1024), data_errors, ctrl_errors))
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
bist.stop()
|
||||
###
|
||||
wb.close()
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
import time
|
||||
from config import *
|
||||
from tools import *
|
||||
from miscope.host.drivers import MiLaDriver
|
||||
|
||||
mila = MiLaDriver(wb.regs, "mila")
|
||||
wb.open()
|
||||
regs = wb.regs
|
||||
###
|
||||
|
||||
cond = {
|
||||
#"sata_phy_source_source_payload_data" : primitives["R_RDY"],
|
||||
#"sata_phy_source_source_payload_data" : primitives["R_OK"],
|
||||
"sata_phy_source_source_payload_data" : primitives["X_RDY"],
|
||||
}
|
||||
|
||||
trigger = 0
|
||||
mask = 0
|
||||
for k, v in cond.items():
|
||||
trigger |= getattr(mila, k+"_o")*v
|
||||
mask |= getattr(mila, k+"_m")
|
||||
|
||||
mila.prog_term(port=0, trigger=trigger, mask=mask)
|
||||
mila.prog_sum("term")
|
||||
|
||||
# Trigger / wait / receive
|
||||
mila.trigger(offset=32, length=512)
|
||||
regs.command_generator_identify.write(1)
|
||||
mila.wait_done()
|
||||
mila.read()
|
||||
mila.export("dump.vcd")
|
||||
###
|
||||
wb.close()
|
||||
|
||||
print_link_trace(mila,
|
||||
tx_data_name="sata_phy_sink_sink_payload_data",
|
||||
rx_data_name="sata_phy_source_source_payload_data"
|
||||
)
|
|
@ -1,23 +0,0 @@
|
|||
from config import *
|
||||
from miscope.host.drivers import MiLaDriver
|
||||
|
||||
mila = MiLaDriver(wb.regs, "mila", use_rle=False)
|
||||
wb.open()
|
||||
###
|
||||
trigger0 = mila.cont_remover_source_stb_o*1
|
||||
mask0 = mila.cont_remover_source_stb_m
|
||||
|
||||
trigger0 = 0
|
||||
mask0 = 0
|
||||
|
||||
mila.prog_term(port=0, trigger=trigger0, mask=mask0)
|
||||
mila.prog_sum("term")
|
||||
|
||||
# Trigger / wait / receive
|
||||
mila.trigger(offset=32, length=1024)
|
||||
mila.wait_done()
|
||||
mila.read()
|
||||
mila.export("dump.vcd")
|
||||
mila.export("dump.csv")
|
||||
###
|
||||
wb.close()
|
|
@ -1,41 +0,0 @@
|
|||
import time
|
||||
from config import *
|
||||
from tools import *
|
||||
from miscope.host.drivers import MiLaDriver
|
||||
|
||||
mila = MiLaDriver(wb.regs, "mila")
|
||||
wb.open()
|
||||
regs = wb.regs
|
||||
###
|
||||
|
||||
cond = {
|
||||
#"sata_phy_source_source_payload_data" : primitives["R_RDY"],
|
||||
#"sata_phy_source_source_payload_data" : primitives["R_OK"],
|
||||
#"sata_phy_source_source_payload_data" : primitives["X_RDY"],
|
||||
"sata_con_source_source_stb" : 1,
|
||||
}
|
||||
|
||||
trigger = 0
|
||||
mask = 0
|
||||
for k, v in cond.items():
|
||||
trigger |= getattr(mila, k+"_o")*v
|
||||
mask |= getattr(mila, k+"_m")
|
||||
|
||||
mila.prog_term(port=0, trigger=trigger, mask=mask)
|
||||
mila.prog_sum("term")
|
||||
|
||||
# Trigger / wait / receive
|
||||
mila.trigger(offset=32, length=512)
|
||||
regs.command_generator_sector.write(0)
|
||||
regs.command_generator_count.write(1)
|
||||
regs.command_generator_read.write(1)
|
||||
mila.wait_done()
|
||||
mila.read()
|
||||
mila.export("dump.vcd")
|
||||
###
|
||||
wb.close()
|
||||
|
||||
print_link_trace(mila,
|
||||
tx_data_name="sata_phy_sink_sink_payload_data",
|
||||
rx_data_name="sata_phy_source_source_payload_data"
|
||||
)
|
|
@ -1,42 +0,0 @@
|
|||
import time
|
||||
from config import *
|
||||
from tools import *
|
||||
from miscope.host.drivers import MiLaDriver
|
||||
|
||||
mila = MiLaDriver(wb.regs, "mila")
|
||||
wb.open()
|
||||
regs = wb.regs
|
||||
###
|
||||
|
||||
cond = {
|
||||
#"sata_phy_source_source_payload_data" : primitives["R_RDY"],
|
||||
#"sata_phy_source_source_payload_data" : primitives["R_OK"],
|
||||
#"sata_phy_source_source_payload_data" : primitives["X_RDY"],
|
||||
"sata_con_source_source_stb" : 1,
|
||||
}
|
||||
|
||||
trigger = 0
|
||||
mask = 0
|
||||
for k, v in cond.items():
|
||||
trigger |= getattr(mila, k+"_o")*v
|
||||
mask |= getattr(mila, k+"_m")
|
||||
|
||||
mila.prog_term(port=0, trigger=trigger, mask=mask)
|
||||
mila.prog_sum("term")
|
||||
|
||||
# Trigger / wait / receive
|
||||
mila.trigger(offset=32, length=512)
|
||||
regs.command_generator_sector.write(0)
|
||||
regs.command_generator_count.write(1)
|
||||
regs.command_generator_data.write(0x12345678)
|
||||
regs.command_generator_write.write(1)
|
||||
mila.wait_done()
|
||||
mila.read()
|
||||
mila.export("dump.vcd")
|
||||
###
|
||||
wb.close()
|
||||
|
||||
print_link_trace(mila,
|
||||
tx_data_name="sata_phy_sink_sink_payload_data",
|
||||
rx_data_name="sata_phy_source_source_payload_data"
|
||||
)
|
Loading…
Reference in a new issue