Example #1
0
def wire_expand(n, source, destr = None):
	"""Prend un fil, et retourne une nappe consistant en
	   n copies de ce fil (par exponentiation rapide)"""
	assert(n > 0)
	assert(destr == None or nl.get_size(destr) == n * nl.get_size(source))
	if n == 1 and destr == None:
		return source
	elif n == 1:
		return nl.WIRE(source, destr)
	nl.push_context("wire_expand")
	c = 1
	k = 0
	l = [source]
	bits = []
	m = n
	while 2 * c < n:
		l.append(nl.CONCAT(l[-1], l[-1]))
		if m % 2 == 1:
			bits.append(k)
		m //= 2
		c *= 2
		k += 1
	if 2 * c == n:
		nl.pop_context()
		return nl.CONCAT(l[-1], l[-1], destr)
	u = l[bits[0]]
	for i in range(1, len(bits)):
		u = nl.CONCAT(u, l[bits[i]])
	nl.pop_context()
	return nl.CONCAT(u, l[k], destr)
Example #2
0
def alu(instr, useCarry, op1, op2, carryFlag, val = None, flags = None):
	nl.push_context("alu")
	"""calcule les opposés de op1 et op2 si (et seulement si) nécessaire"""
	op1_1 = nl.XOR(op1, hel.wire_expand(64, nl.SELECT(2, instr)))
	op2_1 = nl.XOR(op2, hel.wire_expand(64, nl.SELECT(4, instr)))
	"""calcule la sortie pour les opérations arithmétiques seulement"""
	c_in = nl.MUX(nl.OR(nl.SELECT(4, instr), nl.SELECT(2, instr)), \
		carryFlag, useCarry)
	arith, flag_C, flag_V = full_adder_n(64, op1_1, op2_1, c_in, True)
	"""calcule la sortie pour les opérations booléennes seulement"""
	eor = nl.XOR(op1, op2_1)
	orr = nl.OR(op1, op2_1)
	oand = nl.AND(op1, op2_1)
	boo_1 = nl.MUX(eor, orr, hel.wire_expand(64, nl.SELECT(1, instr)))
	boo = nl.MUX(boo_1, oand, hel.wire_expand(64, nl.SELECT(2, instr)))
	"""sélectionne la bonne sortie parmi les deux propositions"""
	val = nl.MUX(arith, boo, hel.wire_expand(64, nl.SELECT(3, instr)), val)
	"""détermine les flags"""
	n_flag_Z = hel.or_all(val)
	flag_Z = nl.NOT(n_flag_Z)
	flag_N = nl.SELECT(64, val)
	flags_1 = nl.CONCAT(flag_N, flag_Z)
	flags_2 = nl.CONCAT(flags_1, flag_C)
	flags = nl.CONCAT(flags_2, flag_V, flags)
	nl.pop_context()
	return (val, flags)
Example #3
0
def registers(set_val, r1addr, r2addr, setaddr, value, r1 = None, r2 = None,
	      pc = None):
	nl.push_context("registers")
	n = nl.get_size(value)
	regs = []
	for i in range(constants.REGISTERS.number):
		write_enable = nl.fresh()
		if i == constants.REGISTERS.pc:
			pc = register_pc(value, write_enable, pc)
			reg = pc
		elif i in constants.REGISTERS.inputs:
			reg = nl.fresh(n)
			nl.input(reg)
		else:
			reg = register(value, write_enable)
		if i in constants.REGISTERS.outputs:
			nl.output(reg)
		regs.append((write_enable, reg))
	addr_size = nl.get_size(r1addr)
	assert(1 << addr_size == constants.REGISTERS.number)
	r1 = mux_n(addr_size, [r[1] for r in regs], r1addr, r1)
	r2 = mux_n(addr_size, [r[1] for r in regs], r2addr, r2)
	demux_n(addr_size, [r[0] for r in regs], set_val, setaddr)
	nl.pop_context()
	return r1, r2, pc
Example #4
0
def memory_unit(instr, value, addr, result = None):
	nl.push_context("memory_unit")
	is_memory = nl.AND(nl.SELECT(1, instr), nl.SELECT(4, instr))
	we = nl.AND(is_memory, nl.SELECT(2, instr))
	addr = nl.SLICE(1, 16, addr)
	if UNUSED_ADDR_ZERO:
		addr = nl.AND(addr, helpers.wire_expand(16, is_memory))
	uu = nl.fresh(16)
	nl.pop_context()
	return nl.RAM(16, 64, addr, we, nl.WIRE(addr, uu), value, result)
Example #5
0
def register_pc(data, write_enable, destr = None):
	n = nl.get_size(data)
	u = nl.fresh(n)
	destr = nl.REG(u, destr)
	nl.push_context("incr")
	incremented, _ = alu.incr(n, destr)
	nl.pop_context()
	write_n = helpers.wire_expand(n, write_enable)
	nl.MUX(incremented, data, write_n, u)
	return destr
Example #6
0
def or_all(source, destr = None):
        n = nl.get_size(source)
        if n == 1:
                return nl.WIRE(source, destr)
        nl.push_context("or_all")
        c = 1
        while 2 * c < n:
                c *= 2
        w = source
        if 2 * c > n:
                w = nl.CONCAT(wire_expand(2 * c - n, nl.CONST(0)), source)
        while c > 1:
                w = nl.OR(nl.SLICE(1, c, w), nl.SLICE(c + 1, 2 * c, w))
                c //= 2
        destr = nl.OR(nl.SLICE(1, c, w), nl.SLICE(c + 1, 2 * c, w), destr)
        nl.pop_context()
        return destr
Example #7
0
def result_selector(instr, mem_result, alu_result, output = None):
	nl.push_context("result_selector")
	is_STR = nl.AND(nl.SELECT(1, instr), nl.SELECT(4, instr))
	output = nl.MUX(alu_result, mem_result, hel.wire_expand(64, is_STR), output)
	nl.pop_context()
	return output