def __init__(self, cb=None): self.RANGE = range(8) self.EGNAR = range(7,-1,-1) self.RANGE3 = range(3) self.RANGE16 = range(16) self.EGNAR16 = range(15,-1,-1) self.PAUSE = True self.NOSTEP = False self.RUN = True self.ALU = alu() self.REGISTER = register() self.CONTROL = control() self.DATABUS = [0,0,0,0,0,0,0,0] self.ADDRESSBUS = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] self.MEMORY = memory() self.CALLBACK = cb self.CONTROLREGISTER = [0,0,0] # Cy, Z, S self.Inst = [0,0,0,0,0,0,0,0] self.regLoadMap = { (0,0,0) : self.loadA, \ (0,0,1) : self.loadB, \ (0,1,0) : self.loadC, \ (0,1,1) : self.loadD, \ (1,0,0) : self.loadM1, \ (1,0,1) : self.loadM2, \ (1,1,0) : self.loadX, \ (1,1,1) : self.loadY } self.regSelectMap = { (0,0,0) : self.selectA, \ (0,0,1) : self.selectB, \ (0,1,0) : self.selectC, \ (0,1,1) : self.selectD, \ (1,0,0) : self.selectM1, \ (1,0,1) : self.selectM2, \ (1,1,0) : self.selectX, \ (1,1,1) : self.selectY } self.start = time() self.H = "" self.M = "" self.S = "" self.ENCODER = encodercore()
def testAlu(self): """ Test decoding """ def test(inst, data, op, selA, selB, selD, en, we, clk): en.next = True # or(RRR) inst.next = intbv('0100001001001100') yield delay(10) self.assertEqual(op, intbv('01000')) self.assertEqual(selA, intbv(2)) self.assertEqual(selB, intbv(3)) self.assertEqual(selD, intbv(1)) self.assertEqual(en, True) self.assertEqual(we, True) inst.next = intbv('1100111010101010') yield delay(10) self.assertEqual(op, intbv('11000')) self.assertEqual(selD, intbv('111')) self.assertEqual(data, intbv('1010101010101010')) self.assertEqual(we, False) raise StopSimulation def ClkDrv(clk): while True: clk.next = not clk yield delay(5) data = Signal( intbv(0) ) inst = Signal( intbv(0) ) op = Signal( intbv(0) ) selA = Signal( intbv(0) ) selB = Signal( intbv(0) ) selD = Signal( intbv(0) ) en = Signal(bool()) we = Signal(bool()) clk = Signal(bool()) dut = alu(inst, data, op, selA, selB, selD, en, we, clk) check = test(inst, data, op, selA, selB, selD, en, we, clk) clkdrv = ClkDrv(clk) sim = Simulation(dut, check, clkdrv) sim.run()
def testAlu(self): """ Test decoding """ def test(inst, data, op, selA, selB, selD, en, we, clk): en.next = True # or(RRR) inst.next = intbv('0100001001001100') yield delay(10) self.assertEqual(op, intbv('01000')) self.assertEqual(selA, intbv(2)) self.assertEqual(selB, intbv(3)) self.assertEqual(selD, intbv(1)) self.assertEqual(en, True) self.assertEqual(we, True) inst.next = intbv('1100111010101010') yield delay(10) self.assertEqual(op, intbv('11000')) self.assertEqual(selD, intbv('111')) self.assertEqual(data, intbv('1010101010101010')) self.assertEqual(we, False) raise StopSimulation def ClkDrv(clk): while True: clk.next = not clk yield delay(5) data = Signal(intbv(0)) inst = Signal(intbv(0)) op = Signal(intbv(0)) selA = Signal(intbv(0)) selB = Signal(intbv(0)) selD = Signal(intbv(0)) en = Signal(bool()) we = Signal(bool()) clk = Signal(bool()) dut = alu(inst, data, op, selA, selB, selD, en, we, clk) check = test(inst, data, op, selA, selB, selD, en, we, clk) clkdrv = ClkDrv(clk) sim = Simulation(dut, check, clkdrv) sim.run()
def main(): ### OPCODE_GETTER ### class opcodeGetPin: i_pctr = fresh(64) i_flagValue = fresh(1) o_flagSelect = fresh(4) o_opcode = fresh(64) show(opcodeGetPin.i_pctr, "pc") show(opcodeGetPin.o_opcode, "opcode") opcodeGetter.opcodeGetter(opcodeGetPin.i_pctr,\ opcodeGetPin.i_flagValue,\ opcodeGetPin.o_flagSelect,\ opcodeGetPin.o_opcode) ### ALU ### class aluPin: i_instr = SLICE(constants.OPCODE_FRAME.instruction,\ constants.OPCODE_FRAME.instruction+3, opcodeGetPin.o_opcode) i_useCarry = SELECT(constants.OPCODE_FRAME.useCarry,\ opcodeGetPin.o_opcode) i_op1 = fresh(64) i_op2 = fresh(64) i_carryFlag = fresh(1) o_val = fresh(64) o_flags = fresh(4) show(aluPin.i_op1, "alu_op1") show(aluPin.i_op2, "alu_op2") show(aluPin.i_instr, "alu_instr") show(aluPin.o_val, "alu_val") alu.alu(aluPin.i_instr,\ aluPin.i_useCarry,\ aluPin.i_op1,\ aluPin.i_op2,\ aluPin.i_carryFlag,\ aluPin.o_val,\ aluPin.o_flags) ### REGISTERS ### class registersPin: i_setVal = SELECT(constants.OPCODE_FRAME.writeResult,\ opcodeGetPin.o_opcode) i_reg1addr = fresh(4) i_reg2addr = fresh(4) i_destReg = SLICE(constants.OPCODE_FRAME.destRegister,\ constants.OPCODE_FRAME.destRegister+3, opcodeGetPin.o_opcode) i_value = fresh(64) o_reg1 = fresh(64) o_reg2 = fresh(64) o_pctr = opcodeGetPin.i_pctr show(registersPin.i_setVal, "writeResult") show(registersPin.i_reg1addr, "r1addr") show(registersPin.i_reg2addr, "r2addr") show(registersPin.i_destReg, "destReg") show(registersPin.i_value, "value") registers.registers( registersPin.i_setVal,\ registersPin.i_reg1addr,\ registersPin.i_reg2addr,\ registersPin.i_destReg,\ registersPin.i_value,\ registersPin.o_reg1,\ registersPin.o_reg2,\ registersPin.o_pctr) ### OP1_PROCESSOR ### class op1processorPin: i_op1 = SLICE(constants.OPCODE_FRAME.op1,constants.OPCODE_FRAME.op1+3,\ opcodeGetPin.o_opcode) i_op1cst = SELECT(constants.OPCODE_FRAME.isOp1Filled,\ opcodeGetPin.o_opcode) i_regVal = registersPin.o_reg1 o_reqAddr = registersPin.i_reg1addr o_val = aluPin.i_op1 show(op1processorPin.i_op1, "op1a") show(op1processorPin.o_reqAddr, "op1b") show(op1processorPin.i_op1cst, "op1cst") op1processor.op1processor( op1processorPin.i_op1,\ op1processorPin.i_op1cst,\ op1processorPin.i_regVal,\ op1processorPin.o_reqAddr,\ op1processorPin.o_val) ### OP2_PROCESSOR ### class op2processorPin: i_op2 = SLICE(constants.OPCODE_FRAME.op2,\ constants.OPCODE_FRAME.op2+24,\ opcodeGetPin.o_opcode) i_regVal = registersPin.o_reg2 o_reqAddr = registersPin.i_reg2addr o_val = aluPin.i_op2 op2processor.op2processor( op2processorPin.i_op2,\ op2processorPin.i_regVal,\ op2processorPin.o_reqAddr,\ op2processorPin.o_val) ### FLAGS ### class flagsPin: i_flags = aluPin.o_flags i_flagWrite = \ SELECT(constants.OPCODE_FRAME.setFlags, opcodeGetPin.o_opcode) i_flagSelect = opcodeGetPin.o_flagSelect o_flagVal = opcodeGetPin.i_flagValue o_flagsOut = fresh(4) SELECT(constants.FLAGS_POSITION.C, flagsPin.o_flagsOut, aluPin.i_carryFlag) flags.flags( flagsPin.i_flags,\ flagsPin.i_flagWrite,\ flagsPin.i_flagSelect,\ flagsPin.o_flagVal,\ flagsPin.o_flagsOut) class memoryUnitPin: i_instr = aluPin.i_instr i_value = op1processorPin.o_val i_addr = op2processorPin.o_val o_data = fresh(64) memory_unit.memory_unit( memoryUnitPin.i_instr,\ memoryUnitPin.i_value,\ memoryUnitPin.i_addr,\ memoryUnitPin.o_data) class resultSelectorPin: i_instr = aluPin.i_instr i_mem_result = memoryUnitPin.o_data i_alu_result = aluPin.o_val o_output = registersPin.i_value result_selector.result_selector( resultSelectorPin.i_instr,\ resultSelectorPin.i_mem_result,\ resultSelectorPin.i_alu_result,\ resultSelectorPin.o_output) ### WE'RE DONE! ### print_netlist()
def alu_convert(): ds1, ds2, imm, alu_out = [Signal(intbv(0)[8:]) for _ in range(4)] unsign, bra, branch = [Signal(bool(0)) for _ in range(3)] alu_signal = Signal(intbv(0)[5:]) alu_ins = alu(ds1, ds2, imm, bra, branch, alu_out, alu_signal) return alu_ins
else: data_list = decode(RMEM, full_text) # Decode instruction and fetch registers # Instantiate register values reg1 = data_list[0] if len(data_list) == 2: reg2 = data_list[1] else: if text_split[0] in ['LDUR', 'STUR']: reg2 = 0 else: reg2 = int(text_split[1]) result_alu = alu(text_split[0], reg1, reg2) # Input registers into ALU if text_split[0] in ['CBZ', 'CBNZ']: if result_alu == False: i += 1 else: i = i + int(text_split[1]) else: # Update registers RMEM[last_entry] = result_alu if opcode_text in ['LDUR', 'STUR']: data_access(DMEM, RMEM, full_text) i += 1
def TZR1(clk_i, rst_i, addr_o, data_i, data_o, write_o, read_o, program) : """ Nucleo del micro :: .------------------------------. | | | v .-------------------. | .--------------------. | Program ROM | | | a_i | | 2Ki x 16 | .---------------------------------. | | | | | | Program Counter | | | REG FILE | | | | | | | | | addr_i |<--| pc_o | | we_reg_file --->| we_i | | | | | | | | | | | inc_pc jmp call ret pck | | addr_a --->| addr_a_i | | | '---------------------------------' | | | | | ^ ^ ^ ^ ^ | addr_b --->| addr_b_i | | | | | | | | | | | | d_o | inc_pc jmp call ret pck | | | '-------------------' | | a_o b_o | | | '--------------------' | | | | | | | | .----- K v | | | | .------------------------. | | v v | ir_i | | | .-------. | | | | | MUX |<--- ctrl_mux_reg_k | DECO | | | '-------' | | | | | | | status_reg_i |<--- | | |--------------------------------------------------> addr_o | | ce_status_reg_o |---> | | | | | alu_fun_o |---> | | | ----> write_o | | addr_a_o |---> | v v | | addr_b_o |---> | ----- ALU ----- ----> read_o | | we_reg_file_o |---> | \ \ / / | | ctrl_mux_reg_k_o |---> | \ ------ / .------------. | | k_o |---> | alu_fun --->\ /------->| STATUS REG |---> status_reg | I/O MEM | wr_mem_o |---> | \ / '------------' | | ctrl_mux_alu_mem_o |---> | ---------- ^ | | inc_pc_o |---> | | | | | jmp_o |---> | .-------. | ce_status | | pck_o |---> | | MUX | | | | call_o |---> | | |<----------------------------------------------------------------------> data_o | | | ret_o |---> '---------| | | | rd_mem_o |---> | |<----------------------------------------------------------------------- data_i | '------------------------' | | | '-------' ^ | ctrl_mux_alu_mem """ ####### Senales ####### ######################## # Reg addr_a = Signal(intbv(0)[3:]) # 8 Registros addr_b = Signal(intbv(0)[3:]) we_reg_file = Signal(Lo) a_i = Signal(intbv(0)[8:]) a_o = Signal(intbv(0)[8:]) b_o = Signal(intbv(0)[8:]) ######################## # Alu ALU_fun = Signal(alu_fun.ALU_OPA) ALU_resul = Signal(intbv(0)[8:]) ALU_status = Signal(intbv(0)[2:]) ######################## # Status reg status_reg_q = Signal(intbv(0)[2:]) ce_status_reg = Signal(Lo) ######################## # Inst Deco ir = Signal(intbv(0)[16:]) ctrl_mux_reg_k = Signal(Lo) k = Signal(intbv(0)[8:]) ctrl_mux_alu_mem = Signal(Lo) inc_pc = Signal(Lo) jmp = Signal(Lo) call = Signal(Lo) ret = Signal(Lo) pck = Signal(intbv(0)[11:]) ######################## # Program counter pc_q = Signal(intbv(0)[11:]) ######################### # Muxes mux_alu_mem_o = Signal(intbv(0)[8:]) mux_reg_k_o = Signal(intbv(0)[8:]) ############################### ## Estructura INST_DECO = inst_deco(ir_i = ir, status_reg_i = status_reg_q, ce_status_reg_o = ce_status_reg, alu_fun_o = ALU_fun, addr_a_o = addr_a, addr_b_o = addr_b, we_reg_file_o = we_reg_file, ctrl_mux_reg_k_o = ctrl_mux_reg_k, k_o = k, wr_mem_o = write_o, rd_mem_o = read_o, ctrl_mux_alu_mem_o = ctrl_mux_alu_mem, inc_pc_o = inc_pc, jmp_o = jmp, call_o = call, ret_o = ret, pck_o = pck) PROG_COUNTER = pc(clk_i = clk_i, rst_i = rst_i, inc_pc_i = inc_pc, jmp_i = jmp, call_i = call, ret_i = ret, pck_i = pck, pc_o = pc_q, stack_size = 16) @always_comb def ROM_read() : ir.next = program[int(pc_q)] REG_FILE = RegFile(clk_i = clk_i, addr_a_i = addr_a, we_i = we_reg_file, a_i = a_i, a_o = a_o, addr_b_i = addr_b, b_o = b_o) ALU = alu(op_A_i = a_o, op_B_i = mux_reg_k_o, fun_i = ALU_fun, resul_o = ALU_resul, status_o = ALU_status) STATUS_REG = FD_E(clk_i = clk_i, ce_i = ce_status_reg, d_i = ALU_status, q_o = status_reg_q) @always_comb def MUXES() : mux_reg_k_o.next = k if ctrl_mux_reg_k else b_o a_i.next = data_i if ctrl_mux_alu_mem else ALU_resul @always_comb def conex() : addr_o.next = mux_reg_k_o data_o.next = ALU_resul return instances()
def top(clk, rst, write, read, rdy, pc, ins, addr, wdata, rdata, int0, int1, int2, int3): ''' clk = Signal(bool(0)) rst = ResetSignal(1, active=1, isasync=False) write = Signal(bool(0)) read = Signal(bool(0)) rdy = Signal(bool(0)) pc = Signal(intbv(0)[16:]) ins = Signal(intbv(0)[16:]) addr = Signal(intbv(0)[16:]) wdata = Signal(intbv(0)[8:]) rdata = Signal(intbv(0)[8:]) int0 = Signal(bool(0)) int1 = Signal(bool(0)) int2 = Signal(bool(0)) int3 = Signal(bool(0)) ''' imm = Signal(intbv(0)[8:]) alu_out = Signal(intbv(0)[8:]) rd_data = Signal(intbv(0)[8:]) lsu_out = Signal(intbv(0)[8:]) r6_r7_data = Signal(intbv(0)[16:]) branch_offset = Signal(intbv(0)[16:]) ds1_data = Signal(intbv(0)[8:]) ds2_data = Signal(intbv(0)[8:]) rd_mux1 = Signal(bool(0)) rd_mux0 = Signal(bool(0)) register_write = Signal(intbv(0)[8:]) alu_signal = Signal(intbv(0)[4:]) selector = Signal(intbv(0)[3:]) ds1_rx = Signal(intbv(0)[3:]) ds2_rx = Signal(intbv(0)[3:]) rd_r1_mux = Signal(bool(0)) rd_r0_mux = Signal(bool(0)) cr_write = Signal(bool(0)) mem_read = Signal(bool(0)) mem_write = Signal(bool(0)) jmp = Signal(bool(0)) ret = Signal(bool(0)) apc = Signal(bool(0)) bra = Signal(bool(0)) pc_next = Signal(intbv(0)[16:]) cr_data = Signal(intbv(0)[16:]) mem_ok = Signal(bool(0)) branch = Signal(bool(0)) main_state = Signal(bool(0)) @always_comb def rd_data_logic(): if rd_mux1: if rd_mux0: rd_data.next = imm else: rd_data.next = lsu_out else: rd_data.next = alu_out id_instance = id(ins, alu_signal, mem_read, mem_write, register_write, rd_r0_mux, rd_r1_mux, ds1_rx, ds2_rx, rd_mux0, rd_mux1, cr_write, selector, imm, branch_offset, bra, ret, apc, jmp) cr_instance = cr( pc, branch_offset, r6_r7_data, cr_data, clk, rst, int0, int1, int2, int3, mem_read, mem_write, mem_ok, branch, selector, cr_write, ret, apc, jmp, bra, main_state ) #toVerilog(cr,pc_next, branch_offset, r6_r7_data, cr_data,clk, rst, int0, int1, int2, int3, mem_read, mem_write, mem_ok, branch, selector, cr_write, ret, apc, jmp, bra , main_state) alu_instance = alu(ds1_data, ds2_data, imm, bra, branch, alu_out, alu_signal) lsu_instance = lsu(r6_r7_data, ds1_data, mem_read, mem_write, mem_ok, lsu_out, addr, wdata, rdata, write, read, rdy) gpr_instance = gpr(clk, rst, register_write, rd_r0_mux, rd_r1_mux, ds1_rx, ds2_rx, rd_data, cr_data, ds1_data, ds2_data, r6_r7_data) return instances()