📄 sim-pipe.c
字号:
#include <stdio.h>#include <stdlib.h>#include <math.h>/* An implementation of 5-stage classic pipeline simulation *//* don't count instructions flag, enabled by default, disable for inst count */#undef NO_INSN_COUNT#include "host.h"#include "misc.h"#include "machine.h"#include "regs.h"#include "memory.h"#include "loader.h"#include "syscall.h"#include "dlite.h"#include "sim.h"#include "sim-pipe.h"/* simulated registers */static struct regs_t regs;/* simulated memory */static struct mem_t *mem = NULL;/* register simulator-specific options */voidsim_reg_options(struct opt_odb_t *odb){ opt_reg_header(odb, "sim-pipe: This simulator implements based on sim-fast.\n" );}/* check simulator-specific option values */voidsim_check_options(struct opt_odb_t *odb, int argc, char **argv){ if (dlite_active) fatal("sim-pipe does not support DLite debugging");}/* register simulator-specific statistics */voidsim_reg_stats(struct stat_sdb_t *sdb){#ifndef NO_INSN_COUNT stat_reg_counter(sdb, "sim_num_insn", "total number of instructions executed", &sim_num_insn, sim_num_insn, NULL);#endif /* !NO_INSN_COUNT */ stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", &sim_elapsed_time, 0, NULL);#ifndef NO_INSN_COUNT stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL);#endif /* !NO_INSN_COUNT */ ld_reg_stats(sdb); mem_reg_stats(mem, sdb);}/* initialize the simulator */voidsim_init(void){ /* allocate and initialize register file */ regs_init(®s); /* allocate and initialize memory space */ mem = mem_create("mem"); mem_init(mem);}/* load program into simulated state */voidsim_load_prog(char *fname, /* program to load */ int argc, char **argv, /* program arguments */ char **envp) /* program environment */{ /* load program text and data, set up environment, memory, and regs */ ld_load_prog(fname, argc, argv, envp, ®s, mem, TRUE);}/* print simulator-specific configuration information */voidsim_aux_config(FILE *stream){ /* nothing currently */}/* dump simulator-specific auxiliary simulator statistics */voidsim_aux_stats(FILE *stream){ /* nada */}/* un-initialize simulator-specific state */void sim_uninit(void){ /* nada */ }struct ifid fd;struct idex de;struct exmem em;struct memwb mw;/* * configure the execution engine *//* next program counter */#define SET_NPC(EXPR) (regs.regs_NPC = (EXPR))/* current program counter */#define CPC (regs.regs_PC)/* general purpose registers */#define GPR(N) (regs.regs_R[N])#define SET_GPR(N,EXPR) (regs.regs_R[N] = (EXPR))#if defined(TARGET_PISA)/* floating point registers, L->word, F->single-prec, D->double-prec */#define FPR_L(N) (regs.regs_F.l[(N)])#define SET_FPR_L(N,EXPR) (regs.regs_F.l[(N)] = (EXPR))#define FPR_F(N) (regs.regs_F.f[(N)])#define SET_FPR_F(N,EXPR) (regs.regs_F.f[(N)] = (EXPR))#define FPR_D(N) (regs.regs_F.d[(N) >> 1])#define SET_FPR_D(N,EXPR) (regs.regs_F.d[(N) >> 1] = (EXPR))/* miscellaneous register accessors */#define SET_HI(EXPR) (regs.regs_C.hi = (EXPR))#define HI (regs.regs_C.hi)#define SET_LO(EXPR) (regs.regs_C.lo = (EXPR))#define LO (regs.regs_C.lo)#define FCC (regs.regs_C.fcc)#define SET_FCC(EXPR) (regs.regs_C.fcc = (EXPR))#endif/* precise architected memory state accessor macros */#define READ_BYTE(SRC, FAULT) \ ((FAULT) = md_fault_none, MEM_READ_BYTE(mem, (SRC)))#define READ_HALF(SRC, FAULT) \ ((FAULT) = md_fault_none, MEM_READ_HALF(mem, (SRC)))#define READ_WORD(SRC, FAULT) \ ((FAULT) = md_fault_none, MEM_READ_WORD(mem, (SRC)))#ifdef HOST_HAS_QWORD#define READ_QWORD(SRC, FAULT) \ ((FAULT) = md_fault_none, MEM_READ_QWORD(mem, (SRC)))#endif /* HOST_HAS_QWORD */#define WRITE_BYTE(SRC, DST, FAULT) \ ((FAULT) = md_fault_none, MEM_WRITE_BYTE(mem, (DST), (SRC)))#define WRITE_HALF(SRC, DST, FAULT) \ ((FAULT) = md_fault_none, MEM_WRITE_HALF(mem, (DST), (SRC)))#define WRITE_WORD(SRC, DST, FAULT) \ ((FAULT) = md_fault_none, MEM_WRITE_WORD(mem, (DST), (SRC)))#ifdef HOST_HAS_QWORD#define WRITE_QWORD(SRC, DST, FAULT) \ ((FAULT) = md_fault_none, MEM_WRITE_QWORD(mem, (DST), (SRC)))#endif /* HOST_HAS_QWORD *//* system call handler macro */#define SYSCALL(INST) sys_syscall(®s, mem_access, mem, INST, TRUE)#ifndef NO_INSN_COUNT#define INC_INSN_CTR() sim_num_insn++#else /* !NO_INSN_COUNT */#define INC_INSN_CTR() /* nada */#endif /* NO_INSN_COUNT *//* start simulation, program loaded, processor precise state initialized */voidsim_main(void){ fprintf(stderr, "sim: ** starting *pipe* functional simulation **\n"); /* must have natural byte/word ordering */ if (sim_swap_bytes || sim_swap_words) fatal("sim: *pipe* functional simulation cannot swap bytes or words"); /* maintain $r0 semantics */ regs.regs_R[MD_REG_ZERO] = 0; while (TRUE) { }}void do_ifid(){ md_inst_t instruction; /* load instruction */ MD_FETCH_INSTI(instruction, mem, regs.regs_PC); fd.inst = instruction; fd.PC = regs.regs_PC; regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);}void do_idex(){ int op; de.PC = fd.PC; de.rsValue = GPR(RSI(fd.inst)); de.rtValue = GPR(RTI(fd.inst)); de.rt = RTI(fd.inst); de.rd = RDI(fd.inst); de.branchaddress = IMMI(fd.inst); SET_OPCODE(op, fd.inst); de.opcode = op; de.targ = TARGI(fd.inst); //only when instruction is LW, //then it means instruction needs to read memory. if (op == LW) { de.signal_memread = 1; de.signal_memtoreg = 1; } else { de.signal_memread = 0; de.signal_memtoreg = 0; } //if operation is LUI, then alu source A will be immediate value if (op == LUI) de.signal_alusrca = 2; //if operation is sll, then alu source A will be rt else if (op == SLL) de.signal_alusrca = 1; else de.signal_alusrca = 0; //only operations are add, addu and bne, //alu source b will be rt. if ((op == ADD) || (op == ADDU) || (op == BNE)) de.signal_alusrcb = 0; //if operation is sll, then alu source b is shamt else if (op == SLL) de.signal_alusrcb = 1; //The others will be immediate value. else de.signal_alusrcb = 2; //when operations are add and addu, //then destination register is rd. //The others are rt if ((op == ADDU) || (op == ADD) || (op == SLL)) de.signal_regdst = 1; else de.signal_regdst = 0;}void do_exmem(){ em.PC = de.PC; em.rtValue = de.rtValue; //possible to jump to another address if (de.rsValue==de.rtValue) em.whetherjump = 1; int op = de.opcode; //whether there is a branch if (op==BNE) em.signal_branch = 1; else em.signal_branch = 0; //get register number if (de.signal_regdst == 1) em.regDst = de.rd; else em.regDst = de.rt; em.signal_memread = de.signal_memread; if (op == SW) em.signal_memwrite = 1; else em.signal_memwrite = 0; em.signal_memtoreg = de.signal_memtoreg; if (( op== BNE) || ( op== JUMP) || ( op== SW)) em.signal_regwrite = 0; else em.signal_regwrite = 1; }void do_memwb(){ mw.regDst = em.regDst; mw.signal_memtoreg = em.signal_memtoreg; mw.signal_regwrite = em.signal_regwrite;}void writeback(){ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -