def test_time_run(self): """ Runs a time simulation to verify correct end result behavior of simple simulation. """ arch, hooks, entities = self._generate_architecture() t = arch.time_run(0, 1) self.assertEqual(t, 0.25) rmsg = arch.hook({'inspect': hooks}) self.assertEqual(rmsg['reg']['state'], 255) self.assertEqual(rmsg['clk']['state'], 0) self.assertEqual(rmsg['rst']['state'], 0) self.assertEqual(rmsg['d_bus']['state'], 0) self.assertEqual(rmsg['q_bus']['state'], 255) self.assertEqual(rmsg['const_1']['state'], 1) t = arch.time_run(t, 2) self.assertEqual(t, 0.75) rmsg = arch.hook({'inspect': hooks}) self.assertEqual(rmsg['reg']['state'], 0) self.assertEqual(rmsg['clk']['state'], 1) self.assertEqual(rmsg['rst']['state'], 0) self.assertEqual(rmsg['d_bus']['state'], 1) self.assertEqual(rmsg['q_bus']['state'], 0) self.assertEqual(rmsg['const_1']['state'], 1) # test with empty arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), OrderedDict()) t = arch.time_run(0, 2) t = arch.time_run(t, 3)
def test_reset(self): """ Runs a simple simulation for some time, then reset. Expect sequential components to change state to default. After time-step expect buses to be same as initial time-step """ arch, hooks, entities = self._generate_architecture() arch.logic_run() rmsg = arch.hook({'inspect': ['reg']}) self.assertTrue('reg' in rmsg) self.assertEqual(rmsg['reg']['state'], 0) arch.reset() rmsg = arch.hook({'inspect': ['reg']}) self.assertTrue('reg' in rmsg) self.assertEqual(rmsg['reg']['state'], 255) arch.logic_run() rmsg = arch.hook({'inspect': ['reg']}) self.assertTrue('reg' in rmsg) self.assertEqual(rmsg['reg']['state'], 0) # test with empty arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), OrderedDict()) arch.reset()
def _gen(): f = open(PIPELINE_DEMO_CONFIG_FILEPATH) config = json.loads(f.read()) arch = Architecture.from_dict(config) hooks = arch.get_hooks() f.close() return arch, hooks
def _generate_architecture(): "Generates a valid simple architecture for test" hooks = OrderedDict([('clk', Clock(1)), ('rst', Reset(0))]) hooks.update({'d_bus': Bus(8, 0)}) hooks.update({'q_bus': Bus(8, 0)}) hooks.update({'const_1': Constant(8, 1)}) entities = OrderedDict([('clk', hooks['clk'])]) entities.update({ 'reg': Register(8, hooks['clk'], hooks['rst'], hooks['d_bus'], hooks['q_bus'], default_state=255) }) hooks.update({'reg': entities['reg']}) entities.update({ 'adder': Adder(8, hooks['q_bus'], hooks['const_1'], hooks['d_bus']) }) arch = Architecture(0.25, hooks['clk'], hooks['rst'], None, hooks, entities) return arch, hooks, entities
def _gen(): f = open(SINGLE_CYCLE_FULL_CONFIG_FILEPATH) config = json.loads(f.read()) arch = Architecture.from_dict(config) hooks = arch.get_hooks() f.close() return arch, hooks
def test_hook_inspect(self): """ Test hook interface for valid inspect behavior """ arch, hooks, entities = self._generate_architecture() # valid case rmsg = arch.hook({'inspect': hooks}) self.assertEqual(rmsg['reg']['state'], 255) self.assertEqual(rmsg['clk']['state'], 0) self.assertEqual(rmsg['rst']['state'], 0) self.assertEqual(rmsg['d_bus']['state'], 0) self.assertEqual(rmsg['q_bus']['state'], 0) self.assertEqual(rmsg['const_1']['state'], 1) # invalid missing hook in architecture rmsg = arch.hook({'inspect': ['test']}) self.assertTrue('error' in rmsg['test']) # invalid not an iterable type rmsg = arch.hook({'inspect': 7}) self.assertTrue('error' in rmsg['architecture-hooks-inspect']) # invalid not an iterable type rmsg = arch.hook({'inspect': None}) self.assertTrue('error' in rmsg['architecture-hooks-inspect']) # invalid hook type does not support inspect hooks.update( {'test': Adder(8, hooks['d_bus'], hooks['q_bus'], Bus(8))}) rmsg = arch.hook({'inspect': ['test']}) self.assertTrue('error' in rmsg['test']) # invalid string is not used as an iterable hooks.update( {'test': Adder(8, hooks['d_bus'], hooks['q_bus'], Bus(8))}) rmsg = arch.hook({'inspect': 'test'}) self.assertTrue('error' in rmsg['architecture-hooks-inspect']) # test with empty arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), OrderedDict()) arch.hook({'inspect': []})
def test_generate(self): """ Test generate interface for valid object generate """ arch, hooks, entities = self._generate_architecture() # valid operation rmsg = arch.hook({'inspect': ['clk']}) self.assertEqual(rmsg['clk']['state'], 0) rmsg = arch.generate({'name': 'clk', 'parameters': {'state': 1}}) self.assertTrue('clk' in rmsg) self.assertTrue(rmsg['clk']['success']) rmsg = arch.hook({'inspect': ['clk']}) self.assertEqual(rmsg['clk']['state'], 1) # invalid (lack of entity name) rmsg = arch.generate({'came': 'clk', 'parameters': {'state': 0}}) self.assertTrue('error' in rmsg['architecture-hooks-generate']) rmsg = arch.hook({'inspect': ['clk']}) self.assertEqual(rmsg['clk']['state'], 1) # invalid hook is not in architecture rmsg = arch.generate({'name': 'test', 'parameters': {'state': 0}}) self.assertTrue('error' in rmsg['test']) # invalid, hook does not support generate rmsg = arch.generate({'name': 'reg', 'parameters': {'state': 0}}) self.assertTrue('error' in rmsg['reg']) rmsg = arch.hook({'inspect': ['reg']}) self.assertEqual(rmsg['reg']['state'], 255) # test with empty arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), OrderedDict()) rmsg = arch.generate({'name': 'test', 'parameters': {'state': 99}}) self.assertTrue('error' in rmsg['test'])
def load(self, msg): """ Loads the an architecture from a configuration file. Param: msg is dictionary with a filepath specified to config file Return: dictionary noting resulting state of operation. """ try: f = open(msg['filepath']) config = json.loads(f.read()) self.arch = Architecture.from_dict(config) self.hooks = self.arch.get_hooks() f.close() except KeyError as e: traceback.print_exc() return { 'status': False, 'error': 'invalid key : {}'.format(str(e)) } except Exception as e: traceback.print_exc() return {'status': False, 'error': 'exception : {}'.format(str(e))} return {'status': True}
def generate_single_cycle_architecture(): "Illustrates the necessary process to construct an architecture" # define system resources clk = Clock(10, 0) rst = Reset(0) hooks = OrderedDict([('clk', clk), ('rst', rst)]) # define input hooks and constants hooks.update({'const8': Constant(32, 8)}) hooks.update({'const4': Constant(32, 4)}) hooks.update({'const14': Constant(4, 14)}) # define buses hooks.update({'pc': Bus(32, 0)}) hooks.update({'pc8': Bus(32, 0)}) hooks.update({'pc4': Bus(32, 0)}) hooks.update({'instr': Bus(32, 0)}) hooks.update({'instr_23_0': Bus(24, 0)}) hooks.update({'instr_19_16': Bus(4, 0)}) hooks.update({'instr_3_0': Bus(4, 0)}) hooks.update({'instr_15_12': Bus(4, 0)}) hooks.update({'instr_11_8': Bus(4, 0)}) hooks.update({'instr_31_28': Bus(4, 0)}) hooks.update({'instr_27_26': Bus(2, 0)}) hooks.update({'instr_25_20': Bus(6, 0)}) hooks.update({'instr_4_4': Bus(1, 0)}) hooks.update({'imm32': Bus(32, 0)}) hooks.update({'ra1': Bus(4, 0)}) hooks.update({'ra2': Bus(4, 0)}) hooks.update({'ra3': Bus(4, 0)}) hooks.update({'rwd': Bus(32, 0)}) hooks.update({'rd1': Bus(32, 0)}) hooks.update({'rd2': Bus(32, 0)}) hooks.update({'alub': Bus(32, 0)}) hooks.update({'branch': Bus(32, 0)}) hooks.update({'aluf': Bus(32, 0)}) hooks.update({'aluc': Bus(1, 0)}) hooks.update({'aluv': Bus(1, 0)}) hooks.update({'alun': Bus(1, 0)}) hooks.update({'aluz': Bus(1, 0)}) hooks.update({'aluflag': Bus(4, 0)}) hooks.update({'flag': Bus(4, 0)}) hooks.update({'c': Bus(1, 0)}) hooks.update({'v': Bus(1, 0)}) hooks.update({'n': Bus(1, 0)}) hooks.update({'z': Bus(1, 0)}) hooks.update({'memrd': Bus(32, 0)}) hooks.update({'wdb': Bus(32, 0)}) hooks.update({'pcwb': Bus(32, 0)}) # control signals hooks.update({'pcwr': Bus(1, 0)}) hooks.update({'regsa': Bus(1, 0)}) hooks.update({'regdst': Bus(2, 0)}) hooks.update({'regwrs': Bus(2, 0)}) hooks.update({'wdbs': Bus(1, 0)}) hooks.update({'regwr': Bus(1, 0)}) hooks.update({'exts': Bus(2, 0)}) hooks.update({'alu8rcb': Bus(1, 0)}) hooks.update({'alus': Bus(4, 0)}) hooks.update({'aluflagwr': Bus(1, 0)}) hooks.update({'memwr': Bus(1, 0)}) hooks.update({'regsrc': Bus(1, 0)}) hooks.update({'pcsrc': Bus(2, 0)}) # generate components # FETCH entities = OrderedDict([('clk', clk)]) entities.update({'pc_reg': Register(32, hooks['clk'], hooks['rst'], hooks['pcwb'], hooks['pc'], 0, enable=hooks['pcwr'], edge_type=Latch_Type.FALLING_EDGE)}) entities.update({'add8': Adder(32, hooks['pc'], hooks['const8'], hooks['pc8'])}) entities.update({'add4': Adder(32, hooks['pc'], hooks['const4'], hooks['pc4'])}) entities.update({'progmem': ProgramMemory(hooks['pc'], hooks['rst'], hooks['instr'])}) # DECODE entities.update({'instr_subset': BusSubset(hooks['instr'], [hooks['instr_23_0'], hooks['instr_19_16'], hooks['instr_3_0'], hooks['instr_15_12'], hooks['instr_11_8'], hooks['instr_31_28'], hooks['instr_27_26'], hooks['instr_25_20'], hooks['instr_4_4']], [(0, 24), (16, 20), (0, 4), (12, 16), (8, 12), (28, 32), (26, 28), (20, 26), (4, 5)])}) entities.update({'controller': ControllerSingleCycle(hooks['instr_31_28'], hooks['instr_27_26'], hooks['instr_25_20'], hooks['instr_15_12'], hooks['instr_4_4'], hooks['c'], hooks['v'], hooks['n'], hooks['z'], hooks['pcsrc'], hooks['pcwr'], hooks['regsa'], hooks['regdst'], hooks['regwrs'], hooks['regwr'], hooks['exts'], hooks['alu8rcb'], hooks['alus'], hooks['aluflagwr'], hooks['memwr'], hooks['regsrc'], hooks['wdbs'])}) entities.update({'ra1_mux': Mux(4, [hooks['instr_3_0'], hooks['instr_19_16']], hooks['regsa'], hooks['ra1'])}) entities.update({'ra2_mux': Mux(4, [hooks['instr_11_8'], hooks['instr_3_0'], hooks['instr_15_12']], hooks['regdst'], hooks['ra2'])}) entities.update({'ra3_mux': Mux(4, [hooks['instr_19_16'], hooks['instr_15_12'], hooks['const14']], hooks['regwrs'], hooks['ra3'])}) entities.update({'rwd_mux': Mux(32, [hooks['wdb'], hooks['pc4']], hooks['wdbs'], hooks['rwd'])}) entities.update({'extimm': Extender(hooks['instr_23_0'], hooks['exts'], hooks['imm32'])}) entities.update({'regfile': RegisterFile(hooks['clk'], hooks['rst'], hooks['regwr'], hooks['rwd'], hooks['ra1'], hooks['ra2'], hooks['ra3'], hooks['rd1'], hooks['rd2'])}) # EXECUTE entities.update({'alu_mux': Mux(32, [hooks['imm32'], hooks['rd2']], hooks['alu8rcb'], hooks['alub'])}) entities.update({'add_br': Adder(32, hooks['pc8'], hooks['imm32'], hooks['branch'])}) entities.update({'alu': Alu(hooks['rd1'], hooks['alub'], hooks['alus'], hooks['aluf'], hooks['aluc'], hooks['aluv'], hooks['alun'], hooks['aluz'])}) entities.update({'aluflag_reg': ALUFlagRegister(hooks['aluc'], hooks['aluv'], hooks['alun'], hooks['aluz'], hooks['rst'], hooks['clk'], hooks['aluflagwr'], hooks['c'], hooks['v'], hooks['n'], hooks['z'])}) # MEMORY & WRITE-BACK entities.update({'datamem': DataMemory(hooks['aluf'], hooks['rd2'], hooks['memwr'], hooks['rst'], hooks['clk'], hooks['memrd'])}) entities.update({'wdb_mux': Mux(32, [hooks['memrd'], hooks['aluf']], hooks['regsrc'], hooks['wdb'])}) entities.update({'pcwb_mux': Mux(32, [hooks['branch'], hooks['pc4'], hooks['wdb']], hooks['pcsrc'], hooks['pcwb'])}) # place memory (Internal) hooks into hook list hooks.update({'pc_reg': entities['pc_reg']}) hooks.update({'progmem': entities['progmem']}) hooks.update({'regfile': entities['regfile']}) hooks.update({'aluflag_reg': entities['aluflag_reg']}) hooks.update({'datamem': entities['datamem']}) hooks.update({'controller': entities['controller']}) # generate simulatable architecture arch = Architecture(0.0001, clk, rst, None, hooks, entities) return arch, hooks
def test_from_dict(self): "Validates dictionary constructor" config = { "packages": ["user"], "system_clock": "clk", "system_reset": "rst", "system_memory": None, "time_step": 0.001, "signals": [{ "name": "container", "symbolic": True, "view": {}, "signals": [{ "name": "clk", "package": "core", "simulation": { "model": "Clock", "frequency": 1, "append_to_entities": True, "width": 1 }, "view": {} }, { "name": "rst", "package": "core", "simulation": { "model": "Reset", "width": 1 }, "view": {} }, { "name": "d", "package": "core", "simulation": { "model": "Bus", "width": 4 }, "view": {} }, { "name": "q", "package": "core", "simulation": { "model": "Bus", "width": 4 }, "view": {} }, { "name": "const", "package": "core", "simulation": { "model": "Constant", "width": 4, "value": 3 }, "view": {} }] }], "entities": [{ "name": "container", "symbolic": True, "view": {}, "entities": [{ "name": "adder", "package": "core", "simulation": { "model": "Adder", "width": 4, "input_1": "const", "input_2": "q", "output": "d" }, "view": {} }, { "name": "register", "package": "core", "simulation": { "model": "Register", "append_to_signals": True, "width": 4, "clock": "clk", "reset": "rst", "input": "d", "output": "q", "edge_type": "both_edge" }, "view": {} }] }] } arch = Architecture.from_dict(config) self.assertEqual(arch.inspect(["q"])["q"]["state"], 0) arch.logic_run() arch.logic_run() arch.logic_run() self.assertEqual(arch.inspect(["q"])["q"]["state"], 15)
def test_constructor(self): """ Test constructor with a simple architecture along with invalid cases. """ hooks = OrderedDict([('clk', Clock(1)), ('rst', Reset(0))]) hooks.update({'d_bus': Bus(8, 0)}) hooks.update({'q_bus': Bus(8, 0)}) hooks.update({'const_1': Constant(8, 1)}) entities = OrderedDict([('clk', hooks['clk'])]) entities.update({ 'reg': Register(8, hooks['clk'], hooks['rst'], hooks['d_bus'], hooks['q_bus'], default_state=255) }) hooks.update({'reg': entities['reg']}) entities.update({ 'adder': Adder(8, hooks['q_bus'], hooks['const_1'], hooks['d_bus']) }) # time step must be positive with self.assertRaises(ValueError): arch = Architecture(0, hooks['clk'], hooks['rst'], None, hooks, entities) # time step must not be greater than logic step with self.assertRaises(ValueError): arch = Architecture(0.6, hooks['clk'], hooks['rst'], None, hooks, entities) # provide a not Clock type clock with self.assertRaises(TypeError): arch = Architecture(0.25, Bus(1), hooks['rst'], None, hooks, entities) # provide a not Reset type reset with self.assertRaises(TypeError): arch = Architecture(0.25, hooks['clk'], Bus(1), None, hooks, entities) # provide wrong data structure for hooks with self.assertRaises(TypeError): arch = Architecture(0.25, Clock(1), Reset(), None, [], OrderedDict()) # provide wrong data structure for entities with self.assertRaises(TypeError): arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), {}) # provide wrong data structure for entities with self.assertRaises(TypeError): arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), []) # construct valid empty architecture arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), OrderedDict()) # construct valid architecture with contents arch = Architecture(0.25, hooks['clk'], hooks['rst'], None, hooks, entities)
def test_hook_modify(self): """ Test hook interface for valid modify behavior """ arch, hooks, entities = self._generate_architecture() # valid operation rmsg = arch.hook({'inspect': ['reg']}) self.assertEqual(rmsg['reg']['state'], 255) rmsg = arch.hook( {'modify': { 'name': 'reg', 'parameters': { 'state': 15 } }}) self.assertTrue('reg' in rmsg) self.assertTrue(rmsg['reg']['success']) rmsg = arch.hook({'inspect': ['reg']}) self.assertEqual(rmsg['reg']['state'], 15) # invalid (lack of entity name) rmsg = arch.hook( {'modify': { 'came': 'reg', 'parameters': { 'state': 25 } }}) self.assertTrue('error' in rmsg['architecture-hooks-modify']) rmsg = arch.hook({'inspect': ['reg']}) self.assertEqual(rmsg['reg']['state'], 15) # invalid hook is not in architecture rmsg = arch.hook( {'modify': { 'name': 'test', 'parameters': { 'state': 35 } }}) self.assertTrue('error' in rmsg['test']) # invalid, hook does not support modify rmsg = arch.hook( {'modify': { 'name': 'rst', 'parameters': { 'state': 45 } }}) self.assertTrue('error' in rmsg['rst']) rmsg = arch.hook({'inspect': ['rst']}) self.assertEqual(rmsg['rst']['state'], 0) # test with empty arch = Architecture(0.25, Clock(1), Reset(), None, OrderedDict(), OrderedDict()) rmsg = arch.hook( {'modify': { 'name': 'test', 'parameters': { 'state': 99 } }}) self.assertTrue('error' in rmsg['test'])
def generate_pipeline_architecture(): "Illustrates the necessary process to construct an architecture" ########## define system resources ########## clk = Clock(10, 0) rst = Reset(0) hooks = OrderedDict([('clk', clk), ('rst', rst)]) ########## define input hooks and constants ########## hooks.update({'const4': Constant(32, 4)}) hooks.update({'const8': Constant(32, 8)}) hooks.update({'const14': Constant(4, 14)}) ########## define buses ########## hooks.update({'pc': Bus(32, 0)}) hooks.update({'pc4f': Bus(32, 0)}) hooks.update({'pc4d': Bus(32, 0)}) hooks.update({'pc4e': Bus(32, 0)}) hooks.update({'pc4m': Bus(32, 0)}) hooks.update({'pc4w': Bus(32, 0)}) hooks.update({'pc8f': Bus(32, 0)}) hooks.update({'pc8d': Bus(32, 0)}) hooks.update({'braddr': Bus(32, 0)}) hooks.update({'nextaddr': Bus(32, 0)}) hooks.update({'instrf': Bus(32, 0)}) hooks.update({'instrd': Bus(32, 0)}) hooks.update({'instrd_31_28': Bus(4, 0)}) hooks.update({'instrd_27_26': Bus(2, 0)}) hooks.update({'instrd_25_20': Bus(6, 0)}) hooks.update({'instrd_19_16': Bus(4, 0)}) hooks.update({'instrd_15_12': Bus(4, 0)}) hooks.update({'instrd_11_8': Bus(4, 0)}) hooks.update({'instrd_4': Bus(1, 0)}) hooks.update({'instrd_3_0': Bus(4, 0)}) hooks.update({'instrd_23_0': Bus(24, 0)}) hooks.update({'imm32d': Bus(32, 0)}) hooks.update({'imm32e': Bus(32, 0)}) hooks.update({'rdm': Bus(32, 0)}) hooks.update({'rdw': Bus(32, 0)}) hooks.update({'rd1': Bus(32, 0)}) hooks.update({'rd2': Bus(32, 0)}) hooks.update({'rd1d': Bus(32, 0)}) hooks.update({'rd2d': Bus(32, 0)}) hooks.update({'rd1e': Bus(32, 0)}) hooks.update({'rd2e': Bus(32, 0)}) hooks.update({'rd2m': Bus(32, 0)}) hooks.update({'ra1d': Bus(4, 0)}) hooks.update({'ra2d': Bus(4, 0)}) hooks.update({'ra3d': Bus(4, 0)}) hooks.update({'ra1e': Bus(4, 0)}) hooks.update({'ra2e': Bus(4, 0)}) hooks.update({'ra3e': Bus(4, 0)}) hooks.update({'ra3m': Bus(4, 0)}) hooks.update({'ra3w': Bus(4, 0)}) hooks.update({'fe': Bus(32, 0)}) hooks.update({'fm': Bus(32, 0)}) hooks.update({'fw': Bus(32, 0)}) hooks.update({'alub': Bus(32, 0)}) hooks.update({'aluc': Bus(1, 0)}) hooks.update({'aluv': Bus(1, 0)}) hooks.update({'alun': Bus(1, 0)}) hooks.update({'aluz': Bus(1, 0)}) hooks.update({'c': Bus(1, 0)}) hooks.update({'v': Bus(1, 0)}) hooks.update({'n': Bus(1, 0)}) hooks.update({'z': Bus(1, 0)}) hooks.update({'aluflag': Bus(4, 0)}) hooks.update({'flag': Bus(4, 0)}) hooks.update({'data': Bus(32, 0)}) hooks.update({'wd': Bus(32, 0)}) hooks.update({'wd3': Bus(32, 0)}) ########## control signals ########## # decode stage hooks.update({'pcsrcd': Bus(2, 0)}) hooks.update({'pcwrd': Bus(1, 0)}) hooks.update({'regsad': Bus(1, 0)}) hooks.update({'regdstd': Bus(2, 0)}) hooks.update({'regwrsd': Bus(2, 0)}) hooks.update({'regwrd': Bus(1, 0)}) hooks.update({'extsd': Bus(2, 0)}) hooks.update({'alusrcbd': Bus(1, 0)}) hooks.update({'alusd': Bus(4, 0)}) hooks.update({'aluflagwrd': Bus(1, 0)}) hooks.update({'memwrd': Bus(1, 0)}) hooks.update({'regsrcd': Bus(1, 0)}) hooks.update({'wd3sd': Bus(1, 0)}) # execute stage hooks.update({'regwre': Bus(1, 0)}) hooks.update({'alusrcbe': Bus(1, 0)}) hooks.update({'aluse': Bus(4, 0)}) hooks.update({'aluflagwre': Bus(1, 0)}) hooks.update({'memwre': Bus(1, 0)}) hooks.update({'regsrce': Bus(1, 0)}) hooks.update({'wd3se': Bus(1, 0)}) # memory stage hooks.update({'regwrm': Bus(1, 0)}) hooks.update({'memwrm': Bus(1, 0)}) hooks.update({'regsrcm': Bus(1, 0)}) hooks.update({'wd3sm': Bus(1, 0)}) # write back stage hooks.update({'regwrw': Bus(1, 0)}) hooks.update({'regsrcw': Bus(1, 0)}) hooks.update({'wd3sw': Bus(1, 0)}) ########## hazard control signals ########## hooks.update({'fwda': Bus(3, 0)}) hooks.update({'fwdb': Bus(3, 0)}) hooks.update({'fwds': Bus(1, 0)}) hooks.update({'stallf': Bus(1, 0)}) hooks.update({'flushf': Bus(1, 0)}) hooks.update({'flushd': Bus(1, 0)}) ########## generate components ########## entities = OrderedDict([('clk', clk)]) # memwb entities.update({ 'memwb': Memwb(hooks['pc4m'], hooks['regwrm'], hooks['regsrcm'], hooks['wd3sm'], hooks['fm'], hooks['rdm'], hooks['ra3m'], hooks['clk'], hooks['pc4w'], hooks['regwrw'], hooks['regsrcw'], hooks['wd3sw'], hooks['fw'], hooks['rdw'], hooks['ra3w']) }) # exmem entities.update({ 'exmem': Exmem(hooks['pc4e'], hooks['regwre'], hooks['memwre'], hooks['regsrce'], hooks['wd3se'], hooks['rd2'], hooks['fe'], hooks['ra3e'], hooks['clk'], hooks['pc4m'], hooks['regwrm'], hooks['memwrm'], hooks['regsrcm'], hooks['wd3sm'], hooks['fm'], hooks['rd2m'], hooks['ra3m']) }) # idex entities.update({ 'idex': Idex(hooks['pc4d'], hooks['regwrd'], hooks['alusrcbd'], hooks['alusd'], hooks['aluflagwrd'], hooks['memwrd'], hooks['regsrcd'], hooks['wd3sd'], hooks['rd1d'], hooks['rd2d'], hooks['imm32d'], hooks['ra1d'], hooks['ra2d'], hooks['ra3d'], hooks['flushd'], hooks['clk'], hooks['pc4e'], hooks['regwre'], hooks['alusrcbe'], hooks['aluse'], hooks['aluflagwre'], hooks['memwre'], hooks['regsrce'], hooks['wd3se'], hooks['rd1e'], hooks['rd2e'], hooks['imm32e'], hooks['ra1e'], hooks['ra2e'], hooks['ra3e']) }) # ifid entities.update({ 'ifid': Ifid(hooks['pc4f'], hooks['pc8f'], hooks['instrf'], hooks['stallf'], hooks['flushf'], hooks['clk'], hooks['pc4d'], hooks['pc8d'], hooks['instrd']) }) # fetch entities.update({ 'addr_mux': Mux(32, [hooks['braddr'], hooks['pc4d'], hooks['fe']], hooks['pcsrcd'], hooks['nextaddr']) }) entities.update({ 'pc_reg': Register(32, hooks['clk'], hooks['rst'], hooks['nextaddr'], hooks['pc'], 0, enable=hooks['pcwrd']) }) entities.update( {'add8': Adder(32, hooks['pc'], hooks['const8'], hooks['pc8f'])}) entities.update( {'add4': Adder(32, hooks['pc'], hooks['const4'], hooks['pc4f'])}) entities.update( {'progmem': ProgramMemory(hooks['pc'], hooks['rst'], hooks['instrf'])}) # decode entities.update({ 'instr_subset': BusSubset(hooks['instrd'], [ hooks['instrd_23_0'], hooks['instrd_31_28'], hooks['instrd_27_26'], hooks['instrd_25_20'], hooks['instrd_19_16'], hooks['instrd_15_12'], hooks['instrd_11_8'], hooks['instrd_4'], hooks['instrd_3_0'] ], [(0, 24), (28, 32), (26, 28), (20, 26), (16, 20), (12, 16), (8, 12), (4, 5), (0, 4)]) }) entities.update({ 'controller': ControllerPipeline(hooks['instrd_31_28'], hooks['instrd_27_26'], hooks['instrd_25_20'], hooks['instrd_15_12'], hooks['instrd_4'], hooks['c'], hooks['v'], hooks['n'], hooks['z'], hooks['stallf'], hooks['pcsrcd'], hooks['pcwrd'], hooks['regsad'], hooks['regdstd'], hooks['regwrsd'], hooks['regwrd'], hooks['extsd'], hooks['alusrcbd'], hooks['alusd'], hooks['aluflagwrd'], hooks['memwrd'], hooks['regsrcd'], hooks['wd3sd']) }) entities.update({ 'ra1_mux': Mux(4, [hooks['instrd_3_0'], hooks['instrd_19_16']], hooks['regsad'], hooks['ra1d']) }) entities.update({ 'ra2_mux': Mux(4, [hooks['instrd_11_8'], hooks['instrd_3_0'], hooks['instrd_15_12']], hooks['regdstd'], hooks['ra2d']) }) entities.update({ 'ra3_mux': Mux(4, [hooks['instrd_19_16'], hooks['instrd_15_12'], hooks['const14']], hooks['regwrsd'], hooks['ra3d']) }) entities.update({ 'extimm': Extender(hooks['instrd_23_0'], hooks['extsd'], hooks['imm32d']) }) entities.update({ 'add_branch': Adder(32, hooks['pc8d'], hooks['imm32d'], hooks['braddr']) }) entities.update({ 'regfile': RegisterFile(hooks['clk'], hooks['rst'], hooks['regwrw'], hooks['wd'], hooks['ra1d'], hooks['ra2d'], hooks['ra3w'], hooks['rd1d'], hooks['rd2d'], edge_type=Latch_Type.FALLING_EDGE) }) # execute entities.update({ 'hazard_controller': HazardController(hooks['ra1e'], hooks['ra2e'], hooks['ra3e'], hooks['ra3m'], hooks['ra3w'], hooks['regwrm'], hooks['regwrw'], hooks['regsrcm'], hooks['regsrcw'], hooks['memwrm'], hooks['pcsrcd'], hooks['fwda'], hooks['fwdb'], hooks['fwds'], hooks['stallf'], hooks['flushf'], hooks['flushd']) }) entities.update({ 'fwda_mux': Mux(32, [ hooks['rd1e'], hooks['fw'], hooks['fm'], hooks['rdm'], hooks['rdw'] ], hooks['fwda'], hooks['rd1']) }) entities.update({ 'fwdb_mux': Mux(32, [ hooks['rd2e'], hooks['fw'], hooks['fm'], hooks['rdm'], hooks['rdw'] ], hooks['fwdb'], hooks['rd2']) }) entities.update({ 'alu_mux': Mux(32, [hooks['imm32e'], hooks['rd2']], hooks['alusrcbe'], hooks['alub']) }) entities.update({ 'alu': Alu(hooks['rd1'], hooks['alub'], hooks['aluse'], hooks['fe'], hooks['aluc'], hooks['aluv'], hooks['alun'], hooks['aluz']) }) entities.update({ 'aluflag_join': BusJoin([hooks['aluc'], hooks['aluv'], hooks['alun'], hooks['aluz']], hooks['aluflag']) }) entities.update({ 'aluflag_reg': Register(4, hooks['clk'], hooks['rst'], hooks['aluflag'], hooks['flag'], enable=hooks['aluflagwre']) }) entities.update({ 'flag_subset': BusSubset(hooks['flag'], [hooks['c'], hooks['v'], hooks['n'], hooks['z']], [(0, 1), (1, 2), (2, 3), (3, 4)]) }) # writeback entities.update({ 'wd3_mux': Mux(32, [hooks['rdw'], hooks['fw']], hooks['regsrcw'], hooks['wd3']) }) entities.update({ 'rwd_mux': Mux(32, [hooks['wd3'], hooks['pc4w']], hooks['wd3sw'], hooks['wd']) }) # memory entities.update({ 'fwds_mux': Mux(32, [hooks['rd2m'], hooks['wd3']], hooks['fwds'], hooks['data']) }) entities.update({ 'datamem': DataMemory(hooks['fm'], hooks['data'], hooks['memwrm'], hooks['rst'], hooks['clk'], hooks['rdm']) }) # place memory (Internal) hooks into hook list hooks.update({'pc_reg': entities['pc_reg']}) hooks.update({'progmem': entities['progmem']}) hooks.update({'regfile': entities['regfile']}) hooks.update({'aluflag_reg': entities['aluflag_reg']}) hooks.update({'datamem': entities['datamem']}) hooks.update({'controller': entities['controller']}) #hooks.update({'hazard_controller': entities['hazard_controller']}) hooks.update({'ifid': entities['ifid']}) hooks.update({'idex': entities['idex']}) hooks.update({'exmem': entities['exmem']}) hooks.update({'memwb': entities['memwb']}) # generate simulatable architecture arch = Architecture(0.0001, clk, rst, None, hooks, entities) return arch, hooks