-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsim_pipe.h
More file actions
187 lines (140 loc) · 6.05 KB
/
Copy pathsim_pipe.h
File metadata and controls
187 lines (140 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef SIM_PIPE_H_
#define SIM_PIPE_H_
#include <stdio.h>
#include <string>
using namespace std;
#define PROGRAM_SIZE 50
#define UNDEFINED 0xFFFFFFFF //used to initialize the registerss
#define NULL_BADFOOD 0xBAADF00D
#define NUM_SP_REGISTERS 9
#define NUM_GP_REGISTERS 32
#define NUM_OPCODES 16
#define NUM_STAGES 5
typedef enum {PC, NPC, IR, A, B, IMM, COND, ALU_OUTPUT, LMD} sp_register_t;
typedef enum {LW, SW, ADD, ADDI, SUB, SUBI, XOR, BEQZ, BNEZ, BLTZ, BGTZ, BLEZ, BGEZ, JUMP, EOP, NOP, UNDEF_OP} opcode_t;
typedef enum {IF, ID, EXE, MEM, WB} stage_t;
typedef struct{
opcode_t opcode; //opcode
unsigned src1; //first source register in the assembly instruction (for SW, register to be written to memory)
unsigned src2; //second source register in the assembly instruction
unsigned dest; //destination register
unsigned immediate; //immediate field
string label; //for conditional branches, label of the target instruction - used only for parsing/debugging purposes
string human_text;
} instruction_t;
// Struct definitions for pipeline registers
/*typedef struct{
unsigned IR;
unsigned NPC;
// See the table. Why is there NPC, PC? Why set them both to the same thing?
} IF_ID;
typedef struct{
unsigned A;
unsigned B;
unsigned NPC;
unsigned IR;
unsigned IMM;
} ID_EX;
typedef struct{
unsigned IR;
unsigned ALUOutput;
unsigned B;
unsigned cond;
} EX_MEM;
typedef struct{
unsigned IR;
unsigned ALUOutput;
unsigned LMD;
} MEM_WB;*/
class sim_pipe{
unsigned troubleshooting;
unsigned blocking_stage[NUM_STAGES];
// Data members for testing purposes only
// To make these remember after different function calls and reset
instruction_t IF_ID_IR, ID_EXE_IR, EXE_MEM_IR, MEM_WB_IR, WB_DONE_IR;//the last one is barely used
unsigned IF_ID_Addy;
unsigned pending_reg_writes[NUM_GP_REGISTERS];
unsigned pending_branch;
unsigned block_prev_stages;
unsigned wait_for_memory;
// Hold the real PC before the simulated clock cycle struck
unsigned Current_IF_PC_Preclk;
/* Add the data members required by your simulator's implementation here */
// Structures for general purpose registers
int Regs[NUM_GP_REGISTERS];
unsigned SP_Regs[NUM_STAGES][NUM_SP_REGISTERS];
// Structures for pipeline registers
/*IF_ID IF_ID;
ID_EX ID_EX;
EX_MEM EX_MEM;
MEM_WB MEM_WB;*/
// Save the number of clock cycles
unsigned clock_cycles;
// Save the number of stalls
unsigned stalls;
// Save the number of instructions executed
unsigned instructions_executed;
//instruction memory
instruction_t instr_memory[PROGRAM_SIZE];
//base address in the instruction memory where the program is loaded
unsigned instr_base_address;
//data memory - should be initialize to all 0xFF
unsigned char *data_memory;
//memory size in bytes
unsigned data_memory_size;
//memory latency in clock cycles
unsigned data_memory_latency;
public:
//instantiates the simulator with a data memory of given size (in bytes) and latency (in clock cycles)
/* Note:
- initialize the registers to UNDEFINED value
- initialize the data memory to all 0xFF values
*/
sim_pipe(unsigned data_mem_size, unsigned data_mem_latency, unsigned troubleshooting=0);
//de-allocates the simulator
~sim_pipe();
//loads the assembly program in file "filename" in instruction memory at the specified address
void load_program(const char *filename, unsigned base_address=0x0);
//runs the simulator for "cycles" clock cycles (run the program to completion if cycles=0)
void run(unsigned cycles=0);
//resets the state of the simulator
/* Note:
- registers should be reset to UNDEFINED value
- data memory should be reset to all 0xFF values
*/
void reset();
// returns value of the specified special purpose register for a given stage (at the "entrance" of that stage)
// if that special purpose register is not used in that stage, returns UNDEFINED
//
// Examples (refer to page C-37 in the 5th edition textbook, A-32 in 4th edition of textbook)::
// - get_sp_register(PC, IF) returns the value of PC
// - get_sp_register(NPC, ID) returns the value of IF/ID.NPC
// - get_sp_register(NPC, EX) returns the value of ID/EX.NPC
// - get_sp_register(ALU_OUTPUT, MEM) returns the value of EX/MEM.ALU_OUTPUT
// - get_sp_register(ALU_OUTPUT, WB) returns the value of MEM/WB.ALU_OUTPUT
// - get_sp_register(LMD, ID) returns UNDEFINED
/* Note: you are allowed to use a custom format for the IR register.
Therefore, the test cases won't check the value of IR using this method.
You can add an extra method to retrieve the content of IR */
unsigned get_sp_register(sp_register_t reg, stage_t stage);
unsigned set_sp_reg(stage_t s, sp_register_t reg, int value);
//returns value of the specified general purpose register
int get_gp_register(unsigned reg);
// set the value of the given general purpose register to "value"
void set_gp_register(unsigned reg, int value);
//returns the IPC
float get_IPC();
//returns the number of instructions fully executed
unsigned get_instructions_executed();
//returns the number of clock cycles
unsigned get_clock_cycles();
//returns the number of stalls added by processor
unsigned get_stalls();
//prints the content of the data memory within the specified address range
void print_memory(unsigned start_address, unsigned end_address);
// writes an integer value to data memory at the specified address (use little-endian format: https://en.wikipedia.org/wiki/Endianness)
void write_memory(unsigned address, unsigned value);
// prints the values of the registers
void print_registers();
};
#endif /*SIM_PIPE_H_*/