bist: add loops parameter for more precision in speed computation

This commit is contained in:
Florent Kermarrec 2015-01-22 01:33:02 +01:00
parent c9761be54f
commit 91bb531641
3 changed files with 63 additions and 12 deletions

View File

@ -146,7 +146,9 @@ class LiteSATABISTUnitCSR(Module, AutoCSR):
self._start = CSR() self._start = CSR()
self._sector = CSRStorage(48) self._sector = CSRStorage(48)
self._count = CSRStorage(16) self._count = CSRStorage(16)
self._loops = CSRStorage(8)
self._random = CSRStorage() self._random = CSRStorage()
self._done = CSRStatus() self._done = CSRStatus()
self._aborted = CSRStatus() self._aborted = CSRStatus()
self._errors = CSRStatus(32) self._errors = CSRStatus(32)
@ -155,21 +157,50 @@ class LiteSATABISTUnitCSR(Module, AutoCSR):
### ###
self.bist_unit = bist_unit self.bist_unit = bist_unit
start = self._start.r & self._start.re
done = self._done.status
loops = self._loops.storage
self.comb += [ self.comb += [
bist_unit.start.eq(self._start.r & self._start.re),
bist_unit.sector.eq(self._sector.storage), bist_unit.sector.eq(self._sector.storage),
bist_unit.count.eq(self._count.storage), bist_unit.count.eq(self._count.storage),
bist_unit.random.eq(self._random.storage), bist_unit.random.eq(self._random.storage),
self._done.status.eq(bist_unit.done),
self._aborted.status.eq(bist_unit.aborted), self._aborted.status.eq(bist_unit.aborted),
self._errors.status.eq(bist_unit.errors) 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.cycles_counter = Counter(self._cycles.status)
self.sync += [ self.sync += [
self.cycles_counter.reset.eq(bist_unit.start), self.cycles_counter.reset.eq(start),
self.cycles_counter.ce.eq(~bist_unit.done) self.cycles_counter.ce.eq(~fsm.ongoing("IDLE"))
] ]
class LiteSATABISTIdentify(Module): class LiteSATABISTIdentify(Module):

View File

@ -9,27 +9,45 @@ GB = 1024*MB
logical_sector_size = 512 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: class LiteSATABISTUnitDriver:
def __init__(self, regs, name): def __init__(self, regs, name):
self.regs = regs self.regs = regs
self.name = name self.name = name
self.frequency = regs.identifier_frequency.read() self.frequency = regs.identifier_frequency.read()
self.time = 0 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)) 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.sector.write(sector)
self.count.write(count) self.count.write(count)
self.loops.write(loops)
self.random.write(random) self.random.write(random)
timer = Timer()
timer.start()
self.start.write(1) self.start.write(1)
if blocking: if blocking:
while (self.done.read() == 0): while (self.done.read() == 0):
pass pass
timer.stop()
aborted = self.aborted.read() aborted = self.aborted.read()
if not aborted: if not aborted:
self.time = self.cycles.read()/self.frequency if hw_timer:
speed = (count*logical_sector_size)/self.time self.time = self.cycles.read()/self.frequency
else:
self.time = timer.value
speed = (loops*count*logical_sector_size)/self.time
errors = self.errors.read() errors = self.errors.read()
else: else:
speed = 0 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("-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("-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("-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("-c", "--continuous", action="store_true", help="continuous mode (Escape to exit)")
parser.add_argument("-i", "--identify", action="store_true", help="only run identify") parser.add_argument("-i", "--identify", action="store_true", help="only run identify")
@ -130,6 +149,7 @@ if __name__ == "__main__":
if not int(args.identify): if not int(args.identify):
sector = 0 sector = 0
count = int(args.transfer_size)*KB//logical_sector_size count = int(args.transfer_size)*KB//logical_sector_size
loops = int(args.loops)
length = int(args.total_length)*MB length = int(args.total_length)*MB
random = int(args.random) random = int(args.random)
continuous = int(args.continuous) continuous = int(args.continuous)
@ -139,7 +159,7 @@ if __name__ == "__main__":
# generator (write data to HDD) # generator (write data to HDD)
write_done = False write_done = False
while not write_done: 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 write_done = not write_aborted
if not write_done: if not write_done:
retry += 1 retry += 1
@ -147,7 +167,7 @@ if __name__ == "__main__":
# checker (read and check data from HDD) # checker (read and check data from HDD)
read_done = False read_done = False
while not read_done: 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 read_done = not read_aborted
if not read_done: if not read_done:
retry += 1 retry += 1

View File

@ -48,8 +48,8 @@ mila.prog_sum("term")
mila.trigger(offset=512, length=2000) mila.trigger(offset=512, length=2000)
#identify.run() #identify.run()
generator.run(0, 2, 0) generator.run(0, 2, 1, 0)
#checker.run(0, 2, 0) #checker.run(0, 2, 1, 0)
mila.wait_done() mila.wait_done()
mila.read() mila.read()