def test_comparator(circuit): with scope("a"): a_values = bus(2) with scope("b"): b_values = bus(2) inputs = a_values >> b_values output = inputs >> comp truth_table_test( inputs, output, ( ((0, 0, 0, 0), (1, 0, 0, 0)), ((0, 0, 1, 0), (0, 0, 1, 0)), ((0, 0, 0, 1), (0, 0, 0, 1)), ((0, 0, 1, 1), (0, 0, 1, 1)), ((1, 0, 0, 0), (0, 1, 1, 0)), ((1, 0, 1, 0), (1, 0, 0, 0)), ((1, 0, 0, 1), (0, 1, 1, 1)), ((1, 0, 1, 1), (0, 0, 0, 1)), ((0, 1, 0, 0), (0, 1, 0, 1)), ((0, 1, 1, 0), (0, 0, 1, 1)), ((0, 1, 0, 1), (1, 0, 0, 0)), ((0, 1, 1, 1), (0, 0, 1, 0)), ((1, 1, 0, 0), (0, 1, 1, 1)), ((1, 1, 1, 0), (0, 1, 0, 1)), ((1, 1, 0, 1), (0, 1, 1, 0)), ((1, 1, 1, 1), (1, 0, 0, 0)), ), draw=1, )
def test_alu_runner(circuit): with scope("StepperIn"): stepper = bus(circuit_module.Stepper.N_OUTS - 1) with scope("IrIn"): ir = bus(8) output = stepper >> ir >> circuit_module.AluRunner() inputs = stepper[3:6] >> ir[:4] truth_table_test( inputs, output, ( ((0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0)), ((1, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0)), ((0, 1, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0)), ((0, 0, 1, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0)), ((0, 0, 0, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0)), ((1, 0, 0, 1, 0, 0, 0), (0, 0, 0, 1, 0, 0)), ((1, 0, 0, 1, 1, 0, 0), (0, 0, 0, 1, 0, 0)), ((1, 0, 0, 1, 1, 1, 1), (0, 0, 0, 1, 0, 0)), ((0, 1, 0, 1, 0, 0, 0), (0, 0, 0, 0, 1, 0)), ((0, 1, 0, 1, 1, 0, 0), (1, 0, 0, 0, 1, 0)), ((0, 1, 0, 1, 1, 1, 1), (1, 1, 1, 0, 1, 0)), ((0, 0, 1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 1)), ((0, 0, 1, 1, 1, 0, 0), (0, 0, 0, 0, 0, 1)), ((0, 0, 1, 1, 1, 1, 1), (0, 0, 0, 0, 0, 0)), ), draw=1, )
def test_adder(circuit): with scope("a"): a_values = bus(2) with scope("b"): b_values = bus(2) carry_in = Line("CarryIn") inputs = carry_in >> a_values >> b_values output = inputs >> adder truth_table_test( inputs, output, ( ((0, 0, 0, 0, 0), (0, 0, 0)), ((1, 0, 0, 0, 0), (0, 0, 1)), ((0, 1, 0, 0, 0), (0, 1, 0)), ((0, 0, 0, 1, 0), (0, 1, 0)), ((0, 1, 0, 1, 0), (1, 0, 0)), ((1, 1, 0, 1, 0), (1, 0, 1)), ((1, 1, 1, 1, 1), (1, 1, 1)), ((0, 1, 1, 1, 1), (1, 1, 0)), ((0, 1, 0, 1, 1), (1, 0, 1)), ((0, 1, 1, 1, 0), (1, 0, 1)), ((0, 0, 1, 0, 0), (0, 0, 1)), ((0, 0, 0, 0, 1), (0, 0, 1)), ((0, 0, 0, 1, 1), (0, 1, 1)), ((0, 1, 1, 0, 0), (0, 1, 1)), ), draw=1, )
def test_io_unit(circuit): s, e = Lines("se") bus_ = bus() inputs = s >> e >> bus_ ins, outs = (inputs >> circuit_module.IoUnit()).split() outs >>= bus_ inputs >>= ins truth_table_test( inputs, outs, ( ((0, 0, "3"), ("0", "3")), ((0, 0, "3", "42"), ("0", "3")), ((0, 0, "3"), ("0", "3")), ((1, 0, "3"), ("3", "3")), ((0, 0, "3"), ("3", "3")), ((1, 0, "3"), ("3", "3")), ((0, 0, "3"), ("3", "3")), ((0, 0, "52"), ("3", "52")), ((0, 0, "52"), ("3", "52")), ((1, 0, "52"), []), ((1, 0, "52"), ("52", "52")), ((0, 0, "52"), ("52", "52")), ((0, 1, "52"), ("52", "52")), ((0, 0, "52"), ("52", "52")), ((1, 0, "42"), []), ((1, 0, "42"), ("42", "42")), ), draw=1, )
def run_controller(circuit, instruction: str, flags=""): parsed, _ = parser.parse_line(instruction) print(instruction, parsed) clock = circuit_module.Clock() with scope("IR"): ir = bus() with scope("FLAGS"): flags_in = Lines("CAEZ") with scope("STEPPER"): stepper = bus(6) inputs = clock.clk >> clock.clk_s >> clock.clk_e >> ir >> flags_in >> stepper output = inputs >> circuit_module.controller simulation = {} es = tag_outputs(circuit, ["CONTROL", "ENABLER"]) ss = tag_outputs(circuit, ["CONTROL", "SELECTOR"]) rounds = [] for step in range(6): e_found = set() s_found = set() for clock_round in range(4): f = clock.step() f.update({stepper[j]: int(j == step) for j in range(6)}) f.update({ir[j]: k for j, k in enumerate(parsed)}) f.update( {flags_in[j]: int(letter in flags) for j, letter in enumerate("CAEZ")} ) simulation.update(simulate(f, circuit, simulation)) new_es = set(e for e in es if simulation[e]) new_ss = set(s for s in ss if simulation[s]) if clock_round == 3: assert ( len( [ line for line in new_es if line not in Lines(new_es).typed(("E", "B1")) and line not in Lines(new_es).typed(("ALU", "OP")) ] ) == 0 ) if clock_round != 1: assert len(new_ss) == 0 e_found.update(new_es) s_found.update(new_ss) rounds.append({"e": Lines(e_found), "s": Lines(s_found)}) return rounds
def test_zero_gate(circuit): inputs = bus(3) output = inputs >> zero_gate truth_table_test( inputs, output, (((0, 0, 0), 1), ((1, 0, 0), 0), ((0, 1, 1), 0), ((1, 1, 1), 0)), draw=1, )
def test_non_alu(circuit): with scope("StepperIn"): stepper = bus(circuit_module.Stepper.N_OUTS - 1) with scope("IrIn"): ir = bus(8) with scope("Flags"): flags = bus(4) output = stepper >> ir >> flags >> circuit_module.NonAluModule() inputs = stepper[3:5] >> ir[:4] truth_table_test( inputs, output[:4], ( ((0, 0, 1, 0, 0, 0), (0, 0, 0, 0)), ((1, 0, 1, 0, 0, 0), (0, 0, 0, 0)), ((0, 1, 1, 0, 0, 0), (0, 0, 0, 0)), ((0, 0, 0, 0, 0, 0), (0, 0, 0, 0)), ((1, 0, 0, 0, 0, 0), (1, 0, 0, 0)), ((0, 1, 0, 0, 0, 0), (0, 1, 0, 0)), ((0, 0, 0, 0, 0, 1), (0, 0, 0, 0)), ((1, 0, 0, 0, 0, 1), (0, 0, 1, 0)), ((0, 1, 0, 0, 0, 1), (0, 0, 0, 1)), ), draw=1, ) truth_table_test( stepper[3:6] >> flags >> ir, output.typed(("INSTRUCTION", "J")), ( ((1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0), (1, 0, 0)), ((0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0), (0, 1, 0)), ((0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0), (0, 0, 0)), ((0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0), (0, 0, 0)), ((0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0), (0, 0, 1)), ((0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0), (0, 0, 1)), ((0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0), (0, 0, 0)), ((0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0), (0, 0, 0)), ((0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0), (0, 0, 0)), ((0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1), (0, 0, 1)), ((0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0), (0, 0, 1)), ), draw=1, )
def test_decoder(circuit): n_inputs = 4 inputs = bus(n_inputs) outputs = inputs >> decoder assert len(outputs) == 2 ** n_inputs truth_table_test( inputs, outputs, [ ( list(map(int, "{0:06b}".format(i)[2:])), [int(i == j) for j in range(2 ** n_inputs)][::-1], ) for i in range(2 ** n_inputs) ], )
def test_bus1(circuit): inputs = bus(3) s = Line("s") inputs = s >> inputs output = inputs >> bus1 truth_table_test( inputs, output, ( ((0, 0, 0, 0), (0, 0, 0)), ((0, 1, 1, 0), (1, 1, 0)), ((0, 1, 0, 1), (1, 0, 1)), ((1, 1, 1, 0), (0, 0, 1)), ((1, 0, 0, 0), (0, 0, 1)), ((1, 0, 0, 1), (0, 0, 1)), ), draw=1, )
def test_rshifter(circuit): inputs = bus(3) output = inputs >> rshift truth_table_test( inputs, output, ( ((0, 0, 0), (0, 0, 0)), ((0, 0, 1), (1, 0, 0)), ((0, 1, 0), (0, 0, 1)), ((0, 1, 1), (1, 0, 1)), ((1, 0, 0), (0, 1, 0)), ((1, 0, 1), (1, 1, 0)), ((1, 1, 0), (0, 1, 1)), ((1, 1, 1), (1, 1, 1)), ), draw=1, )
def test_byte(circuit): inputs = Line("s") >> bus() outputs = inputs >> byte assert len(inputs) == 9 assert len(outputs) == 8 truth_table_test( inputs, outputs, ( ((1, "1"), "1"), ((1, "25"), "25"), ((0, "25"), "25"), ((0, "42"), "25"), ((1, "42"), []), ((1, "42"), "42"), ((1, "0"), "0"), ((1, "251"), "251"), ((1, "120"), "120"), ), draw=1, )
def test_register(circuit): inputs = Lines("se") >> bus() outputs = inputs >> register truth_table_test( inputs, outputs, ( ((1, 1, "1"), "1"), ((1, 0, "1"), "0"), ((0, 0, "1"), "0"), ((0, 1, "1"), "1"), ((0, 1, "25"), "1"), ((0, 0, "25"), "0"), ((0, 1, "25"), "1"), ((1, 0, "25"), "0"), ((0, 1, "4"), "25"), ((1, 0, "4"), "0"), ((0, 0, "4"), "0"), ((0, 1, "12"), "4"), ((1, 1, "12"), "12"), ), )
def test_alu(circuit): with scope("a"): a = bus(4) with scope("b"): b = bus(4) with scope("op"): op = bus(3) carry_in = Line("CarryIn") inputs = op >> carry_in >> a >> b a_larger, equal, out_zero, carry_out, cs = (inputs >> alu).split(1, 1, 1, 1) feed_dict = {i: 0 for i in inputs} feed_dict[op[0]] = 0 feed_dict[op[1]] = 0 feed_dict[op[2]] = 0 feed_dict[a[0]] = 1 feed_dict[b[1]] = 1 feed_dict[a[3]] = 1 feed_dict[b[3]] = 1 simulation = simulate(feed_dict, circuit) graph_tools.draw(circuit, feed_dict, simulation) assert simulation[cs[0]] assert simulation[cs[1]] assert simulation[cs[2]] assert not simulation[cs[3]] assert not simulation[carry_out] assert not simulation[out_zero] feed_dict = {i: 0 for i in inputs} feed_dict[op[0]] = 1 feed_dict[op[1]] = 1 feed_dict[op[2]] = 0 feed_dict[a[1]] = 1 feed_dict[b[2]] = 1 feed_dict[a[3]] = 1 feed_dict[b[3]] = 1 simulation = simulate(feed_dict, circuit) graph_tools.draw(circuit, feed_dict, simulation) assert not simulation[cs[0]] assert simulation[cs[1]] assert simulation[cs[2]] assert not simulation[cs[3]] assert not simulation[carry_out] assert not simulation[out_zero] assert simulation[a_larger] assert not simulation[equal] feed_dict = {i: 0 for i in inputs} feed_dict[op[0]] = 0 feed_dict[op[1]] = 0 feed_dict[op[2]] = 1 feed_dict[a[2]] = 1 feed_dict[b[2]] = 1 feed_dict[a[3]] = 1 feed_dict[b[3]] = 1 feed_dict[carry_in] = 1 simulation = simulate(feed_dict, circuit) graph_tools.draw(circuit, feed_dict, simulation) assert simulation[cs[0]] assert not simulation[cs[1]] assert not simulation[cs[2]] assert simulation[cs[3]] assert simulation[carry_out] assert not simulation[out_zero] feed_dict = {i: 0 for i in inputs} feed_dict[op[0]] = 0 feed_dict[op[1]] = 0 feed_dict[op[2]] = 1 feed_dict[a[2]] = 1 feed_dict[b[2]] = 1 feed_dict[a[3]] = 1 feed_dict[b[3]] = 1 feed_dict[carry_in] = 0 simulation = simulate(feed_dict, circuit) # graph_tools.draw(circuit, feed_dict, simulation) assert not simulation[cs[0]] assert not simulation[cs[1]] assert not simulation[cs[2]] assert simulation[cs[3]] assert simulation[carry_out] assert not simulation[out_zero]
def test_ram(smallest_circuit): circuit = smallest_circuit with scope("BusInput"): inputs = bus() s = Line("s") e = Line("e") with scope("MarInput"): mar_inputs = bus() sa = Line("sa") previous_state = {} all_inputs = s >> e >> sa >> inputs >> mar_inputs all_inputs >> ram mi1 = mar_inputs[-1] i1 = inputs[-1] i2 = inputs[-2] feed_dict = {} def run(): previous_state.update( simulate(feed_dict, circuit, previous_state=previous_state) ) def setv(line, value): feed_dict[line] = value def chkv(line, value): assert previous_state[line] == value def rmv(line): del feed_dict[line] def viz(skip=False): graph_tools.draw(circuit, feed_dict, previous_state) # skip() # S set setv(s, 1) # MAR set setv(sa, 1) run() # MAR 1 set setv(mi1, 1) run() # MAR unset setv(sa, 0) run() # INPUT 0 0 chkv(i1, 0) chkv(i2, 0) # CHANGE INPUT to 1 0 setv(i1, 1) run() # CHECK INPUT STILL ACTIVE chkv(i1, 1) chkv(i2, 0) setv(s, 1) # CHECK INPUT STILL ACTIVE run() # Remove S chkv(i1, 1) setv(s, 0) run() # In still exists chkv(i1, 1) rmv(i1) run() # E disabled setv(e, 1) run() # E Enabled, I persists from bytes chkv(i1, 1) chkv(i2, 0) setv(e, 0) # Disable E run() # Values turn off again chkv(i1, 0) chkv(i2, 0) # Reenable E setv(e, 1) run() # Values come back chkv(i1, 1) chkv(i2, 0) # Disable again setv(e, 0) run() # disabled chkv(i1, 0) chkv(i2, 0) # MI Changed to 0 setv(mi1, 0) # Nothing enabled run() chkv(i1, 0) chkv(i2, 0) # Set MAR turned on setv(sa, 1) run() # MAR is now set to 0 chkv(i1, 0) chkv(i2, 0) setv(sa, 0) run() # MAR disabled chkv(i1, 0) chkv(i2, 0) # E re-enabled setv(e, 1) run() # But no input value has been set chkv(i1, 0) chkv(i2, 0) setv(e, 0) run() setv(i1, 0) setv(i2, 1) run() chkv(i1, 0) chkv(i2, 1) setv(s, 1) run() chkv(i1, 0) chkv(i2, 1) setv(s, 0) run() chkv(i1, 0) chkv(i2, 1) rmv(i1) rmv(i2) run() setv(e, 1) run() chkv(i1, 0) chkv(i2, 1) setv(e, 0) run() chkv(i1, 0) chkv(i2, 0) setv(e, 1) run() chkv(i1, 0) chkv(i2, 1) setv(e, 0) run() chkv(i1, 0) chkv(i2, 0) setv(mi1, 1) run() chkv(i1, 0) chkv(i2, 0) chkv(mi1, 1) setv(sa, 1) run() chkv(i1, 0) chkv(i2, 0) chkv(mi1, 1) setv(sa, 0) run() chkv(i1, 0) chkv(i2, 0) chkv(mi1, 1) setv(e, 1) run() chkv(i1, 1) chkv(i2, 0) setv(mi1, 0) run() chkv(i1, 1) chkv(i2, 0) viz()
def test_bus(): assert len(bus()) == 8