StateMachine.py (10972:53d63eeee46f) StateMachine.py (11021:e8a6637afa4c)
1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
2# Copyright (c) 2009 The Hewlett-Packard Development Company
3# Copyright (c) 2013 Advanced Micro Devices, Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met: redistributions of source code must retain the above copyright

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

230 code.indent()
231 for param in self.config_parameters:
232 dflt_str = ''
233
234 if param.rvalue is not None:
235 dflt_str = str(param.rvalue.inline()) + ', '
236
237 if param.type_ast.type.c_ident == "MessageBuffer":
1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
2# Copyright (c) 2009 The Hewlett-Packard Development Company
3# Copyright (c) 2013 Advanced Micro Devices, Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met: redistributions of source code must retain the above copyright

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

230 code.indent()
231 for param in self.config_parameters:
232 dflt_str = ''
233
234 if param.rvalue is not None:
235 dflt_str = str(param.rvalue.inline()) + ', '
236
237 if param.type_ast.type.c_ident == "MessageBuffer":
238 if param["network"] == "To":
239 code('${{param.ident}} = MasterPort(${dflt_str}"")')
240 else:
241 code('${{param.ident}} = SlavePort(${dflt_str}"")')
238 # The MessageBuffer MUST be instantiated in the protocol config
239 code('${{param.ident}} = Param.MessageBuffer("")')
242
243 elif python_class_map.has_key(param.type_ast.type.c_ident):
244 python_type = python_class_map[param.type_ast.type.c_ident]
245 code('${{param.ident}} = Param.${{python_type}}(${dflt_str}"")')
246
247 else:
248 self.error("Unknown c++ to python class conversion for c++ " \
249 "type: '%s'. Please update the python_class_map " \
250 "in StateMachine.py", param.type_ast.type.c_ident)
240
241 elif python_class_map.has_key(param.type_ast.type.c_ident):
242 python_type = python_class_map[param.type_ast.type.c_ident]
243 code('${{param.ident}} = Param.${{python_type}}(${dflt_str}"")')
244
245 else:
246 self.error("Unknown c++ to python class conversion for c++ " \
247 "type: '%s'. Please update the python_class_map " \
248 "in StateMachine.py", param.type_ast.type.c_ident)
249
250 # Also add any MessageBuffers declared internally to the controller
251 # Note: This includes mandatory and memory queues
252 for var in self.objects:
253 if var.type.c_ident == "MessageBuffer":
254 code('${{var.ident}} = Param.MessageBuffer("")')
255
251 code.dedent()
252 code.write(path, '%s.py' % py_ident)
253
254
255 def printControllerHH(self, path):
256 '''Output the method declarations for the class declaration'''
257 code = self.symtab.codeFormatter()
258 ident = self.ident

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

