yosys-witness: add append option to yw2yw

Can now append a user defined number of steps to input traces when joining.
If the number of steps is +ve, inputs are all set to 0.
If -ve then steps are skipped.
If all of steps are skipped (including init step) then the input trace will not be copied.
If more than one input trace is provided, the append option will need to be provided the same number of times as there are input traces.
This commit is contained in:
Krystine Sherwin 2023-05-22 11:44:19 +12:00
parent 8c9a0b51d4
commit 18b44a1e84
No known key found for this signature in database
2 changed files with 36 additions and 7 deletions

View File

@ -88,14 +88,31 @@ If two or more inputs are provided they will be concatenated together into the o
""") """)
@click.argument("inputs", type=click.File("r"), nargs=-1) @click.argument("inputs", type=click.File("r"), nargs=-1)
@click.argument("output", type=click.File("w")) @click.argument("output", type=click.File("w"))
def yw2yw(inputs, output): @click.option("--append", "-p", type=int, multiple=True,
help="Number of steps (+ve or -ve) to append to end of input trace. "
+"Can be defined multiple times, following the same order as input traces. ")
def yw2yw(inputs, output, append):
outyw = WriteWitness(output, "yosys-witness yw2yw") outyw = WriteWitness(output, "yosys-witness yw2yw")
join_inputs = len(inputs) > 1 join_inputs = len(inputs) > 1
inyws = {} inyws = {}
for input in inputs:
if not append:
# default to 0
append = [0] * len(inputs)
if len(append) != len(inputs):
print(f"Mismatch in number of --append values ({len(append)}) and input traces ({len(inputs)}).")
sys.exit(1)
for (input, p) in zip(inputs, append):
if (join_inputs): if (join_inputs):
click.echo(f"Loading signals from yosys witness trace {input.name!r}...") click.echo(f"Loading signals from yosys witness trace {input.name!r}...")
inyw = ReadWitness(input) inyw = ReadWitness(input)
if p:
click.echo(f" appending {p} steps")
if (p + len(inyw) <= 0):
click.echo(f" skipping {input.name!r} (only {len(inyw)} steps to skip)")
continue
inyw.append_steps(p)
inyws[input] = inyw inyws[input] = inyw
for clock in inyw.clocks: for clock in inyw.clocks:
if clock not in outyw.clocks: if clock not in outyw.clocks:
@ -119,7 +136,7 @@ def yw2yw(inputs, output):
for t, values in inyw.steps(1): for t, values in inyw.steps(1):
outyw.step(values) outyw.step(values)
click.echo(f"Copied {t + 1} time steps.") click.echo(f" copied {t + 1} time steps.")
first_witness = False first_witness = False
outyw.end_trace() outyw.end_trace()

View File

@ -393,12 +393,16 @@ class ReadWitness:
def init_step(self): def init_step(self):
return self.step(0) return self.step(0)
def non_init_bits(self):
if len(self) > 1:
return len(self.bits[1])
else:
return sum([sig.width for sig in self.signals if not sig.init_only])
def first_step(self): def first_step(self):
values = WitnessValues() values = WitnessValues()
if len(self.bits) <= 1: # may have issues when non_init_bits is 0
raise NotImplementedError("ReadWitness.first_step() not supported for less than 2 steps") values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-self.non_init_bits():])
non_init_bits = len(self.bits[1])
values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-non_init_bits:])
return values return values
def step(self, t): def step(self, t):
@ -410,5 +414,13 @@ class ReadWitness:
for i in range(start, len(self.bits)): for i in range(start, len(self.bits)):
yield i, self.step(i) yield i, self.step(i)
def append_steps(self, t):
if not t:
pass
elif t < 0:
self.bits = self.bits[:t]
else:
self.bits.extend(["0"*self.non_init_bits()]*t)
def __len__(self): def __len__(self):
return len(self.bits) return len(self.bits)