StateMachine.py (10308:8c0870dbae5c) StateMachine.py (10311:ad9c042dce54)
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;

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

46 "Prefetcher":"Prefetcher",
47 "Cycles":"Cycles",
48 }
49
50class StateMachine(Symbol):
51 def __init__(self, symtab, ident, location, pairs, config_parameters):
52 super(StateMachine, self).__init__(symtab, ident, location, pairs)
53 self.table = None
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;

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

46 "Prefetcher":"Prefetcher",
47 "Cycles":"Cycles",
48 }
49
50class StateMachine(Symbol):
51 def __init__(self, symtab, ident, location, pairs, config_parameters):
52 super(StateMachine, self).__init__(symtab, ident, location, pairs)
53 self.table = None
54
55 # Data members in the State Machine that have been declared before
56 # the opening brace '{' of the machine. Note that these along with
57 # the members in self.objects form the entire set of data members.
54 self.config_parameters = config_parameters
58 self.config_parameters = config_parameters
59
55 self.prefetchers = []
56
57 for param in config_parameters:
58 if param.pointer:
59 var = Var(symtab, param.ident, location, param.type_ast.type,
60 "(*m_%s_ptr)" % param.ident, {}, self)
61 else:
62 var = Var(symtab, param.ident, location, param.type_ast.type,

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

69
70 self.states = orderdict()
71 self.events = orderdict()
72 self.actions = orderdict()
73 self.request_types = orderdict()
74 self.transitions = []
75 self.in_ports = []
76 self.functions = []
60 self.prefetchers = []
61
62 for param in config_parameters:
63 if param.pointer:
64 var = Var(symtab, param.ident, location, param.type_ast.type,
65 "(*m_%s_ptr)" % param.ident, {}, self)
66 else:
67 var = Var(symtab, param.ident, location, param.type_ast.type,

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

74
75 self.states = orderdict()
76 self.events = orderdict()
77 self.actions = orderdict()
78 self.request_types = orderdict()
79 self.transitions = []
80 self.in_ports = []
81 self.functions = []
82
83 # Data members in the State Machine that have been declared inside
84 # the {} machine. Note that these along with the config params
85 # form the entire set of data members of the machine.
77 self.objects = []
78 self.TBEType = None
79 self.EntryType = None
80
81 def __repr__(self):
82 return "[StateMachine: %s]" % self.ident
83
84 def addState(self, state):

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

195''')
196 code.indent()
197 for param in self.config_parameters:
198 dflt_str = ''
199
200 if param.rvalue is not None:
201 dflt_str = str(param.rvalue.inline()) + ', '
202
86 self.objects = []
87 self.TBEType = None
88 self.EntryType = None
89
90 def __repr__(self):
91 return "[StateMachine: %s]" % self.ident
92
93 def addState(self, state):

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

204''')
205 code.indent()
206 for param in self.config_parameters:
207 dflt_str = ''
208
209 if param.rvalue is not None:
210 dflt_str = str(param.rvalue.inline()) + ', '
211
203 if python_class_map.has_key(param.type_ast.type.c_ident):
212 if param.type_ast.type.c_ident == "MessageBuffer":
213 if param["network"] == "To":
214 code('${{param.ident}} = MasterPort(${dflt_str}"")')
215 else:
216 code('${{param.ident}} = SlavePort(${dflt_str}"")')
217
218 elif python_class_map.has_key(param.type_ast.type.c_ident):
204 python_type = python_class_map[param.type_ast.type.c_ident]
205 code('${{param.ident}} = Param.${{python_type}}(${dflt_str}"")')
206
207 else:
208 self.error("Unknown c++ to python class conversion for c++ " \
209 "type: '%s'. Please update the python_class_map " \
210 "in StateMachine.py", param.type_ast.type.c_ident)
211 code.dedent()

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

236#include "mem/protocol/Types.hh"
237#include "mem/ruby/common/Consumer.hh"
238#include "mem/ruby/common/Global.hh"
239#include "mem/ruby/slicc_interface/AbstractController.hh"
240#include "params/$c_ident.hh"
241''')
242
243 seen_types = set()
219 python_type = python_class_map[param.type_ast.type.c_ident]
220 code('${{param.ident}} = Param.${{python_type}}(${dflt_str}"")')
221
222 else:
223 self.error("Unknown c++ to python class conversion for c++ " \
224 "type: '%s'. Please update the python_class_map " \
225 "in StateMachine.py", param.type_ast.type.c_ident)
226 code.dedent()

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

251#include "mem/protocol/Types.hh"
252#include "mem/ruby/common/Consumer.hh"
253#include "mem/ruby/common/Global.hh"
254#include "mem/ruby/slicc_interface/AbstractController.hh"
255#include "params/$c_ident.hh"
256''')
257
258 seen_types = set()
244 has_peer = False
245 for var in self.objects:
246 if var.type.ident not in seen_types and not var.type.isPrimitive:
247 code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
259 for var in self.objects:
260 if var.type.ident not in seen_types and not var.type.isPrimitive:
261 code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
248 if "network" in var and "physical_network" in var:
249 has_peer = True
250 seen_types.add(var.type.ident)
262 seen_types.add(var.type.ident)
251
252 # for adding information to the protocol debug trace
253 code('''
254extern std::stringstream ${ident}_transitionComment;
255
256class $c_ident : public AbstractController
257{
258 public:
259 typedef ${c_ident}Params Params;
260 $c_ident(const Params *p);
261 static int getNumControllers();
262 void init();
263
264 # for adding information to the protocol debug trace
265 code('''
266extern std::stringstream ${ident}_transitionComment;
267
268class $c_ident : public AbstractController
269{
270 public:
271 typedef ${c_ident}Params Params;
272 $c_ident(const Params *p);
273 static int getNumControllers();
274 void init();
275
263 MessageBuffer* getMandatoryQueue() const;
276 MessageBuffer* getMandatoryQueue() const;
277 void setNetQueue(const std::string& name, MessageBuffer *b);
264
265 void print(std::ostream& out) const;
266 void wakeup();
267 void resetStats();
268 void regStats();
269 void collateStats();
270
271 void recordCacheTrace(int cntrl, CacheRecorder* tr);

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

335// Internal functions
336''')
337
338 for func in self.functions:
339 proto = func.prototype
340 if proto:
341 code('$proto')
342
278
279 void print(std::ostream& out) const;
280 void wakeup();
281 void resetStats();
282 void regStats();
283 void collateStats();
284
285 void recordCacheTrace(int cntrl, CacheRecorder* tr);

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

349// Internal functions
350''')
351
352 for func in self.functions:
353 proto = func.prototype
354 if proto:
355 code('$proto')
356
343 if has_peer:
344 code('void getQueuesFromPeer(AbstractController *);')
345 if self.EntryType != None:
346 code('''
347
348// Set and Reset for cache_entry variable
349void set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry);
350void unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr);
351''')
352

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

399 code.write(path, '%s.hh' % c_ident)
400
401 def printControllerCC(self, path, includes):
402 '''Output the actions for performing the actions'''
403
404 code = self.symtab.codeFormatter()
405 ident = self.ident
406 c_ident = "%s_Controller" % self.ident
357 if self.EntryType != None:
358 code('''
359
360// Set and Reset for cache_entry variable
361void set_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr, AbstractCacheEntry* m_new_cache_entry);
362void unset_cache_entry(${{self.EntryType.c_ident}}*& m_cache_entry_ptr);
363''')
364

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

411 code.write(path, '%s.hh' % c_ident)
412
413 def printControllerCC(self, path, includes):
414 '''Output the actions for performing the actions'''
415
416 code = self.symtab.codeFormatter()
417 ident = self.ident
418 c_ident = "%s_Controller" % self.ident
407 has_peer = False
408
409 code('''
410/** \\file $c_ident.cc
411 *
412 * Auto generated C++ code started by $__file__:$__line__
413 * Created by slicc definition of Module "${{self.short}}"
414 */
415

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

481 code.indent()
482
483 #
484 # After initializing the universal machine parameters, initialize the
485 # this machines config parameters. Also if these configuration params
486 # include a sequencer, connect the it to the controller.
487 #
488 for param in self.config_parameters:
419
420 code('''
421/** \\file $c_ident.cc
422 *
423 * Auto generated C++ code started by $__file__:$__line__
424 * Created by slicc definition of Module "${{self.short}}"
425 */
426

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

492 code.indent()
493
494 #
495 # After initializing the universal machine parameters, initialize the
496 # this machines config parameters. Also if these configuration params
497 # include a sequencer, connect the it to the controller.
498 #
499 for param in self.config_parameters:
500
501 # Do not initialize messgage buffers since they are initialized
502 # when the port based connections are made.
503 if param.type_ast.type.c_ident == "MessageBuffer":
504 continue
505
489 if param.pointer:
490 code('m_${{param.ident}}_ptr = p->${{param.ident}};')
491 else:
492 code('m_${{param.ident}} = p->${{param.ident}};')
506 if param.pointer:
507 code('m_${{param.ident}}_ptr = p->${{param.ident}};')
508 else:
509 code('m_${{param.ident}} = p->${{param.ident}};')
510
493 if re.compile("sequencer").search(param.ident):
494 code('m_${{param.ident}}_ptr->setController(this);')
495
496 for var in self.objects:
497 if var.ident.find("mandatoryQueue") >= 0:
498 code('''
499m_${{var.ident}}_ptr = new ${{var.type.c_ident}}();
500m_${{var.ident}}_ptr->setReceiver(this);
501''')
511 if re.compile("sequencer").search(param.ident):
512 code('m_${{param.ident}}_ptr->setController(this);')
513
514 for var in self.objects:
515 if var.ident.find("mandatoryQueue") >= 0:
516 code('''
517m_${{var.ident}}_ptr = new ${{var.type.c_ident}}();
518m_${{var.ident}}_ptr->setReceiver(this);
519''')
502 else:
503 if "network" in var and "physical_network" in var and \
504 var["network"] == "To":
505 has_peer = True
506 code('''
507m_${{var.ident}}_ptr = new ${{var.type.c_ident}}();
508peerQueueMap[${{var["physical_network"]}}] = m_${{var.ident}}_ptr;
509m_${{var.ident}}_ptr->setSender(this);
510''')
511
512 code('''
520
521 code('''
513if (p->peer != NULL)
514 connectWithPeer(p->peer);
515
516for (int state = 0; state < ${ident}_State_NUM; state++) {
517 for (int event = 0; event < ${ident}_Event_NUM; event++) {
518 m_possible[state][event] = false;
519 m_counters[state][event] = 0;
520 }
521}
522for (int event = 0; event < ${ident}_Event_NUM; event++) {
523 m_event_counters[event] = 0;
524}
525''')
526 code.dedent()
527 code('''
528}
529
530void
522
523for (int state = 0; state < ${ident}_State_NUM; state++) {
524 for (int event = 0; event < ${ident}_Event_NUM; event++) {
525 m_possible[state][event] = false;
526 m_counters[state][event] = 0;
527 }
528}
529for (int event = 0; event < ${ident}_Event_NUM; event++) {
530 m_event_counters[event] = 0;
531}
532''')
533 code.dedent()
534 code('''
535}
536
537void
531$c_ident::init()
538$c_ident::setNetQueue(const std::string& name, MessageBuffer *b)
532{
539{
533 MachineType machine_type = string_to_MachineType("${{var.machine.ident}}");
540 MachineType machine_type = string_to_MachineType("${{self.ident}}");
534 int base M5_VAR_USED = MachineType_base_number(machine_type);
535
541 int base M5_VAR_USED = MachineType_base_number(machine_type);
542
543''')
544 code.indent()
545
546 # set for maintaining the vnet, direction pairs already seen for this
547 # machine. This map helps in implementing the check for avoiding
548 # multiple message buffers being mapped to the same vnet.
549 vnet_dir_set = set()
550
551 for var in self.config_parameters:
552 if "network" in var:
553 vtype = var.type_ast.type
554 vid = "m_%s_ptr" % var.ident
555
556 code('''
557if ("${{var.ident}}" == name) {
558 $vid = b;
559 assert($vid != NULL);
560''')
561 code.indent()
562 # Network port object
563 network = var["network"]
564 ordered = var["ordered"]
565
566 if "virtual_network" in var:
567 vnet = var["virtual_network"]
568 vnet_type = var["vnet_type"]
569
570 assert (vnet, network) not in vnet_dir_set
571 vnet_dir_set.add((vnet,network))
572
573 code('''
574m_net_ptr->set${network}NetQueue(m_version + base, $ordered, $vnet,
575 "$vnet_type", b);
576''')
577 # Set the end
578 if network == "To":
579 code('$vid->setSender(this);')
580 else:
581 code('$vid->setReceiver(this);')
582
583 # Set ordering
584 code('$vid->setOrdering(${{var["ordered"]}});')
585
586 # Set randomization
587 if "random" in var:
588 # A buffer
589 code('$vid->setRandomization(${{var["random"]}});')
590
591 # Set Priority
592 if "rank" in var:
593 code('$vid->setPriority(${{var["rank"]}})')
594
595 # Set buffer size
596 code('$vid->resize(m_buffer_size);')
597
598 if "recycle_latency" in var:
599 code('$vid->setRecycleLatency( ' \
600 'Cycles(${{var["recycle_latency"]}}));')
601 else:
602 code('$vid->setRecycleLatency(m_recycle_latency);')
603
604 # set description (may be overriden later by port def)
605 code('''
606$vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{var.ident}}]");
607''')
608 code.dedent()
609 code('}\n')
610
611 code.dedent()
612 code('''
613}
614
615void
616$c_ident::init()
617{
536 // initialize objects
537
538''')
539
540 code.indent()
618 // initialize objects
619
620''')
621
622 code.indent()
623
541 for var in self.objects:
542 vtype = var.type
543 vid = "m_%s_ptr" % var.ident
544 if "network" not in var:
545 # Not a network port object
546 if "primitive" in vtype:
547 code('$vid = new ${{vtype.c_ident}};')
548 if "default" in var:

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

584 code('$vid->setSender(this);')
585 code('$vid->setReceiver(this);')
586 elif vtype.c_ident == "TimerTable":
587 code('$vid->setClockObj(this);')
588 elif var.ident.find("optionalQueue") >= 0:
589 code('$vid->setSender(this);')
590 code('$vid->setReceiver(this);')
591
624 for var in self.objects:
625 vtype = var.type
626 vid = "m_%s_ptr" % var.ident
627 if "network" not in var:
628 # Not a network port object
629 if "primitive" in vtype:
630 code('$vid = new ${{vtype.c_ident}};')
631 if "default" in var:

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

667 code('$vid->setSender(this);')
668 code('$vid->setReceiver(this);')
669 elif vtype.c_ident == "TimerTable":
670 code('$vid->setClockObj(this);')
671 elif var.ident.find("optionalQueue") >= 0:
672 code('$vid->setSender(this);')
673 code('$vid->setReceiver(this);')
674
592 else:
593 # Network port object
594 network = var["network"]
595 ordered = var["ordered"]
596
597 if "virtual_network" in var:
598 vnet = var["virtual_network"]
599 vnet_type = var["vnet_type"]
600
601 assert var.machine is not None
602 code('''
603$vid = m_net_ptr->get${network}NetQueue(m_version + base, $ordered, $vnet, "$vnet_type");
604assert($vid != NULL);
605''')
606
607 # Set the end
608 if network == "To":
609 code('$vid->setSender(this);')
610 else:
611 code('$vid->setReceiver(this);')
612
613 # Set ordering
614 if "ordered" in var:
615 # A buffer
616 code('$vid->setOrdering(${{var["ordered"]}});')
617
618 # Set randomization
619 if "random" in var:
620 # A buffer
621 code('$vid->setRandomization(${{var["random"]}});')
622
623 # Set Priority
624 if "rank" in var:
625 code('$vid->setPriority(${{var["rank"]}})')
626
627 # Set buffer size
628 if vtype.isBuffer:
629 code('''
630if (m_buffer_size > 0) {
631 $vid->resize(m_buffer_size);
632}
633''')
634
635 # set description (may be overriden later by port def)
636 code('''
637$vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{var.ident}}]");
638
639''')
640
641 if vtype.isBuffer:
642 if "recycle_latency" in var:
643 code('$vid->setRecycleLatency( ' \
644 'Cycles(${{var["recycle_latency"]}}));')
645 else:
646 code('$vid->setRecycleLatency(m_recycle_latency);')
647
648 # Set the prefetchers

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

960$c_ident::functionalReadBuffers(PacketPtr& pkt)
961{
962''')
963 for var in self.objects:
964 vtype = var.type
965 if vtype.isBuffer:
966 vid = "m_%s_ptr" % var.ident
967 code('if ($vid->functionalRead(pkt)) { return true; }')
675 if vtype.isBuffer:
676 if "recycle_latency" in var:
677 code('$vid->setRecycleLatency( ' \
678 'Cycles(${{var["recycle_latency"]}}));')
679 else:
680 code('$vid->setRecycleLatency(m_recycle_latency);')
681
682 # Set the prefetchers

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

994$c_ident::functionalReadBuffers(PacketPtr& pkt)
995{
996''')
997 for var in self.objects:
998 vtype = var.type
999 if vtype.isBuffer:
1000 vid = "m_%s_ptr" % var.ident
1001 code('if ($vid->functionalRead(pkt)) { return true; }')
1002
1003 for var in self.config_parameters:
1004 vtype = var.type_ast.type
1005 if vtype.isBuffer:
1006 vid = "m_%s_ptr" % var.ident
1007 code('if ($vid->functionalRead(pkt)) { return true; }')
1008
968 code('''
969 return false;
970}
971''')
972
973 # Function for functional writes to messages buffered in the controller
974 code('''
975uint32_t
976$c_ident::functionalWriteBuffers(PacketPtr& pkt)
977{
978 uint32_t num_functional_writes = 0;
979''')
980 for var in self.objects:
981 vtype = var.type
982 if vtype.isBuffer:
983 vid = "m_%s_ptr" % var.ident
984 code('num_functional_writes += $vid->functionalWrite(pkt);')
1009 code('''
1010 return false;
1011}
1012''')
1013
1014 # Function for functional writes to messages buffered in the controller
1015 code('''
1016uint32_t
1017$c_ident::functionalWriteBuffers(PacketPtr& pkt)
1018{
1019 uint32_t num_functional_writes = 0;
1020''')
1021 for var in self.objects:
1022 vtype = var.type
1023 if vtype.isBuffer:
1024 vid = "m_%s_ptr" % var.ident
1025 code('num_functional_writes += $vid->functionalWrite(pkt);')
1026
1027 for var in self.config_parameters:
1028 vtype = var.type_ast.type
1029 if vtype.isBuffer:
1030 vid = "m_%s_ptr" % var.ident
1031 code('num_functional_writes += $vid->functionalWrite(pkt);')
1032
985 code('''
986 return num_functional_writes;
987}
988''')
989
1033 code('''
1034 return num_functional_writes;
1035}
1036''')
1037
990 # Check if this controller has a peer, if yes then write the
991 # function for connecting to the peer.
992 if has_peer:
993 code('''
994
995void
996$c_ident::getQueuesFromPeer(AbstractController *peer)
997{
998''')
999 for var in self.objects:
1000 if "network" in var and "physical_network" in var and \
1001 var["network"] == "From":
1002 code('''
1003m_${{var.ident}}_ptr = peer->getPeerQueue(${{var["physical_network"]}});
1004assert(m_${{var.ident}}_ptr != NULL);
1005m_${{var.ident}}_ptr->setReceiver(this);
1006
1007''')
1008 code('}')
1009
1010 code.write(path, "%s.cc" % c_ident)
1011
1012 def printCWakeup(self, path, includes):
1013 '''Output the wakeup loop for the events'''
1014
1015 code = self.symtab.codeFormatter()
1016 ident = self.ident
1017

--- 505 unchanged lines hidden ---
1038 code.write(path, "%s.cc" % c_ident)
1039
1040 def printCWakeup(self, path, includes):
1041 '''Output the wakeup loop for the events'''
1042
1043 code = self.symtab.codeFormatter()
1044 ident = self.ident
1045

--- 505 unchanged lines hidden ---