mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	rewrite functional backend test code in python
This commit is contained in:
		
							parent
							
								
									9ad859fc0a
								
							
						
					
					
						commit
						674e6d201d
					
				
					 57 changed files with 554 additions and 1238 deletions
				
			
		
							
								
								
									
										275
									
								
								tests/functional/rtlil_cells.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								tests/functional/rtlil_cells.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,275 @@ | |||
| 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) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue