Example #1
0
void do_mem_stage()
{
    bool_t read = gen_mem_read();
    bool_t mem_ok = TRUE;
    word_t valm = 0;

    mem_addr = gen_mem_addr();
    mem_data = ex_mem_curr->vala;
    mem_write = gen_mem_write();

    if (read) {
	mem_ok = get_word_val(mem, mem_addr, &valm);
	sim_log("Memory: Read 0x%x from 0x%x, instruction = %s\n",
		valm, mem_addr,
		iname(HPACK(ex_mem_curr->icode, ex_mem_curr->ifun)));
    }
    if (mem_write) {
	word_t sink;
	/* Do a read of address just to check validity */
	mem_ok = get_word_val(mem, mem_addr, &sink);
    }
    mem_wb_next->icode = ex_mem_curr->icode;
    mem_wb_next->ifun = ex_mem_curr->ifun;
    mem_wb_next->vale = ex_mem_curr->vale;
    mem_wb_next->valm = valm;
    mem_wb_next->deste = ex_mem_curr->deste;
    mem_wb_next->destm = ex_mem_curr->destm;
    mem_wb_next->exception = mem_ok ? ex_mem_curr->exception : EXC_ADDR;
    mem_wb_next->stage_pc = ex_mem_curr->stage_pc;
}
/* do a branch if necessary */
static void process_dobranch(int pnum, Process *q, Branch *b, Bcontext *c) {
   if (bcontext_decide(c)) { 
	// must document where we branched from
       if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,branch_from\n", 
		sysclock, pnum, q->pid, q->kind, q->pc); 
       q->pc = b->whereto; 
	// and where we branched to
       if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,branch_to\n", 
		sysclock, pnum, q->pid, q->kind, q->pc); 
       sim_log(LOG_BRANCH,"process %2d; pc %04d: branch\n",pnum, q->pc); 
   } else { 
       q->pc++; 
       sim_log(LOG_BRANCH,"process %2d; pc %04d: no branch\n",pnum, q->pc); 
   } 
   if (q->pc<0 || q->pc>=q->program->size) q->pc=0; /* start over */ 
} 
Example #3
0
/* Implements both ID and WB */
void do_id_wb_stages()
{
    /* Set up write backs.  Don't occur until end of cycle */
    wb_destE = gen_w_dstE();
    wb_valE = gen_w_valE();
    wb_destM = gen_w_dstM();
    wb_valM = gen_w_valM();

    id_ex_next->srca = gen_new_E_srcA();
    id_ex_next->srcb = gen_new_E_srcB();
    id_ex_next->deste = gen_new_E_dstE();
    id_ex_next->destm = gen_new_E_dstM();

    /* Read the registers */
    d_regvala = get_reg_val(reg, id_ex_next->srca);
    d_regvalb = get_reg_val(reg, id_ex_next->srcb);

    /* Do forwarding and valA selection */
    id_ex_next->vala = gen_new_E_valA();
    id_ex_next->valb = gen_new_E_valB();

    id_ex_next->icode = if_id_curr->icode;
    id_ex_next->ifun = if_id_curr->ifun;
    id_ex_next->valc = if_id_curr->valc;
    id_ex_next->stage_pc = if_id_curr->stage_pc;
    id_ex_next->exception = (if_id_curr->icode == I_HALT) ?
	EXC_HALT : if_id_curr->exception;
    sim_log("Decode: instr = %s, exc=%s\n",
	    iname(HPACK(if_id_curr->icode, if_id_curr->ifun)),
	    exc_name(if_id_curr->exception));
}
Example #4
0
/* Max_instr indicates maximum number of instructions that
   want to complete during this simulation run.  */
