bist: use hardware counter for speed calc and remove loops mode
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 16 Jan 2015 17:14:13 +0000 (18:14 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 16 Jan 2015 17:48:34 +0000 (18:48 +0100)
lib/sata/bist.py
targets/test.py
test/bist.py

index 5de8e7c1ac67dfa286bd940e21923e95fba6b465..9f0707c42dda54bb23e8cdce0dbdf01e13e5c493 100644 (file)
@@ -9,7 +9,6 @@ class SATABISTGenerator(Module):
                self.start = Signal()
                self.sector = Signal(48)
                self.count = Signal(16)
-               self.loops = Signal(8)
                self.random = Signal()
 
                self.done = Signal()
@@ -20,7 +19,6 @@ class SATABISTGenerator(Module):
                source, sink = sata_master_port.source, sata_master_port.sink
 
                self.counter = counter = Counter(bits_sign=32)
-               self.loops_counter = loops_counter = Counter(bits_sign=8)
 
                self.scrambler = scrambler = InsertReset(Scrambler())
                self.comb += [
@@ -32,7 +30,6 @@ class SATABISTGenerator(Module):
                fsm.act("IDLE",
                        self.done.eq(1),
                        counter.reset.eq(1),
-                       loops_counter.reset.eq(1),
                        If(self.start,
                                NextState("SEND_CMD_AND_DATA")
                        )
@@ -61,13 +58,7 @@ class SATABISTGenerator(Module):
                fsm.act("WAIT_ACK",
                        sink.ack.eq(1),
                        If(sink.stb,
-                               loops_counter.ce.eq(1),
-                               If(loops_counter.value == (self.loops-1),
-                                       NextState("IDLE")
-                               ).Else(
-                                       counter.reset.eq(1),
-                                       NextState("SEND_CMD_AND_DATA")
-                               )
+                               NextState("IDLE")
                        )
                )
 
@@ -76,7 +67,6 @@ class SATABISTChecker(Module):
                self.start = Signal()
                self.sector = Signal(48)
                self.count = Signal(16)
-               self.loops = Signal(8)
                self.random = Signal()
 
                self.done = Signal()
@@ -87,7 +77,6 @@ class SATABISTChecker(Module):
                source, sink = sata_master_port.source, sata_master_port.sink
 
                self.counter = counter = Counter(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())
@@ -100,7 +89,6 @@ class SATABISTChecker(Module):
                fsm.act("IDLE",
                        self.done.eq(1),
                        counter.reset.eq(1),
-                       loops_counter.reset.eq(1),
                        If(self.start,
                                self.error_counter.reset.eq(1),
                                NextState("SEND_CMD")
@@ -141,12 +129,7 @@ class SATABISTChecker(Module):
                                ),
                                If(sink.eop,
                                        If(sink.last,
-                                               loops_counter.ce.eq(1),
-                                               If(loops_counter.value == (self.loops-1),
-                                                       NextState("IDLE")
-                                               ).Else(
-                                                       NextState("SEND_CMD")
-                                               )
+                                               NextState("IDLE")
                                        ).Else(
                                                NextState("WAIT_ACK")
                                        )
@@ -160,9 +143,9 @@ class SATABISTControl(Module, AutoCSR):
                self._sector = CSRStorage(48)
                self._count = CSRStorage(16)
                self._random = CSRStorage()
-               self._loops = CSRStorage(8)
                self._done = CSRStatus()
                self._errors = CSRStatus(32)
+               self._cycles = CSRStatus(32)
 
                ###
                self.bist_unit = bist_unit
@@ -170,13 +153,17 @@ class SATABISTControl(Module, AutoCSR):
                        bist_unit.start.eq(self._start.r & self._start.re),
                        bist_unit.sector.eq(self._sector.storage),
                        bist_unit.count.eq(self._count.storage),
-                       bist_unit.loops.eq(self._loops.storage),
                        bist_unit.random.eq(self._random.storage),
 
                        self._done.status.eq(bist_unit.done),
                        self._errors.status.eq(bist_unit.errors)
                ]
 
+               self.cycles_counter = Counter(self._cycles.status)
+               self.sync += [
+                       self.cycles_counter.reset.eq(bist_unit.start),
+                       self.cycles_counter.ce.eq(~bist_unit.done)
+               ]
 class SATABIST(Module, AutoCSR):
        def __init__(self, sata_master_ports, with_control=False):
                generator = SATABISTGenerator(sata_master_ports[0])
index 2cc5f5a8de6566a84f278381487780af4259baa6..00fa7205eb07e65eb9b57f28a32ba72d4505b7cd 100644 (file)
@@ -164,12 +164,12 @@ class TestDesign(UART2WB, AutoCSR):
        }
        csr_map.update(UART2WB.csr_map)
 
-       def __init__(self, platform, with_mila=True, export_mila=False):
+       def __init__(self, platform, with_mila=False, export_mila=False):
                clk_freq = 166*1000000
                UART2WB.__init__(self, platform, clk_freq)
                self.crg = _CRG(platform)
 
-               self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, speed="SATA3")
+               self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, speed="SATA2")
                self.comb += self.crg.sata_reset.eq(self.sata_phy.ctrl.need_reset)
                self.sata_con = SATACON(self.sata_phy)
 
index 82d11a726fe0c63cd3155ee8acf8373334ba6bda..40b191ff8b7410bceecafc258fe6709e3aeb108a 100644 (file)
@@ -8,18 +8,22 @@ class SATABISTDriver:
        def __init__(self, regs, name):
                self.regs = regs
                self.name = name
-               for s in ["start", "sector", "count", "loops", "random", "done", "errors"]:
+               self.frequency = regs.identifier_frequency.read()
+               self.time = 0
+               for s in ["start", "sector", "count", "random", "done", "errors", "cycles"]:
                        setattr(self, s, getattr(regs, name + "_"+ s))
 
-       def run(self, sector, count, loops, random):
+       def run(self, sector, count, random):
                self.sector.write(sector)
                self.count.write(count)
-               self.loops.write(loops)
                self.random.write(random)
                self.start.write(1)
                while (self.done.read() == 0):
                        pass
-               return self.errors.read()
+               self.time = self.cycles.read()/self.frequency
+               speed = (count*logical_sector_size)/self.time
+               errors = self.errors.read()
+               return (speed, errors)
 
 class SATABISTGeneratorDriver(SATABISTDriver):
        def __init__(self, regs, name):
@@ -29,34 +33,22 @@ class SATABISTCheckerDriver(SATABISTDriver):
        def __init__(self, regs, name):
                SATABISTDriver.__init__(self, regs, name + "_checker")
 
-class Timer:
-       def __init__(self):
-               self.value = None
-
-       def start(self):
-               self._start = time.time()
-
-       def stop(self):
-               self._stop = time.time()
-               self.value = self._stop - self._start
-
 KB = 1024
 MB = 1024*KB
 GB = 1024*MB
 
-def compute_speed(loops, count, elapsed_time, unit):
-       return loops*count*logical_sector_size/unit/elapsed_time
+# Note: use IDENTIFY command to find numbers of sectors
+hdd_max_sector = (32*MB)/logical_sector_size
 
 def _get_args():
        parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
                description="""\
 SATA BIST utility.
 """)
