-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfive_stage.c
121 lines (103 loc) · 2.87 KB
/
five_stage.c
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
/** Code by @author Wonsun Ahn
*
* Main function. Parses commandline arguments and invokes the five stages in
* CPU.c at every clock cycle.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <getopt.h>
#include <assert.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include "CPU.h"
#include "trace.h"
#include "MemObj.h"
void print_usage_info()
{
printf("USAGE: five_stage [OPTIONS]\n");
printf("Runs a CPU simulation given a CPU configuration file and an instruction trace file.\n\n");
printf(" -h this help screen.\n");
printf(" -v verbose output (shows each instruction).\n");
printf(" -d debug output (shows pipeline on each cycle).\n");
printf(" -c file [Required] uses file as configuration file.\n");
printf(" -t file [Required] uses file as input trace file.\n");
}
int main(int argc, char **argv)
{
char *trace_file_name = NULL;
char *config_file_name = NULL;
char c;
while ((c = getopt (argc, argv, "hvdc:t:")) != -1) {
switch (c) {
case 'h':
print_usage_info();
return 0;
case 'v':
verbose = true;
break;
case 'd':
debug = true;
verbose = true;
break;
case 't':
trace_file_name = optarg;
break;
case 'c':
config_file_name = optarg;
break;
case '?':
if (optopt == 't' || optopt == 'c')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
}
if (config_file_name == NULL || trace_file_name == NULL) {
print_usage_info();
exit(1);
}
if (!parse_config(config_file_name)) {
fprintf(stderr, "\nError while parsing config file %s.\n\n", trace_file_name);
exit(1);
}
trace_fd = fopen(trace_file_name, "rb");
if (!trace_fd) {
fprintf(stderr, "\nError while opening trace file %s.\n\n", trace_file_name);
exit(1);
}
trace_init();
while(1) {
/* move the pipeline forward */
cycle_number++;
/* move instructions one stage ahead */
writeback();
memory();
issue();
decode();
fetch();
if (is_finished()) {
/* all instructions simulated to completion */
/* print memory stats*/
MemObj::printAllStats();
/* print pipeline stats*/
printf("+ Memory stall cycles : %u\n", mem_stall_cycles);
printf("+ Number of cycles : %u\n", cycle_number);
printf("+ IPC (Instructions Per Cycle) : %0.4f\n", (float)inst_number / (float)cycle_number);
break;
}
}
trace_uninit();
MemObj::freeAll();
free_config();
return 0;
}