Inferno
0.2
|
00001 #ifndef SCTREE_HPP 00002 #define SCTREE_HPP 00003 00004 #include "clang/Basic/SourceLocation.h" 00005 #include "clang/Basic/TokenKinds.h" 00006 #include "llvm/ADT/APSInt.h" 00007 #include "llvm/ADT/APFloat.h" 00008 #include <string> 00009 #include <deque> 00010 #include "node/node.hpp" 00011 #include "clang/Parse/DeclSpec.h" 00012 #include "tree/type_db.hpp" 00013 #include "tree/cpptree.hpp" 00014 00015 /// SCTree namespace contains node definitions that represent elements of SystemC, expressed as though native language elements 00016 namespace SCTree { 00017 00018 /** Base for all SystemC nodes, permitting detection of SystemC dialect eg for rendering */ 00019 struct SCConstruct {}; 00020 00021 /** Base for SystemC nodes that helps with detection and rendering by allowing constructs 00022 that differ only in source-code-name to be treated as a group. The actual source-code-name 00023 is available via a virtual accessor. */ 00024 struct SCNamedConstruct : public SCConstruct 00025 { 00026 virtual string GetToken() {ASSERTFAIL("GetToken() called on intermediate node\n")} ///< Produce the source-code-name of the corresponding SystemC construct 00027 }; 00028 00029 /// Anything derived from this renders like an identifier 00030 struct SCNamedIdentifier : SCNamedConstruct {}; 00031 00032 /// Anything derived from this renders like a record 00033 struct SCNamedRecord : SCNamedConstruct {}; 00034 00035 /// Anything derived from this renders like a function 00036 struct SCNamedFunction : SCNamedConstruct {}; 00037 00038 /** SystemC event type, no members need to be set up. Event instances 00039 are declared to be of this type. They can then be signalled, waited etc. */ 00040 struct Event : CPPTree::Type, 00041 SCNamedIdentifier 00042 { 00043 NODE_FUNCTIONS_FINAL 00044 virtual string GetToken() { return "sc_event"; } 00045 }; 00046 00047 /** SystemC module type. The processes, registers, submodules and everything 00048 else within the module appear as members of the record. No constructor/destructor 00049 is needed (so module is not a kind of class) - the renderer generates a constructor 00050 based on the module's members. Thus elaboration is structural in the tree 00051 (as with Verilog) and the renderer generates the run-time elaboration 00052 fu to satisfy SystemC. */ 00053 struct Module : CPPTree::InheritanceRecord, 00054 SCNamedRecord 00055 { 00056 NODE_FUNCTIONS_FINAL 00057 virtual string GetToken() { return "sc_module"; } 00058 }; 00059 00060 /** SystemC interface construct. Not exactly sure whether/how I will use 00061 this. Presumably this is why Module comes from InheritanceRecord not Record. */ 00062 struct Interface : CPPTree::InheritanceRecord, 00063 SCNamedRecord 00064 { 00065 NODE_FUNCTIONS_FINAL 00066 virtual string GetToken() { return "sc_interface"; } 00067 }; 00068 00069 /** Intermediate node for SystemC wait() primitive. wait() can be used 00070 in a few fundamentally different ways and to be explicit we use specialised 00071 nodes for each. All waits must be done in local execution contexts 00072 like threads. Waits allow the SystemC kernel to run other processes. */ 00073 struct Wait : CPPTree::Statement, 00074 SCNamedFunction, 00075 CPPTree::Uncombable 00076 { 00077 NODE_FUNCTIONS 00078 virtual string GetToken() { return "wait"; } 00079 }; 00080 00081 /** Waiting for a SystemC event - blocks until the event indicated by the expression is 00082 triggered, regardless of clocks, deltas etc. Ands and ors etc are probably OK as 00083 the correpsonding boolean expressions on the events. */ 00084 struct WaitDynamic : Wait 00085 { 00086 NODE_FUNCTIONS_FINAL 00087 TreePtr<CPPTree::Expression> event; ///< event to wait for 00088 }; 00089 00090 /** Waiting for a SystemC event - blocks until an event is triggered. I think the event 00091 is specified during elaboration, but I'm not sure if nodes exist for this yet */ 00092 struct WaitStatic : Wait 00093 { 00094 NODE_FUNCTIONS_FINAL 00095 }; 00096 00097 /** Basically a yield. Blocks for a short period of time (a delta cycle) and then continues. 00098 Allows other processes to run immediately. Equivalent to wait(SC_ZERO_TIME) */ 00099 struct WaitDelta : Wait 00100 { 00101 NODE_FUNCTIONS_FINAL 00102 }; 00103 00104 /** Intermediate node for SystemC next_trigger() primitive. next_trigger() can be used 00105 in a few fundamentally different ways and to be explicit we use specialised 00106 nodes for each. All next_triggers must be done in combable contexts like SC_METHOD. 00107 Next_triggers do NOT allow the SystemC kernel to run other processes until 00108 the combable block completes. */ 00109 struct NextTrigger : CPPTree::Statement, 00110 SCNamedFunction 00111 { 00112 NODE_FUNCTIONS 00113 virtual string GetToken() { return "next_trigger"; } 00114 }; 00115 00116 /** Causes the method to be triggered again when the event indicated by the expression is 00117 triggered, regardless of clocks, deltas etc. Ands and ors etc are probably OK as 00118 the correpsonding boolean expressions on the events. */ 00119 struct NextTriggerDynamic : NextTrigger 00120 { 00121 NODE_FUNCTIONS_FINAL 00122 TreePtr<CPPTree::Expression> event; ///< event to wait for 00123 }; 00124 00125 /** Causes the method to be triggered again when an event is triggered. I think the event 00126 is specified during elaboration, but I'm not sure if nodes exist for this yet */ 00127 struct NextTriggerStatic : NextTrigger 00128 { 00129 NODE_FUNCTIONS_FINAL 00130 }; 00131 00132 /** Causes the method to be triggered again very soon after it completes. 00133 Other things run when combable block completes. Equivalent to 00134 next_trigger(SC_ZERO_TIME) */ 00135 struct NextTriggerDelta : NextTrigger 00136 { 00137 NODE_FUNCTIONS_FINAL 00138 }; 00139 00140 /** Triggers the event instance given in the expression. It must be an lvalue of 00141 type Event I would think. This is an intermediate because there are a few 00142 distinct flavours. */ 00143 struct Notify : CPPTree::Statement, 00144 SCNamedFunction 00145 { 00146 NODE_FUNCTIONS 00147 virtual string GetToken() { return "notify"; } 00148 TreePtr<CPPTree::Expression> event; ///< event to notify 00149 }; 00150 00151 /** Notify the event immediately. Not sure if this can force control to go 00152 directly to a waiting process like a function call. Probably not. */ 00153 struct NotifyImmediate : Notify 00154 { 00155 NODE_FUNCTIONS_FINAL 00156 }; 00157 00158 /** Notify the event with a delta cycle delay (SC_ZERO_TIME). */ 00159 struct NotifyDelta : Notify 00160 { 00161 NODE_FUNCTIONS_FINAL 00162 }; 00163 00164 /** Notify the event with a specified time delay. */ 00165 struct NotifyTimed : Notify 00166 { 00167 NODE_FUNCTIONS_FINAL 00168 TreePtr<CPPTree::Expression> time; ///< how long to wait for before notifying 00169 }; 00170 00171 /** Intermediate class for processes, which are the places in SystemC where we 00172 put code. Different final nodes have different invocation and execution models. 00173 Processes look like functions that have no params or return value. */ 00174 struct Process : CPPTree::Subroutine, 00175 SCNamedConstruct 00176 { 00177 NODE_FUNCTIONS 00178 }; 00179 00180 /** Any process that begins or resumes execution in return to events (presumably 00181 including the virtual events created by deltas). Essentially unclocked */ 00182 struct EventProcess : Process 00183 { 00184 NODE_FUNCTIONS 00185 //TODO Collection<Sensitivity> sensitivity; 00186 }; 00187 00188 /** SystemC method process. This must contain a combable block of code. The method 00189 will return when the combinational block has settled and then issued any state 00190 updates. */ 00191 struct Method : EventProcess 00192 { 00193 NODE_FUNCTIONS_FINAL 00194 virtual string GetToken() { return "SC_METHOD"; } 00195 }; 00196 00197 /** SystemC thread process. Local context, so this can run forever (stopping only to indicate completion 00198 of a test run) and may block in wait or run busy for a while. Actually I dont think 00199 the SystemC kernel can pre-empt, so it should not run busy all the time. */ 00200 struct Thread : EventProcess // TODO if SystemC really can't pre-empt, then this should be renamed to Context 00201 // TODO and I should create a real thread support extension because user's threads will run busy sometimes 00202 { 00203 NODE_FUNCTIONS_FINAL 00204 virtual string GetToken() { return "SC_THREAD"; } 00205 }; 00206 00207 /** SystemC clocked thread process. A local context as with Thread, but can only 00208 wait on clock cycles. I forget the advantage of this over Thread. 00209 Sensitivity must be a ClockInPort */ 00210 struct ClockedThread : Process 00211 { 00212 NODE_FUNCTIONS_FINAL 00213 virtual string GetToken() { return "SC_CTHREAD"; } 00214 //TODO TreePtr<Sensitivity> clock; 00215 }; 00216 00217 /** Evaluates to the total number of delta cycles thus far. Can be compared with zero 00218 to produce an inferred reset signal for initialising state machines */ 00219 struct DeltaCount : CPPTree::Operator, 00220 SCNamedFunction // TODO rename as InferredReset() since that will transform more easily to a real reset system 00221 { 00222 NODE_FUNCTIONS_FINAL 00223 virtual string GetToken() { return "sc_delta_count"; } 00224 }; 00225 00226 /// Termination functions 00227 /** These are used to stop the program and produce an exit code because 00228 SystemC does not allow control of the return value from its main 00229 function. */ 00230 struct TerminationFunction : CPPTree::Statement, 00231 SCNamedFunction 00232 { 00233 NODE_FUNCTIONS 00234 TreePtr<CPPTree::Expression> code; ///< exit code for program, 0 to 255 00235 }; 00236 00237 /// The exit() system call; cease() below is preferred. 00238 struct Exit : TerminationFunction 00239 { 00240 NODE_FUNCTIONS_FINAL 00241 virtual string GetToken() { return "exit"; } 00242 }; 00243 00244 /// Cease function 00245 /** an alternative to exit(), supplied by the inferno runtime glue for SC 00246 to complete logging activities etc before calling exit(). */ 00247 struct Cease : TerminationFunction 00248 { 00249 NODE_FUNCTIONS_FINAL 00250 virtual string GetToken() { return "cease"; } 00251 }; 00252 00253 }; 00254 00255 #endif