From 91bb5316413c26462b52731c38ec78480d2259fb Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 22 Jan 2015 01:33:02 +0100 Subject: [PATCH] bist: add loops parameter for more precision in speed computation --- litesata/frontend/bist.py | 39 +++++++++++++++++++++++++++++++++++---- test/bist.py | 32 ++++++++++++++++++++++++++------ test/test_link.py | 4 ++-- 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/litesata/frontend/bist.py b/litesata/frontend/bist.py index afb8daef..e34e71bc 100644 --- a/litesata/frontend/bist.py +++ b/litesata/frontend/bist.py @@ -146,7 +146,9 @@ class LiteSATABISTUnitCSR(Module, AutoCSR): self._start = CSR() self._sector = CSRStorage(48) self._count = CSRStorage(16) + self._loops = CSRStorage(8) self._random = CSRStorage() + self._done = CSRStatus() self._aborted = CSRStatus() self._errors = CSRStatus(32) @@ -155,21 +157,50 @@ class LiteSATABISTUnitCSR(Module, AutoCSR): ### self.bist_unit = bist_unit + start = self._start.r & self._start.re + done = self._done.status + loops = self._loops.storage + self.comb += [ - 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.random.eq(self._random.storage), - self._done.status.eq(bist_unit.done), self._aborted.status.eq(bist_unit.aborted), self._errors.status.eq(bist_unit.errors) ] + self.fsm = fsm = FSM(reset_state="IDLE") + self.loop_counter = Counter(bits_sign=8) + fsm.act("IDLE", + self._done.status.eq(1), + self.loop_counter.reset.eq(1), + If(start, + NextState("CHECK") + ) + ) + fsm.act("CHECK", + If(self.loop_counter.value < loops, + NextState("START") + ).Else( + NextState("IDLE") + ) + ) + fsm.act("START", + bist_unit.start.eq(1), + NextState("WAIT_DONE") + ) + fsm.act("WAIT_DONE", + If(bist_unit.done, + self.loop_counter.ce.eq(1), + NextState("CHECK") + ) + ) + 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) + self.cycles_counter.reset.eq(start), + self.cycles_counter.ce.eq(~fsm.ongoing("IDLE")) ] class LiteSATABISTIdentify(Module): diff --git a/test/bist.py b/test/bist.py index 464954d2..a707199c 100644 --- a/test/bist.py +++ b/test/bist.py @@ -9,27 +9,45 @@ GB = 1024*MB logical_sector_size = 512 +class Timer: + def __init__(self): + self.value = None + + def start(self): + self._start = time.time() + + def stop(self): + self._stop = time.time() + self.value = max(self._stop - self._start, 1/1000000) + class LiteSATABISTUnitDriver: def __init__(self, regs, name): self.regs = regs self.name = name self.frequency = regs.identifier_frequency.read() self.time = 0 - for s in ["start", "sector", "count", "random", "done", "aborted", "errors", "cycles"]: + for s in ["start", "sector", "count", "loops", "random", "done", "aborted", "errors", "cycles"]: setattr(self, s, getattr(regs, name + "_"+ s)) - def run(self, sector, count, random, blocking=True): + def run(self, sector, count, loops, random, blocking=True, hw_timer=False): self.sector.write(sector) self.count.write(count) + self.loops.write(loops) self.random.write(random) + timer = Timer() + timer.start() self.start.write(1) if blocking: while (self.done.read() == 0): pass + timer.stop() aborted = self.aborted.read() if not aborted: - self.time = self.cycles.read()/self.frequency - speed = (count*logical_sector_size)/self.time + if hw_timer: + self.time = self.cycles.read()/self.frequency + else: + self.time = timer.value + speed = (loops*count*logical_sector_size)/self.time errors = self.errors.read() else: speed = 0 @@ -111,6 +129,7 @@ SATA BIST utility. """) parser.add_argument("-s", "--transfer_size", default=1024, help="transfer sizes (in KB, up to 16MB)") parser.add_argument("-l", "--total_length", default=256, help="total transfer length (in MB, up to HDD capacity)") + parser.add_argument("-n", "--loops", default=1, help="number of loop per transfer (allow more precision on speed calculation for small transfers)") 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)") parser.add_argument("-i", "--identify", action="store_true", help="only run identify") @@ -130,6 +149,7 @@ if __name__ == "__main__": if not int(args.identify): sector = 0 count = int(args.transfer_size)*KB//logical_sector_size + loops = int(args.loops) length = int(args.total_length)*MB random = int(args.random) continuous = int(args.continuous) @@ -139,7 +159,7 @@ if __name__ == "__main__": # generator (write data to HDD) write_done = False while not write_done: - write_aborted, write_errors, write_speed = generator.run(sector, count, random) + write_aborted, write_errors, write_speed = generator.run(sector, count, loops, random) write_done = not write_aborted if not write_done: retry += 1 @@ -147,7 +167,7 @@ if __name__ == "__main__": # checker (read and check data from HDD) read_done = False while not read_done: - read_aborted, read_errors, read_speed = checker.run(sector, count, random) + read_aborted, read_errors, read_speed = checker.run(sector, count, loops, random) read_done = not read_aborted if not read_done: retry += 1 diff --git a/test/test_link.py b/test/test_link.py index fa4a5d0a..de8013cc 100644 --- a/test/test_link.py +++ b/test/test_link.py @@ -48,8 +48,8 @@ mila.prog_sum("term") mila.trigger(offset=512, length=2000) #identify.run() -generator.run(0, 2, 0) -#checker.run(0, 2, 0) +generator.run(0, 2, 1, 0) +#checker.run(0, 2, 1, 0) mila.wait_done() mila.read() -- 2.30.2