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