mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 20:38:44 +00:00
275 lines
9.9 KiB
Python
275 lines
9.9 KiB
Python
from itertools import chain
|
|
import random
|
|
|
|
widths = [
|
|
(16, 32, 48, True),
|
|
(16, 32, 48, False),
|
|
(32, 16, 48, True),
|
|
(32, 16, 48, False),
|
|
(32, 32, 16, True),
|
|
(32, 32, 16, False)
|
|
]
|
|
|
|
shift_widths = [
|
|
(32, 6, 32, True, False),
|
|
(32, 6, 32, False, False),
|
|
(32, 6, 64, True, False),
|
|
(32, 6, 64, False, False),
|
|
(32, 32, 16, True, False),
|
|
(32, 32, 16, False, False),
|
|
(32, 6, 32, True, True),
|
|
(32, 6, 32, False, True),
|
|
(32, 6, 64, True, True),
|
|
(32, 6, 64, False, True),
|
|
(32, 32, 16, True, True),
|
|
(32, 32, 16, False, True),
|
|
]
|
|
|
|
def write_rtlil_cell(f, cell_type, inputs, outputs, parameters):
|
|
f.write('autoidx 1\n')
|
|
f.write('module \\gold\n')
|
|
idx = 1
|
|
for name, width in inputs.items():
|
|
f.write(f'\twire width {width} input {idx} \\{name}\n')
|
|
idx += 1
|
|
for name, width in outputs.items():
|
|
f.write(f'\twire width {width} output {idx} \\{name}\n')
|
|
idx += 1
|
|
f.write(f'\tcell ${cell_type} \\UUT\n')
|
|
for (name, value) in parameters.items():
|
|
f.write(f'\t\tparameter \\{name} {value}\n')
|
|
for name in chain(inputs.keys(), outputs.keys()):
|
|
f.write(f'\t\tconnect \\{name} \\{name}\n')
|
|
f.write(f'\tend\nend\n')
|
|
|
|
class BaseCell:
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
class UnaryCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (a_width, _, y_width, signed) in widths:
|
|
yield (f'{a_width}-{y_width}-{'S' if signed else 'U'}',
|
|
{'A_WIDTH' : a_width,
|
|
'A_SIGNED' : int(signed),
|
|
'Y_WIDTH' : y_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['A_WIDTH']}, {'Y': parameters['Y_WIDTH']}, parameters)
|
|
|
|
class BinaryCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (a_width, b_width, y_width, signed) in widths:
|
|
yield (f'{a_width}-{b_width}-{y_width}-{'S' if signed else 'U'}',
|
|
{'A_WIDTH' : a_width,
|
|
'A_SIGNED' : int(signed),
|
|
'B_WIDTH' : b_width,
|
|
'B_SIGNED' : int(signed),
|
|
'Y_WIDTH' : y_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['A_WIDTH'], 'B': parameters['B_WIDTH']}, {'Y': parameters['Y_WIDTH']}, parameters)
|
|
|
|
class ShiftCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (a_width, b_width, y_width, a_signed, b_signed) in shift_widths:
|
|
if not self.name in ('shift', 'shiftx') and b_signed: continue
|
|
if self.name == 'shiftx' and a_signed: continue
|
|
yield (f'{a_width}-{b_width}-{y_width}-{'S' if a_signed else 'U'}{'S' if b_signed else 'U'}',
|
|
{'A_WIDTH' : a_width,
|
|
'A_SIGNED' : int(a_signed),
|
|
'B_WIDTH' : b_width,
|
|
'B_SIGNED' : int(b_signed),
|
|
'Y_WIDTH' : y_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['A_WIDTH'], 'B': parameters['B_WIDTH']}, {'Y': parameters['Y_WIDTH']}, parameters)
|
|
|
|
class MuxCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for width in [10, 20, 40]:
|
|
yield (f'{width}', {'WIDTH' : width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['WIDTH'], 'B': parameters['WIDTH'], 'S': 1}, {'Y': parameters['WIDTH']}, parameters)
|
|
|
|
class BWCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for width in [10, 20, 40]:
|
|
yield (f'{width}', {'WIDTH' : width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
inputs = {'A': parameters['WIDTH'], 'B': parameters['WIDTH']}
|
|
if self.name == "bwmux": inputs['S'] = parameters['WIDTH']
|
|
write_rtlil_cell(f, self.name, inputs, {'Y': parameters['WIDTH']}, parameters)
|
|
|
|
class PMuxCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (width, s_width) in [(10, 1), (10, 4), (20, 4)]:
|
|
yield (f'{width}-{s_width}',
|
|
{'WIDTH' : width,
|
|
'S_WIDTH' : s_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
s_width = parameters['S_WIDTH']
|
|
b_width = parameters['WIDTH'] * s_width
|
|
write_rtlil_cell(f, self.name, {'A': parameters['WIDTH'], 'B': b_width, 'S': s_width}, {'Y': parameters['WIDTH']}, parameters)
|
|
|
|
class BMuxCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (width, s_width) in [(10, 1), (10, 2), (10, 4)]:
|
|
yield (f'{width}-{s_width}', {'WIDTH' : width, 'S_WIDTH' : s_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['WIDTH'] << parameters['S_WIDTH'], 'S': parameters['S_WIDTH']}, {'Y': parameters['WIDTH']}, parameters)
|
|
|
|
class DemuxCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (width, s_width) in [(10, 1), (32, 2), (16, 4)]:
|
|
yield (f'{width}-{s_width}', {'WIDTH' : width, 'S_WIDTH' : s_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['WIDTH'], 'S': parameters['S_WIDTH']}, {'Y': parameters['WIDTH'] << parameters['S_WIDTH']}, parameters)
|
|
|
|
def seeded_randint(seed, a, b):
|
|
r = random.getstate()
|
|
random.seed(seed)
|
|
n = random.randint(a, b)
|
|
random.setstate(r)
|
|
return n
|
|
|
|
class LUTCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for width in [4, 6, 8]:
|
|
lut = seeded_randint(width, 0, 2**width - 1)
|
|
yield (f'{width}', {'WIDTH' : width, 'LUT' : lut})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['WIDTH']}, {'Y': 1}, parameters)
|
|
|
|
class ConcatCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (a_width, b_width) in [(16, 16), (8, 14), (20, 10)]:
|
|
yield (f'{a_width}-{b_width}', {'A_WIDTH' : a_width, 'B_WIDTH' : b_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['A_WIDTH'], 'B' : parameters['B_WIDTH']}, {'Y': parameters['A_WIDTH'] + parameters['B_WIDTH']}, parameters)
|
|
|
|
class SliceCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
for (a_width, offset, y_width) in [(32, 10, 15), (8, 0, 4), (10, 0, 10)]:
|
|
yield (f'{a_width}-{offset}-{y_width}', {'A_WIDTH' : a_width, 'OFFSET' : offset, 'Y_WIDTH': y_width})
|
|
def write_rtlil_file(self, f, parameters):
|
|
write_rtlil_cell(f, self.name, {'A': parameters['A_WIDTH']}, {'Y': parameters['Y_WIDTH']}, parameters)
|
|
|
|
class FailCell(BaseCell):
|
|
def __init__(self, name):
|
|
super().__init__(name)
|
|
def generate_tests(self):
|
|
yield ('', {})
|
|
def write_rtlil_file(self, f, parameters):
|
|
raise Exception(f'\'{self.name}\' cell unimplemented in test generator')
|
|
|
|
rtlil_cells = [
|
|
UnaryCell("not"),
|
|
UnaryCell("pos"),
|
|
UnaryCell("neg"),
|
|
BinaryCell("and"),
|
|
BinaryCell("or"),
|
|
BinaryCell("xor"),
|
|
BinaryCell("xnor"),
|
|
UnaryCell("reduce_and"),
|
|
UnaryCell("reduce_or"),
|
|
UnaryCell("reduce_xor"),
|
|
UnaryCell("reduce_xnor"),
|
|
UnaryCell("reduce_bool"),
|
|
ShiftCell("shl"),
|
|
ShiftCell("shr"),
|
|
ShiftCell("sshl"),
|
|
ShiftCell("sshr"),
|
|
ShiftCell("shift"),
|
|
ShiftCell("shiftx"),
|
|
# ("fa", ["A", "B", "C", "X", "Y"]),
|
|
# ("lcu", ["P", "G", "CI", "CO"]),
|
|
# ("alu", ["A", "B", "CI", "BI", "X", "Y", "CO"]),
|
|
BinaryCell("lt"),
|
|
BinaryCell("le"),
|
|
BinaryCell("eq"),
|
|
BinaryCell("ne"),
|
|
BinaryCell("eqx"),
|
|
BinaryCell("nex"),
|
|
BinaryCell("ge"),
|
|
BinaryCell("gt"),
|
|
BinaryCell("add"),
|
|
BinaryCell("sub"),
|
|
BinaryCell("mul"),
|
|
# BinaryCell("macc"),
|
|
BinaryCell("div"),
|
|
BinaryCell("mod"),
|
|
BinaryCell("divfloor"),
|
|
BinaryCell("modfloor"),
|
|
BinaryCell("pow"),
|
|
UnaryCell("logic_not"),
|
|
BinaryCell("logic_and"),
|
|
BinaryCell("logic_or"),
|
|
SliceCell("slice"),
|
|
ConcatCell("concat"),
|
|
MuxCell("mux"),
|
|
BMuxCell("bmux"),
|
|
PMuxCell("pmux"),
|
|
DemuxCell("demux"),
|
|
LUTCell("lut"),
|
|
# ("sop", ["A", "Y"]),
|
|
# ("tribuf", ["A", "EN", "Y"]),
|
|
# ("specify2", ["EN", "SRC", "DST"]),
|
|
# ("specify3", ["EN", "SRC", "DST", "DAT"]),
|
|
# ("specrule", ["EN_SRC", "EN_DST", "SRC", "DST"]),
|
|
BWCell("bweqx"),
|
|
BWCell("bwmux"),
|
|
# ("assert", ["A", "EN"]),
|
|
# ("assume", ["A", "EN"]),
|
|
# ("live", ["A", "EN"]),
|
|
# ("fair", ["A", "EN"]),
|
|
# ("cover", ["A", "EN"]),
|
|
# ("initstate", ["Y"]),
|
|
# ("anyconst", ["Y"]),
|
|
# ("anyseq", ["Y"]),
|
|
# ("anyinit", ["D", "Q"]),
|
|
# ("allconst", ["Y"]),
|
|
# ("allseq", ["Y"]),
|
|
# ("equiv", ["A", "B", "Y"]),
|
|
# ("print", ["EN", "TRG", "ARGS"]),
|
|
# ("check", ["A", "EN", "TRG", "ARGS"]),
|
|
# ("set_tag", ["A", "SET", "CLR", "Y"]),
|
|
# ("get_tag", ["A", "Y"]),
|
|
# ("overwrite_tag", ["A", "SET", "CLR"]),
|
|
# ("original_tag", ["A", "Y"]),
|
|
# ("future_ff", ["A", "Y"]),
|
|
# ("scopeinfo", []),
|
|
]
|
|
|
|
def generate_test_cases(per_cell):
|
|
tests = []
|
|
names = []
|
|
for cell in rtlil_cells:
|
|
seen_names = set()
|
|
for (name, parameters) in cell.generate_tests():
|
|
if not name in seen_names:
|
|
seen_names.add(name)
|
|
tests.append((cell, parameters))
|
|
names.append(f'{cell.name}-{name}' if name != '' else cell.name)
|
|
if per_cell is not None and len(seen_names) >= per_cell:
|
|
break
|
|
return (names, tests) |