-       parser.add_argument("-s", "--sector", default=0, help="start sector")
-       parser.add_argument("-c", "--count", default=16384, help="number of sectors per transaction")
-       parser.add_argument("-l", "--loops", default=4, help="number of loop for each transaction")
-       parser.add_argument("-r", "--random", default=True, help="use random data")
-
+       parser.add_argument("-s", "--transfer_size", default=4, help="transfer sizes (in MB, up to 16MB)")
+       parser.add_argument("-l", "--total_length", default=256, help="total transfer length (in MB, up to HDD capacity)")
+       parser.add_argument("-r", "--random", action="store_true", help="use random data")
+       parser.add_argument("-c", "--continuous", action="store_true", help="continuous mode (Escape to exit)")
        return parser.parse_args()
 
 if __name__ == "__main__":
@@ -65,28 +57,22 @@ if __name__ == "__main__":
        ###
        generator = SATABISTGeneratorDriver(wb.regs, "sata_bist")
        checker = SATABISTCheckerDriver(wb.regs, "sata_bist")
-       timer = Timer()
 
-       sector = int(args.sector)
-       count = int(args.count)
-       loops = int(args.loops)
+       sector = 0
+       count = int(args.transfer_size)*MB//logical_sector_size
+       length = int(args.total_length)*MB
        random = int(args.random)
+       continuous = int(args.continuous)
        try:
-               while True:
+               while (sector*logical_sector_size < length) or continuous:
                        # generator (write data to HDD)
-                       timer.start()
-                       generator.run(sector, count, loops, random)
-                       timer.stop()
-                       write_speed = compute_speed(loops, count, timer.value, MB)
+                       write_speed, write_errors = generator.run(sector, count, random)
 
                        # checker (read and check data from HDD)
-                       timer.start()
-                       errors = checker.run(sector, count, loops, random)
-                       timer.stop()
-                       read_speed = compute_speed(loops, count, timer.value, MB)
-                       sector += count
+                       read_speed, read_errors = checker.run(sector, count, random)
 
-                       print("sector=%d write_speed=%4.2fMB/sec read_speed=%4.2fMB/sec errors=%d" %(sector, write_speed, read_speed, errors))
+                       print("sector=%d write_speed=%4.2fMB/sec read_speed=%4.2fMB/sec errors=%d" %(sector, write_speed/MB, read_speed/MB, write_errors + read_errors))
+                       sector += count
 
        except KeyboardInterrupt:
                pass