simplify bist
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 7 Jan 2015 21:15:57 +0000 (22:15 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 7 Jan 2015 21:15:57 +0000 (22:15 +0100)
lib/sata/bist.py
lib/sata/test/bist_tb.py
targets/test.py
test/bist.py
test/test_bist_mila.py

index 12a869c445c6ef0f42e1b36a1a69c4096816093b..4948022fd8f41a46075c38511f98b5b875430b78 100644 (file)
@@ -2,23 +2,25 @@ from lib.sata.common import *
 from lib.sata.link.scrambler import Scrambler
 from migen.bank.description import *
 
-class SATABISTUnit(Module):
+class SATABIST(Module):
        def __init__(self, sata_con):
-               sink = sata_con.source
-               source = sata_con.sink
-
-               self.start = Signal()
-               self.write_only = Signal()
-               self.read_only = Signal()
+               self.write = Signal()
+               self.read = Signal()
                self.sector = Signal(48)
                self.count = Signal(16)
+               self.loops = Signal(8)
+
                self.done = Signal()
-               self.ctrl_errors = Signal(32)
-               self.data_errors = Signal(32)
+               self.errors = Signal(32)
+
+       ###
+
+               sink = sata_con.source
+               source = sata_con.sink
 
                self.counter = counter = Counter(bits_sign=32)
-               self.ctrl_error_counter = Counter(self.ctrl_errors, bits_sign=32)
-               self.data_error_counter = Counter(self.data_errors, bits_sign=32)
+               self.loops_counter = loops_counter = Counter(bits_sign=8)
+               self.error_counter = Counter(self.errors, bits_sign=32)
 
                self.scrambler = scrambler = InsertReset(Scrambler())
                self.comb += [
@@ -30,39 +32,39 @@ class SATABISTUnit(Module):
                fsm.act("IDLE",
                        self.done.eq(1),
                        counter.reset.eq(1),
-                       If(self.start,
-                               self.ctrl_error_counter.reset.eq(1),
-                               self.data_error_counter.reset.eq(1),
-                               If(self.read_only,
-                                       NextState("SEND_READ_CMD")
-                               ).Else(
-                                       NextState("SEND_WRITE_CMD_AND_DATA")
-                               )
+                       loops_counter.reset.eq(1),
+                       If(self.write,
+                               self.error_counter.reset.eq(1),
+                               NextState("SEND_WRITE_CMD_AND_DATA")
+                       ).Elif(self.read,
+                               self.error_counter.reset.eq(1),
+                               NextState("SEND_READ_CMD")
                        )
                )
                fsm.act("SEND_WRITE_CMD_AND_DATA",
                        source.stb.eq(1),
-                       source.sop.eq((counter.value == 0)),
-                       source.eop.eq((counter.value == (logical_sector_size//4*self.count)-1)),
+                       source.sop.eq(counter.value == 0),
+                       source.eop.eq(counter.value == (logical_sector_size//4*self.count)-1),
                        source.write.eq(1),
                        source.sector.eq(self.sector),
                        source.count.eq(self.count),
                        source.data.eq(scrambler.value),
-                       counter.ce.eq(source.ack),
-                       If(source.stb & source.eop & source.ack,
-                               NextState("WAIT_WRITE_ACK")
+                       If(source.stb & source.ack,
+                               counter.ce.eq(1),
+                               If(source.eop,
+                                       NextState("WAIT_WRITE_ACK")
+                               )
                        )
                )
                fsm.act("WAIT_WRITE_ACK",
                        sink.ack.eq(1),
                        If(sink.stb,
-                               If(~sink.write | ~sink.success | sink.failed,
-                                       self.ctrl_error_counter.ce.eq(1)
-                               ),
-                               If(self.write_only,
+                               loops_counter.ce.eq(1),
+                               If(loops_counter.value == (self.loops-1),
                                        NextState("IDLE")
                                ).Else(
-                                       NextState("SEND_READ_CMD")
+                                       counter.reset.eq(1),
+                                       NextState("SEND_WRITE_CMD_AND_DATA")
                                )
                        )
                )
@@ -80,9 +82,6 @@ class SATABISTUnit(Module):
                )
                fsm.act("WAIT_READ_ACK",
                        If(sink.stb & sink.read,
-                               If(~sink.read | ~sink.success | sink.failed,
-                                       self.ctrl_error_counter.ce.eq(1)
-                               ),
                                NextState("RECEIVE_READ_DATA")
                        )
                )
@@ -91,11 +90,16 @@ class SATABISTUnit(Module):
                        If(sink.stb,
                                counter.ce.eq(1),
                                If(sink.data != scrambler.value,
-                                       self.data_error_counter.ce.eq(1)
+                                       self.error_counter.ce.eq(1)
                                ),
                                If(sink.eop,
                                        If(sink.last,
-                                               NextState("IDLE")
+                                               loops_counter.ce.eq(1),
+                                               If(loops_counter.value == (self.loops-1),
+                                                       NextState("IDLE")
+                                               ).Else(
+                                                       NextState("SEND_READ_CMD")
+                                               )
                                        ).Else(
                                                NextState("WAIT_READ_ACK")
                                        )
@@ -103,71 +107,24 @@ class SATABISTUnit(Module):
                        )
                )
 
-class SATABIST(Module, AutoCSR):
-       def __init__(self, sata_con):
-               self._start = CSR()
-               self._start_sector = CSRStorage(48)
+class SATABISTControl(Module, AutoCSR):
+       def __init__(self, sata_bist):
+               self._write = CSR()
+               self._read = CSR()
+               self._sector = CSRStorage(48)
                self._count = CSRStorage(16)
-               self._write_only = CSRStorage()
-               self._read_only = CSRStorage()
-
-               self._stop = CSRStorage()
+               self._loops = CSRStorage(8)
 
-               self._sector = CSRStatus(48)
+               self._done = CSRStatus()
                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
-
-               compute = Signal()
-
-               write_only = self._write_only.storage
-               read_only = self._read_only.storage
-               sector = self._sector.status
-               errors = self._errors.status
-
-               ###
-
-               self.unit = SATABISTUnit(sata_con)
                self.comb += [
-                       self.unit.write_only.eq(write_only),
-                       self.unit.read_only.eq(read_only),
-                       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("COMPUTE")
-                       ).Elif(stop,
-                               NextState("IDLE")
-                       )
-               )
-               fsm.act("COMPUTE",
-                       compute.eq(1),
-                       NextState("START")
-               )
-
-               self.sync += [
-                       If(start,
-                               errors.eq(0),
-                               sector.eq(start_sector)
-                       ).Elif(compute,
-                               errors.eq(errors + self.unit.data_errors),
-                               sector.eq(sector + count)
-                       )
+                       sata_bist.write.eq(self._write.r & self._write.re),
+                       sata_bist.read.eq(self._read.r & self._read.re),
+                       sata_bist.sector.eq(self._sector.storage),
+                       sata_bist.count.eq(self._count.storage),
+                       sata_bist.loops.eq(self._loops.storage),
+
+                       self._done.status.eq(sata_bist.done),
+                       self._errors.status.eq(sata_bist.errors)
                ]
index a3a8114a4fd1fddd8b82a2c37f84cc21615c6dd6..06476737736acf92b01dc2effe8b5585049e2dba 100644 (file)
@@ -1,6 +1,6 @@
 from lib.sata.common import *
 from lib.sata import SATACON
-from lib.sata.bist import SATABISTUnit
+from lib.sata.bist import SATABIST
 
 from lib.sata.test.hdd import *
 from lib.sata.test.common import *
@@ -12,21 +12,28 @@ class TB(Module):
                                transport_debug=False, transport_loopback=False,
                                hdd_debug=True)
                self.con = SATACON(self.hdd.phy)
-               self.bist = SATABISTUnit(self.con)
+               self.bist = SATABIST(self.con)
 
        def gen_simulation(self, selfp):
                hdd = self.hdd
                hdd.malloc(0, 64)
                selfp.bist.sector = 0
                selfp.bist.count = 17
+               selfp.bist.loops = 1
                while True:
-                       selfp.bist.start = 1
+                       selfp.bist.write = 1
                        yield
-                       selfp.bist.start = 0
+                       selfp.bist.write = 0
                        yield
                        while selfp.bist.done == 0:
                                yield
-                       print("ctrl_errors: {} / data_errors {}".format(selfp.bist.ctrl_errors, selfp.bist.data_errors))
+                       selfp.bist.read = 1
+                       yield
+                       selfp.bist.read = 0
+                       yield
+                       while selfp.bist.done == 0:
+                               yield
+                       print("errors {}".format(selfp.bist.errors))
                        selfp.bist.sector += 1
                        selfp.bist.count = max((selfp.bist.count + 1)%8, 1)
 
index 25b04e47f18de38d424587bb9b6613c828c6fc68..b6346eb66ecff5e331649e24be2970d20547cb2d 100644 (file)
@@ -13,7 +13,7 @@ from misoclib import identifier
 from lib.sata.common import *
 from lib.sata.phy import SATAPHY
 from lib.sata import SATACON
-from lib.sata.bist import SATABIST
+from lib.sata.bist import SATABIST, SATABISTControl
 
 from migen.genlib.cdc import *
 
@@ -159,8 +159,8 @@ class DebugLeds(Module):
 class TestDesign(UART2WB, AutoCSR):
        default_platform = "kc705"
        csr_map = {
-               "sata_bist":    10,
-               "mila":                 11
+               "sata_bist_ctrl":       10,
+               "mila":                         11
        }
        csr_map.update(UART2WB.csr_map)
 
@@ -172,6 +172,8 @@ class TestDesign(UART2WB, AutoCSR):
                self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, speed="SATA2")
                self.sata_con = SATACON(self.sata_phy)
                self.sata_bist = SATABIST(self.sata_con)
+               self.sata_bist_ctrl = SATABISTControl(self.sata_bist)
+
 
                self.leds = DebugLeds(platform, self.sata_phy)
 
index 41482fd6cc1ea61aa335f8a9eb238fb7a8f246bc..86d116a2e35d2a0126f3ff588bee1d66dc761d98 100644 (file)
@@ -7,47 +7,24 @@ logical_sector_size = 512
 class SATABISTDriver:
        def __init__(self, regs):
                self.regs = regs
-               self.last_sector = 0
-               self.last_time = time.time()
-               self.last_errors = 0
-               self.mode = "rw"
 
-       def set_mode(self, mode):
-               self.mode = mode
-               self.regs.sata_bist_write_only.write(0)
-               self.regs.sata_bist_read_only.write(0)
-               if mode == "wr":
-                       self.regs.sata_bist_write_only.write(1)
-               if mode == "rd":
-                       self.regs.sata_bist_read_only.write(1)
+       def run(self, sector, count, loops, mode):
+               self.regs.sata_bist_ctrl_sector.write(sector)
+               self.regs.sata_bist_ctrl_count.write(count)
+               self.regs.sata_bist_ctrl_loops.write(loops)
+               if mode == "write":
+                       self.regs.sata_bist_ctrl_write.write(1)
+               elif mode == "read":
+                       self.regs.sata_bist_ctrl_read.write(1)
+               while (self.regs.sata_bist_ctrl_done.read() == 0):
+                       pass
+               return self.regs.sata_bist_ctrl_errors.read()
 
-       def start(self, sector, count, mode):
-               self.set_mode(mode)
-               self.regs.sata_bist_start_sector.write(sector)
-               self.regs.sata_bist_count.write(count)
-               self.regs.sata_bist_stop.write(0)
-               self.regs.sata_bist_start.write(1)
-
-       def stop(self):
-               self.regs.sata_bist_stop.write(1)
-
-       def show_status(self):
-               errors = self.regs.sata_bist_errors.read() - self.last_errors
-               self.last_errors += errors
-
-               sector = self.regs.sata_bist_sector.read()
-               n = sector - self.last_sector
-               self.last_sector = sector
-
-               t = self.last_time - time.time()
-               self.last_time = time.time()
-
-               if self.mode in ["wr", "rd"]:
-                       speed_mult = 1
-               else:
-                       speed_mult = 2
-               print("%4.2f MB/sec errors=%d sector=%d" %(n*logical_sector_size*speed_mult/(1024*1024), errors, sector))
+       def write(self, sector, count, loops):
+               self.run(sector, count, loops, "write")
 
+       def read(self, sector, count, loops):
+               return self.run(sector, count, loops, "read")
 
 def _get_args():
        parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
@@ -55,8 +32,8 @@ def _get_args():
 SATA BIST utility.
 """)
        parser.add_argument("-s", "--sector", default=0, help="BIST start sector")
-       parser.add_argument("-c", "--count", default=4, help="BIST count (number of sectors per transaction)")
-       parser.add_argument("-m", "--mode", default="rw", help="BIST mode (rw, wr, rd")
+       parser.add_argument("-c", "--count", default=16384, help="BIST count (number of sectors per transaction)")
+       parser.add_argument("-l", "--loops", default=4, help="BIST loops (number of loop for each transaction")
 
        return parser.parse_args()
 
@@ -65,13 +42,32 @@ if __name__ == "__main__":
        wb.open()
        ###
        bist = SATABISTDriver(wb.regs)
+       sector = int(args.sector)
+       count = int(args.count)
+       loops = int(args.loops)
        try:
-               bist.start(int(args.sector), int(args.count), args.mode)
+               write_time = 0
+               read_time = 0
                while True:
-                       bist.show_status()
-                       time.sleep(1)
+                       # Write
+                       start = time.time()
+                       bist.write(sector, count, loops)
+                       end = time.time()
+                       write_time = end-start
+                       write_speed = loops*count*logical_sector_size/(1024*1024)/write_time
+
+                       # Read
+                       start = time.time()
+                       read_errors = bist.read(sector, count, loops)
+                       end = time.time()
+                       read_time = end-start
+                       read_speed = loops*count*logical_sector_size/(1024*1024)/read_time
+
+                       sector += count
+
+                       print("sector=%d write_speed=%4.2fMB/sec read_speed=%4.2fMB/sec errors=%d" %(sector, write_speed, read_speed, read_errors))
+
        except KeyboardInterrupt:
                pass
-       bist.stop()
        ###
        wb.close()
index 7e6c2767168d6063ffb6dc2e4f828b92f7308936..0fa211eec4f8368021ed72399f858d902ade6a5a 100644 (file)
@@ -27,9 +27,9 @@ mila.prog_sum("term")
 # Trigger / wait / receive
 mila.trigger(offset=32, length=1024)
 
-bist.start(0, 4, "rw")
+bist.write(0, 16, 1)
+bist.read(0, 16, 1)
 mila.wait_done()
-bist.stop()
 
 mila.read()
 mila.export("dump.vcd")