-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdanke.cpp
More file actions
157 lines (136 loc) · 4.89 KB
/
danke.cpp
File metadata and controls
157 lines (136 loc) · 4.89 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
#include "danke.h"
#include <iostream>
using namespace std;
// Interfaces needed: instruction memory,
void danke_core(unsigned instruction_memory[INSTR_MEM_SIZE], data_t data_memory[DATA_MEM_SIZE], halted_t * halted, unsigned * core_id)
{
data_t pc;
instr_t ir;
data_t regfile[NUM_REGISTERS];
data_t special_regfile[NUM_REGISTERS];
special_regfile[0] = *core_id;
cout << "[BOOT] Core ID: " << hex << *core_id << endl;
int i = 0;
while(/* true i++ < 10*/ *halted == 0)
{
//cout << "[HALT CHECK] " << hex << *halted << endl;
//if(~(*halted))
{
// FETCH
ir = instruction_memory[pc];
cout << "[FETCH] Program counter: " << hex << pc << endl;
cout << "[FETCH] Fetched instruction: " << hex << ir << endl;
// DECODE
opcode_t opcode = ir.range(BITS_INSTR-1, BITS_INSTR-BITS_OPCODE);
reg_t sr1 = ir.range(BITS_INSTR-BITS_OPCODE-1, BITS_INSTR-BITS_OPCODE-BITS_REG);
reg_t sr2 = ir.range(BITS_INSTR-BITS_OPCODE-BITS_REG-1, BITS_INSTR-BITS_OPCODE-(BITS_REG)*2);
reg_t dr = ir.range(BITS_INSTR-BITS_OPCODE-(BITS_REG)*2-1, BITS_INSTR-BITS_OPCODE-(BITS_REG)*3);
intop_t intop = ir.range(BITS_INTOP-1, 0);
/*
gbmemop_t global_mem_atomic_op = ir.range(BITS_GBMEMOP-1, 0);
grmemtblop_t graphmem_table_op = ir.range(BITS_GRMTBLOP+BITS_GRMEMNDEOP-1, BITS_GRMEMNDEOP);
grmemndeop_t graphmem_node_atr = ir.range(BITS_GRMEMNDEOP-1, 0);
*/
imm_t immediate = ir.range(BITS_INSTR-BITS_OPCODE-BITS_REG-1, BITS_INSTR-BITS_OPCODE-(BITS_REG)*2);
off_t offset = ir.range(BITS_INSTR-BITS_OPCODE-(BITS_REG)*2-1, 0);
data_t op1 = (sr1 >= 32) ? special_regfile[sr1-32] : regfile[sr1];
// Make sure this casting actually sign extends the value
data_t op2 = (opcode == OPCODE_INTIMM || opcode == OPCODE_LD || opcode == OPCODE_ST) ? ((data_t) immediate) : (sr2 >= 32) ? special_regfile[sr2-32] : regfile[sr2];
cout << "[DECODE] Opcode: " << hex << opcode << endl;
//cout << "[DECODE] Source Reg 1: " << hex << sr1 << endl;
//cout << "[DECODE] Source Reg 2: " << hex << sr2 << endl;
cout << "[DECODE] Destination Reg: " << hex << dr << endl;
cout << "[DECODE] Operand 1: " << hex << op1 << endl;
cout << "[DECODE] Operand 2: " << hex << op2 << endl;
// EXECUTE
switch(opcode)
{
case OPCODE_INTREG :
case OPCODE_INTIMM :
{
cout << "[EXECUTE] Performing integer op" ;
data_t result;
switch(intop)
{
case INTOP_ADD : result = op1 + op2; cout << " add " << endl; break;
case INTOP_SUB : result = op1 - op2; cout << " sub " << endl; break;
case INTOP_MUL : result = op1 * op2; cout << " mul " << endl; break;
case INTOP_DIV : result = op1 / op2; cout << " div " << endl; break;
case INTOP_GR : result = op1 > op2; cout << " gr " << endl; break;
case INTOP_LT : result = op1 < op2; cout << " lt " << endl; break;
case INTOP_GRE : result = op1 >= op2; cout << " gre " << endl; break;
case INTOP_LTE : result = op1 <= op2; cout << " lte " << endl; break;
case INTOP_EQ : result = op1 == op2; cout << " eq " << endl; break;
case INTOP_NEQ : result = op1 != op2; cout << " neq " << endl; break;
case INTOP_AND : result = op1 & op2; cout << " and " << endl; break;
case INTOP_OR : result = op1 | op2; cout << " or " << endl; break;
case INTOP_NOT : result = ~op1; cout << " not " << endl; break;
case INTOP_SHR : result = op1 << op2; cout << " shr " << endl; break;
case INTOP_SHL : result = op1 >> op2; cout << " shl " << endl; break;
default : result = 0; cout << " IDK " << endl; break;
}
cout << "[EXECUTE] Integer op result: " << hex << result << endl;
regfile[dr] = result;
pc++;
break;
}
case OPCODE_BR :
{
cout << "[EXECUTE] Performing branch!" << endl;
if(op1 == op2)
{
cout << "[EXECUTE] Branch taken!" << endl;
pc += (data_t) offset;
}
else
{
cout << "[EXECUTE] Branch not taken!" << endl;
pc++;
}
break;
}
case OPCODE_LD :
{
cout << "[EXECUTE] Performing load!" << endl;
data_t addr = op1 + op2;
data_t mem_data_read = data_memory[addr];
regfile[dr] = mem_data_read;
cout << "[EXECUTE] Read value: " << mem_data_read << endl;
cout << "[EXECUTE] Read address: " << addr << endl;
pc++;
break;
}
case OPCODE_ST :
{
cout << "[EXECUTE] Performing store!" << endl;
data_t addr = op1 + op2;
data_t mem_data_write = regfile[dr];
data_memory[addr] = mem_data_write;
cout << "[EXECUTE] Store value: " << mem_data_write << endl;
cout << "[EXECUTE] Store address: " << addr << endl;
pc++;
break;
}
/*
case OPCODE_GRMEM :
{
}
case OPCODE_GLMEM :
{
}*/
case OPCODE_SCHED :
{
}
case OPCODE_HALT :
{
cout << "[EXECUTE] Performing halt!" << endl;
*halted = 1;
}
default :
{
pc++;
}
}
}
}
}