294{
295 public:
296 typedef ${c_ident}Params Params;
297 $c_ident(const Params *p);
298 static int getNumControllers();
299 void init();
300
301 MessageBuffer* getMandatoryQueue() const;
256 code.dedent()
257 code.write(path, '%s.py' % py_ident)
258
259
260 def printControllerHH(self, path):
261 '''Output the method declarations for the class declaration'''
262 code = self.symtab.codeFormatter()
263 ident = self.ident

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

299{
300 public:
301 typedef ${c_ident}Params Params;
302 $c_ident(const Params *p);
303 static int getNumControllers();
304 void init();
305
306 MessageBuffer* getMandatoryQueue() const;
302 void setNetQueue(const std::string& name, MessageBuffer *b);
307 MessageBuffer* getMemoryQueue() const;
308 void initNetQueues();
303
304 void print(std::ostream& out) const;
305 void wakeup();
306 void resetStats();
307 void regStats();
308 void collateStats();
309
310 void recordCacheTrace(int cntrl, CacheRecorder* tr);

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

520 code.indent()
521
522 #
523 # After initializing the universal machine parameters, initialize the
524 # this machines config parameters. Also if these configuration params
525 # include a sequencer, connect the it to the controller.
526 #
527 for param in self.config_parameters:
309
310 void print(std::ostream& out) const;
311 void wakeup();
312 void resetStats();
313 void regStats();
314 void collateStats();
315
316 void recordCacheTrace(int cntrl, CacheRecorder* tr);

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

526 code.indent()
527
528 #
529 # After initializing the universal machine parameters, initialize the
530 # this machines config parameters. Also if these configuration params
531 # include a sequencer, connect the it to the controller.
532 #
533 for param in self.config_parameters:
528
529 # Do not initialize messgage buffers since they are initialized
530 # when the port based connections are made.
531 if param.type_ast.type.c_ident == "MessageBuffer":
532 continue
533
534 if param.pointer:
535 code('m_${{param.ident}}_ptr = p->${{param.ident}};')
536 else:
537 code('m_${{param.ident}} = p->${{param.ident}};')
538
539 if re.compile("sequencer").search(param.ident):
540 code('m_${{param.ident}}_ptr->setController(this);')
541
542 for var in self.objects:
534 if param.pointer:
535 code('m_${{param.ident}}_ptr = p->${{param.ident}};')
536 else:
537 code('m_${{param.ident}} = p->${{param.ident}};')
538
539 if re.compile("sequencer").search(param.ident):
540 code('m_${{param.ident}}_ptr->setController(this);')
541
542 for var in self.objects:
543 if var.ident.find("mandatoryQueue") >= 0:
543 # Some MessageBuffers (e.g. mandatory and memory queues) are
544 # instantiated internally to StateMachines but exposed to
545 # components outside SLICC, so make sure to set up this
546 # controller as their receivers
547 if var.type.c_ident == "MessageBuffer":
544 code('''
548 code('''
545m_${{var.ident}}_ptr = new ${{var.type.c_ident}}();
549m_${{var.ident}}_ptr = p->${{var.ident}};
546m_${{var.ident}}_ptr->setReceiver(this);
547''')
548
549 code('''
550
551for (int state = 0; state < ${ident}_State_NUM; state++) {
552 for (int event = 0; event < ${ident}_Event_NUM; event++) {
553 m_possible[state][event] = false;

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

558 m_event_counters[event] = 0;
559}
560''')
561 code.dedent()
562 code('''
563}
564
565void
550m_${{var.ident}}_ptr->setReceiver(this);
551''')
552
553 code('''
554
555for (int state = 0; state < ${ident}_State_NUM; state++) {
556 for (int event = 0; event < ${ident}_Event_NUM; event++) {
557 m_possible[state][event] = false;

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

562 m_event_counters[event] = 0;
563}
564''')
565 code.dedent()
566 code('''
567}
568
569void
566$c_ident::setNetQueue(const std::string& name, MessageBuffer *b)
570$c_ident::initNetQueues()
567{
568 MachineType machine_type = string_to_MachineType("${{self.ident}}");
569 int base M5_VAR_USED = MachineType_base_number(machine_type);
570
571''')
572 code.indent()
573
574 # set for maintaining the vnet, direction pairs already seen for this
575 # machine. This map helps in implementing the check for avoiding
576 # multiple message buffers being mapped to the same vnet.
577 vnet_dir_set = set()
578
579 for var in self.config_parameters:
580 if "network" in var:
581 vtype = var.type_ast.type
582 vid = "m_%s_ptr" % var.ident
583
571{
572 MachineType machine_type = string_to_MachineType("${{self.ident}}");
573 int base M5_VAR_USED = MachineType_base_number(machine_type);
574
575''')
576 code.indent()
577
578 # set for maintaining the vnet, direction pairs already seen for this
579 # machine. This map helps in implementing the check for avoiding
580 # multiple message buffers being mapped to the same vnet.
581 vnet_dir_set = set()
582
583 for var in self.config_parameters:
584 if "network" in var:
585 vtype = var.type_ast.type
586 vid = "m_%s_ptr" % var.ident
587
584 code('''
585if ("${{var.ident}}" == name) {
586 $vid = b;
587 assert($vid != NULL);
588''')
589 code.indent()
588 code('assert($vid != NULL);')
589
590 # Network port object
591 network = var["network"]
590 # Network port object
591 network = var["network"]
592 ordered = var["ordered"]
593
594 if "virtual_network" in var:
595 vnet = var["virtual_network"]
596 vnet_type = var["vnet_type"]
597
598 assert (vnet, network) not in vnet_dir_set
599 vnet_dir_set.add((vnet,network))
600
601 code('''
592
593 if "virtual_network" in var:
594 vnet = var["virtual_network"]
595 vnet_type = var["vnet_type"]
596
597 assert (vnet, network) not in vnet_dir_set
598 vnet_dir_set.add((vnet,network))
599
600 code('''
602m_net_ptr->set${network}NetQueue(m_version + base, $ordered, $vnet,
603 "$vnet_type", b);
601m_net_ptr->set${network}NetQueue(m_version + base, $vid->getOrdered(), $vnet,
602 "$vnet_type", $vid);
604''')
605 # Set the end
606 if network == "To":
607 code('$vid->setSender(this);')
608 else:
609 code('$vid->setReceiver(this);')
610
603''')
604 # Set the end
605 if network == "To":
606 code('$vid->setSender(this);')
607 else:
608 code('$vid->setReceiver(this);')
609
611 # Set ordering
612 code('$vid->setOrdering(${{var["ordered"]}});')
613
614 # Set randomization
615 if "random" in var:
616 # A buffer
617 code('$vid->setRandomization(${{var["random"]}});')
618
619 # Set Priority
620 if "rank" in var:
621 code('$vid->setPriority(${{var["rank"]}})')
622
610 # Set Priority
611 if "rank" in var:
612 code('$vid->setPriority(${{var["rank"]}})')
613
623 # Set buffer size
624 code('$vid->resize(m_buffer_size);')
625
626 if "recycle_latency" in var:
627 code('$vid->setRecycleLatency( ' \
628 'Cycles(${{var["recycle_latency"]}}));')
629 else:
630 code('$vid->setRecycleLatency(m_recycle_latency);')
631
632 # set description (may be overriden later by port def)
633 code('''
634$vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{var.ident}}]");
635''')
636 code.dedent()
637 code('}\n')
638
639 code.dedent()
640 code('''
641}
642
643void
644$c_ident::init()
645{
646 // initialize objects
614 code.dedent()
615 code('''
616}
617
618void
619$c_ident::init()
620{
621 // initialize objects
647
622 initNetQueues();
648''')
649
650 code.indent()
651
652 for var in self.objects:
653 vtype = var.type
654 vid = "m_%s_ptr" % var.ident
655 if "network" not in var:
656 # Not a network port object
657 if "primitive" in vtype:
658 code('$vid = new ${{vtype.c_ident}};')
659 if "default" in var:
660 code('(*$vid) = ${{var["default"]}};')
661 else:
662 # Normal Object
623''')
624
625 code.indent()
626
627 for var in self.objects:
628 vtype = var.type
629 vid = "m_%s_ptr" % var.ident
630 if "network" not in var:
631 # Not a network port object
632 if "primitive" in vtype:
633 code('$vid = new ${{vtype.c_ident}};')
634 if "default" in var:
635 code('(*$vid) = ${{var["default"]}};')
636 else:
637 # Normal Object
663 if var.ident.find("mandatoryQueue") < 0:
638 if var.type.c_ident != "MessageBuffer":
664 th = var.get("template", "")
665 expr = "%s = new %s%s" % (vid, vtype.c_ident, th)
666 args = ""
667 if "non_obj" not in vtype and not vtype.isEnumeration:
668 args = var.get("constructor", "")
669 code('$expr($args);')
670
671 code('assert($vid != NULL);')
672
673 if "default" in var:
674 code('*$vid = ${{var["default"]}}; // Object default')
675 elif "default" in vtype:
676 comment = "Type %s default" % vtype.ident
677 code('*$vid = ${{vtype["default"]}}; // $comment')
678
639 th = var.get("template", "")
640 expr = "%s = new %s%s" % (vid, vtype.c_ident, th)
641 args = ""
642 if "non_obj" not in vtype and not vtype.isEnumeration:
643 args = var.get("constructor", "")
644 code('$expr($args);')
645
646 code('assert($vid != NULL);')
647
648 if "default" in var:
649 code('*$vid = ${{var["default"]}}; // Object default')
650 elif "default" in vtype:
651 comment = "Type %s default" % vtype.ident
652 code('*$vid = ${{vtype["default"]}}; // $comment')
653
679 # Set ordering
680 if "ordered" in var:
681 # A buffer
682 code('$vid->setOrdering(${{var["ordered"]}});')
683
684 # Set randomization
685 if "random" in var:
686 # A buffer
687 code('$vid->setRandomization(${{var["random"]}});')
688
689 # Set Priority
690 if vtype.isBuffer and "rank" in var:
691 code('$vid->setPriority(${{var["rank"]}});')
692
693 # Set sender and receiver for trigger queue
694 if var.ident.find("triggerQueue") >= 0:
695 code('$vid->setSender(this);')
696 code('$vid->setReceiver(this);')
697 elif vtype.c_ident == "TimerTable":
698 code('$vid->setClockObj(this);')
699 elif var.ident.find("optionalQueue") >= 0:
700 code('$vid->setSender(this);')
701 code('$vid->setReceiver(this);')
702
654 # Set Priority
655 if vtype.isBuffer and "rank" in var:
656 code('$vid->setPriority(${{var["rank"]}});')
657
658 # Set sender and receiver for trigger queue
659 if var.ident.find("triggerQueue") >= 0:
660 code('$vid->setSender(this);')
661 code('$vid->setReceiver(this);')
662 elif vtype.c_ident == "TimerTable":
663 code('$vid->setClockObj(this);')
664 elif var.ident.find("optionalQueue") >= 0:
665 code('$vid->setSender(this);')
666 code('$vid->setReceiver(this);')
667
703 if vtype.isBuffer:
704 if "recycle_latency" in var:
705 code('$vid->setRecycleLatency( ' \
706 'Cycles(${{var["recycle_latency"]}}));')
707 else:
708 code('$vid->setRecycleLatency(m_recycle_latency);')
709
710 # Set the prefetchers
711 code()
712 for prefetcher in self.prefetchers:
713 code('${{prefetcher.code}}.setController(this);')
714
715 code()
716 for port in self.in_ports:
717 # Set the queue consumers
718 code('${{port.code}}.setConsumer(this);')
668 # Set the prefetchers
669 code()
670 for prefetcher in self.prefetchers:
671 code('${{prefetcher.code}}.setController(this);')
672
673 code()
674 for port in self.in_ports:
675 # Set the queue consumers
676 code('${{port.code}}.setConsumer(this);')
719 # Set the queue descriptions
720 code('${{port.code}}.setDescription("[Version " + to_string(m_version) + ", $ident, $port]");')
721
722 # Initialize the transition profiling
723 code()
724 for trans in self.transitions:
725 # Figure out if we stall
726 stall = False
727 for action in trans.actions:
728 if action.ident == "z_stall":

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

741}
742''')
743
744 mq_ident = "NULL"
745 for port in self.in_ports:
746 if port.code.find("mandatoryQueue_ptr") >= 0:
747 mq_ident = "m_mandatoryQueue_ptr"
748
677
678 # Initialize the transition profiling
679 code()
680 for trans in self.transitions:
681 # Figure out if we stall
682 stall = False
683 for action in trans.actions:
684 if action.ident == "z_stall":

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

697}
698''')
699
700 mq_ident = "NULL"
701 for port in self.in_ports:
702 if port.code.find("mandatoryQueue_ptr") >= 0:
703 mq_ident = "m_mandatoryQueue_ptr"
704
705 memq_ident = "NULL"
706 for port in self.in_ports:
707 if port.code.find("responseFromMemory_ptr") >= 0:
708 memq_ident = "m_responseFromMemory_ptr"
709
749 seq_ident = "NULL"
750 for param in self.config_parameters:
751 if param.ident == "sequencer":
752 assert(param.pointer)
753 seq_ident = "m_%s_ptr" % param.ident
754
755 code('''
756

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

867}
868
869MessageBuffer*
870$c_ident::getMandatoryQueue() const
871{
872 return $mq_ident;
873}
874
710 seq_ident = "NULL"
711 for param in self.config_parameters:
712 if param.ident == "sequencer":
713 assert(param.pointer)
714 seq_ident = "m_%s_ptr" % param.ident
715
716 code('''
717

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

828}
829
830MessageBuffer*
831$c_ident::getMandatoryQueue() const
832{
833 return $mq_ident;
834}
835
836MessageBuffer*
837$c_ident::getMemoryQueue() const
838{
839 return $memq_ident;
840}
841
875Sequencer*
876$c_ident::getSequencer() const
877{
878 return $seq_ident;
879}
880
881void
882$c_ident::print(ostream& out) const

--- 729 unchanged lines hidden ---
842Sequencer*
843$c_ident::getSequencer() const
844{
845 return $seq_ident;
846}
847
848void
849$c_ident::print(ostream& out) const

--- 729 unchanged lines hidden ---