")
StateMachine.py (7002:48a19d52d939) StateMachine.py (7007:79413d1ec307)
1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
2# Copyright (c) 2009 The Hewlett-Packard Development Company
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met: redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer;

--- 173 unchanged lines hidden (view full) ---

182 '''Output the method declarations for the class declaration'''
183 code = self.symtab.codeFormatter()
184 ident = self.ident
185 c_ident = "%s_Controller" % self.ident
186
187 self.message_buffer_names = []
188
189 code('''
1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
2# Copyright (c) 2009 The Hewlett-Packard Development Company
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met: redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer;

--- 173 unchanged lines hidden (view full) ---

182 '''Output the method declarations for the class declaration'''
183 code = self.symtab.codeFormatter()
184 ident = self.ident
185 c_ident = "%s_Controller" % self.ident
186
187 self.message_buffer_names = []
188
189 code('''
190/** \\file $ident.hh
190/** \\file $c_ident.hh
191 *
192 * Auto generated C++ code started by $__file__:$__line__
193 * Created by slicc definition of Module "${{self.short}}"
194 */
195
191 *
192 * Auto generated C++ code started by $__file__:$__line__
193 * Created by slicc definition of Module "${{self.short}}"
194 */
195
196#ifndef ${ident}_CONTROLLER_H
197#define ${ident}_CONTROLLER_H
196#ifndef __${ident}_CONTROLLER_HH__
197#define __${ident}_CONTROLLER_HH__
198
199#include <iostream>
200#include <sstream>
201#include <string>
202
203#include "params/$c_ident.hh"
204
205#include "mem/ruby/common/Global.hh"

--- 9 unchanged lines hidden (view full) ---

215 if var.type.ident not in seen_types and not var.type.isPrimitive:
216 code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
217 seen_types.add(var.type.ident)
218
219 # for adding information to the protocol debug trace
220 code('''
221extern std::stringstream ${ident}_transitionComment;
222
198
199#include <iostream>
200#include <sstream>
201#include <string>
202
203#include "params/$c_ident.hh"
204
205#include "mem/ruby/common/Global.hh"

--- 9 unchanged lines hidden (view full) ---

215 if var.type.ident not in seen_types and not var.type.isPrimitive:
216 code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
217 seen_types.add(var.type.ident)
218
219 # for adding information to the protocol debug trace
220 code('''
221extern std::stringstream ${ident}_transitionComment;
222
223class $c_ident : public AbstractController {
224#ifdef CHECK_COHERENCE
225#endif /* CHECK_COHERENCE */
223class $c_ident : public AbstractController
224{
225// the coherence checker needs to call isBlockExclusive() and isBlockShared()
226// making the Chip a friend class is an easy way to do this for now
227
226public:
227 typedef ${c_ident}Params Params;
228 $c_ident(const Params *p);
229 static int getNumControllers();
230 void init();
231 MessageBuffer* getMandatoryQueue() const;
232 const int & getVersion() const;
233 const std::string toString() const;
234 const std::string getName() const;
235 const MachineType getMachineType() const;
236 void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
237 void print(std::ostream& out) const;
238 void printConfig(std::ostream& out) const;
239 void wakeup();
240 void printStats(std::ostream& out) const;
241 void clearStats();
242 void blockOnQueue(Address addr, MessageBuffer* port);
243 void unblock(Address addr);
228public:
229 typedef ${c_ident}Params Params;
230 $c_ident(const Params *p);
231 static int getNumControllers();
232 void init();
233 MessageBuffer* getMandatoryQueue() const;
234 const int & getVersion() const;
235 const std::string toString() const;
236 const std::string getName() const;
237 const MachineType getMachineType() const;
238 void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }
239 void print(std::ostream& out) const;
240 void printConfig(std::ostream& out) const;
241 void wakeup();
242 void printStats(std::ostream& out) const;
243 void clearStats();
244 void blockOnQueue(Address addr, MessageBuffer* port);
245 void unblock(Address addr);
246
244private:
245''')
246
247 code.indent()
248 # added by SS
249 for param in self.config_parameters:
250 if param.pointer:
251 code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;')
252 else:
253 code('${{param.type_ast.type}} m_${{param.ident}};')
254
255 code('''
256int m_number_of_TBEs;
257
247private:
248''')
249
250 code.indent()
251 # added by SS
252 for param in self.config_parameters:
253 if param.pointer:
254 code('${{param.type_ast.type}}* m_${{param.ident}}_ptr;')
255 else:
256 code('${{param.type_ast.type}} m_${{param.ident}};')
257
258 code('''
259int m_number_of_TBEs;
260
258TransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc
259TransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc
261TransitionResult doTransition(${ident}_Event event,
262 ${ident}_State state,
263 const Address& addr);
264
265TransitionResult doTransitionWorker(${ident}_Event event,
266 ${ident}_State state,
267 ${ident}_State& next_state,
268 const Address& addr);
269
260std::string m_name;
261int m_transitions_per_cycle;
262int m_buffer_size;
263int m_recycle_latency;
264map<std::string, std::string> m_cfg;
265NodeID m_version;
266Network* m_net_ptr;
267MachineID m_machineID;
268bool m_is_blocking;
269map< Address, MessageBuffer* > m_block_map;
270${ident}_Profiler s_profiler;
271static int m_num_controllers;
270std::string m_name;
271int m_transitions_per_cycle;
272int m_buffer_size;
273int m_recycle_latency;
274map<std::string, std::string> m_cfg;
275NodeID m_version;
276Network* m_net_ptr;
277MachineID m_machineID;
278bool m_is_blocking;
279map< Address, MessageBuffer* > m_block_map;
280${ident}_Profiler s_profiler;
281static int m_num_controllers;
282
272// Internal functions
273''')
274
275 for func in self.functions:
276 proto = func.prototype
277 if proto:
278 code('$proto')
279
280 code('''
281
282// Actions
283''')
284 for action in self.actions.itervalues():
285 code('/** \\brief ${{action.desc}} */')
286 code('void ${{action.ident}}(const Address& addr);')
287
288 # the controller internal variables
289 code('''
290
283// Internal functions
284''')
285
286 for func in self.functions:
287 proto = func.prototype
288 if proto:
289 code('$proto')
290
291 code('''
292
293// Actions
294''')
295 for action in self.actions.itervalues():
296 code('/** \\brief ${{action.desc}} */')
297 code('void ${{action.ident}}(const Address& addr);')
298
299 # the controller internal variables
300 code('''
301
291// Object
302// Objects
292''')
293 for var in self.objects:
294 th = var.get("template_hack", "")
295 code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;')
296
297 if var.type.ident == "MessageBuffer":
298 self.message_buffer_names.append("m_%s_ptr" % var.c_ident)
299
300 code.dedent()
301 code('};')
303''')
304 for var in self.objects:
305 th = var.get("template_hack", "")
306 code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;')
307
308 if var.type.ident == "MessageBuffer":
309 self.message_buffer_names.append("m_%s_ptr" % var.c_ident)
310
311 code.dedent()
312 code('};')
302 code('#endif // ${ident}_CONTROLLER_H')
313 code('#endif // __${ident}_CONTROLLER_H__')
303 code.write(path, '%s.hh' % c_ident)
304
305 def printControllerCC(self, path):
306 '''Output the actions for performing the actions'''
307
308 code = self.symtab.codeFormatter()
309 ident = self.ident
310 c_ident = "%s_Controller" % self.ident
311
312 code('''
314 code.write(path, '%s.hh' % c_ident)
315
316 def printControllerCC(self, path):
317 '''Output the actions for performing the actions'''
318
319 code = self.symtab.codeFormatter()
320 ident = self.ident
321 c_ident = "%s_Controller" % self.ident
322
323 code('''
313/** \\file $ident.cc
324/** \\file $c_ident.cc
314 *
315 * Auto generated C++ code started by $__file__:$__line__
316 * Created by slicc definition of Module "${{self.short}}"
317 */
318
319#include <sstream>
320#include <string>
321

--- 17 unchanged lines hidden (view full) ---

339
340 code('''
341$c_ident *
342${c_ident}Params::create()
343{
344 return new $c_ident(this);
345}
346
325 *
326 * Auto generated C++ code started by $__file__:$__line__
327 * Created by slicc definition of Module "${{self.short}}"
328 */
329
330#include <sstream>
331#include <string>
332

--- 17 unchanged lines hidden (view full) ---

350
351 code('''
352$c_ident *
353${c_ident}Params::create()
354{
355 return new $c_ident(this);
356}
357
347
348int $c_ident::m_num_controllers = 0;
349
358int $c_ident::m_num_controllers = 0;
359
360// for adding information to the protocol debug trace
350stringstream ${ident}_transitionComment;
351#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
361stringstream ${ident}_transitionComment;
362#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
363
352/** \\brief constructor */
353$c_ident::$c_ident(const Params *p)
354 : AbstractController(p)
355{
356 m_version = p->version;
357 m_transitions_per_cycle = p->transitions_per_cycle;
358 m_buffer_size = p->buffer_size;
359 m_recycle_latency = p->recycle_latency;

--- 46 unchanged lines hidden (view full) ---

406 for var in self.objects:
407 if var.ident.find("mandatoryQueue") >= 0:
408 code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();')
409
410 code.dedent()
411 code('''
412}
413
364/** \\brief constructor */
365$c_ident::$c_ident(const Params *p)
366 : AbstractController(p)
367{
368 m_version = p->version;
369 m_transitions_per_cycle = p->transitions_per_cycle;
370 m_buffer_size = p->buffer_size;
371 m_recycle_latency = p->recycle_latency;

--- 46 unchanged lines hidden (view full) ---

418 for var in self.objects:
419 if var.ident.find("mandatoryQueue") >= 0:
420 code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();')
421
422 code.dedent()
423 code('''
424}
425
414void $c_ident::init()
426void
427$c_ident::init()
415{
428{
429 MachineType machine_type;
430 int base;
431
416 m_machineID.type = MachineType_${ident};
417 m_machineID.num = m_version;
418
432 m_machineID.type = MachineType_${ident};
433 m_machineID.num = m_version;
434
419 // Objects
435 // initialize objects
420 s_profiler.setVersion(m_version);
436 s_profiler.setVersion(m_version);
437
421''')
422
423 code.indent()
424 for var in self.objects:
425 vtype = var.type
426 vid = "m_%s_ptr" % var.c_ident
427 if "network" not in var:
428 # Not a network port object

--- 11 unchanged lines hidden (view full) ---

440 expr = "%s = new %s%s" % (vid, vtype.c_ident, th)
441
442 args = ""
443 if "non_obj" not in vtype and not vtype.isEnumeration:
444 if expr.find("TBETable") >= 0:
445 args = "m_number_of_TBEs"
446 else:
447 args = var.get("constructor_hack", "")
438''')
439
440 code.indent()
441 for var in self.objects:
442 vtype = var.type
443 vid = "m_%s_ptr" % var.c_ident
444 if "network" not in var:
445 # Not a network port object

--- 11 unchanged lines hidden (view full) ---

457 expr = "%s = new %s%s" % (vid, vtype.c_ident, th)
458
459 args = ""
460 if "non_obj" not in vtype and not vtype.isEnumeration:
461 if expr.find("TBETable") >= 0:
462 args = "m_number_of_TBEs"
463 else:
464 args = var.get("constructor_hack", "")
448 args = "(%s)" % args
449
465
450 code('$expr$args;')
451 else:
452 code(';')
466 code('$expr($args);')
453
454 code('assert($vid != NULL);')
455
456 if "default" in var:
467
468 code('assert($vid != NULL);')
469
470 if "default" in var:
457 code('(*$vid) = ${{var["default"]}}; // Object default')
471 code('*$vid = ${{var["default"]}}; // Object default')
458 elif "default" in vtype:
472 elif "default" in vtype:
459 code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default')
473 comment = "Type %s default" % vtype.ident
474 code('*$vid = ${{vtype["default"]}}; // $comment')
460
461 # Set ordering
462 if "ordered" in var and "trigger_queue" not in var:
463 # A buffer
464 code('$vid->setOrdering(${{var["ordered"]}});')
465
466 # Set randomization
467 if "random" in var:

--- 7 unchanged lines hidden (view full) ---

475 else:
476 # Network port object
477 network = var["network"]
478 ordered = var["ordered"]
479 vnet = var["virtual_network"]
480
481 assert var.machine is not None
482 code('''
475
476 # Set ordering
477 if "ordered" in var and "trigger_queue" not in var:
478 # A buffer
479 code('$vid->setOrdering(${{var["ordered"]}});')
480
481 # Set randomization
482 if "random" in var:

--- 7 unchanged lines hidden (view full) ---

490 else:
491 # Network port object
492 network = var["network"]
493 ordered = var["ordered"]
494 vnet = var["virtual_network"]
495
496 assert var.machine is not None
497 code('''
483$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet);
498machine_type = string_to_MachineType("${{var.machine.ident}}");
499base = MachineType_base_number(machine_type);
500$vid = m_net_ptr->get${network}NetQueue(m_version + base, $ordered, $vnet);
484''')
485
486 code('assert($vid != NULL);')
487
488 # Set ordering
489 if "ordered" in var:
490 # A buffer
491 code('$vid->setOrdering(${{var["ordered"]}});')

--- 11 unchanged lines hidden (view full) ---

503 if vtype.isBuffer:
504 code('''
505if (m_buffer_size > 0) {
506 $vid->setSize(m_buffer_size);
507}
508''')
509
510 # set description (may be overriden later by port def)
501''')
502
503 code('assert($vid != NULL);')
504
505 # Set ordering
506 if "ordered" in var:
507 # A buffer
508 code('$vid->setOrdering(${{var["ordered"]}});')

--- 11 unchanged lines hidden (view full) ---

520 if vtype.isBuffer:
521 code('''
522if (m_buffer_size > 0) {
523 $vid->setSize(m_buffer_size);
524}
525''')
526
527 # set description (may be overriden later by port def)
511 code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");')
528 code('''
529$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");
512
530
531''')
532
513 # Set the queue consumers
514 code.insert_newline()
515 for port in self.in_ports:
516 code('${{port.code}}.setConsumer(this);')
517
518 # Set the queue descriptions
519 code.insert_newline()
520 for port in self.in_ports:

--- 27 unchanged lines hidden (view full) ---

548 has_mandatory_q = True
549
550 if has_mandatory_q:
551 mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident
552 else:
553 mq_ident = "NULL"
554
555 code('''
533 # Set the queue consumers
534 code.insert_newline()
535 for port in self.in_ports:
536 code('${{port.code}}.setConsumer(this);')
537
538 # Set the queue descriptions
539 code.insert_newline()
540 for port in self.in_ports:

--- 27 unchanged lines hidden (view full) ---

568 has_mandatory_q = True
569
570 if has_mandatory_q:
571 mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident
572 else:
573 mq_ident = "NULL"
574
575 code('''
556int $c_ident::getNumControllers() {
576int
577$c_ident::getNumControllers()
578{
557 return m_num_controllers;
558}
559
579 return m_num_controllers;
580}
581
560MessageBuffer* $c_ident::getMandatoryQueue() const {
582MessageBuffer*
583$c_ident::getMandatoryQueue() const
584{
561 return $mq_ident;
562}
563
585 return $mq_ident;
586}
587
564const int & $c_ident::getVersion() const{
588const int &
589$c_ident::getVersion() const
590{
565 return m_version;
566}
567
591 return m_version;
592}
593
568const string $c_ident::toString() const{
594const string
595$c_ident::toString() const
596{
569 return "$c_ident";
570}
571
597 return "$c_ident";
598}
599
572const string $c_ident::getName() const{
600const string
601$c_ident::getName() const
602{
573 return m_name;
574}
603 return m_name;
604}
575const MachineType $c_ident::getMachineType() const{
605
606const MachineType
607$c_ident::getMachineType() const
608{
576 return MachineType_${ident};
577}
578
609 return MachineType_${ident};
610}
611
579void $c_ident::blockOnQueue(Address addr, MessageBuffer* port) {
612void
613$c_ident::blockOnQueue(Address addr, MessageBuffer* port)
614{
580 m_is_blocking = true;
581 m_block_map[addr] = port;
582}
615 m_is_blocking = true;
616 m_block_map[addr] = port;
617}
583void $c_ident::unblock(Address addr) {
618
619void
620$c_ident::unblock(Address addr)
621{
584 m_block_map.erase(addr);
585 if (m_block_map.size() == 0) {
586 m_is_blocking = false;
587 }
588}
589
622 m_block_map.erase(addr);
623 if (m_block_map.size() == 0) {
624 m_is_blocking = false;
625 }
626}
627
590void $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; }
628void
629$c_ident::print(ostream& out) const
630{
631 out << "[$c_ident " << m_version << "]";
632}
591
633
592void $c_ident::printConfig(ostream& out) const {
634void
635$c_ident::printConfig(ostream& out) const
636{
593 out << "$c_ident config: " << m_name << endl;
594 out << " version: " << m_version << endl;
637 out << "$c_ident config: " << m_name << endl;
638 out << " version: " << m_version << endl;
595 for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {
596 out << " " << (*it).first << ": " << (*it).second << endl;
597 }
639 map<string, string>::const_iterator it;
640 for (it = m_cfg.begin(); it != m_cfg.end(); it++)
641 out << " " << it->first << ": " << it->second << endl;
598}
599
642}
643
600void $c_ident::printStats(ostream& out) const {
644void
645$c_ident::printStats(ostream& out) const
646{
601''')
602 #
603 # Cache and Memory Controllers have specific profilers associated with
604 # them. Print out these stats before dumping state transition stats.
605 #
606 for param in self.config_parameters:
607 if param.type_ast.type.ident == "CacheMemory" or \
608 param.type_ast.type.ident == "MemoryControl":

--- 24 unchanged lines hidden (view full) ---

633''')
634
635 for action in self.actions.itervalues():
636 if "c_code" not in action:
637 continue
638
639 code('''
640/** \\brief ${{action.desc}} */
647''')
648 #
649 # Cache and Memory Controllers have specific profilers associated with
650 # them. Print out these stats before dumping state transition stats.
651 #
652 for param in self.config_parameters:
653 if param.type_ast.type.ident == "CacheMemory" or \
654 param.type_ast.type.ident == "MemoryControl":

--- 24 unchanged lines hidden (view full) ---

679''')
680
681 for action in self.actions.itervalues():
682 if "c_code" not in action:
683 continue
684
685 code('''
686/** \\brief ${{action.desc}} */
641void $c_ident::${{action.ident}}(const Address& addr)
687void
688$c_ident::${{action.ident}}(const Address& addr)
642{
643 DEBUG_MSG(GENERATED_COMP, HighPrio, "executing");
644 ${{action["c_code"]}}
645}
646
647''')
648 code.write(path, "%s.cc" % c_ident)
649
650 def printCWakeup(self, path):
651 '''Output the wakeup loop for the events'''
652
653 code = self.symtab.codeFormatter()
654 ident = self.ident
655
656 code('''
657// Auto generated C++ code started by $__file__:$__line__
658// ${ident}: ${{self.short}}
659
689{
690 DEBUG_MSG(GENERATED_COMP, HighPrio, "executing");
691 ${{action["c_code"]}}
692}
693
694''')
695 code.write(path, "%s.cc" % c_ident)
696
697 def printCWakeup(self, path):
698 '''Output the wakeup loop for the events'''
699
700 code = self.symtab.codeFormatter()
701 ident = self.ident
702
703 code('''
704// Auto generated C++ code started by $__file__:$__line__
705// ${ident}: ${{self.short}}
706
707#include "base/misc.hh"
660#include "mem/ruby/common/Global.hh"
661#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
662#include "mem/protocol/${ident}_Controller.hh"
663#include "mem/protocol/${ident}_State.hh"
664#include "mem/protocol/${ident}_Event.hh"
665#include "mem/protocol/Types.hh"
666#include "mem/ruby/system/System.hh"
667
708#include "mem/ruby/common/Global.hh"
709#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
710#include "mem/protocol/${ident}_Controller.hh"
711#include "mem/protocol/${ident}_State.hh"
712#include "mem/protocol/${ident}_Event.hh"
713#include "mem/protocol/Types.hh"
714#include "mem/ruby/system/System.hh"
715
668void ${ident}_Controller::wakeup()
716void
717${ident}_Controller::wakeup()
669{
718{
719 // DEBUG_EXPR(GENERATED_COMP, MedPrio, *this);
720 // DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
670
671 int counter = 0;
672 while (true) {
673 // Some cases will put us into an infinite loop without this limit
674 assert(counter <= m_transitions_per_cycle);
675 if (counter == m_transitions_per_cycle) {
721
722 int counter = 0;
723 while (true) {
724 // Some cases will put us into an infinite loop without this limit
725 assert(counter <= m_transitions_per_cycle);
726 if (counter == m_transitions_per_cycle) {
676 g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized
677 g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again
727 // Count how often we are fully utilized
728 g_system_ptr->getProfiler()->controllerBusy(m_machineID);
729
730 // Wakeup in another cycle and try again
731 g_eventQueue_ptr->scheduleEvent(this, 1);
678 break;
679 }
680''')
681
682 code.indent()
683 code.indent()
684
685 # InPorts

--- 6 unchanged lines hidden (view full) ---

692
693 code('')
694
695 code.dedent()
696 code.dedent()
697 code('''
698 break; // If we got this far, we have nothing left todo
699 }
732 break;
733 }
734''')
735
736 code.indent()
737 code.indent()
738
739 # InPorts

--- 6 unchanged lines hidden (view full) ---

746
747 code('')
748
749 code.dedent()
750 code.dedent()
751 code('''
752 break; // If we got this far, we have nothing left todo
753 }
754 // g_eventQueue_ptr->scheduleEvent(this, 1);
755 // DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
700}
701''')
702
703 code.write(path, "%s_Wakeup.cc" % self.ident)
704
705 def printCSwitch(self, path):
706 '''Output switch statement for transition table'''
707

--- 11 unchanged lines hidden (view full) ---

719#include "mem/protocol/Types.hh"
720#include "mem/ruby/system/System.hh"
721
722#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event))
723
724#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str())
725#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str(""))
726
756}
757''')
758
759 code.write(path, "%s_Wakeup.cc" % self.ident)
760
761 def printCSwitch(self, path):
762 '''Output switch statement for transition table'''
763

--- 11 unchanged lines hidden (view full) ---

775#include "mem/protocol/Types.hh"
776#include "mem/ruby/system/System.hh"
777
778#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event))
779
780#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str())
781#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str(""))
782
727TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr
728)
783TransitionResult
784${ident}_Controller::doTransition(${ident}_Event event,
785 ${ident}_State state,
786 const Address &addr)
729{
730 ${ident}_State next_state = state;
731
732 DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
733 DEBUG_MSG(GENERATED_COMP, MedPrio, *this);
734 DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
735 DEBUG_EXPR(GENERATED_COMP, MedPrio,state);
736 DEBUG_EXPR(GENERATED_COMP, MedPrio,event);
737 DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);
738
787{
788 ${ident}_State next_state = state;
789
790 DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
791 DEBUG_MSG(GENERATED_COMP, MedPrio, *this);
792 DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
793 DEBUG_EXPR(GENERATED_COMP, MedPrio,state);
794 DEBUG_EXPR(GENERATED_COMP, MedPrio,event);
795 DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);
796
739 TransitionResult result = doTransitionWorker(event, state, next_state, addr);
797 TransitionResult result =
798 doTransitionWorker(event, state, next_state, addr);
740
741 if (result == TransitionResult_Valid) {
742 DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);
743 DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
744 s_profiler.countTransition(state, event);
745 if (Debug::getProtocolTrace()) {
799
800 if (result == TransitionResult_Valid) {
801 DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);
802 DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
803 s_profiler.countTransition(state, event);
804 if (Debug::getProtocolTrace()) {
746 g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
805 g_system_ptr->getProfiler()->profileTransition("${ident}",
806 m_version, addr,
747 ${ident}_State_to_string(state),
748 ${ident}_Event_to_string(event),
807 ${ident}_State_to_string(state),
808 ${ident}_Event_to_string(event),
749 ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT());
809 ${ident}_State_to_string(next_state),
810 GET_TRANSITION_COMMENT());
750 }
751 CLEAR_TRANSITION_COMMENT();
752 ${ident}_setState(addr, next_state);
753
754 } else if (result == TransitionResult_ResourceStall) {
755 if (Debug::getProtocolTrace()) {
811 }
812 CLEAR_TRANSITION_COMMENT();
813 ${ident}_setState(addr, next_state);
814
815 } else if (result == TransitionResult_ResourceStall) {
816 if (Debug::getProtocolTrace()) {
756 g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
817 g_system_ptr->getProfiler()->profileTransition("${ident}",
818 m_version, addr,
757 ${ident}_State_to_string(state),
758 ${ident}_Event_to_string(event),
759 ${ident}_State_to_string(next_state),
760 "Resource Stall");
761 }
762 } else if (result == TransitionResult_ProtocolStall) {
763 DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling");
764 DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
765 if (Debug::getProtocolTrace()) {
819 ${ident}_State_to_string(state),
820 ${ident}_Event_to_string(event),
821 ${ident}_State_to_string(next_state),
822 "Resource Stall");
823 }
824 } else if (result == TransitionResult_ProtocolStall) {
825 DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling");
826 DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
827 if (Debug::getProtocolTrace()) {
766 g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
828 g_system_ptr->getProfiler()->profileTransition("${ident}",
829 m_version, addr,
767 ${ident}_State_to_string(state),
768 ${ident}_Event_to_string(event),
769 ${ident}_State_to_string(next_state),
770 "Protocol Stall");
771 }
772 }
773
774 return result;
775}
776
830 ${ident}_State_to_string(state),
831 ${ident}_Event_to_string(event),
832 ${ident}_State_to_string(next_state),
833 "Protocol Stall");
834 }
835 }
836
837 return result;
838}
839
777TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr
778)
840TransitionResult
841${ident}_Controller::doTransitionWorker(${ident}_Event event,
842 ${ident}_State state,
843 ${ident}_State& next_state,
844 const Address& addr)
779{
780 switch(HASH_FUN(state, event)) {
781''')
782
783 # This map will allow suppress generating duplicate code
784 cases = orderdict()
785
786 for trans in self.transitions:

--- 9 unchanged lines hidden (view full) ---

796 actions = trans.actions
797
798 # Check for resources
799 case_sorter = []
800 res = trans.resources
801 for key,val in res.iteritems():
802 if key.type.ident != "DNUCAStopTable":
803 val = '''
845{
846 switch(HASH_FUN(state, event)) {
847''')
848
849 # This map will allow suppress generating duplicate code
850 cases = orderdict()
851
852 for trans in self.transitions:

--- 9 unchanged lines hidden (view full) ---

862 actions = trans.actions
863
864 # Check for resources
865 case_sorter = []
866 res = trans.resources
867 for key,val in res.iteritems():
868 if key.type.ident != "DNUCAStopTable":
869 val = '''
804if (!%s.areNSlotsAvailable(%s)) {
870if (!%s.areNSlotsAvailable(%s))
805 return TransitionResult_ResourceStall;
871 return TransitionResult_ResourceStall;
806}
807''' % (key.code, val)
808 case_sorter.append(val)
809
810
811 # Emit the code sequences in a sorted order. This makes the
812 # output deterministic (without this the output order can vary
813 # since Map's keys() on a vector of pointers is not deterministic
814 for c in sorted(case_sorter):

--- 23 unchanged lines hidden (view full) ---

838
839 # Walk through all of the unique code blocks and spit out the
840 # corresponding case statement elements
841 for case,transitions in cases.iteritems():
842 # Iterative over all the multiple transitions that share
843 # the same code
844 for trans in transitions:
845 code(' case HASH_FUN($trans):')
872''' % (key.code, val)
873 case_sorter.append(val)
874
875
876 # Emit the code sequences in a sorted order. This makes the
877 # output deterministic (without this the output order can vary
878 # since Map's keys() on a vector of pointers is not deterministic
879 for c in sorted(case_sorter):

--- 23 unchanged lines hidden (view full) ---

903
904 # Walk through all of the unique code blocks and spit out the
905 # corresponding case statement elements
906 for case,transitions in cases.iteritems():
907 # Iterative over all the multiple transitions that share
908 # the same code
909 for trans in transitions:
910 code(' case HASH_FUN($trans):')
846 code(' {')
847 code(' $case')
911 code(' $case')
848 code(' }')
849
850 code('''
851 default:
852 WARN_EXPR(m_version);
853 WARN_EXPR(g_eventQueue_ptr->getTime());
854 WARN_EXPR(addr);
855 WARN_EXPR(event);
856 WARN_EXPR(state);

--- 7 unchanged lines hidden (view full) ---

864 def printProfilerHH(self, path):
865 code = self.symtab.codeFormatter()
866 ident = self.ident
867
868 code('''
869// Auto generated C++ code started by $__file__:$__line__
870// ${ident}: ${{self.short}}
871
912
913 code('''
914 default:
915 WARN_EXPR(m_version);
916 WARN_EXPR(g_eventQueue_ptr->getTime());
917 WARN_EXPR(addr);
918 WARN_EXPR(event);
919 WARN_EXPR(state);

--- 7 unchanged lines hidden (view full) ---

927 def printProfilerHH(self, path):
928 code = self.symtab.codeFormatter()
929 ident = self.ident
930
931 code('''
932// Auto generated C++ code started by $__file__:$__line__
933// ${ident}: ${{self.short}}
934
872#ifndef ${ident}_PROFILER_H
873#define ${ident}_PROFILER_H
935#ifndef __${ident}_PROFILER_HH_
936#define __${ident}_PROFILER_HH_
874
875#include <iostream>
876
877#include "mem/ruby/common/Global.hh"
878#include "mem/protocol/${ident}_State.hh"
879#include "mem/protocol/${ident}_Event.hh"
880
937
938#include <iostream>
939
940#include "mem/ruby/common/Global.hh"
941#include "mem/protocol/${ident}_State.hh"
942#include "mem/protocol/${ident}_Event.hh"
943
881class ${ident}_Profiler {
944class ${ident}_Profiler
945{
882 public:
883 ${ident}_Profiler();
884 void setVersion(int version);
885 void countTransition(${ident}_State state, ${ident}_Event event);
886 void possibleTransition(${ident}_State state, ${ident}_Event event);
887 void dumpStats(std::ostream& out) const;
888 void clearStats();
889
890 private:
891 int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
892 int m_event_counters[${ident}_Event_NUM];
893 bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
894 int m_version;
895};
896
946 public:
947 ${ident}_Profiler();
948 void setVersion(int version);
949 void countTransition(${ident}_State state, ${ident}_Event event);
950 void possibleTransition(${ident}_State state, ${ident}_Event event);
951 void dumpStats(std::ostream& out) const;
952 void clearStats();
953
954 private:
955 int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
956 int m_event_counters[${ident}_Event_NUM];
957 bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
958 int m_version;
959};
960
897#endif // ${ident}_PROFILER_H
961#endif // __${ident}_PROFILER_HH__
898''')
899 code.write(path, "%s_Profiler.hh" % self.ident)
900
901 def printProfilerCC(self, path):
902 code = self.symtab.codeFormatter()
903 ident = self.ident
904
905 code('''

--- 9 unchanged lines hidden (view full) ---

915 m_possible[state][event] = false;
916 m_counters[state][event] = 0;
917 }
918 }
919 for (int event = 0; event < ${ident}_Event_NUM; event++) {
920 m_event_counters[event] = 0;
921 }
922}
962''')
963 code.write(path, "%s_Profiler.hh" % self.ident)
964
965 def printProfilerCC(self, path):
966 code = self.symtab.codeFormatter()
967 ident = self.ident
968
969 code('''

--- 9 unchanged lines hidden (view full) ---

979 m_possible[state][event] = false;
980 m_counters[state][event] = 0;
981 }
982 }
983 for (int event = 0; event < ${ident}_Event_NUM; event++) {
984 m_event_counters[event] = 0;
985 }
986}
923void ${ident}_Profiler::setVersion(int version)
987
988void
989${ident}_Profiler::setVersion(int version)
924{
925 m_version = version;
926}
990{
991 m_version = version;
992}
927void ${ident}_Profiler::clearStats()
993
994void
995${ident}_Profiler::clearStats()
928{
929 for (int state = 0; state < ${ident}_State_NUM; state++) {
930 for (int event = 0; event < ${ident}_Event_NUM; event++) {
931 m_counters[state][event] = 0;
932 }
933 }
934
935 for (int event = 0; event < ${ident}_Event_NUM; event++) {
936 m_event_counters[event] = 0;
937 }
938}
996{
997 for (int state = 0; state < ${ident}_State_NUM; state++) {
998 for (int event = 0; event < ${ident}_Event_NUM; event++) {
999 m_counters[state][event] = 0;
1000 }
1001 }
1002
1003 for (int event = 0; event < ${ident}_Event_NUM; event++) {
1004 m_event_counters[event] = 0;
1005 }
1006}
939void ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
1007void
1008${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
940{
941 assert(m_possible[state][event]);
942 m_counters[state][event]++;
943 m_event_counters[event]++;
944}
1009{
1010 assert(m_possible[state][event]);
1011 m_counters[state][event]++;
1012 m_event_counters[event]++;
1013}
945void ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event)
1014void
1015${ident}_Profiler::possibleTransition(${ident}_State state,
1016 ${ident}_Event event)
946{
947 m_possible[state][event] = true;
948}
1017{
1018 m_possible[state][event] = true;
1019}
949void ${ident}_Profiler::dumpStats(std::ostream& out) const
1020
1021void
1022${ident}_Profiler::dumpStats(std::ostream& out) const
950{
951 using namespace std;
952
953 out << " --- ${ident} " << m_version << " ---" << endl;
954 out << " - Event Counts -" << endl;
955 for (int event = 0; event < ${ident}_Event_NUM; event++) {
956 int count = m_event_counters[event];
957 out << (${ident}_Event) event << " " << count << endl;
958 }
959 out << endl;
960 out << " - Transitions -" << endl;
961 for (int state = 0; state < ${ident}_State_NUM; state++) {
962 for (int event = 0; event < ${ident}_Event_NUM; event++) {
963 if (m_possible[state][event]) {
964 int count = m_counters[state][event];
1023{
1024 using namespace std;
1025
1026 out << " --- ${ident} " << m_version << " ---" << endl;
1027 out << " - Event Counts -" << endl;
1028 for (int event = 0; event < ${ident}_Event_NUM; event++) {
1029 int count = m_event_counters[event];
1030 out << (${ident}_Event) event << " " << count << endl;
1031 }
1032 out << endl;
1033 out << " - Transitions -" << endl;
1034 for (int state = 0; state < ${ident}_State_NUM; state++) {
1035 for (int event = 0; event < ${ident}_Event_NUM; event++) {
1036 if (m_possible[state][event]) {
1037 int count = m_counters[state][event];
965 out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count;
1038 out << (${ident}_State) state << " "
1039 << (${ident}_Event) event << " " << count;
966 if (count == 0) {
967 out << " <-- ";
968 }
969 out << endl;
970 }
971 }
972 out << endl;
973 }
974}
975''')
976 code.write(path, "%s_Profiler.cc" % self.ident)
977
978 # **************************
979 # ******* HTML Files *******
980 # **************************
1040 if (count == 0) {
1041 out << " <-- ";
1042 }
1043 out << endl;
1044 }
1045 }
1046 out << endl;
1047 }
1048}
1049''')
1050 code.write(path, "%s_Profiler.cc" % self.ident)
1051
1052 # **************************
1053 # ******* HTML Files *******
1054 # **************************
981 def frameRef(self, click_href, click_target, over_href, over_target_num,
982 text):
1055 def frameRef(self, click_href, click_target, over_href, over_num, text):
983 code = self.symtab.codeFormatter(fix_newlines=False)
1056 code = self.symtab.codeFormatter(fix_newlines=False)
984 code("""<A href=\"$click_href\" target=\"$click_target\" onMouseOver=\"if (parent.frames[$over_target_num].location != parent.location + '$over_href') { parent.frames[$over_target_num].location='$over_href' }\" >${{html.formatShorthand(text)}}</A>""")
1057 code("""<A href=\"$click_href\" target=\"$click_target\" onmouseover=\"
1058 if (parent.frames[$over_num].location != parent.location + '$over_href') {
1059 parent.frames[$over_num].location='$over_href'
1060 }\">
1061 ${{html.formatShorthand(text)}}
1062 </A>""")
985 return str(code)
986
987 def writeHTMLFiles(self, path):
988 # Create table with no row hilighted
989 self.printHTMLTransitions(path, None)
990
991 # Generate transition tables
992 for state in self.states.itervalues():

--- 16 unchanged lines hidden (view full) ---

1009 name = "%s_Event_%s.html" % (self.ident, event.ident)
1010 code = html.createSymbol(event, "Event")
1011 code.write(path, name)
1012
1013 def printHTMLTransitions(self, path, active_state):
1014 code = self.symtab.codeFormatter()
1015
1016 code('''
1063 return str(code)
1064
1065 def writeHTMLFiles(self, path):
1066 # Create table with no row hilighted
1067 self.printHTMLTransitions(path, None)
1068
1069 # Generate transition tables
1070 for state in self.states.itervalues():

--- 16 unchanged lines hidden (view full) ---

1087 name = "%s_Event_%s.html" % (self.ident, event.ident)
1088 code = html.createSymbol(event, "Event")
1089 code.write(path, name)
1090
1091 def printHTMLTransitions(self, path, active_state):
1092 code = self.symtab.codeFormatter()
1093
1094 code('''
1017<HTML><BODY link="blue" vlink="blue">
1095
1096<BODY link="blue" vlink="blue">
1018
1019<H1 align="center">${{html.formatShorthand(self.short)}}:
1020''')
1021 code.indent()
1022 for i,machine in enumerate(self.symtab.getAllType(StateMachine)):
1023 mid = machine.ident
1024 if i != 0:
1025 extra = " - "

--- 67 unchanged lines hidden (view full) ---

1093
1094 elif active_state and next.ident == active_state.ident:
1095 color = "aqua"
1096 elif state == active_state:
1097 color = "yellow"
1098 else:
1099 color = "white"
1100
1097
1098<H1 align="center">${{html.formatShorthand(self.short)}}:
1099''')
1100 code.indent()
1101 for i,machine in enumerate(self.symtab.getAllType(StateMachine)):
1102 mid = machine.ident
1103 if i != 0:
1104 extra = " - "

--- 67 unchanged lines hidden (view full) ---

1172
1173 elif active_state and next.ident == active_state.ident:
1174 color = "aqua"
1175 elif state == active_state:
1176 color = "yellow"
1177 else:
1178 color = "white"
1179
1101 fix = code.nofix()
1102 code('<TD bgcolor=$color>')
1103 for action in trans.actions:
1104 href = "%s_action_%s.html" % (self.ident, action.ident)
1105 ref = self.frameRef(href, "Status", href, "1",
1106 action.short)
1180 code('<TD bgcolor=$color>')
1181 for action in trans.actions:
1182 href = "%s_action_%s.html" % (self.ident, action.ident)
1183 ref = self.frameRef(href, "Status", href, "1",
1184 action.short)
1107 code(' $ref\n')
1185 code(' $ref')
1108 if next != state:
1109 if trans.actions:
1110 code('/')
1111 click = "%s_table_%s.html" % (self.ident, next.ident)
1112 over = "%s_State_%s.html" % (self.ident, next.ident)
1113 ref = self.frameRef(click, "Table", over, "1", next.short)
1114 code("$ref")
1186 if next != state:
1187 if trans.actions:
1188 code('/')
1189 click = "%s_table_%s.html" % (self.ident, next.ident)
1190 over = "%s_State_%s.html" % (self.ident, next.ident)
1191 ref = self.frameRef(click, "Table", over, "1", next.short)
1192 code("$ref")
1115 code("</TD>\n")
1116 code.fix(fix)
1193 code("
1117
1118 # -- Each row
1119 if state == active_state:
1120 color = "yellow"
1121 else:
1122 color = "white"
1123
1124 click = "%s_table_%s.html" % (self.ident, state.ident)
1125 over = "%s_State_%s.html" % (self.ident, state.ident)
1126 ref = self.frameRef(click, "Table", over, "1", state.short)
1127 code('''
1128 <TH bgcolor=$color>$ref</TH>
1129</TR>
1130''')
1131 code('''
1194
1195 # -- Each row
1196 if state == active_state:
1197 color = "yellow"
1198 else:
1199 color = "white"
1200
1201 click = "%s_table_%s.html" % (self.ident, state.ident)
1202 over = "%s_State_%s.html" % (self.ident, state.ident)
1203 ref = self.frameRef(click, "Table", over, "1", state.short)
1204 code('''
1205 <TH bgcolor=$color>$ref</TH>
1206</TR>
1207''')
1208 code('''
1209<!- Column footer->
1132<TR>
1133 <TH> </TH>
1134''')
1135
1136 for event in self.events.itervalues():
1137 href = "%s_Event_%s.html" % (self.ident, event.ident)
1138 ref = self.frameRef(href, "Status", href, "1", event.short)
1139 code('<TH bgcolor=white>$ref</TH>')

--- 14 unchanged lines hidden ---
1210<TR>
1211 <TH> </TH>
1212''')
1213
1214 for event in self.events.itervalues():
1215 href = "%s_Event_%s.html" % (self.ident, event.ident)
1216 ref = self.frameRef(href, "Status", href, "1", event.short)
1217 code('<TH bgcolor=white>$ref</TH>')

--- 14 unchanged lines hidden ---