Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)
Пример #6
0
class DataMemory(Memory):
    """
    ARM specific data memory with 32-bit word size. Thsi component is to be used
    to store data during execution of architecture.

    Note to change state during operation, use modify functionality.

    Note that address space is ghosted if the address bus is greater than the
    size defined for the module.
    """

    DEFAULT_MODE = None
    DEFAULT_SIZE = 4096
    DEFAULT_STATE = 0x81
    DEFAULT_LATCH_TYPE = Latch_Type.RISING_EDGE
    DEFAULT_RESET_TYPE = Logic_States.ACTIVE_HIGH
    DEFAULT_ENABLE_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 run(self, time=None):
        """
        Update address sub-entities before calling general memory run operation
        """
        self._address_subset.run(time)
        Memory.run(self, time)

    @classmethod
    def from_dict(cls, config, hooks):
        "Implements conversion from configuration to component"

        if "mode" in config:
            mode = hooks[config["mode"]]
        else:
            mode = DataMemory.DEFAULT_MODE

        if "size" in config:
            size = config["size"]
        else:
            size = DataMemory.DEFAULT_SIZE

        if "value" in config:
            value = config["value"]
        else:
            value = DataMemory.DEFAULT_STATE

        if "edge_type" in config:
            edge_type = Latch_Type.fromString(config["edge_type"])
        else:
            edge_type = DataMemory.DEFAULT_LATCH_TYPE

        if "reset_type" in config:
            reset_type = Logic_States.fromString(config["reset_type"])
        else:
            reset_type = DataMemory.DEFAULT_RESET_TYPE

        if "enable_type" in config:
            enable_type = Logic_States.fromString(config["enable_type"])
        else:
            enable_type = DataMemory.DEFAULT_ENABLE_TYPE

        return DataMemory(hooks[config["address"]], hooks[config["write"]],
                          hooks[config["write_enable"]],
                          hooks[config["reset"]], hooks[config["clock"]],
                          hooks[config["read"]], mode, size, value, edge_type,
                          reset_type, enable_type)
Пример #7
0
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
Пример #8
0
    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)])
Пример #9
0
class ProgramMemory(Memory):
    """
    ARM specific program memory with 32-bit word size. This component is to be
    used for storing a program in an architecture. Note that this device does
    not allow writes from inside the architecture.

    Note to program this memory use the modify functionality.

    Note that address space is ghosted if the address bus is greater than the
    size defined for the module.
    """

    DEFAULT_SIZE = 4096
    DEFAULT_STATE = 0
    DEFAULT_RESET_TYPE = Logic_States.ACTIVE_HIGH

    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 run(self, time=None):
        """
        Update address sub-entities before calling general memory run operation
        """
        self._address_subset.run(time)
        Memory.run(self, time)

    @classmethod
    def from_dict(cls, config, hooks):
        "Implements conversion from configuration to component"

        if "size" in config:
            size = config["size"]
        else:
            size = ProgramMemory.DEFAULT_SIZE

        if "value" in config:
            value = config["value"]
        else:
            value = ProgramMemory.DEFAULT_STATE

        if "reset_type" in config:
            reset_type = Logic_States.fromString(config["reset_type"])
        else:
            reset_type = ProgramMemory.DEFAULT_RESET_TYPE

        return ProgramMemory(hooks[config["address"]], hooks[config["reset"]],
                             hooks[config["read"]], size, value, reset_type)
Пример #10
0
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
Пример #11
0
    ss0_bus = Bus(8, 0)
    ss1_bus = Bus(8, 0)
    ss2_bus = Bus(8, 0)
    ss3_bus = Bus(8, 0)

    bj0 = Bus(32, 0)

    reg = Register(32, clk, rst, d_bus, q_bus)
    add = Adder(32, q_bus, c1, d_bus)
    regFile = Register_File(clk, rst, c2, d_bus, address, address, address,
                            q_bus, m_bus)
    m = Mux(32, [q_bus, m_bus], c2, f_bus)
    alu = Alu(f_bus, q_bus, Bus(1, 0), r_bus, c_bus, v_bus, n_bus, z_bus)
    subset = BusSubset(q_bus, [ss0_bus, ss1_bus, ss2_bus, ss3_bus], [(0, 8),
                                                                     (8, 16),
                                                                     (16, 24),
                                                                     (24, 32)])
    join = BusJoin([ss3_bus, ss2_bus, ss1_bus, ss0_bus], bj0)

    add.run()
    reg.run()
    regFile.run()
    m.run()
    alu.run()
    subset.run()
    join.run()

    while True:
        print('-----------------------------------------------------------')
        print(clk.inspect())
        print(rst.inspect())
Пример #12
0
class ALUFlagRegister(Register):
    """
    ALU Flag Register is a specific state register for ARM architecture.
    Developed to simplifiy design by reducing need for join and subset.
    """

    DEFAULT_STATE = 0
    DEFAULT_LATCH_TYPE = Latch_Type.RISING_EDGE
    DEFAULT_RESET_TYPE = Logic_States.ACTIVE_HIGH
    DEFAULT_ENABLE_TYPE = Logic_States.ACTIVE_HIGH

    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 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)

    @classmethod
    def from_dict(cls, config, hooks):
        "Implements conversion from configuration to component"

        if "value" in config:
            default_state = config["value"]
        else:
            default_state = ALUFlagRegister.DEFAULT_STATE

        if "edge_type" in config:
            edge_type = Latch_Type.fromString(config["edge_type"])
        else:
            edge_type = ALUFlagRegister.DEFAULT_LATCH_TYPE

        if "reset_type" in config:
            reset_type = Logic_States.fromString(config["reset_type"])
        else:
            reset_type = ALUFlagRegister.DEFAULT_RESET_TYPE

        if "enable_type" in config:
            enable_type = Logic_States.fromString(config["enable_type"])
        else:
            enable_type = ALUFlagRegister.DEFAULT_ENABLE_TYPE

        return ALUFlagRegister(hooks[config["c_in"]], hooks[config["v_in"]], hooks[config["n_in"]],
                               hooks[config["z_in"]], hooks[config["reset"]], hooks[config["clock"]],
                               hooks[config["enable"]], hooks[config["c_out"]], hooks[config["v_out"]],
                               hooks[config["n_out"]], hooks[config["z_out"]], default_state, edge_type,
                               reset_type, enable_type)