📄 project1.c
字号:
// CDA 5155 Computer Architecture Project 1 LC-2K7
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define NUMMEMORY 65536 /* maximum number of data words in memory */
#define NUMREGS 8 /* number of machine registers */
#define ADD 0
#define NAND 1
#define LW 2
#define SW 3
#define BEQ 4
#define MULT 5
#define HALT 6
#define NOOP 7
#define NOOPINSTRUCTION 0x1c00000
/* hazard type */
#define FWD 0
/* H1 denotes the hazard from regA */
#define H1 1
/* H2 denotes the hazard from regB */
#define H2 2
/* H12 denotes the hazard from both regA and regB */
#define H12 3
/* HLW denotes the hazard from the previous lw instruction that contains the register being loaded and needed in the currect instruction */
#define HLW 4
/* HC_target denotes the control hazard that should fetch branch target*/
#define HC_target 5
/* HC_pcPlus1 denotes the control hazard that should fetch pc+1 */
#define HC_pcPlus1 6
/*
* Data Structures for Pipeline Registers
*/
typedef struct IFIDStruct {
int instr;
int pcPlus1;
int regA;
int regB;
int predictedCond;
} IFIDType;
typedef struct IDEXStruct {
int instr;
int pcPlus1;
int readRegA;
int readRegB;
int offset;
int destReg;
int hazard_status;
int hazard_positionA;
int hazard_positionB;
int regA;
int regB;
int predictedCond;
} IDEXType;
typedef struct EXMEMStruct {
int instr;
int branchTarget;
int aluResult;
int readRegB;
int destReg;
int cond;
int hazard_status;
int predictedCond;
int controlHazard;
int pcPlus1;
} EXMEMType;
typedef struct MEMWBStruct {
int instr;
int writeData;
int destReg;
int aluResult;
int pcPlus1;
} MEMWBType;
typedef struct WBENDStruct {
int instr;
int writeData;
} WBENDType;
typedef struct stateStruct {
int pc;
int instrMem[NUMMEMORY];
int dataMem[NUMMEMORY];
int reg[NUMREGS];
int numMemory;
IFIDType IFID;
IDEXType IDEX;
EXMEMType EXMEM;
MEMWBType MEMWB;
WBENDType WBEND;
int cycles; /* number of cycles run so far */
}stateType;
typedef struct dataHazard {
int in[3];
int out[3];
}hazard_detector;
int field0(int instruction)
{
return( (instruction>>19) & 0x7);
}
int field1(int instruction)
{
return( (instruction>>16) & 0x7);
}
int field2(int instruction)
{
return(instruction & 0xFFFF);
}
int opcode(int instruction)
{
return(instruction>>22);
}
void printInstruction(int instr)
{
char opcodeString[10];
if (opcode(instr) == ADD) {
strcpy(opcodeString, "add");
} else if (opcode(instr) == NAND) {
strcpy(opcodeString, "nand");
} else if (opcode(instr) == LW) {
strcpy(opcodeString, "lw");
} else if (opcode(instr) == SW) {
strcpy(opcodeString, "sw");
} else if (opcode(instr) == BEQ) {
strcpy(opcodeString, "beq");
} else if (opcode(instr) == MULT) {
strcpy(opcodeString, "mult");
} else if (opcode(instr) == HALT) {
strcpy(opcodeString, "halt");
} else if (opcode(instr) == NOOP) {
strcpy(opcodeString, "noop");
} else {
strcpy(opcodeString, "data");
}
printf("%s %d %d %d\n", opcodeString, field0(instr), field1(instr),
field2(instr));
}
void printState(stateType *statePtr)
{
int i;
printf("\n@@@\nstate before cycle %d starts\n", statePtr->cycles);
printf("\tpc %d\n", statePtr->pc);
printf("\tdata memory:\n");
for (i=0; i<statePtr->numMemory; i++) {
printf("\t\tdataMem[ %d ] %d\n", i, statePtr->dataMem[i]);
}
printf("\tregisters:\n");
for (i=0; i<NUMREGS; i++) {
printf("\t\treg[ %d ] %d\n", i, statePtr->reg[i]);
}
printf("\tIFID:\n");
printf("\t\tinstruction ");
printInstruction(statePtr->IFID.instr);
printf("\t\tpcPlus1 %d\n", statePtr->IFID.pcPlus1);
printf("\t\tregA %d\n", statePtr->IFID.regA);
printf("\t\tregB %d\n", statePtr->IFID.regB);
printf("\tIDEX:\n");
printf("\t\tinstruction ");
printInstruction(statePtr->IDEX.instr);
printf("\t\tpcPlus1 %d\n", statePtr->IDEX.pcPlus1);
printf("\t\treadRegA %d\n", statePtr->IDEX.readRegA);
printf("\t\treadRegB %d\n", statePtr->IDEX.readRegB);
printf("\t\toffset %d\n", statePtr->IDEX.offset);
printf("\t\thazard_status %d\n", statePtr->IDEX.hazard_status);
printf("\t\thazard_positionA %d\n", statePtr->IDEX.hazard_positionA);
printf("\t\thazard_positionB %d\n", statePtr->IDEX.hazard_positionB);
printf("\tEXMEM:\n");
printf("\t\tinstruction ");
printInstruction(statePtr->EXMEM.instr);
printf("\t\tbranchTarget %d\n", statePtr->EXMEM.branchTarget);
printf("\t\taluResult %d\n", statePtr->EXMEM.aluResult);
printf("\t\treadRegB %d\n", statePtr->EXMEM.readRegB);
printf("\t\thazard_status %d\n", statePtr->EXMEM.hazard_status);
printf("\tMEMWB:\n");
printf("\t\tinstruction ");
printInstruction(statePtr->MEMWB.instr);
printf("\t\twriteData %d\n", statePtr->MEMWB.writeData);
printf("\tWBEND:\n");
printf("\t\tinstruction ");
printInstruction(statePtr->WBEND.instr);
printf("\t\twriteData %d\n", statePtr->WBEND.writeData);
printf("the end of the circle\n");}
/*
* Main body of simulator
*/
int main(int argc, char *argv[])
{
char machine_codefile[100];
char readline [100];
char memory[NUMMEMORY][100];
int k=0;
int branches = 0;
int fetched = 0;
int countfetched= 0;
int retired = 0;
int countretired = 0;
int mispred = 0;
int i;
int index;
int insert;
FILE *file;
stateType state;
stateType newState;
hazard_detector hd1;
int bhr = 0;
int btb[4][2];
int pht[64];
for(i=0;i<4;i++) btb[i][0]= -1;
for(i=0;i<64;i++) pht[i]=0;
/* Initialize the pc and all registers to zero.*/
/* pc indicates the memory address of the instruction in the IF stage */
state.pc = -1;
for(i=0;i<NUMREGS;i++)
state.reg[i]=0;
state.EXMEM.cond = 0;
state.IDEX.hazard_status = FWD;
state.IDEX.hazard_positionA = state.IDEX.hazard_positionB = -1;
state.IDEX.destReg = 8;
state.EXMEM.destReg = 8;
state.MEMWB.destReg = 8;
state.IFID.instr = NOOPINSTRUCTION;
state.IDEX.instr = NOOPINSTRUCTION;
state.EXMEM.instr = NOOPINSTRUCTION;
state.MEMWB.instr = NOOPINSTRUCTION;
state.WBEND.instr = NOOPINSTRUCTION;
if (argc < 2){
printf("Usage: simulate machine_codefile > output\n");
exit(0);
}
strcpy(machine_codefile, argv[1]);
file = fopen(machine_codefile, "r");
if(file != NULL)
{
while(fgets(readline, sizeof readline, file) != NULL)
{
strcpy(memory[k], readline);
printf("memory[%d] = %s",k,memory[k]);
state.instrMem[k]=atoi(memory[k]);
state.dataMem[k] = state.instrMem[k];
k++;
}
fclose(file);
}
else
{
printf("\nCan not open %s. Please see if the file exists.", machine_codefile);
exit(1);
}
state.numMemory = k;
printf("%d memory words\n",k);
printf(" instruction memory:\n");
for(i=0;i<k;i++){
printf(" instrMem[%d] ",i);
printInstruction(state.instrMem[i]);
}
while(1){
hd1.in[0]= state.IDEX.destReg;
hd1.in[1]= state.EXMEM.destReg;
hd1.in[2]= state.MEMWB.destReg;
hd1.out[0] = state.EXMEM.aluResult;
hd1.out[1] = state.MEMWB.writeData;
hd1.out[2] = state.WBEND.writeData;
printf("\n\nhazard detector:\n");
for (i=0;i<3;i++) printf("\tin[ %d ] %d\n", i, hd1.in[i]);
for (i=0;i<3;i++) printf("\tout[ %d ] %d\n", i, hd1.out[i]);
printState(&state);
/* check for halt */
if(opcode(state.MEMWB.instr) == HALT){
for(i=0;i<state.numMemory;i++)
if(opcode(state.instrMem[i])==BEQ) branches++;
printf("machine halted\n");
printf("CYCLES: %d\n",state.cycles);
printf("FETCHED: %d\n",fetched);
printf("RETIRED: %d\n",retired);
printf("BRANCHES: %d\n", branches);
printf("MISPRED: %d\n", mispred);
exit(0);
}
newState = state;
newState.cycles++;
/* --------------------- IF stage --------------------- */
if((state.EXMEM.controlHazard==HC_target) || (state.IDEX.hazard_status == HLW) || (state.EXMEM.controlHazard==HC_pcPlus1)){
if(state.EXMEM.controlHazard==HC_target){
newState.IFID.pcPlus1 = state.MEMWB.aluResult%65536+1;
newState.pc = state.MEMWB.aluResult%65536;
newState.IFID.instr = state.instrMem[newState.pc];
newState.IFID.regA = field0(state.instrMem[newState.pc]);
newState.IFID.regB = field1(state.instrMem[newState.pc]);
countfetched++;
}else if(state.EXMEM.controlHazard==HC_pcPlus1)
{
newState.IFID.pcPlus1 = state.MEMWB.pcPlus1+1;
newState.pc = state.MEMWB.pcPlus1;
newState.IFID.instr = state.instrMem[newState.pc];
newState.IFID.regA = field0(state.instrMem[newState.pc]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -