From: Florent Kermarrec Date: Mon, 15 Dec 2014 15:44:12 +0000 (+0100) Subject: add simple synthetizable BIST X-Git-Tag: 24jan2021_ls180~2572^2~115 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=707b43178ba3d80aa5a4b60ee13c78c4f6879fa9;p=litex.git add simple synthetizable BIST --- diff --git a/lib/sata/bist.py b/lib/sata/bist.py new file mode 100644 index 00000000..2aed02fa --- /dev/null +++ b/lib/sata/bist.py @@ -0,0 +1,91 @@ +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") + ) + ) diff --git a/lib/sata/test/Makefile b/lib/sata/test/Makefile index ffee2fdd..ef772ae9 100644 --- a/lib/sata/test/Makefile +++ b/lib/sata/test/Makefile @@ -20,6 +20,9 @@ link_tb: command_tb: $(CMD) command_tb.py +bist_tb: + $(CMD) bist_tb.py + all: crc_tb scrambler_tb link_tb command_tb clean: diff --git a/lib/sata/test/bist_tb.py b/lib/sata/test/bist_tb.py new file mode 100644 index 00000000..41d5af56 --- /dev/null +++ b/lib/sata/test/bist_tb.py @@ -0,0 +1,46 @@ +import random, copy + +from migen.fhdl.std import * +from migen.genlib.record import * +from migen.sim.generic import run_simulation + +from lib.sata.common import * +from lib.sata.link import SATALink +from lib.sata.transport import SATATransport +from lib.sata.command import SATACommand +from lib.sata.bist import SATABIST + +from lib.sata.test.hdd import * +from lib.sata.test.common import * + +class TB(Module): + def __init__(self): + self.submodules.hdd = HDD( + link_debug=False, link_random_level=50, + transport_debug=False, transport_loopback=False, + hdd_debug=True) + self.submodules.link = SATALink(self.hdd.phy) + self.submodules.transport = SATATransport(self.link) + self.submodules.command = SATACommand(self.transport) + self.submodules.bist = SATABIST(sector_size=512, max_count=1) + + self.comb += [ + self.bist.source.connect(self.command.sink), + self.command.source.connect(self.bist.sink) + ] + + def gen_simulation(self, selfp): + hdd = self.hdd + hdd.malloc(0, 64) + while True: + selfp.bist.start = 1 + yield + selfp.bist.start = 0 + yield + while selfp.bist.done == 0: + yield + print("errors: {}".format(selfp.bist.errors)) + selfp.bist.sector += 1 + +if __name__ == "__main__": + run_simulation(TB(), ncycles=4096, vcd_name="my.vcd", keep_files=True)