Exemplo n.º 1
1
/* 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;
		}
    }
}
Exemplo n.º 2
0
/* 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 1 - BEGIN CODE */

  int r_in[3], r_out[2];

  /* ECE552 Assignment 1 - 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:							\
	  r_out[0] = (O1); r_out[1] = (O2);				\
	  r_in[0] = (I1); r_in[1] = (I2); r_in[2] = (I3);		\
          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 1 - BEGIN CODE */

      /* ECE552 Part 1 */

      int i, counter_q1 = 0, counter_q2 = 0, counter_q3 = 0;

      for (i = 0;  i < 3; i++)
      {
	if (r_in[i] != DNA && reg_ready_q1[r_in[i]] > sim_num_insn)
	{
	  int cycle = reg_ready_q1[r_in[i]] - sim_num_insn;
	  
	  if (cycle ==  1)
	  {
  	    counter_q1++;
	  }
	  else if (cycle == 2)
	  {
	    counter_q1 =  counter_q1 + 2;
	  }

	  //reset the register
	  reg_ready_q1[r_in[i]] = DNA;
	}
      }

      if (counter_q1 == 1)
      {
        sim_num_one_cycle_hazard_q1++;
      }
      else if (counter_q1 >= 2)
      {
	 sim_num_two_cycle_hazard_q1++;
      }	

      if (r_out[0] != DNA)
      {
	reg_ready_q1[r_out[0]] = sim_num_insn + 3;
      }

      if (r_out[1] != DNA)
      {
	reg_ready_q1[r_out[1]] = sim_num_insn + 3;
      }
    
      sim_num_RAW_hazard_q1 = sim_num_one_cycle_hazard_q1 + sim_num_two_cycle_hazard_q1; 

      /* ECE552 Part 2*/

      for (i = 0;  i < 3; i++)
      {
	if (r_in[i] != DNA && reg_ready_q2[r_in[i]] > sim_num_insn)
	{
	  if ((i == 0) && (MD_OP_FLAGS(op) & F_MEM) &&
	      (MD_OP_FLAGS(op) & F_STORE))
	  {
	      continue;
	  }
          
	  int cycle = reg_ready_q2[r_in[i]] - sim_num_insn;

	  if (cycle == 1)
	  {
	    counter_q2++;
	  }
	  else if (cycle == 2)
	  {
		counter_q2 = counter_q2 + 2;
	  }

          //reset the register
	  reg_ready_q2[r_in[i]] = DNA;
	}
      }
      
      if (counter_q2 == 1)
      {
	sim_num_one_cycle_hazard_q2++;
      }
      else if (counter_q2 >= 2)
      {
	sim_num_two_cycle_hazard_q2++;
      }

      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
        if (r_out[0] != DNA)
        {
	  reg_ready_q2[r_out[0]] = sim_num_insn + 3;
        }

        if (r_out[1] != DNA)
        {
	  reg_ready_q2[r_out[1]] = sim_num_insn + 3;
        }
      }
      else if (!(MD_OP_FLAGS(op) & F_MEM))
      {
        if (r_out[0] != DNA)
        {
	  reg_ready_q2[r_out[0]] = sim_num_insn + 2;
        }

        if (r_out[1] != DNA)
        {
	  reg_ready_q2[r_out[1]] = sim_num_insn + 2;
        }
      }

      sim_num_RAW_hazard_q2 = sim_num_one_cycle_hazard_q2 + sim_num_two_cycle_hazard_q2;

      /* ECE552 Part 3 */


      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
	is_current_load = true;
      }
      else if (!(MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
	is_previous_load = false;
      }
 
      if (!(MD_OP_FLAGS(op) & F_LOAD))
      {
		
        for (i = 0;  i < 2; i++)
        {
	  if (r_out[i] != DNA && reg_ready_q3[r_out[i]] > sim_num_insn)
	  {
   	    int cycle = reg_ready_q3[r_out[i]] - sim_num_insn;
	  
	    if (cycle == 1)
	    {
	      //two cycle stall for non mem instruction
	      if (is_current_load == true && is_current_load == true)
	      {
		 sim_num_two_cycle_hazard_q3++;
	      }
	      else
	      {
		sim_num_one_cycle_hazard_q3++;	
	      }
	  }
   	  else if (cycle == 2)
	  {
	    sim_num_two_cycle_hazard_q3++;
	  }

 	  reg_ready_q3[r_out[i]] = DNA;
          counter_q3 = 1;
        }
      } 

	if(counter_q3 == 0 && (r_out[0] != DNA || r_out[1] != DNA))
	{
	  if(is_current_load && is_previous_load && write_back_ready == sim_num_insn + 1)
          {
		sim_num_structural_hazard_q3 = sim_num_structural_hazard_q3 + 2;
          }
	  else if(write_back_ready == sim_num_insn)
	  {
	    sim_num_structural_hazard_q3++;
	  }
	}
    }
      
     if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
     {
       if (r_out[0] != DNA)
       {
	 reg_ready_q3[r_out[0]] = sim_num_insn + 3;
       }

       if (r_out[1] != DNA)
       {
	 reg_ready_q3[r_out[1]] = sim_num_insn + 3;
       }

       write_back_ready = sim_num_insn + 2;
       is_previous_load = true;
     }
     else if (!(MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
     {
	is_previous_load = false;
     }

     sim_num_WAW_hazard_q3  = sim_num_one_cycle_hazard_q3 + sim_num_two_cycle_hazard_q3;

     /* ECE552 Assignment 1 - 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;
    }
}
Exemplo n.º 3
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 ) {
                // src[i] has not written to register file this cycle or earlier
		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;
}
Exemplo n.º 4
0
/* 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;
    }
}
Exemplo n.º 5
0
/* 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;
    }
}
Exemplo n.º 6
0
/* 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); 
}
Exemplo n.º 7
0
/* 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;
    }