コード例 #1
0
ファイル: sim-safe.c プロジェクト: isaiahtan/ece552
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* ECE552 Pre-Assignment - BEGIN CODE*/
  int r_out[2], r_in[3];
  /* ECE552 Pre-Assignment - END CODE*/

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {

      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */

      switch (op)
      {
	      /* ECE552 Pre-Assignment - BEGIN CODE*/
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \
	      case OP: \
		       r_out[0] = (O1); r_out[1] = (O2); \
	      r_in[0] = (I1); r_in[1] = (I2); r_in[2] = (I3); \
	      SYMCAT(OP,_IMPL); \
	      break;
	      /* ECE552 Pre-Assignment - END CODE*/
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      /* ECE552 Pre-Assignment - BEGIN CODE*/
      if ( (MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD) ) {
	      sim_num_loads++;
      }
      {
	      int i;
	      for (i = 0; i < 3; i++) {
		      if (r_in[i] != DNA && reg_ready [r_in [i]] > sim_num_insn) {
			      if ((i == 0) && (MD_OP_FLAGS(op) & F_MEM) &&
					      (MD_OP_FLAGS(op) & F_STORE)) {
				      continue;
			      }
			      sim_num_lduh++;
			      break;
		      }
	      }
      }
      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD)) {
	      if (r_out[0] != DNA)
		      reg_ready[r_out[0]] = sim_num_insn + 2;
	      if (r_out[1] != DNA)
		      reg_ready[r_out[1]] = sim_num_insn + 2;
      }
      /* ECE552 Pre-Assignment - END CODE*/

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
コード例 #2
0
ファイル: sim-dis.c プロジェクト: k4v/CA614-Project
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_PC = ld_text_base;
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
#ifndef TARGET_ARM
      regs.regs_R[MD_REG_ZERO] = 0;
#endif
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      if (regs.regs_PC >= ld_text_bound)
	{
	  info("all instructions decoded...");
	  exit(0);
	}

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

#if 0
      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3,I4)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);
#endif

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  myfprintf(stderr, "           op: %d, inst: 0x%08x\n", op, inst);
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
コード例 #3
0
ファイル: sim-profile.c プロジェクト: palmerc/lab
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  int i;
  md_inst_t inst;
  register md_addr_t addr;
  register int is_write;
  enum md_opcode op;
  unsigned int flags;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t));

      if (verbose)
	{
	  myfprintf(stderr, "%10n @ 0x%08p: ", sim_num_insn, regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /*
       * profile this instruction
       */
      flags = MD_OP_FLAGS(op);

      if (prof_ic)
	{
	  enum inst_class_t ic;

	  /* compute instruction class */
	  if (flags & F_LOAD)
	    ic = ic_load;
	  else if (flags & F_STORE)
	    ic = ic_store;
	  else if (flags & F_UNCOND)
	    ic = ic_uncond;
	  else if (flags & F_COND)
	    ic = ic_cond;      
	  else if (flags & F_ICOMP)
	    ic = ic_icomp;
	  else if (flags & F_FCOMP)
	    ic = ic_fcomp;
	  else if (flags & F_TRAP)
	    ic = ic_trap;
	  else
	    panic("instruction has no class");

	  /* update instruction class profile */
	  stat_add_sample(ic_prof, (int)ic);
	}

      if (prof_inst)
	{
	  /* update instruction profile */
	  stat_add_sample(inst_prof, (int)op - /* skip NA */1);
	}

      if (prof_bc)
	{
	  enum branch_class_t bc;

	  /* compute instruction class */
	  if (flags & F_CTRL)
	    {
	      if ((flags & (F_CALL|F_DIRJMP)) == (F_CALL|F_DIRJMP))
		bc = bc_call_dir;
	      else if ((flags & (F_CALL|F_INDIRJMP)) == (F_CALL|F_INDIRJMP))
		bc = bc_call_indir;
	      else if ((flags & (F_UNCOND|F_DIRJMP)) == (F_UNCOND|F_DIRJMP))
		bc = bc_uncond_dir;
	      else if ((flags & (F_UNCOND|F_INDIRJMP))== (F_UNCOND|F_INDIRJMP))
		bc = bc_uncond_indir;
	      else if ((flags & (F_COND|F_DIRJMP)) == (F_COND|F_DIRJMP))
		bc = bc_cond_dir;
	      else if ((flags & (F_COND|F_INDIRJMP)) == (F_COND|F_INDIRJMP))
		bc = bc_cond_indir;
	      else
		panic("branch has no class");

	      /* update instruction class profile */
	      stat_add_sample(bc_prof, (int)bc);
	    }
	}

      if (prof_am)
	{
	  enum md_amode_type am;

	  /* update addressing mode pre-probe FSM */
	  MD_AMODE_PREPROBE(op, fsm);

	  /* compute addressing mode */
	  if (flags & F_MEM)
	    {
	      /* compute addressing mode */
	      MD_AMODE_PROBE(am, op, fsm);

	      /* update the addressing mode profile */
	      stat_add_sample(am_prof, (int)am);

	      /* addressing mode pre-probe FSM, after all loads and stores */
	      MD_AMODE_POSTPROBE(fsm);
	    }
	}

      if (prof_seg)
	{
	  if (flags & F_MEM)
	    {
	      /* update instruction profile */
	      stat_add_sample(seg_prof, (int)bind_to_seg(addr));
	    }
	}

      if (prof_tsyms)
	{
	  int tindex;

	  /* attempt to bind inst address to a text segment symbol */
	  sym_bind_addr(regs.regs_PC, &tindex, /* !exact */FALSE, sdb_text);

	  if (tindex >= 0)
	    {
	      if (tindex > sym_ntextsyms)
		panic("bogus text symbol index");

	      stat_add_sample(tsym_prof, tindex);
	    }
	  /* else, could not bind to a symbol */
	}

      if (prof_dsyms)
	{
	  int dindex;

	  if (flags & F_MEM)
	    {
	      /* attempt to bind inst address to a text segment symbol */
	      sym_bind_addr(addr, &dindex, /* !exact */FALSE, sdb_data);

	      if (dindex >= 0)
		{
		  if (dindex > sym_ndatasyms)
		    panic("bogus data symbol index");

		  stat_add_sample(dsym_prof, dindex);
		}
	      /* else, could not bind to a symbol */
	    }
	}

      if (prof_taddr)
	{
	  /* add regs_PC exec event to text address profile */
	  stat_add_sample(taddr_prof, regs.regs_PC);
	}

      /* update any stats tracked by PC */
      for (i=0; i<pcstat_nelt; i++)
	{
	  counter_t newval;
	  int delta;

	  /* check if any tracked stats changed */
	  newval = STATVAL(pcstat_stats[i]);
	  delta = newval - pcstat_lastvals[i];
	  if (delta != 0)
	    {
	      stat_add_samples(pcstat_sdists[i], regs.regs_PC, delta);
	      pcstat_lastvals[i] = newval;
	    }

	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
コード例 #4
0
void decode(void)
{
    md_inst_t inst;
    register md_addr_t addr;
    enum md_opcode op;
    register int is_write;
    enum md_fault_type fault;
    int i;
    int i1, i2, i3, o1, o2;

    inst_t *pI = g_piperegister[IF_ID_REGISTER];

    if( g_piperegister[ID_EX_REGISTER] != NULL )
        return; // stall
    if( pI == NULL )
        return; // bubble

    if( !pI->stalled ) {
        // BEGIN FUNCTIONAL EXECUTION -->
        assert( pI->pc == regs.regs_PC );

        /* maintain $r0 semantics */
        regs.regs_R[MD_REG_ZERO] = 0;
        inst = pI->inst;

        /* keep an instruction count */
        sim_num_insn++;

        /* set default reference address and access mode */
        addr = 0; is_write = FALSE;

        /* set default fault - none */
        fault = md_fault_none;

        /* decode the instruction */
        MD_SET_OPCODE(op, inst);
        pI->op = op;

        /* execute the instruction */
        switch (op)
        {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)    \
        case OP:                                                    \
              i1 = I1; i2 = I2; i3 = I3; o1 = O1; o2 = O2;          \
              SYMCAT(OP,_IMPL);                                     \
              break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)                         \
            case OP:                                                \
              panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)                                    \
          { fault = (FAULT); break; }
#include "machine.def"
        default:
          panic("attempted to execute a bogus opcode");
        }

        if (fault != md_fault_none)
            fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

        if (verbose) {
            myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
            sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
            md_print_insn(inst, regs.regs_PC, stderr);
            if (MD_OP_FLAGS(op) & F_MEM)
            myfprintf(stderr, "  mem: 0x%08p", addr);
            fprintf(stderr, "\n");
            /* fflush(stderr); */
        }

        if (MD_OP_FLAGS(op) & F_MEM) {
          sim_num_refs++;
          if (MD_OP_FLAGS(op) & F_STORE)
            is_write = TRUE;
        }

        /* go to the next instruction */
        regs.regs_PC = regs.regs_NPC;
        regs.regs_NPC += sizeof(md_inst_t);

        // <---  END FUNCTIONAL EXECUTION

	// record correct next instruction address (use for branches/jumps)
	pI->next_pc = regs.regs_PC;

        // record dependencies on instructions already in the pipeline 
        pI->src[0] = g_raw[i1];
        pI->src[1] = g_raw[i2];
        pI->src[2] = g_raw[i3];

        // record which register(s) this instruction writes to
        if( o1 != DNA ) g_raw[o1] = pI;
        if( o2 != DNA ) g_raw[o2] = pI;
        pI->dst[0] = o1;
        pI->dst[1] = o2;

        // determine instruction type
        if( MD_OP_FLAGS(op) & F_CTRL ) 
            pI->taken = (regs.regs_PC != (pI->pc+sizeof(md_inst_t)));
    }

    // check for RAW hazard
    for ( i=0; i < 3; ++i ) { // for each potential source operand...
        if ( pI->src[i] != NULL ) {
            if( pI->src[i]->donecycle > sim_cycle )
            {
            	pI->stalled = 1;
            	return;
            }
        }
    }

    if( pI->taken ) {
        g_fetch_redirected = 1;
        g_target_pc = pI->next_pc;
    }

    // move instruction from IF/ID to ID/EX register...
    pI->stalled = 0;
    pI->status = DECODED;
    g_piperegister[ID_EX_REGISTER] = pI; // move to ID/EX register
    g_piperegister[IF_ID_REGISTER] = NULL;
}
コード例 #5
0
ファイル: sim-safe.c プロジェクト: alista24ftp/cpen411
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;
  
  // conditional-branch offset bits
  int offbits = 0;
  int twoscompl = 0;
  unsigned int abs_offbits = 0;
  
  // number of bits changed in a GPR
  int bits_changed;
  
  int dst_reg; // destination register in part 3

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

	// initialize all the arrays
	init_arrays();
	
		
  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
		  dst_reg = O1;					\
		  if(dst_reg > 0 && dst_reg < NUM_REGS) prev_val[dst_reg] = regs.regs_R[dst_reg];		\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}
	
	
	// for registers 0-31 determine the new value written to dst_reg
	if(dst_reg > 0 && dst_reg < NUM_REGS){
		
		bits_changed = func_bits_chng(prev_val[dst_reg], regs.regs_R[dst_reg]);
		reg_contents[dst_reg] += bits_changed;
		num_inst_chng_bits++;
		
	}
	
	
	  if(MD_OP_FLAGS(op) & F_COND)
	{
		g_total_cond_branches++;
		
		// increment histogram index with corresp. offset bits
		offbits = (regs.regs_TPC - regs.regs_PC)/8;
		
		// absolute value representation of the offbits
		abs_offbits = abs(regs.regs_TPC - regs.regs_PC)/8;
				
		if(offbits < 0){
			// if offset is negative, simply add one bit (the signed bit) to its absolute value
			// this is equivalent to offbits = ceil(log10(-1*offbits)/log10(2) + 1); (trust me, I've tried it)
			offbits = floor(log10(abs_offbits)/log10(2) + 2) + 1; 
		}else{
			offbits = floor(log10(abs_offbits)/log10(2) + 2);
		}
		
		
		histogram[offbits]++;
	}
	
	  if(MD_OP_FLAGS(op) & F_DIRJMP)
	{
		g_total_uncond_branches++;
	}
	
	  if((MD_OP_FLAGS(op) & F_FCOMP) || (MD_OP_FLAGS(op) & F_FPCOND))
	{
		g_total_fp_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_STORE)
	{
		g_total_store_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_LOAD)
	{
		g_total_ld_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_IMM)
	{
		g_total_imm_inst++;
	}
	
      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

	

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts){
			
			return;
		}
    }
}
コード例 #6
0
ファイル: sim-bpred-koba-orig.c プロジェクト: palmerc/lab
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr, target_PC;
  enum md_opcode op;
  register int is_write;
  int stack_idx;
  enum md_fault_type fault;

  int out1, out2, in1, in2, in3;	  /* register names */
  int v_out1, v_out2, v_in1, v_in2, v_in3;/* register values */
  int vl_out1, vl_out2, vl_in1, vl_in2, vl_in3;
  md_addr_t addr_dispatch;              /* access_address */
  int m_size;                           /* access_size */
  FILE *stream;
  md_addr_t predicted_PC;

  fprintf(stderr, "sim: ** starting functional simulation w/ predictors **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t));

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,CLASS,O1,O2,I1,I2,I3,            \
                VO1,LO1,VO2,LO2,ADDR,VI1,LI1,VI2,LI2,VI3,LI3,M_Size)    \
	case OP:							\
	  in1 = I1; in2 = I2; in3 = I3;					\
	  v_in1 = VI1; v_in2 = VI2; v_in3 = VI3;			\
	  vl_in1 = LI1; vl_in2 = LI2; vl_in3 = LI3;			\
          SYMCAT(OP,_IMPL);						\
	  out1 = O1; out2 = O2;						\
	  v_out1 = VO1; v_out2 = VO2;					\
	  vl_out1 = LO1; vl_out2 = LO2;					\
	  addr_dispatch = ADDR;						\
	  m_size = M_Size;						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "operand.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  md_addr_t pred_PC;
	  struct bpred_update_t update_rec;

	  sim_num_branches++;

	  if (pred)
	    {
	      /* get the next predicted fetch address */
	      pred_PC = bpred_lookup(pred,
				     /* branch addr */regs.regs_PC,
				     /* target */target_PC,
				     /* inst opcode */op,
				     /* call? */MD_IS_CALL(op),
				     /* return? */MD_IS_RETURN(op),
				     /* stash an update ptr */&update_rec,
				     /* stash return stack ptr */&stack_idx);

	      /* valid address returned from branch predictor? */
	      if (!pred_PC)
		{
		  /* no predicted taken target, attempt not taken target */
		  pred_PC = regs.regs_PC + sizeof(md_inst_t);
		}

	      bpred_update(pred,
			   /* branch addr */regs.regs_PC,
			   /* resolved branch target */regs.regs_NPC,
			   /* taken? */regs.regs_NPC != (regs.regs_PC +
							 sizeof(md_inst_t)),
			   /* pred taken? */pred_PC != (regs.regs_PC +
							sizeof(md_inst_t)),
			   /* correct pred? */pred_PC == regs.regs_NPC,
			   /* opcode */op,
			   /* predictor update pointer */&update_rec);
	    }
	  predicted_PC = pred_PC;
	}

      /*   ここから下を見ればどの変数に何が入っているか分かるはず。 */
      stream = stdout;
      fprintf(stream, "############################################################ \n");
      fprintf(stream, " --- trace count(%d) \n", (int)sim_num_insn);
      fprintf(sim_fd, "%s, inst: `",
      fprintf(stream, "       opcode: %s, inst: `",
	      MD_OP_NAME(op));
      md_print_insn(inst, regs.regs_PC, stream);
      fprintf(stream, "'\n");
      myfprintf(stream, "         PC: 0x%08p, NPC: 0x%08p",
		regs.regs_PC, regs.regs_NPC);
      if(pred)
	myfprintf(stream, " (pred_PC: 0x%08p)\n",
		  regs.regs_PC, regs.regs_NPC, predicted_PC);
      else
	myfprintf(stream, "\n");
      fprintf(stream," |  in(r%02d,r%02d,r%02d),out(r%02d,r%02d),\n",
	      in1, in2, in3, out1, out2);
      fprintf(stream," |  IN(%8x,%8x,%8x),OUT(%8x,%8x)addr(%8x)|\n",
	      v_in1, v_in2, v_in3, v_out1, v_out2, addr_dispatch);
      /* ダブルワードだった場合,この変数がセットされる */
      fprintf(stream," |  in(%8x,%8x,%8x),out(%8x,%8x)         |\n",
	      vl_in1, vl_in2, vl_in3, vl_out1, vl_out2);

      /* machine.h をみるとopから命令の種類を判別する方法が分かる。以下は例 */
      if (op == MD_NOP_OP)
	{
	  fprintf(stream, "   NOP instruction \n");
	}
      else if (MD_OP_FLAGS(op) & F_MEM)
	{
	  fprintf(stream, "   MEMORY instruction \n");
	  if (MD_OP_FLAGS(op) & F_STORE)
	    fprintf(stream, "        store instruction \n");
	  else if (MD_OP_FLAGS(op) & F_LOAD)
	    fprintf(stream, "        load instruction \n");
	  fprintf(stream, "          ld/st address is %010x\n",
		  addr_dispatch);
	  fprintf(stream, "          ld/st size is %2d\n",
		  m_size);
	  /* ロードストアがバイト単位なのか,ワード単位なのか,
	     ハーフワード単位なのかは,opを見て判断できる。
	     例えば, md_op2name[op] が "sh"ならハーフワードである。
	     しかし、これだと面倒なのでoperand.defを改良した方が良い
	     かも知れない。これはおまかせ。
	     */
	  
	  /* ロードストアの詳細に関しては,machine.def を参照。
	     例えば,store halfの場合,(machine.def をエディタで開いて
	     "sh"と言う文字列をサーチすれば該当箇所が見つかる)
	     以下のようにかかれている。*/
	  /*
                #define SH_IMPL                                     
                  {                                                 
                    half_t _src;                                    
                    enum md_fault_type _fault;                      
                    _src = (half_t)(word_t)GPR(RT);                 
                    WRITE_HALF(_src, GPR(BS) + OFS, _fault);        
                    if (_fault != md_fault_none)                    
                      DECLARE_FAULT(_fault);                        
                   }
		   */
	  /*ここで、GPR(BS)はBS番レジスタの値 OFS はオフセットを示す。
	    そして,GPR(RT)はRT番レジスタの値を示す。
	    そしてWRITE_HALF(_src, GPR(BS) + OFS, _fault);は
	    値 _src をアドレス GPR(BS) + OFS に書き込む事を意味する。
	    書き込みのサイズは,halfワードである。*/
	}
      else if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  fprintf(stream, "   BRANCH instruction \n");
	  if (MD_IS_CALL(op))
	    fprintf(stream, "        function call \n");
	  else if (MD_IS_RETURN(op))
	    fprintf(stream, "        function return \n");
	  else if (MD_IS_INDIR(op))
	    fprintf(stream, "        indirect jump \n");
	  else if ((MD_OP_FLAGS(op) & (F_CTRL|F_DIRJMP)) == (F_CTRL|F_DIRJMP))
	    fprintf(stream, "        direct jump \n");
	}
      else
	{
	  fprintf(stream, "   other instruction \n");
	}
      /* この応用として,いきなりopからstoreを判別するには,以下のようにすれば良い*/
      if ((MD_OP_FLAGS(op) & (F_MEM|F_STORE)) == (F_MEM|F_STORE))
	{
	  /*fprintf(stream, "   store instruction \n");*/
	}
      else if ((MD_OP_FLAGS(op) & (F_MEM|F_LOAD)) == (F_MEM|F_LOAD))
	{
	  /*fprintf(stream, "   load instruction \n");*/
	}

      /* ここまで */


      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
コード例 #7
0
ファイル: sim-cache.c プロジェクト: HackLinux/sim-R10K
/* start simulation, program loaded, processor precise state initialized */
bool_t
sim_sample(unsigned int n_insn)
{
  md_inst_t inst;
  enum md_fault_t fault;
  struct predec_insn_t *pdi;
  counter_t sim_num_insn_begin = sim_num_insn;
  bool_t fdumpinsn;

  while (n_insn == 0 || sim_num_insn < sim_num_insn_begin + n_insn)
    {
      /* maintain $r0 semantics */
      regs.regs[MD_REG_ZERO].q = 0;
      regs.regs[MD_FREG_ZERO].d = 0.0;

      /* get the next instruction to execute */
      if (itlb)
	cache_access(itlb, mc_READ, regs.PC, sizeof(md_inst_t), 0, NULL, tlb_miss_handler);
      if (cache_il1)
	cache_access(cache_il1, mc_READ, regs.PC, sizeof(md_inst_t), 0, NULL, l1_miss_handler);

      mem_access(mem, mc_READ, regs.PC, &inst, sizeof(md_inst_t));

      /* set default reference address and access mode */
      regs.addr = 0; regs.dsize = 0;

      /* set default fault - none */
      fault = md_fault_none;

      /* get the next instruction to execute */
      pdi = predec_lookup(regs.PC);
      if (!pdi)
	{
	  mem_access(mem, mc_READ, regs.PC, &inst, sizeof(md_inst_t));
	  pdi = predec_enter(regs.PC, inst);
	}

      /* keep an instruction count */
      if (pdi->iclass != ic_nop)
	{
	  sim_num_insn++;
	  sim_sample_insn++;
	  sim_sample_insn_split[pdi->iclass]++;
	}

      fdumpinsn = fdump && sim_num_insn >= insn_dumpbegin && sim_num_insn < insn_dumpend; 
      inst = pdi->inst;
      
      /* execute the instruction */
      switch (pdi->poi.op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
          panic("attempted to execute a bogus opcode");
	}

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.PC);

      if (pdi->iclass == ic_load || pdi->iclass == ic_store || pdi->iclass == ic_prefetch)
	{
	  enum mem_cmd_t dl1_cmd = pdi->iclass == ic_store ? mc_WRITE : (pdi->iclass == ic_load ? mc_READ : mc_PREFETCH);
	  enum mem_cmd_t dtlb_cmd = (pdi->iclass == ic_store || pdi->iclass == ic_load) ? mc_READ : mc_PREFETCH;
	  bool_t miss_info[ct_NUM] = {FALSE, FALSE, FALSE, FALSE};

	  if (cache_dl1)
	    cache_access(cache_dl1, dl1_cmd, regs.addr, regs.dsize, 0, miss_info, l1_miss_handler);

	  if (dtlb)
	    cache_access(dtlb, dtlb_cmd, regs.addr, regs.dsize, 0, NULL, tlb_miss_handler);
	}


      /* go to the next instruction */
      regs.PC = regs.NPC;
      regs.NPC += sizeof(md_inst_t);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.PC);
	  md_print_insn(inst, regs.PC, stderr);
	  if (MD_OP_HASFLAGS(pdi->poi.op, F_MEM))
	    myfprintf(stderr, "  mem: 0x%08p", regs.addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}
	  
      if (fdumpinsn)
	{
	  fprintf(fdump, "%-9u: 0x%08x ", (word_t)sim_num_insn, (word_t)regs.PC);
	  if (LREG_ISDEP(pdi->lregnums[DEP_O1]))
	    myfprintf(fdump, " O1: %016p", regs_value(pdi->lregnums[DEP_O1]));
	  fprintf(fdump, "\n");
	}

      if (fdump && sim_num_insn == insn_dumpend)
	{
	  fflush(fdump);
	  fclose(fdump);
	}

      /* finish early? */
      if (insn_limit && sim_sample_insn >= insn_limit)
	{
	  myfprintf(stderr, "Reached instruction limit: %u\n", insn_limit);
	  return FALSE;
	}
      
      if (insn_progress && sim_sample_insn >= insn_progress)
	{
	  sim_print_stats(stderr);
	  fflush(stderr);
	  while (sim_sample_insn >= insn_progress)
	    insn_progress += insn_progress_update;
	}
    }

  return (sim_num_insn - sim_num_insn_begin == n_insn); 
}
コード例 #8
0
ファイル: sim-safe.c プロジェクト: BingranLi/branch-predictor
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  /* ECE552 Assignment 2 - BEGIN CODE */
  
  int i, j;
 
  /* Initialization of tables */

  for (i = 0; i < 4096; i++)
  {
    two_bit_table[i] = n;
  }
   
  for (i = 0; i < 8; i++)
  {
    for (j = 0; j < 64; j++)
    {
	PHT[i][j] = n;
    }
  }

  for (i = 0; i < 32; i++)
  {
    for (j = 0; j < 1024; j++)
    {
	GPHT[i][j] = n;
    }
  }

 /* ECE552 Assignment 2 - END CODE */

  fprintf(stderr, "sim: ** starting functional simulation **\n");
  
  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;
	  
      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      /* ECE552 Assignment 2 - BEGIN CODE */

      if (MD_OP_FLAGS(op) & F_COND)
      {
	int index = (regs.regs_PC >> 3) & 0xfff;
	int bht_index = (regs.regs_PC >> 6) & 0x1ff;
	int pht_index = (regs.regs_PC >> 3) & 0x7;
	int pht_row_index = BHT[bht_index];
	int gap_pht_index = (regs.regs_PC >> 3) & 0x1f;
	int g_pht_row_index = GHR;
 	

	if (regs.regs_NPC == regs.regs_PC + sizeof(md_inst_t))
	{
          br_taken = 0;
	  sim_num_mispred_static++;
        }
        else
        {
	  br_taken = 1;
        }

	/* two bit saturation branch predictor */

        switch(two_bit_table[index])
        {
	  case N:
	    if (br_taken)
	    {
	      two_bit_table[index] = n;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      two_bit_table[index] = t;
	      sim_num_mispred_2bitsat++;
	    }
	    else
	    {
	      two_bit_table[index] = N;
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      two_bit_table[index] = T;
	    }
	    else
	    {
	      two_bit_table[index] = n;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
	  case T:
	    if (!br_taken)
	    {
	      two_bit_table[index] = t;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
        }

	/* two level adaptive branch predictor */

	switch(PHT[pht_index][pht_row_index])
        {
	  case N:
	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = n;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f) | 0x1;
	      sim_num_mispred_2level++;
	    }
	    else
	    {
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = t;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	      sim_num_mispred_2level++;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = N;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = T;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = n;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	      sim_num_mispred_2level++;
	    }
	    break;
	  case T:
	    if (br_taken)
	    {
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = t;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	      sim_num_mispred_2level++;
	    }
	    break;
        }

	/* open ended branch predictor */

	switch(GPHT[gap_pht_index][g_pht_row_index])
        {
	  case N:
	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = n;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	      sim_num_mispred_openend++;
	    }
	    else
	    {
	      GHR = ((GHR << 1) & 0x3ff);
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = t;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	      sim_num_mispred_openend++;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = N;
	      GHR = ((GHR << 1) & 0x3ff);
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = T;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = n;
	      GHR = ((GHR << 1) & 0x3ff);
	      sim_num_mispred_openend++;
	    }
	    break;
	  case T:
	    if (br_taken)
	    {
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = t;
	      GHR = ((GHR << 1) & 0x3ff);
	      sim_num_mispred_openend++;
	    }
	    break;
        }
	
        sim_num_br++;
      }

      /* ECE552 Assignment 2 - END CODE */

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }