def test_inspect(self): "Check inspect for valid data presentation" l = Constant(8, 255) ins = l.inspect() self.assertTrue(ins['type'] == 'logic') self.assertTrue(ins['size'] == 8) self.assertTrue(ins['state'] == 255)
def test_run(self): "Prove correct combinational output given signals" c1 = Constant(1, 1) c2 = Constant(2, 0) c3 = Constant(3, 7) b = Bus(6) bj = BusJoin([c1, c2, c3], b) bj.run() self.assertTrue(b.read() == 0x39)
def test_run(self): "Prove correct combinational output given signals" c0 = Constant(8, 150) c1 = Constant(8, 5) c2 = Constant(8, 255) s = Bus(2, 0) y = Bus(8, 1) m = Mux(8, [c0, c1, c2], s, y) m.run() self.assertTrue(y.read() == c0.read()) s.write(1) m.run() self.assertTrue(y.read() == c1.read()) s.write(2) m.run() self.assertTrue(y.read() == c2.read()) s.write(3) m.run() self.assertTrue(y.read() == 0) s.write(0) m = Mux(8, [c0, c1, c2], s) m.run()
def test_out_of_bounds(self): "Test for valid control signal that extends past defined" c0 = Constant(8, 150) c1 = Constant(8, 5) c2 = Constant(8, 255) s = Bus(2, 0) y = Bus(8, 1) m = Mux(8, [c0, c1, c2], s, y) s.write(3) m.run() self.assertTrue(y.read() == 0) # prove valid overflow
def test_from_dict(self): "Validates dictionary constructor" hooks = OrderedDict({ "i1": Constant(8, 0), "i2": Constant(8, 255), "o1": Bus(16) }) config = {"inputs": ["i1", "i2"], "output": "o1"} join = BusJoin.from_dict(config, hooks) join.run() self.assertEqual(hooks["o1"].read(), 0xFF00)
def test_from_dict(self): "Validates dictionary constructor" config = {"width": 64, "value": 0xFFFF0000FFFF0000} const = Constant.from_dict(config, None) #Buses do not need hook reference
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 test_constructor(self): "Constructor with valid and invalid configuration" c0 = Constant(16, 0xAAAA) b0 = Bus(4) b1 = Bus(8) b2 = Bus(2) b3 = Bus(2) with self.assertRaises(TypeError): bj = BusSubset(None, None, None) with self.assertRaises(TypeError): bj = BusSubset('0', None, None) with self.assertRaises(TypeError): bj = BusSubset(c0, None, None) with self.assertRaises(TypeError): bj = BusSubset(c0, [], []) with self.assertRaises(ValueError): bj = BusSubset(c0, ['0'], [(0, 1)]) with self.assertRaises(TypeError): bj = BusSubset(c0, [b0], []) with self.assertRaises(TypeError): bj = BusSubset(c0, [b0], ['0']) with self.assertRaises(TypeError): bj = BusSubset(c0, [b0], [('0', '1')]) with self.assertRaises(ValueError): bj = BusSubset(c0, [b0], [(1, 0)]) with self.assertRaises(ValueError): bj = BusSubset(c0, [b0], [(0, 1)]) with self.assertRaises(ValueError): bj = BusSubset(c0, [b0], [(0, 8)]) bs = BusSubset(c0, [b0, b1, b2, b3], [(0, 4), (4, 12), (12, 14), (14, 16)])
def test_run(self): "Prove correct combinational output given signals" cin = Constant(1, 1) c1 = Constant(8, 1) c2 = Constant(8, 254) y0 = Bus(8) cout = Bus(1) a = Adder(8, c1, c2, y0, cin, cout) a.run() self.assertTrue(y0.read() == 0) self.assertTrue(cout.read() == 1) a.run(50) self.assertTrue(y0.read() == 0) self.assertTrue(cout.read() == 1)
def test_from_dict(self): "Validates dictionary constructor" hooks = OrderedDict({ "i1": Constant(8, 15), "i2": Constant(8, 12), "o1": Bus(8), "cin": Constant(1, 1), "cout": Bus(1) }) config = {"width": 8, "input_1": "i1", "input_2": "i2"} # Without optional adder1 = Adder.from_dict(config, hooks) # With all options config.update({"output": "o1", "carry_in": "cin", "carry_out": "cout"}) adder2 = Adder.from_dict(config, hooks)
def __init__(self, address, rst, read, default_size=DEFAULT_SIZE, default_value=DEFAULT_STATE, rst_type=DEFAULT_RESET_TYPE): """ Buses address : word sized address bus to access program memory rst : Reset bus to clear memory read : word sized bus with addressed instruction Configuration default_size : size of program memory space in bytes default_value : byte value to load into unassigned memory cells rst_type : Activation state for reset line """ # disable write behavior self._wd_const = Constant(32, 0) self._we_const = Constant(1, 0) self._clk_const = Constant(1, 0) # default mode to word access self._mode_const = Constant(2, 3) # ghost memory on bus to lower needed bits if default_size == 0: size = 0 elif default_size < 2: size = 1 else: # len > 2 size = int(math.floor(math.log(default_size - 1, 2) + 1)) self._address_general = Bus(size) self._address_subset = BusSubset(address, [self._address_general], [(0, size)]) # Construct generalized memory passing parameters Memory.__init__(self, default_size, 4, 0, self._address_general, self._wd_const, self._we_const, rst, self._clk_const, self._mode_const, read, default_value, Latch_Type.FALLING_EDGE, rst_type, Logic_States.ACTIVE_HIGH)
def __init__(self, address, write, writeEnable, reset, clock, read, mode=DEFAULT_MODE, default_size=DEFAULT_SIZE, default_value=DEFAULT_STATE, edge_type=DEFAULT_LATCH_TYPE, rst_type=DEFAULT_RESET_TYPE, memwr_type=DEFAULT_ENABLE_TYPE): """ Buses address : bus of size at least as large as size to map to cells write : word sized bus (32-bit) to write to addressed cell writeEnable : enable line to save write data to memory on clock edge reset : System reset line to clear memory clock: System clock line to store memory read : word sized bus (32-bit) to read from addressed cell mode : 2-bit bus signaling read type of memory 0 = memory off (return 0) (no write) 1 = byte access (read/write ignores upper bits) 2 = half-word access (read/write ignores upper bits) 3 = word access (default) Configuration default_size : size of program memory space in bytes default_value : byte value to load into unassigned memory cells edge_type : Store data on this clock edge rst_type : Activation state for reset line memwr_type : Activation state for storing on write clock edge """ # handle optional accessMode bus if mode is None: mode = Constant(2, 3) # ghost memory on bus to lower needed bits if default_size < 0: raise ValueError('Size must be within valid range') elif default_size == 0: size = 0 elif default_size < 2: size = 1 else: # len > 2 size = int(math.floor(math.log(default_size - 1, 2) + 1)) self._address_general = Bus(size) self._address_subset = BusSubset(address, [self._address_general], [(0, size)]) # Construct generalized memory passing parameters Memory.__init__(self, default_size, 4, 0, self._address_general, write, writeEnable, reset, clock, mode, read, default_value, edge_type, rst_type, memwr_type)
def test_constructor(self): "Constructor with valid and invalid configuration" c1 = Constant(1, 1) c2 = Constant(2, 0) c3 = Constant(3, 7) b = Bus(6) with self.assertRaises(TypeError): bj = BusJoin(None, None) with self.assertRaises(TypeError): bj = BusJoin(None, b) with self.assertRaises(TypeError): bj = BusJoin([], b) with self.assertRaises(TypeError): bj = BusJoin([c1, c2], None) with self.assertRaises(ValueError): bj = BusJoin([c1, c2], b) bj = BusJoin([c1, c2, c3], b)
def test_large_mux(self): "Test mux for large size to validate scaling algorithm" c0 = Constant(8, 150) c1 = Constant(8, 5) c2 = Constant(8, 255) c3 = Constant(8, 150) c4 = Constant(8, 5) c5 = Constant(8, 255) c6 = Constant(8, 150) c7 = Constant(8, 5) s = Bus(3, 0) y = Bus(8, 1) m = Mux(8, [c0, c1, c2, c3, c4, c5, c6], s, y) c8 = Constant(8, 255) s = Bus(4, 0) m = Mux(8, [c0, c1, c2, c3, c4, c5, c6, c7, c8], s, y)
def test_constructor(self): "Constructor with valid and invalid configuration" c0 = Constant(8, 150) c1 = Constant(8, 5) c2 = Constant(8, 255) s = Bus(2, 0) y = Bus(8, 1) with self.assertRaises(TypeError): m = Mux('0', [c0, c1, c2], s, y) with self.assertRaises(TypeError): m = Mux(0, [c0, c1, c2], s, y) with self.assertRaises(TypeError): m = Mux(8, None, s, y) with self.assertRaises(TypeError): m = Mux(8, [], s, y) with self.assertRaises(TypeError): m = Mux(8, [None], s, y) with self.assertRaises(TypeError): m = Mux(8, ['0', '1', '2'], s, y) with self.assertRaises(TypeError): c = Constant(1, 0) m = Mux(8, [c1, c0, c], s, y) with self.assertRaises(TypeError): m = Mux(8, [c1, c0], None, y) with self.assertRaises(ValueError): s0 = Bus(8, 0) m = Mux(8, [c1, c0], s0, y) with self.assertRaises(ValueError): m = Mux(8, [c1, c0], s, y) with self.assertRaises(TypeError): m = Mux(8, [c1, c0, c2], s, '0') with self.assertRaises(ValueError): y0 = Bus(2) m = Mux(8, [c1, c0, c2], s, y0) m = Mux(8, [c0, c1, c2], s, y) m = Mux(8, [c0, c1, c2], s)
def test_constructor(self): "Constructor with valid and invalid configuration" cin = Constant(1, 1) c1 = Constant(8, 1) c2 = Constant(8, 254) y0 = Bus(8) cout = Bus(1) with self.assertRaises(TypeError): a = Adder('0', c1, c2) with self.assertRaises(TypeError): a = Adder(-1, c1, c2) with self.assertRaises(TypeError): a = Adder(8, None, c2) with self.assertRaises(TypeError): a = Adder(8, c1, None) with self.assertRaises(ValueError): a = Adder(5, c1, c2) with self.assertRaises(TypeError): a = Adder(8, c1, c2, '0') with self.assertRaises(ValueError): y = Bus(5) a = Adder(8, c1, c2, y) with self.assertRaises(TypeError): a = Adder(8, c1, c2, y0, '0') with self.assertRaises(ValueError): c = Constant(8, 5) a = Adder(8, c1, c2, y0, c) with self.assertRaises(TypeError): a = Adder(8, c1, c2, y0, cin, '0') with self.assertRaises(ValueError): c = Bus(8) a = Adder(8, c1, c2, y0, cin, c) a = Adder(8, c1, c2, y0, cin, cout)
def test_constructor(self): "Constructor with valid and invalid configuration" with self.assertRaises(TypeError): l = Constant('8', 0) with self.assertRaises(TypeError): l = Constant(0, 0) with self.assertRaises(TypeError): l = Constant(1, '0') with self.assertRaises(TypeError): l = Constant(1, -1) with self.assertRaises(TypeError): l = Constant(1, 2) with self.assertRaises(Exception): l = Constant(16) l = Constant(1, 1)
def test_run(self): "Prove correct combinational output given signals" c0 = Constant(16, 0xAAAA) b0 = Bus(4) b1 = Bus(8) b2 = Bus(2) b3 = Bus(2) b4 = Bus(1) bs = BusSubset(c0, [b0, b1, b2, b3, b4], [(0, 4), (4, 12), (12, 14), (14, 16), (3, 4)]) bs.run() self.assertTrue(b0.read() == 0x0A) self.assertTrue(b1.read() == 0xAA) self.assertTrue(b2.read() == 0x02) self.assertTrue(b3.read() == 0x02) self.assertTrue(b4.read() == 1)
def test_from_dict(self): "Validates dictionary constructor" hooks = OrderedDict({ "i1": Constant(8, 0x0F), "o1": Bus(4), "o2": Bus(4) }) config = { "input": "i1", "outputs": ["o1", "o2"], "bounds": [[0, 4], [4, 8]] } subset = BusSubset.from_dict(config, hooks) subset.run() self.assertEqual(hooks["o1"].read(), 0xF) self.assertEqual(hooks["o2"].read(), 0x0)
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
def test_size(self): "Valid bus size presented" l = Constant(16, 56) self.assertTrue(l.size() == 16)
def test_read(self): "Valid data on read" l = Constant(8, 97) self.assertTrue(l.read() == 97)
def test_write(self): "Exception expected on write" l = Constant(32, 2600000) with self.assertRaises(Exception): l.write(152)
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_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)
time.sleep(0.5) count += 1 #tf.write(']}') #tf.close() quit() # websocket prototype clk = Clock(10, 0) rst = Reset(1) b0 = Bus(8, 0) b1 = Bus(8, 0) c1 = Constant(8, 1) reg = Register(8, clk, rst, b0, b1) add = Adder(8, c1, b1, b0) hooks = OrderedDict([('clk', clk), ('rst', rst), ('b0', b0), ('b1', b1), ('c1', c1)]) entities = OrderedDict([('clk', clk), ('add', add), ('reg', reg)]) arch = Architecture(0.0001, clk, rst, hooks, entities) msg_inspect = {'inspect': ['clk', 'rst', 'b0', 'b1', 'c1']} async def interface_to_frontend(websocket, path): async for message in websocket: msg = json.loads(message)