bist: use hardware counter for speed calc and remove loops mode

This commit is contained in:
Florent Kermarrec 2015-01-16 18:14:13 +01:00
parent 7ccc5f5274
commit d13366dd2d
3 changed files with 33 additions and 60 deletions

View 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])

View 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)

View 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