def test_modify(self): "Verifies internal hook modify function" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(8, 0) q_bus = Bus(8, 0) reg = Register(8, clk, rst, d_bus, q_bus, 1) tm = None rm = reg.modify(tm) self.assertTrue('error' in rm) tm = {} rm = reg.modify(tm) self.assertTrue('error' in rm) tm = {'state': '0'} rm = reg.modify(tm) self.assertTrue('error' in rm) tm = {'state': -1} rm = reg.modify(tm) self.assertTrue('error' in rm) tm = {'state': 256} rm = reg.modify(tm) self.assertTrue('error' in rm) tm = {'state': 128} rm = reg.modify(tm) self.assertTrue('success' in rm and rm['success']) reg.run() self.assertTrue(q_bus.read() == 128)
def test_inspect(self): "Verifies hook inspect for valid return" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(8, 0) q_bus = Bus(8, 0) reg = Register(8, clk, rst, d_bus, q_bus, 1) ins = reg.inspect() self.assertTrue(ins['type'] == 'register') self.assertTrue(ins['size'] == 8) self.assertTrue(ins['state'] == 1)
def __init__(self, c_in, v_in, n_in, z_in, rst, clk, en, c_out, v_out, n_out, z_out, default_state=DEFAULT_STATE, edge_type=DEFAULT_LATCH_TYPE, reset_type=DEFAULT_RESET_TYPE, enable_type=DEFAULT_ENABLE_TYPE): """ Constructor will check for valid parameters, exception thrown on invalid Parameters c_in: 1-bit input of 'c' v_in: 1-bit input of 'v' n_in: 1-bit input of 'n' z_in: 1-bit input of 'z' rst: Register reset clk: Register clock en: Register write enable c_out: 1-bit output of 'c' v_out: 1-bit output of 'v' n_out: 1-bit output of 'n' z_out: 1-bit output of 'z' default_state: Initial 4-bit state of ALU Flag edge_type: Clock state change to store flags reset_type: Asynchronous reset to default_state value enable_type: State to allow write to register """ if not isinstance(c_in, iBusRead) or not c_in.size() == 1: raise TypeError('c in must be a 1-bit readable bus') if not isinstance(v_in, iBusRead) or not v_in.size() == 1: raise TypeError('v in must be a 1-bit readable bus') if not isinstance(n_in, iBusRead) or not n_in.size() == 1: raise TypeError('n in must be a 1-bit readable bus') if not isinstance(z_in, iBusRead) or not z_in.size() == 1: raise TypeError('z in must be a 1-bit readable bus') if not isinstance(c_out, iBusWrite) or not c_out.size() == 1: raise TypeError('c out must be a 1-bit readable bus') if not isinstance(v_out, iBusWrite) or not v_out.size() == 1: raise TypeError('v out must be a 1-bit readable bus') if not isinstance(n_out, iBusWrite) or not n_out.size() == 1: raise TypeError('n out must be a 1-bit readable bus') if not isinstance(z_out, iBusWrite) or not z_out.size() == 1: raise TypeError('z out must be a 1-bit readable bus') self._flag_in = Bus(4) self._join = BusJoin([c_in, v_in, n_in, z_in], self._flag_in) self._flag_out = Bus(4) self._subset = BusSubset(self._flag_out, [c_out, v_out, n_out, z_out], [(0, 1), (1, 2), (2, 3), (3, 4)]) Register.__init__(self, 4, clk, rst, self._flag_in, self._flag_out, default_state, edge_type, reset_type, en, enable_type)
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_reset(self): "Verifies reset behavior of component" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(8, 10) q_bus = Bus(8, 0) reg = Register(8, clk, rst, d_bus, q_bus, 0, Latch_Type.RISING_EDGE, Logic_States.ACTIVE_HIGH) clk.write(0) reg.run() self.assertTrue(q_bus.read() == 0) clk.write(1) reg.run() self.assertTrue(q_bus.read() == 10) reg.on_reset() reg.run() self.assertTrue(q_bus.read() == 0)
def test_clear(self): "Tests memory's clear method" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(8, 0) q_bus = Bus(8, 0) reg = Register(8, clk, rst, d_bus, q_bus, 1) #write data reg.modify({'state': 0xFF}) msg = reg.inspect() self.assertEqual(msg['state'], 0xFF) #clear data msg = reg.clear() self.assertTrue('success' in msg) #validate clear msg = reg.inspect() self.assertEqual(msg['state'], 1)
def __init__(self, num_reg, reg_size, clock, reset, write_addr, write_data, read_addrs, read_datas, enable=None, default_state=DEFAULT_STATE, edge_type=DEFAULT_LATCH_TYPE, reset_type=DEFAULT_RESET_TYPE, enable_type=DEFAULT_ENABLE_TYPE): """ Constructor will check for valid parameters, exception thrown on invalid Parameters: num_reg : number of registers in register file reg_size : bit size of registers in register file clock : clock bus of size 1 for register file reset : reset bus of size 1 for register file write_addr : write address of iBusRead size appropriate for num_reg write_data : write address of iBusRead size appropriate for reg_size read_addr : read address array of iBusRead with no more than num_reg each bus must be of size appropriate for reg selection read_data : read data array of iBusWrite with no more than num_reg each bus must have size equal to reg_size enable : bit enabling write behavior for specified registers (Optional) if not specified then assumed active default_state : initial and reset state that registers take on edge_type : Latching type for registers (all must be same) reset_type : logic state to cause reset event enable_type : logic state to allow write behavior """ # configuration if not isinstance(reg_size, int) or reg_size <= 0: raise TypeError('Number of registers must be valid integer') elif not isinstance(num_reg, int) or num_reg <= 0: raise TypeError('Bit-width must be valid') elif not Latch_Type.valid(edge_type): raise ValueError('Invalid latch edge type') elif not Logic_States.valid(reset_type): raise ValueError('Invalid active reset type') elif not Logic_States.valid(enable_type): raise ValueError('Invalid active enable type') self._reg_size = reg_size self._num_reg = num_reg self._edge_type = edge_type self._reset_type = reset_type self._enable_type = enable_type self._default_state = default_state # generate necessary parameters that buses must fit if num_reg == 0: self._necessary_length = 0 elif num_reg < 2: self._necessary_length = 1 else: # len > 2 self._necessary_length = int(math.floor(math.log(num_reg - 1, 2) + 1)) self._necessary_size = self._reg_size # external connections if not isinstance(clock, iBusRead) or not clock.size() == 1: raise TypeError('Clock bus must be valid') elif not isinstance(reset, iBusRead) or not reset.size() == 1: raise TypeError('Reset bus must be valid') elif not isinstance(enable, iBusRead) or not enable.size() == 1: raise TypeError('Write enable bus must be readable') elif not isinstance(write_addr, iBusRead) or not write_addr.size() == self._necessary_length: raise TypeError('Write address bus must be readable') elif not isinstance(write_data, iBusRead) or not write_data.size() == self._necessary_size: raise TypeError('Write data bus must be readable') elif not isinstance(read_addrs, list) or not isinstance(read_datas, list): raise TypeError('Read buses lists must be list') elif not (len(read_addrs) == len(read_datas)) or len(read_addrs) <= 0 or len(read_datas) <= 0: raise TypeError('Read buses must having matching size greater than zero') elif not all((isinstance(x, iBusRead) and x.size() == self._necessary_length) for x in read_addrs): raise TypeError('Read address buses must be have correct size') elif not all((isinstance(x, iBusWrite) and x.size() == self._necessary_size) for x in read_datas): raise TypeError('Read data buses must be have correct size') self._clock = clock self._reset = reset self._enable = enable self._waddr = write_addr self._wdata = write_data self._raddrs = read_addrs self._rdatas = read_datas # internal structure self._regs = [] self._ens = [] self._datas = [] for i in range(num_reg): en = Bus(1, 0) da = Bus(reg_size, 0) self._ens.append(en) self._datas.append(da) self._regs.append(Register(reg_size, clock, reset, write_data, da, default_state, edge_type, reset_type, en, Logic_States.ACTIVE_HIGH))
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_rising_edge(self): "Verifies rising edge capture behavior" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(8, 10) q_bus = Bus(8, 0) reg = Register(8, clk, rst, d_bus, q_bus, 0, Latch_Type.RISING_EDGE, Logic_States.ACTIVE_HIGH) reg.run() self.assertTrue(q_bus.read() == 0) d_bus.write(15) reg.on_rising_edge() reg.run() self.assertTrue(q_bus.read() == 15) d_bus.write(25) reg.on_falling_edge() reg.run() self.assertTrue(q_bus.read() == 15)
def test_run(self): "Verifies correct time based simulation" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(8, 10) q_bus = Bus(8, 0) en = Bus(1, 0) reg = Register(8, clk, rst, d_bus, q_bus, 0, Latch_Type.RISING_EDGE, Logic_States.ACTIVE_HIGH, en, Logic_States.ACTIVE_HIGH) en.write(0) clk.write(0) reg.run() self.assertTrue(q_bus.read() == 0) en.write(1) clk.write(0) reg.run() self.assertTrue(q_bus.read() == 0) en.write(0) clk.write(1) reg.run() self.assertTrue(q_bus.read() == 0) en.write(1) clk.write(1) reg.run() self.assertTrue(q_bus.read() == 0) clk.write(0) reg.run() self.assertTrue(q_bus.read() == 0) clk.write(1) reg.run() self.assertTrue(q_bus.read() == 10) d_bus.write(15) clk.write(0) reg.run() self.assertTrue(q_bus.read() == 10) rst.write(1) clk.write(1) reg.run() self.assertTrue(q_bus.read() == 0)
def test_constructor(self): "Constructor with valid and invalid configuration" clk = Bus(1, 0) rst = Bus(1, 0) d_bus = Bus(2, 1) q_bus = Bus(2, 0) en = Bus(1, 0) with self.assertRaises(TypeError): r = Register('0', clk, rst, d_bus) with self.assertRaises(TypeError): r = Register(0, clk, rst, d_bus) with self.assertRaises(TypeError): r = Register(2, clk, rst, d_bus, q_bus, '0') with self.assertRaises(TypeError): r = Register(2, clk, rst, d_bus, q_bus, -1) with self.assertRaises(TypeError): r = Register(2, clk, rst, d_bus, q_bus, 4) with self.assertRaises(TypeError): r = Register(2, 'clk', rst, d_bus, q_bus) with self.assertRaises(ValueError): c = Bus(2) r = Register(2, c, rst, d_bus, q_bus) with self.assertRaises(TypeError): r = Register(2, clk, 'rst', d_bus, q_bus) with self.assertRaises(ValueError): rs = Bus(2) r = Register(2, clk, rs, d_bus, q_bus) with self.assertRaises(TypeError): r = Register(2, clk, rst, 'd_bus', q_bus) with self.assertRaises(ValueError): d = Bus(3) r = Register(2, clk, rst, d, q_bus) with self.assertRaises(TypeError): r = Register(2, clk, rst, d_bus, q_bus, enable='0') with self.assertRaises(ValueError): e = Bus(3) r = Register(2, clk, rst, d, q_bus, enable=e) with self.assertRaises(TypeError): r = Register(2, clk, rst, d_bus, 'q_bus') with self.assertRaises(ValueError): q = Bus(3) r = Register(2, clk, rst, d_bus, q) with self.assertRaises(ValueError): r = Register(2, clk, rst, d_bus, q_bus, edge_type=5) with self.assertRaises(ValueError): r = Register(2, clk, rst, d_bus, q_bus, reset_type=5) with self.assertRaises(ValueError): r = Register(2, clk, rst, d_bus, q_bus, enable_type=5) reg = Register(2, clk, rst, d_bus, q_bus, 0, Latch_Type.BOTH_EDGE, Logic_States.ACTIVE_LOW, en, Logic_States.ACTIVE_LOW)
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 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
#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) retMsg = {}
def run(self, time=None): "Timestep handler function clocks data into register and asserts output" self._join.run(time) Register.run(self, time) self._subset.run(time)