mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
bist: use hardware counter for speed calc and remove loops mode
This commit is contained in:
parent
7ccc5f5274
commit
d13366dd2d
3 changed files with 33 additions and 60 deletions
|
@ -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])
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
60
test/bist.py
60
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
|
||||
|
|
Loading…
Reference in a new issue