static exc_t sim_step_pipe(int max_instr)
{
    exc_t wb_exc = mem_wb_curr->exception;
    exc_t mem_exc = mem_wb_next->exception;
    /* How many instructions are ahead of one in wb / ex? */
    int ahead_mem = (wb_exc != EXC_BUBBLE);
    int ahead_ex = ahead_mem + (mem_exc != EXC_BUBBLE);
    bool_t wb_ok = (wb_exc == EXC_NONE) || (wb_exc == EXC_BUBBLE);
    bool_t mem_ok = (mem_exc == EXC_NONE) || (mem_exc == EXC_BUBBLE);
    bool_t update_mem = wb_ok && ahead_mem < max_instr;
    bool_t update_cc = update_mem && mem_ok && ahead_ex < max_instr;

    if (!update_mem) {
	sim_log("Disabling memory write.  wb_exc = %s\n", exc_name(wb_exc));
    }

    /* Update program-visible state */
    update_state(update_mem, update_cc);
    /* Update pipe registers */
    update_pipes();
    if (pc_state->op == P_ERROR)
	pc_curr->exception = EXC_PIPE;
    if (if_id_state->op == P_ERROR)
	if_id_curr->exception = EXC_PIPE;
    if (id_ex_state->op == P_ERROR)
	id_ex_curr->exception = EXC_PIPE;
    if (ex_mem_state->op == P_ERROR)
	ex_mem_curr->exception = EXC_PIPE;
    if (mem_wb_state->op == P_ERROR)
	mem_wb_curr->exception = EXC_PIPE;
    
    /* Need to do decode after execute & memory stages,
       and memory stage before execute, in order to propagate
       forwarding values properly */
    do_if_stage();
    do_mem_stage();
    do_ex_stage();
    do_id_wb_stages();

    do_stall_check();
    if (id_ex_curr->exception != EXC_NONE
	&& id_ex_curr->exception != EXC_BUBBLE) {
	if_id_state->op = P_BUBBLE;
	id_ex_state->op = P_BUBBLE;
    }

    /* Performance monitoring */
    if (mem_wb_curr->exception != EXC_BUBBLE && mem_wb_curr->icode != I_POP2) {
	starting_up = 0;
	instructions++;
	cycles++;
    } else {
	if (!starting_up)
	    cycles++;
    }
    
    sim_report();
    return mem_wb_curr->exception;
}
/* unload a process and release all resources */ 
static void process_unload(int pnum, Process *q) { 
   long i; 
   for (i=0; i<q->npages; i++) 
       if (q->pages[i]>=-PAGEWAIT) { 
	   pagesavail++; q->pages[i]=-PAGEWAIT-1; q->blocked[i]=1;
       } 
   q->active=FALSE; 
   sim_log(LOG_LOAD,"process %2d; pc %04d: unloaded\n",pnum, q->pc); 
} 
Example #6
0
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;
}
Example #7
0
void do_mem_stage()
{
    bool_t read = gen_mem_read();

    word_t valm = 0;

    mem_addr = gen_mem_addr();
    mem_data = ex_mem_curr->vala;
    mem_write = gen_mem_write();
    mem_test = gen_mem_test();
    dmem_error = FALSE;

    if (read && !mem_test) {
        dmem_error = dmem_error || !get_word_val(mem, mem_addr, &valm);
        if (!dmem_error)
            sim_log("\tMemory: Read 0x%x from 0x%x\n",
                    valm, mem_addr);
    }
    if (mem_write && !mem_test) {
        word_t sink;
        /* Do a read of address just to check validity */
        dmem_error = dmem_error || !get_word_val(mem, mem_addr, &sink);
        if (dmem_error)
            sim_log("\tMemory: Invalid address 0x%x\n",
                    mem_addr);
    }
    if (mem_test && read){
        mem_test_address = mem_addr;

        int ans = test_memory(mem, mem_test_address);
        valm = ans;
    }
    mem_wb_next->icode = ex_mem_curr->icode;
    mem_wb_next->ifun = ex_mem_curr->ifun;
    mem_wb_next->vale = ex_mem_curr->vale;
    mem_wb_next->valm = valm;
    mem_wb_next->deste = ex_mem_curr->deste;
    mem_wb_next->destm = ex_mem_curr->destm;
    mem_wb_next->status = gen_m_stat();
    mem_wb_next->stage_pc = ex_mem_curr->stage_pc;
}
Example #8
0
/* Text representation of status */
void tty_report(int cyc) {
    sim_log("\nCycle %d. CC=%s, Stat=%s\n", cyc, cc_name(cc), stat_name(status));

    sim_log("F: predPC = 0x%x\n", pc_curr->pc);

    sim_log("D: instr = %s, rA = %s, rB = %s, valC = 0x%x, valP = 0x%x, Stat = %s\n",
            iname(HPACK(if_id_curr->icode, if_id_curr->ifun)),
            reg_name(if_id_curr->ra), reg_name(if_id_curr->rb),
            if_id_curr->valc, if_id_curr->valp,
            stat_name(if_id_curr->status));

    sim_log("E: instr = %s, valC = 0x%x, valA = 0x%x, valB = 0x%x\n   srcA = %s, srcB = %s, dstE = %s, dstM = %s, Stat = %s\n",
            iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)),
            id_ex_curr->valc, id_ex_curr->vala, id_ex_curr->valb,
            reg_name(id_ex_curr->srca), reg_name(id_ex_curr->srcb),
            reg_name(id_ex_curr->deste), reg_name(id_ex_curr->destm),
            stat_name(id_ex_curr->status));

    sim_log("M: instr = %s, Cnd = %d, valE = 0x%x, valA = 0x%x\n   dstE = %s, dstM = %s, Stat = %s\n",
            iname(HPACK(ex_mem_curr->icode, ex_mem_curr->ifun)),
            ex_mem_curr->takebranch,
            ex_mem_curr->vale, ex_mem_curr->vala,
            reg_name(ex_mem_curr->deste), reg_name(ex_mem_curr->destm),
            stat_name(ex_mem_curr->status));

    sim_log("W: instr = %s, valE = 0x%x, valM = 0x%x, dstE = %s, dstM = %s, Stat = %s\n",
            iname(HPACK(mem_wb_curr->icode, mem_wb_curr->ifun)),
            mem_wb_curr->vale, mem_wb_curr->valm,
            reg_name(mem_wb_curr->deste), reg_name(mem_wb_curr->destm),
            stat_name(mem_wb_curr->status));
}
Example #9
0
File: psim.c Project: PiffNP/CSAPP
void do_mem_stage()
{
    bool_t read = gen_mem_read();

    word_t valm = 0;

    mem_addr = gen_mem_addr();
    if(ex_mem_curr->icode == I_MUTEXTEST || ex_mem_curr->icode == I_MUTEXCLEAR)
        mem_addr = MUTEX_BYTE;
    mem_data = ex_mem_curr->vala;
    if(ex_mem_curr->icode == I_MUTEXTEST)
        mem_data = 1;
    else if(ex_mem_curr->icode == I_MUTEXCLEAR)
        mem_data = 0;
    mem_write = gen_mem_write();
    dmem_error = FALSE;

    if (read) {
	dmem_error = dmem_error || !get_word_val(mem, mem_addr, &valm);
	if (!dmem_error)
	  sim_log("\tMemory: Read 0x%x from 0x%x\n",
		  valm, mem_addr);
    }
    if (mem_write) {
	word_t sink;
	/* Do a read of address just to check validity */
	dmem_error = dmem_error || !get_word_val(mem, mem_addr, &sink);
	if (dmem_error)
	  sim_log("\tMemory: Invalid address 0x%x\n",
		  mem_addr);
    }
    mem_wb_next->icode = ex_mem_curr->icode;
    mem_wb_next->ifun = ex_mem_curr->ifun;
    mem_wb_next->vale = ex_mem_curr->vale;
    mem_wb_next->valm = valm;
    mem_wb_next->deste = ex_mem_curr->deste;
    mem_wb_next->destm = ex_mem_curr->destm;
    mem_wb_next->status = gen_m_stat();
    mem_wb_next->stage_pc = ex_mem_curr->stage_pc;
}
Example #10
0
File: psim.c Project: PiffNP/CSAPP
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;

}
Example #11
0
p_status_t pipe_cntl(char *name, int stall, int bubble)
{
    if (stall) {
	if (bubble) {
	    sim_log("%s: Conflicting control signals for pipe register\n",
		    name);
	    return P_ERROR;
	} else 
	    return P_STALL;
    } else {
	return bubble ? P_BUBBLE : P_LOAD;
    }
}
/* public routine: swap one page out */ 
int pageout(int process, int page) { 
    if (process<0 || process>=procs 
     || !processes[process]
     || !processes[process]->active
     || page<0 || page>=processes[process]->npages) 
	return FALSE; 
    if (processes[process]->pages[page]<0) 
	return TRUE; /* on its way out */ 
    if (processes[process]->pages[page]>0) 
	return FALSE; /* not available to swap out */ 
sim_log(LOG_PAGE,"process=%2d page=%3d start pageout\n",process,page);
    if (pages) fprintf(pages,"%ld,%d,%d,%ld,%ld,going\n",
	sysclock,process,page,processes[process]->pid, processes[process]->kind); 
    processes[process]->pages[page]=-1; return TRUE;
} 
Example #13
0
File: ssim.c Project: Azard/icslabs
/* Update the processor state */
static void update_state()
{
    if (plusmode) {
	prev_icode = prev_icode_in;
	prev_ifun  = prev_ifun_in;
	prev_valc  = prev_valc_in;
	prev_valm  = prev_valm_in;
	prev_valp  = prev_valp_in;
	prev_bcond = prev_bcond_in;
    } else {
	pc = pc_in;
    }
    cc = cc_in;
    /* Writeback */
    if (destE != REG_NONE)
	set_reg_val(reg, destE, vale);
    if (destM != REG_NONE)
	set_reg_val(reg, destM, valm);

    if (mem_write) {
      /* Should have already tested this address */
      set_word_val(mem, mem_addr, mem_data);
	sim_log("Wrote 0x%x to address 0x%x\n", mem_data, mem_addr);
#ifdef HAS_GUI
	    if (gui_mode) {
		if (mem_addr % 4 != 0) {
		    /* Just did a misaligned write.
		       Need to display both words */
		    word_t align_addr = mem_addr & ~0x3;
		    word_t val;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		    align_addr+=4;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		} else {
		    set_memory(mem_addr, mem_data);
		}
	    }
#endif /* HAS_GUI */
    }
}
static void allinit () { 
    long i; 
    initqueue(); 
    for (i=0; i<MAXPROCESSES; i++) processes[i]=NULL; 
    for (i=0; i<procs; i++) { 
	// zero out pages from processes
	if (!empty()) {
	    processes[i]=dequeue(); 

	    sim_log(LOG_LOAD,"process %2d; pc %04d: loaded\n",i, processes[i]->pc); 
	    if (output) fprintf(output, "%ld,%ld,%ld,%ld,%ld,load\n", 
		sysclock, i, processes[i]->pid, 
		processes[i]->kind, processes[i]->pc);
	    if (pages) { 
		long j;
		for (j=0; j<MAXPROCPAGES; j++) 
		    fprintf(pages,"%ld,%ld,%ld,%ld,%ld,out\n",
			sysclock,i,j,processes[i]->pid,processes[i]->kind); 
	    } 
	} 
    } 
} 
Example #15
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;
}
Example #16
0
File: ssim.c Project: Azard/icslabs
/* 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;
}
Example #17
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));
}
int main(int argc, char **argv) { 
    
    long i,errors=0,help=0; 
 
    signal(SIGINT, endit); 
    
    log_port=LOG_ALWAYS; 
    for (i=1; i<argc; i++) { 
	if (strcmp(argv[i],"-help")==0) { 
	    help++;
	} else if (strcmp(argv[i],"-all")==0) { 
	    log_port |= LOG_LOAD|LOG_BLOCK|LOG_PAGE|LOG_BRANCH; 
	} else if (strcmp(argv[i],"-load")==0) { 
	    log_port |= LOG_LOAD; 
	} else if (strcmp(argv[i],"-block")==0) { 
	    log_port |= LOG_BLOCK; 
	} else if (strcmp(argv[i],"-page")==0) { 
	    log_port |= LOG_PAGE; 
	} else if (strcmp(argv[i],"-branch")==0) { 
	    log_port |= LOG_BRANCH; 
	} else if (strcmp(argv[i],"-dead")==0) { 
	    log_port |= LOG_DEAD; 
	} else if (strcmp(argv[i],"-seed")==0) { 
	    if (sscanf(argv[++i],"%ld",&seed)!=1) {
		fprintf(stderr,
			"%s: could not read random seed from command line\n",
			argv[0]); 
		errors++; 
	    } else if (seed<1 || seed>((1<<30)-1)) {
		fprintf(stderr,
			"%s: random seed must be between 1 and %d\n",
			argv[0], (1<<30)-1); 
		errors++; 
	    } 
	} else if (strcmp(argv[i],"-csv")==0) { 
	    output = fopen("output.csv", "w"); 
            if (!output) { 
		fprintf(stderr,
			"%s: could not open output.csv for writing\n",
			argv[0]); 
		errors++; 
	    } 
	    pages = fopen("pages.csv", "w"); 
            if (!pages) { 
		fprintf(stderr,
			"%s: could not open pages.csv for writing\n",
			argv[0]); 
		errors++; 
	    } 
	} else if (strcmp(argv[i],"-procs")==0) { 
	    if (sscanf(argv[++i],"%ld",&procs)!=1) {
		fprintf(stderr,
			"%s: could not read number of processors from command line\n",
			argv[0]); 
		errors++; 
	    } else if (procs<1 || procs>MAXPROCESSES) {
		fprintf(stderr,
			"%s: number of processors must be between 1 and %d\n",
			argv[0], MAXPROCESSES); 
		errors++; 
	    } 
        } else { 
	    fprintf(stderr, "t4: unrecognized argument %s\n", argv[i]); 
	    errors++; 
 	} 
    } 
    if (errors || help) { 
	fprintf(stderr, "%s usage: %s \n", argv[0], argv[0]); 
        fprintf(stderr, "  -all       log everything\n"); 
	fprintf(stderr, "  -load      log loading of processes\n"); 
	fprintf(stderr, "  -unload    log unloading of processes\n"); 
	fprintf(stderr, "  -branch    log program branches\n"); 
	fprintf(stderr, "  -page      log page in and out\n"); 
	fprintf(stderr, "  -seed 512  set random seed to 512\n"); 
	fprintf(stderr, "  -procs 4   run only four processors\n"); 
	fprintf(stderr, "  -dead      detect deadlocks\n"); 
	fprintf(stderr, "  -csv       generate output.csv and pages.csv for graphing\n");
	if(errors) {
	    return EXIT_FAILURE;
	}
	else {
	    return EXIT_SUCCESS;
	}
    } 
    if (seed==0) { 
	seed = (time(NULL)*38491+71831+time(NULL)*time(NULL))&((1<<30)-1); 
    } 
    srand48(seed); 
    sim_log(LOG_ALWAYS,"random seed %d\n", seed); 
    sim_log(LOG_ALWAYS,"using %d processors\n", procs); 
    
    allinit(); 
    while (!alldone()) { // all processes inactive
	allstep(); 	 // advance time one tick; if process done, reload
        allage(); 	 // advance time for page wait variables. 
        callyou(); 	 // call your program
	sysclock++;      // remember new time. 
	allblocked();    // deadlock detection 
    } 
    allscore(); 

    return EXIT_SUCCESS;

} 
/* compute one step of a process */ 
static long process_step(int pnum, Process *q) { 
   long pc; 
   long page; 
   long max, min; 
   Branch *b; 
   Bcontext *c; 

   if (!q) return FALSE;  
   pc = q->pc; 
   page = q->pc / PAGESIZE; 
   if (!q->active) { return FALSE; } 

   /* if page swapped out, don't allow to run */ 
   if (q->pages[page]!=0) { 
	if (!q->blocked[page]) { 
	    sim_log(LOG_BLOCK,"process=%2d page=%3d blocked\n",pnum,page);
	    if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,blocked\n", 
		sysclock, pnum, q->pid, q->kind, q->pc); 
	    q->blocked[page]=TRUE; 
	}
	q->block++; return TRUE; 
   } else { 
	if (q->blocked[page]) { 
	    sim_log(LOG_BLOCK,"process=%2d page=%3d unblocked\n",pnum,page);
	    if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,unblocked\n",
		sysclock,pnum, q->pid, q->kind, q->pc);
	    q->blocked[page]=FALSE; 
        } 
	q->compute++; 
   }

   /* should I exit */ 
   ASSERT(q->program->nexits>=0 && q->program->nexits<=MAXEXITS); 
   min=0; max=q->program->nexits-1; 
   while (min+1<max) { 
       long mid=(min+max)/2; 
       if (pc==q->program->exits[mid]) { 
	    if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,exit\n", 
		sysclock, pnum, q->pid, q->kind, q->pc);
	    return FALSE; 
       } 
       else if (pc<q->program->exits[mid])  max=mid; 
       else                                 min=mid; 
   } 
   if (pc==q->program->exits[min] || pc==q->program->exits[max]) { 
	if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,exit\n", 
	    sysclock, pnum, q->pid, q->kind, q->pc);
	return FALSE; 
   } 
   b = q->program->branches; 
   c = q->bcontexts; 
   ASSERT(q->program->nbranches>=0 && q->program->nbranches<=MAXBRANCHES); 
   min=0; max=q->program->nbranches-1; 
   while (min+1<max) { 
       long mid=(min+max)/2; 
       if (pc==b[mid].wherefrom) {
	    process_dobranch(pnum,q,b+mid,c+mid);
	    return TRUE;
       }
       else if (pc<b[mid].wherefrom) max=mid; 
       else                          min=mid; 
   } 
   if (pc==b[min].wherefrom) { process_dobranch(pnum,q,b+min,c+min); return TRUE; } 
   if (pc==b[max].wherefrom) { process_dobranch(pnum,q,b+max,c+max); return TRUE; } 
   q->pc++; /* default action */ 
   if (q->pc<0 || q->pc>q->program->size) { 
	if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,out_of_range\n", 
	    sysclock, pnum, q->pid, q->kind, q->pc);
	q->pc=0; /* start over */ 
	if (output) fprintf(output, "%ld,%d,%ld,%ld,%ld,restart\n", 
	    sysclock, pnum, q->pid, q->kind, q->pc);
   } 
   return TRUE; 
}