void do_ex_stage() { alu_t alufun = gen_alufun(); bool_t setcc = gen_set_cc(); word_t alua, alub; alua = gen_aluA(); alub = gen_aluB(); e_bcond = take_branch(cc, id_ex_curr->ifun); ex_mem_next->takebranch = id_ex_curr->icode == I_JMP && e_bcond; if (id_ex_curr->icode == I_JMP) sim_log("Execute: %s instruction, cc = %s, branch %staken\n", iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)), cc_name(cc), ex_mem_next->takebranch ? "" : "not "); /* Perform the ALU operation */ ex_mem_next->vale = compute_alu(alufun, alua, alub); { byte_t instr = HPACK(id_ex_curr->icode, id_ex_curr->ifun); sim_log("Execute: Instruction %s\n", iname(instr)); } if (setcc) { cc_in = compute_cc(alufun, alua, alub); sim_log("Execute: CC cc = %s\n", cc_name(cc_in)); } ex_mem_next->icode = id_ex_curr->icode; ex_mem_next->ifun = id_ex_curr->ifun; ex_mem_next->vala = gen_new_M_valA(); ex_mem_next->deste = id_ex_curr->deste; ex_mem_next->destm = id_ex_curr->destm; ex_mem_next->srca = id_ex_curr->srca; ex_mem_next->exception = id_ex_curr->exception; ex_mem_next->stage_pc = id_ex_curr->stage_pc; }
void do_ex_stage() { alu_t alufun = gen_alufun(); bool_t setcc = gen_set_cc(); word_t alua, alub; alua = gen_aluA(); alub = gen_aluB(); e_bcond = cond_holds(cc, id_ex_curr->ifun); ex_mem_next->takebranch = e_bcond; if (id_ex_curr->icode == I_JMP) sim_log("\tExecute: instr = %s, cc = %s, branch %staken\n", iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)), cc_name(cc), ex_mem_next->takebranch ? "" : "not "); /* Perform the ALU operation */ word_t aluout = compute_alu(alufun, alua, alub); ex_mem_next->vale = aluout; sim_log("\tExecute: ALU: %c 0x%x 0x%x --> 0x%x\n", op_name(alufun), alua, alub, aluout); if (setcc) { cc_in = compute_cc(alufun, alua, alub); sim_log("\tExecute: New cc = %s\n", cc_name(cc_in)); } ex_mem_next->icode = id_ex_curr->icode; ex_mem_next->ifun = id_ex_curr->ifun; ex_mem_next->vala = gen_e_valA(); ex_mem_next->deste = gen_e_dstE(); ex_mem_next->destm = id_ex_curr->destm; ex_mem_next->srca = id_ex_curr->srca; ex_mem_next->status = id_ex_curr->status; ex_mem_next->stage_pc = id_ex_curr->stage_pc; }
/* Return resulting exception status */ static exc_t sim_step() { word_t aluA; word_t aluB; word_t alufun; exc_t status = update_state(); /* Update state from last cycle */ if (plusmode) { pc = gen_pc(); } valp = pc; if (get_byte_val(mem, valp, &instr)) { icode = HI4(instr); ifun = LO4(instr); } else { instr = HPACK(I_NOP,0); icode = I_NOP; ifun = 0; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; if (gen_need_regids()) { byte_t regids; if (get_byte_val(mem, valp, ®ids)) { ra = GET_RA(regids); rb = GET_RB(regids); } else { ra = REG_NONE; rb = REG_NONE; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; } else { ra = REG_NONE; rb = REG_NONE; } if (gen_need_valC()) { if (get_word_val(mem, valp, &valc)) { } else { valc = 0; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp+=4; } else { valc = 0; } if (status == EXC_NONE && !gen_instr_valid()) { status = EXC_INSTR; } sim_log("IF: Fetched %s at 0x%x. ra=%s, rb=%s, valC = 0x%x\n", iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc); if (status == EXC_NONE && icode == I_HALT) { status = EXC_HALT; } srcA = gen_srcA(); if (srcA != REG_NONE) { vala = get_reg_val(reg, srcA); } else { vala = 0; } srcB = gen_srcB(); if (srcB != REG_NONE) { valb = get_reg_val(reg, srcB); } else { valb = 0; } destE = gen_dstE(); destM = gen_dstM(); aluA = gen_aluA(); aluB = gen_aluB(); alufun = gen_alufun(); vale = compute_alu(alufun, aluA, aluB); cc_in = cc; if (gen_set_cc()) cc_in = compute_cc(alufun, aluA, aluB); bcond = (icode == I_JMP) && take_branch(cc, ifun); mem_addr = gen_mem_addr(); mem_data = gen_mem_data(); if (status == EXC_NONE && gen_mem_read()) { if (!get_word_val(mem, mem_addr, &valm)) { sim_log("Couldn't read at address 0x%x\n", mem_addr); return EXC_ADDR; } } else valm = 0; mem_write = status == EXC_NONE && gen_mem_write(); if (plusmode) { prev_icode_in = icode; prev_ifun_in = ifun; prev_valc_in = valc; prev_valm_in = valm; prev_valp_in = valp; prev_bcond_in = bcond; } else { /* Update PC */ pc_in = gen_new_pc(); } sim_report(); return status; }
/* Return resulting status */ static byte_t sim_step() { word_t aluA; word_t aluB; word_t alufun; status = STAT_AOK; imem_error = dmem_error = FALSE; update_state(); /* Update state from last cycle */ if (plusmode) { pc = gen_pc(); } valp = pc; instr = HPACK(I_NOP, F_NONE); imem_error = !get_byte_val(mem, valp, &instr); if (imem_error) { sim_log("Couldn't fetch at address 0x%x\n", valp); } imem_icode = HI4(instr); imem_ifun = LO4(instr); icode = gen_icode(); ifun = gen_ifun(); instr_valid = gen_instr_valid(); valp++; if (gen_need_regids()) { byte_t regids; if (get_byte_val(mem, valp, ®ids)) { ra = GET_RA(regids); rb = GET_RB(regids); } else { ra = REG_NONE; rb = REG_NONE; status = STAT_ADR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; } else { ra = REG_NONE; rb = REG_NONE; } if (gen_need_valC()) { if (get_word_val(mem, valp, &valc)) { } else { valc = 0; status = STAT_ADR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp+=4; } else { valc = 0; } sim_log("IF: Fetched %s at 0x%x. ra=%s, rb=%s, valC = 0x%x\n", iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc); if (status == STAT_AOK && icode == I_HALT) { status = STAT_HLT; } srcA = gen_srcA(); if (srcA != REG_NONE) { vala = get_reg_val(reg, srcA); } else { vala = 0; } srcB = gen_srcB(); if (srcB != REG_NONE) { valb = get_reg_val(reg, srcB); } else { valb = 0; } cond = cond_holds(cc, ifun); destE = gen_dstE(); destM = gen_dstM(); aluA = gen_aluA(); aluB = gen_aluB(); alufun = gen_alufun(); vale = compute_alu(alufun, aluA, aluB); cc_in = cc; if (gen_set_cc()) cc_in = compute_cc(alufun, aluA, aluB); bcond = cond && (icode == I_JMP); mem_addr = gen_mem_addr(); mem_data = gen_mem_data(); if (gen_mem_read()) { dmem_error = dmem_error || !get_word_val(mem, mem_addr, &valm); if (dmem_error) { sim_log("Couldn't read at address 0x%x\n", mem_addr); } } else valm = 0; mem_write = gen_mem_write(); if (mem_write) { /* Do a test read of the data memory to make sure address is OK */ word_t junk; dmem_error = dmem_error || !get_word_val(mem, mem_addr, &junk); } status = gen_Stat(); if (plusmode) { prev_icode_in = icode; prev_ifun_in = ifun; prev_valc_in = valc; prev_valm_in = valm; prev_valp_in = valp; prev_bcond_in = bcond; } else { /* Update PC */ pc_in = gen_new_pc(); } sim_report(); return status; }