Пример #1
0
void do_if_stage()
{
    byte_t instr = HPACK(I_NOP, F_NONE);
    byte_t regids = HPACK(REG_NONE, REG_NONE);
    word_t valc = 0;
    word_t valp = f_pc = gen_f_pc();

    /* Ready to fetch instruction.  Speculatively fetch register byte
       and immediate word
       */
    imem_error = !get_byte_val(mem, valp+START_PLACE, &instr);
    imem_icode = HI4(instr);
    imem_ifun = LO4(instr);
    if (!imem_error) {
        byte_t junk;
        /* Make sure can read maximum length instruction */
        imem_error = !get_byte_val(mem, valp+5 + START_PLACE, &junk);
    }
    if_id_next->icode = gen_f_icode();
    if_id_next->ifun  = gen_f_ifun();
    if (!imem_error) {
        sim_log("\tFetch: f_pc = 0x%x, imem_instr = %s, f_instr = %s\n",
                f_pc, iname(instr),
                iname(HPACK(if_id_next->icode, if_id_next->ifun)));
    }

    instr_valid = gen_instr_valid();
    if (!instr_valid) 
        sim_log("\tFetch: Instruction code 0x%x invalid\n", instr);
    if_id_next->status = gen_f_stat();

    valp++;
    if (gen_need_regids()) {
        get_byte_val(mem, valp + START_PLACE, &regids);
        valp ++;
    }
    if_id_next->ra = HI4(regids);
    if_id_next->rb = LO4(regids);
    if (gen_need_valC()) {
        get_word_val(mem, valp + START_PLACE, &valc);
        valp+= 4;
    }
    if_id_next->valp = valp;
    if_id_next->valc = valc;
    /*
    if(gen_need_regids() && if_id_next->valc)
        printf("##### vap: %d %d %d\n", if_id_next->ra, if_id_next->rb, if_id_next->valc);
        */

    pc_next->pc = gen_f_predPC();

    pc_next->status = (if_id_next->status == STAT_AOK) ? STAT_AOK : STAT_BUB;

    if_id_next->stage_pc = f_pc;
}
Пример #2
0
/* 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, &regids)) {
	    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;
}
Пример #3
0
void do_if_stage()
{
    exc_t nstatus = EXC_NONE;
    word_t fetchpc = gen_f_pc();
    word_t valp = fetchpc;
    bool_t fetch_ok;
    byte_t instr;
    byte_t regids = HPACK(REG_NONE, REG_NONE);
    word_t valc = 0;

    f_pc = fetchpc;

    if (fetchpc == 0) {
	sim_log("Fetch: Fetch pc = 0, nominal pc = 0x%x\n",
		pc_curr->pc);
    }

    /* Ready to fetch instruction.  Speculatively fetch register byte
       and immediate word
    */
    fetch_ok = get_byte_val(mem, valp, &instr);
    if (fetch_ok) {
	if_id_next->icode = GET_ICODE(instr);
	if_id_next->ifun = GET_FUN(instr);
    } else {
	if_id_next->icode = I_NOP;
	if_id_next->ifun = 0;
	nstatus = EXC_ADDR;
    }
    valp++;
    if (fetch_ok && gen_need_regids()) {
	fetch_ok = get_byte_val(mem, valp, &regids);
	valp ++;
    }
    if_id_next->ra = HI4(regids);
    if_id_next->rb = LO4(regids);
    if (fetch_ok && gen_need_valC()) {
	fetch_ok = get_word_val(mem, valp, &valc);
	valp+= 4;
    }
    if_id_next->valp = valp;
    if_id_next->valc = valc;

    pc_next->pc = gen_new_F_predPC();

    if (!gen_instr_valid())
	{
	    byte_t instr = HPACK(if_id_next->icode, if_id_next->ifun);
	    sim_log("Fetch: Instruction code %s (0x%x) invalid\n",
		    iname(instr), instr);
	    nstatus = EXC_INSTR;
	}

    pc_next->exception = (nstatus == EXC_NONE) ? EXC_NONE : EXC_BUBBLE;

    if_id_next->stage_pc = fetchpc;
    if_id_next->exception = nstatus;

    /* Recompute icode for one-write implementation of popl */
    if_id_next->icode = gen_new_D_icode();

    sim_log("Fetch: Fetched %s at 0x%x, ra = %s, rb = %s, valp = 0x%x, status = %s\n",
	    iname(HPACK(if_id_next->icode, if_id_next->ifun)),
	    if_id_next->stage_pc,
	    reg_name(if_id_next->ra), reg_name(if_id_next->rb),
	    if_id_next->valp,
	    exc_name(nstatus));
}
Пример #4
0
/* 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, &regids)) {
	    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;
}