From d13366dd2dc01f48affe4123ba21ab720c41b16f Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 16 Jan 2015 18:14:13 +0100 Subject: [PATCH] bist: use hardware counter for speed calc and remove loops mode --- lib/sata/bist.py | 29 +++++++---------------- targets/test.py | 4 ++-- test/bist.py | 60 +++++++++++++++++++----------------------------- 3 files changed, 33 insertions(+), 60 deletions(-) diff --git a/lib/sata/bist.py b/lib/sata/bist.py index 5de8e7c1..9f0707c4 100644 --- a/lib/sata/bist.py +++ b/lib/sata/bist.py @@ -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]) diff --git a/targets/test.py b/targets/test.py index 2cc5f5a8..00fa7205 100644 --- a/targets/test.py +++ b/targets/test.py @@ -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) diff --git a/test/bist.py b/test/bist.py index 82d11a72..40b191ff 100644 --- a/test/bist.py +++ b/test/bist.py @@ -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 -- 2.30.2