@@ -49,7 +49,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
49
49
SST_ELI_ELEMENT_VERSION (1 , 0 , 0 ),
50
50
"Implements a RISCV64-compatible decoder for Vanadis CPU processing.",
51
51
SST::Vanadis::VanadisDecoder)
52
-
52
+ SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS({ " gdb_unit " , " GDB Server for Vanadis " , " SST::Vanadis::VanadisRISCV64GDB " })
53
53
SST_ELI_DOCUMENT_PARAMS(
54
54
{" decode_max_ins_per_cycle" , " Maximum number of instructions that can be "
55
55
" decoded and issued per cycle" , " 2" },
@@ -71,6 +71,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
71
71
72
72
fatal_decode_fault = params.find <bool >(" halt_on_decode_fault" , false );
73
73
74
+ gdb = loadUserSubComponent<SST::Vanadis::VanadisRISCV64GDB>(" gdb_unit" );
74
75
}
75
76
76
77
~VanadisRISCV64Decoder () {}
@@ -127,6 +128,66 @@ class VanadisRISCV64Decoder : public VanadisDecoder
127
128
regFile->setIntReg (sp_phys_reg, value);
128
129
}
129
130
131
+ void gdb_tick () {
132
+ if ( gdb != nullptr ) {
133
+ gdb->tick ();
134
+ }
135
+ }
136
+
137
+ void register_pipeline ( SST::Output* output_p ) {
138
+ if ( gdb != nullptr ) {
139
+ gdb->register_pipeline ( output_p, this );
140
+ }
141
+ }
142
+
143
+ bool is_rob_empty () {
144
+ return thread_rob->size () == 0 ;
145
+ }
146
+
147
+ void instruction_to_rob ( SST::Output* output, VanadisInstruction* next_ins, bool * bundle_has_branch, VanadisInstructionBundle* bundle ) {
148
+ // Note: Caller must confirm there is space in the rob before calling
149
+ // Note: last 2 arguments not used if instruction is not a branch
150
+ if ( next_ins->getInstFuncType () == INST_BRANCH ) {
151
+ VanadisSpeculatedInstruction* next_spec_ins =
152
+ dynamic_cast <VanadisSpeculatedInstruction*>(next_ins);
153
+
154
+ if ( branch_predictor->contains (ip) ) {
155
+ // We have an address predicton from the branching unit
156
+ const uint64_t predicted_address = branch_predictor->predictAddress (ip);
157
+ next_spec_ins->setSpeculatedAddress (predicted_address);
158
+
159
+ if (output->getVerboseLevel () >= 16 ) {
160
+ output->verbose (
161
+ CALL_INFO, 16 , 0 ,
162
+ " ----> contains a branch: 0x%" PRI_ADDR " / predicted "
163
+ " (found in predictor): 0x%" PRI_ADDR " \n " ,
164
+ ip, predicted_address);
165
+ }
166
+
167
+ ip = predicted_address;
168
+ *bundle_has_branch = true ;
169
+ }
170
+ else {
171
+ // We don't have an address prediction
172
+ // so just speculate that we are going to drop through to the
173
+ // next instruction as we aren't sure where this will go yet
174
+
175
+ if (output->getVerboseLevel () >= 16 ) {
176
+ output->verbose (
177
+ CALL_INFO, 16 , 0 ,
178
+ " ----> contains a branch: 0x%" PRI_ADDR " / predicted "
179
+ " (not-found in predictor): 0x%" PRI_ADDR " , pc-increment: %" PRIu64 " \n " ,
180
+ ip, ip + 4 , bundle->pcIncrement ());
181
+ }
182
+
183
+ ip += bundle->pcIncrement ();
184
+ next_spec_ins->setSpeculatedAddress (ip);
185
+ *bundle_has_branch = true ;
186
+ }
187
+ }
188
+
189
+ thread_rob->push (next_ins->clone ());
190
+ }
130
191
131
192
void tick (SST::Output* output, uint64_t cycle) override
132
193
{
@@ -145,6 +206,12 @@ class VanadisRISCV64Decoder : public VanadisDecoder
145
206
output->verbose (
146
207
CALL_INFO, 16 , 0 , " ---> Found uop bundle for ip=0x%" PRI_ADDR " , loading from cache...\n " , ip);
147
208
}
209
+
210
+ if ( gdb != nullptr && gdb->should_stall (ip) ) {
211
+ // We are stopped at a breakpoint, so stall this cycle
212
+ break ;
213
+ }
214
+
148
215
stat_uop_hit->addData (1 );
149
216
150
217
VanadisInstructionBundle* bundle = ins_loader->getBundleAt (ip);
@@ -163,46 +230,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
163
230
for ( uint32_t i = 0 ; i < bundle->getInstructionCount (); ++i ) {
164
231
VanadisInstruction* next_ins = bundle->getInstructionByIndex (i);
165
232
166
- if ( next_ins->getInstFuncType () == INST_BRANCH ) {
167
- VanadisSpeculatedInstruction* next_spec_ins =
168
- dynamic_cast <VanadisSpeculatedInstruction*>(next_ins);
169
-
170
- if ( branch_predictor->contains (ip) ) {
171
- // We have an address predicton from the branching unit
172
- const uint64_t predicted_address = branch_predictor->predictAddress (ip);
173
- next_spec_ins->setSpeculatedAddress (predicted_address);
174
-
175
- if (output->getVerboseLevel () >= 16 ) {
176
- output->verbose (
177
- CALL_INFO, 16 , 0 ,
178
- " ----> contains a branch: 0x%" PRI_ADDR " / predicted "
179
- " (found in predictor): 0x%" PRI_ADDR " \n " ,
180
- ip, predicted_address);
181
- }
182
-
183
- ip = predicted_address;
184
- bundle_has_branch = true ;
185
- }
186
- else {
187
- // We don't have an address prediction
188
- // so just speculate that we are going to drop through to the
189
- // next instruction as we aren't sure where this will go yet
190
-
191
- if (output->getVerboseLevel () >= 16 ) {
192
- output->verbose (
193
- CALL_INFO, 16 , 0 ,
194
- " ----> contains a branch: 0x%" PRI_ADDR " / predicted "
195
- " (not-found in predictor): 0x%" PRI_ADDR " , pc-increment: %" PRIu64 " \n " ,
196
- ip, ip + 4 , bundle->pcIncrement ());
197
- }
198
-
199
- ip += bundle->pcIncrement ();
200
- next_spec_ins->setSpeculatedAddress (ip);
201
- bundle_has_branch = true ;
202
- }
203
- }
204
-
205
- thread_rob->push (next_ins->clone ());
233
+ instruction_to_rob ( output, next_ins, &bundle_has_branch, bundle );
206
234
}
207
235
208
236
// Move to the next address, if we had a branch we should have
@@ -304,6 +332,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
304
332
uint16_t icache_max_bytes_per_cycle;
305
333
uint16_t max_decodes_per_cycle;
306
334
uint16_t decode_buffer_max_entries;
335
+ VanadisRISCV64GDB* gdb;
307
336
308
337
void decode (SST::Output* output, const uint64_t ins_address, const uint32_t ins, VanadisInstructionBundle* bundle)
309
338
{
@@ -1112,8 +1141,10 @@ class VanadisRISCV64Decoder : public VanadisDecoder
1112
1141
case 0xc00 :
1113
1142
{
1114
1143
if ( 0 == rs1 ) {
1115
- auto thread_call = std::bind (&VanadisRISCV64Decoder::getCycleCount, this );
1116
- bundle->addInstruction ( new VanadisSetRegisterByCallInstruction<int64_t >( ins_address, hw_thr, options, rd, thread_call));
1144
+ bundle->addInstruction (
1145
+ new VanadisSetRegisterByCallInstruction<int64_t >(
1146
+ ins_address, hw_thr, options, rd,
1147
+ &VanadisRISCV64Decoder::getCycleCount_stub, (void *)this ));
1117
1148
decode_fault = false ;
1118
1149
}
1119
1150
} break ;
0 commit comments