From 4deda89dcb063ffd203ce771c5fd0a13cafaeb30 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 7 Jan 2015 22:15:57 +0100 Subject: [PATCH] simplify bist --- lib/sata/bist.py | 149 ++++++++++++++------------------------- lib/sata/test/bist_tb.py | 17 +++-- targets/test.py | 8 ++- test/bist.py | 84 +++++++++++----------- test/test_bist_mila.py | 4 +- 5 files changed, 112 insertions(+), 150 deletions(-) diff --git a/lib/sata/bist.py b/lib/sata/bist.py index 12a869c4..4948022f 100644 --- a/lib/sata/bist.py +++ b/lib/sata/bist.py @@ -2,23 +2,25 @@ from lib.sata.common import * from lib.sata.link.scrambler import Scrambler from migen.bank.description import * -class SATABISTUnit(Module): +class SATABIST(Module): def __init__(self, sata_con): - sink = sata_con.source - source = sata_con.sink - - self.start = Signal() - self.write_only = Signal() - self.read_only = Signal() + self.write = Signal() + self.read = Signal() self.sector = Signal(48) self.count = Signal(16) + self.loops = Signal(8) + self.done = Signal() - self.ctrl_errors = Signal(32) - self.data_errors = Signal(32) + self.errors = Signal(32) + + ### + + sink = sata_con.source + source = sata_con.sink self.counter = counter = Counter(bits_sign=32) - self.ctrl_error_counter = Counter(self.ctrl_errors, bits_sign=32) - self.data_error_counter = Counter(self.data_errors, 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()) self.comb += [ @@ -30,39 +32,39 @@ class SATABISTUnit(Module): fsm.act("IDLE", self.done.eq(1), counter.reset.eq(1), - If(self.start, - self.ctrl_error_counter.reset.eq(1), - self.data_error_counter.reset.eq(1), - If(self.read_only, - NextState("SEND_READ_CMD") - ).Else( - NextState("SEND_WRITE_CMD_AND_DATA") - ) + loops_counter.reset.eq(1), + If(self.write, + self.error_counter.reset.eq(1), + NextState("SEND_WRITE_CMD_AND_DATA") + ).Elif(self.read, + self.error_counter.reset.eq(1), + NextState("SEND_READ_CMD") ) ) fsm.act("SEND_WRITE_CMD_AND_DATA", source.stb.eq(1), - source.sop.eq((counter.value == 0)), - source.eop.eq((counter.value == (logical_sector_size//4*self.count)-1)), + source.sop.eq(counter.value == 0), + source.eop.eq(counter.value == (logical_sector_size//4*self.count)-1), source.write.eq(1), source.sector.eq(self.sector), source.count.eq(self.count), source.data.eq(scrambler.value), - counter.ce.eq(source.ack), - If(source.stb & source.eop & source.ack, - NextState("WAIT_WRITE_ACK") + If(source.stb & source.ack, + counter.ce.eq(1), + If(source.eop, + NextState("WAIT_WRITE_ACK") + ) ) ) fsm.act("WAIT_WRITE_ACK", sink.ack.eq(1), If(sink.stb, - If(~sink.write | ~sink.success | sink.failed, - self.ctrl_error_counter.ce.eq(1) - ), - If(self.write_only, + loops_counter.ce.eq(1), + If(loops_counter.value == (self.loops-1), NextState("IDLE") ).Else( - NextState("SEND_READ_CMD") + counter.reset.eq(1), + NextState("SEND_WRITE_CMD_AND_DATA") ) ) ) @@ -80,9 +82,6 @@ class SATABISTUnit(Module): ) fsm.act("WAIT_READ_ACK", If(sink.stb & sink.read, - If(~sink.read | ~sink.success | sink.failed, - self.ctrl_error_counter.ce.eq(1) - ), NextState("RECEIVE_READ_DATA") ) ) @@ -91,11 +90,16 @@ class SATABISTUnit(Module): If(sink.stb, counter.ce.eq(1), If(sink.data != scrambler.value, - self.data_error_counter.ce.eq(1) + self.error_counter.ce.eq(1) ), If(sink.eop, If(sink.last, - NextState("IDLE") + loops_counter.ce.eq(1), + If(loops_counter.value == (self.loops-1), + NextState("IDLE") + ).Else( + NextState("SEND_READ_CMD") + ) ).Else( NextState("WAIT_READ_ACK") ) @@ -103,71 +107,24 @@ class SATABISTUnit(Module): ) ) -class SATABIST(Module, AutoCSR): - def __init__(self, sata_con): - self._start = CSR() - self._start_sector = CSRStorage(48) +class SATABISTControl(Module, AutoCSR): + def __init__(self, sata_bist): + self._write = CSR() + self._read = CSR() + self._sector = CSRStorage(48) self._count = CSRStorage(16) - self._write_only = CSRStorage() - self._read_only = CSRStorage() - - self._stop = CSRStorage() + self._loops = CSRStorage(8) - self._sector = CSRStatus(48) + self._done = CSRStatus() self._errors = CSRStatus(32) - start = self._start.r & self._start.re - start_sector = self._start_sector.storage - count = self._count.storage - stop = self._stop.storage - - compute = Signal() - - write_only = self._write_only.storage - read_only = self._read_only.storage - sector = self._sector.status - errors = self._errors.status - - ### - - self.unit = SATABISTUnit(sata_con) self.comb += [ - self.unit.write_only.eq(write_only), - self.unit.read_only.eq(read_only), - self.unit.sector.eq(sector), - self.unit.count.eq(count) - ] - - self.fsm = fsm = FSM(reset_state="IDLE") - - # FSM - fsm.act("IDLE", - If(start, - NextState("START") - ) - ) - fsm.act("START", - self.unit.start.eq(1), - NextState("WAIT_DONE") - ) - fsm.act("WAIT_DONE", - If(self.unit.done, - NextState("COMPUTE") - ).Elif(stop, - NextState("IDLE") - ) - ) - fsm.act("COMPUTE", - compute.eq(1), - NextState("START") - ) - - self.sync += [ - If(start, - errors.eq(0), - sector.eq(start_sector) - ).Elif(compute, - errors.eq(errors + self.unit.data_errors), - sector.eq(sector + count) - ) + sata_bist.write.eq(self._write.r & self._write.re), + sata_bist.read.eq(self._read.r & self._read.re), + sata_bist.sector.eq(self._sector.storage), + sata_bist.count.eq(self._count.storage), + sata_bist.loops.eq(self._loops.storage), + + self._done.status.eq(sata_bist.done), + self._errors.status.eq(sata_bist.errors) ] diff --git a/lib/sata/test/bist_tb.py b/lib/sata/test/bist_tb.py index a3a8114a..06476737 100644 --- a/lib/sata/test/bist_tb.py +++ b/lib/sata/test/bist_tb.py @@ -1,6 +1,6 @@ from lib.sata.common import * from lib.sata import SATACON -from lib.sata.bist import SATABISTUnit +from lib.sata.bist import SATABIST from lib.sata.test.hdd import * from lib.sata.test.common import * @@ -12,21 +12,28 @@ class TB(Module): transport_debug=False, transport_loopback=False, hdd_debug=True) self.con = SATACON(self.hdd.phy) - self.bist = SATABISTUnit(self.con) + self.bist = SATABIST(self.con) def gen_simulation(self, selfp): hdd = self.hdd hdd.malloc(0, 64) selfp.bist.sector = 0 selfp.bist.count = 17 + selfp.bist.loops = 1 while True: - selfp.bist.start = 1 + selfp.bist.write = 1 yield - selfp.bist.start = 0 + selfp.bist.write = 0 yield while selfp.bist.done == 0: yield - print("ctrl_errors: {} / data_errors {}".format(selfp.bist.ctrl_errors, selfp.bist.data_errors)) + selfp.bist.read = 1 + yield + selfp.bist.read = 0 + yield + while selfp.bist.done == 0: + yield + print("errors {}".format(selfp.bist.errors)) selfp.bist.sector += 1 selfp.bist.count = max((selfp.bist.count + 1)%8, 1) diff --git a/targets/test.py b/targets/test.py index 25b04e47..b6346eb6 100644 --- a/targets/test.py +++ b/targets/test.py @@ -13,7 +13,7 @@ from misoclib import identifier from lib.sata.common import * from lib.sata.phy import SATAPHY from lib.sata import SATACON -from lib.sata.bist import SATABIST +from lib.sata.bist import SATABIST, SATABISTControl from migen.genlib.cdc import * @@ -159,8 +159,8 @@ class DebugLeds(Module): class TestDesign(UART2WB, AutoCSR): default_platform = "kc705" csr_map = { - "sata_bist": 10, - "mila": 11 + "sata_bist_ctrl": 10, + "mila": 11 } csr_map.update(UART2WB.csr_map) @@ -172,6 +172,8 @@ class TestDesign(UART2WB, AutoCSR): self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, speed="SATA2") self.sata_con = SATACON(self.sata_phy) self.sata_bist = SATABIST(self.sata_con) + self.sata_bist_ctrl = SATABISTControl(self.sata_bist) + self.leds = DebugLeds(platform, self.sata_phy) diff --git a/test/bist.py b/test/bist.py index 41482fd6..86d116a2 100644 --- a/test/bist.py +++ b/test/bist.py @@ -7,47 +7,24 @@ logical_sector_size = 512 class SATABISTDriver: def __init__(self, regs): self.regs = regs - self.last_sector = 0 - self.last_time = time.time() - self.last_errors = 0 - self.mode = "rw" - def set_mode(self, mode): - self.mode = mode - self.regs.sata_bist_write_only.write(0) - self.regs.sata_bist_read_only.write(0) - if mode == "wr": - self.regs.sata_bist_write_only.write(1) - if mode == "rd": - self.regs.sata_bist_read_only.write(1) + def run(self, sector, count, loops, mode): + self.regs.sata_bist_ctrl_sector.write(sector) + self.regs.sata_bist_ctrl_count.write(count) + self.regs.sata_bist_ctrl_loops.write(loops) + if mode == "write": + self.regs.sata_bist_ctrl_write.write(1) + elif mode == "read": + self.regs.sata_bist_ctrl_read.write(1) + while (self.regs.sata_bist_ctrl_done.read() == 0): + pass + return self.regs.sata_bist_ctrl_errors.read() - def start(self, sector, count, mode): - self.set_mode(mode) - self.regs.sata_bist_start_sector.write(sector) - self.regs.sata_bist_count.write(count) - self.regs.sata_bist_stop.write(0) - self.regs.sata_bist_start.write(1) - - def stop(self): - self.regs.sata_bist_stop.write(1) - - def show_status(self): - errors = self.regs.sata_bist_errors.read() - self.last_errors - self.last_errors += errors - - sector = self.regs.sata_bist_sector.read() - n = sector - self.last_sector - self.last_sector = sector - - t = self.last_time - time.time() - self.last_time = time.time() - - if self.mode in ["wr", "rd"]: - speed_mult = 1 - else: - speed_mult = 2 - print("%4.2f MB/sec errors=%d sector=%d" %(n*logical_sector_size*speed_mult/(1024*1024), errors, sector)) + def write(self, sector, count, loops): + self.run(sector, count, loops, "write") + def read(self, sector, count, loops): + return self.run(sector, count, loops, "read") def _get_args(): parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, @@ -55,8 +32,8 @@ def _get_args(): SATA BIST utility. """) parser.add_argument("-s", "--sector", default=0, help="BIST start sector") - parser.add_argument("-c", "--count", default=4, help="BIST count (number of sectors per transaction)") - parser.add_argument("-m", "--mode", default="rw", help="BIST mode (rw, wr, rd") + parser.add_argument("-c", "--count", default=16384, help="BIST count (number of sectors per transaction)") + parser.add_argument("-l", "--loops", default=4, help="BIST loops (number of loop for each transaction") return parser.parse_args() @@ -65,13 +42,32 @@ if __name__ == "__main__": wb.open() ### bist = SATABISTDriver(wb.regs) + sector = int(args.sector) + count = int(args.count) + loops = int(args.loops) try: - bist.start(int(args.sector), int(args.count), args.mode) + write_time = 0 + read_time = 0 while True: - bist.show_status() - time.sleep(1) + # Write + start = time.time() + bist.write(sector, count, loops) + end = time.time() + write_time = end-start + write_speed = loops*count*logical_sector_size/(1024*1024)/write_time + + # Read + start = time.time() + read_errors = bist.read(sector, count, loops) + end = time.time() + read_time = end-start + read_speed = loops*count*logical_sector_size/(1024*1024)/read_time + + sector += count + + print("sector=%d write_speed=%4.2fMB/sec read_speed=%4.2fMB/sec errors=%d" %(sector, write_speed, read_speed, read_errors)) + except KeyboardInterrupt: pass - bist.stop() ### wb.close() diff --git a/test/test_bist_mila.py b/test/test_bist_mila.py index 7e6c2767..0fa211ee 100644 --- a/test/test_bist_mila.py +++ b/test/test_bist_mila.py @@ -27,9 +27,9 @@ mila.prog_sum("term") # Trigger / wait / receive mila.trigger(offset=32, length=1024) -bist.start(0, 4, "rw") +bist.write(0, 16, 1) +bist.read(0, 16, 1) mila.wait_done() -bist.stop() mila.read() mila.export("dump.vcd") -- 2.30.2