litex/lib/sata/bist.py

92 lines
1.9 KiB
Python

from migen.fhdl.std import *
from migen.genlib.fsm import FSM, NextState
from lib.sata.common import *
class SATABIST(Module):
def __init__(self, sector_size=512, max_count=1):
self.sink = sink = Sink(command_rx_description(32))
self.source = source = Source(command_tx_description(32))
self.start = Signal()
self.sector = Signal(48)
self.done = Signal()
self.errors = Signal(32)
errors = Signal(32)
inc_errors = Signal()
self.sync += \
If(self.start,
errors.eq(0),
).Elif(inc_errors,
errors.eq(errors+1)
)
self.comb += self.errors.eq(errors)
cnt = Signal(32)
inc_cnt = Signal()
clr_cnt = Signal()
self.sync += \
If(clr_cnt,
cnt.eq(0),
).Elif(inc_cnt,
cnt.eq(cnt+1)
)
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
fsm.act("IDLE",
self.done.eq(1),
clr_cnt.eq(1),
If(self.start,
NextState("SEND_WRITE_CMD_AND_DATA")
)
)
fsm.act("SEND_WRITE_CMD_AND_DATA",
source.stb.eq(1),
source.sop.eq((cnt==0)),
source.eop.eq((cnt==(sector_size*max_count)//4-1)),
source.write.eq(1),
source.sector.eq(self.sector),
source.count.eq(max_count),
source.data.eq(cnt), #XXX use LFSR
inc_cnt.eq(source.ack),
If(source.stb & source.eop & source.ack,
NextState("WAIT_WRITE_ACK")
)
)
fsm.act("WAIT_WRITE_ACK",
sink.ack.eq(1),
If(sink.stb & sink.write,
NextState("SEND_READ_CMD")
)
)
fsm.act("SEND_READ_CMD",
source.stb.eq(1),
source.sop.eq(1),
source.eop.eq(1),
source.read.eq(1),
source.sector.eq(self.sector),
source.count.eq(max_count),
If(source.ack,
NextState("WAIT_READ_ACK")
)
)
fsm.act("WAIT_READ_ACK",
clr_cnt.eq(1),
If(sink.stb & sink.read,
NextState("RECEIVE_READ_DATA")
)
)
fsm.act("RECEIVE_READ_DATA",
sink.ack.eq(1),
inc_cnt.eq(sink.stb),
If(sink.stb & (sink.data != cnt), #XXX use LFSR
inc_errors.eq(1)
),
If(sink.stb & sink.eop,
NextState("IDLE")
)
)