1/* Copyright (c) 2012 Massachusetts Institute of Technology
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22#include "model/ModelGen.h"
23
24#include <iostream>
25
26#include "model/Model.h"
27// Standard cells
28#include "model/std_cells/StdCell.h"
29#include "model/std_cells/INV.h"
30#include "model/std_cells/NAND2.h"
31#include "model/std_cells/NOR2.h"
32#include "model/std_cells/MUX2.h"
33#include "model/std_cells/XOR2.h"
34#include "model/std_cells/DFFQ.h"
35#include "model/std_cells/LATQ.h"
36#include "model/std_cells/ADDF.h"
37#include "model/std_cells/OR2.h"
38#include "model/std_cells/AND2.h"
39#include "model/std_cells/BUF.h"
40// Electrical functional units
41#include "model/electrical/TestModel.h"
42#include "model/electrical/RippleAdder.h"
43#include "model/electrical/Multiplexer.h"
44#include "model/electrical/MultiplexerCrossbar.h"
45#include "model/electrical/OR.h"
46#include "model/electrical/Decoder.h"
47#include "model/electrical/DFFRAM.h"
48#include "model/electrical/MatrixArbiter.h"
49#include "model/electrical/SeparableAllocator.h"
50#include "model/electrical/router/Router.h"
51#include "model/electrical/RepeatedLink.h"
52#include "model/electrical/BroadcastHTree.h"
53// Optical functional units
54#include "model/optical/OpticalLinkBackendTx.h"
55#include "model/optical/OpticalLinkBackendRx.h"
56#include "model/optical/SWMRLink.h"
57#include "model/optical/SWSRLink.h"
58#include "model/optical/LaserSource.h"
59#include "model/optical/ThrottledLaserSource.h"
60#include "model/optical/RingModulator.h"
61#include "model/optical/RingDetector.h"
62// Networks
63#include "model/network/ElectricalMesh.h"
64#include "model/network/ElectricalClos.h"
65#include "model/network/PhotonicClos.h"
66
67namespace DSENT
68{
69    using std::cout;
70    using std::endl;
71
72    //TODO: Eventually automate the creation of this file
73
74    Model* ModelGen::createModel(const String& model_name_, const String& instance_name_, const TechModel* tech_model_)
75    {
76        Log::printLine("ModelGen::createModel -> " + model_name_);
77
78        if("INV" == model_name_)
79        {
80            return new INV(instance_name_, tech_model_);
81        }
82        else if("NAND2" == model_name_)
83        {
84            return new NAND2(instance_name_, tech_model_);
85        }
86        else if("NOR2" == model_name_)
87        {
88            return new NOR2(instance_name_, tech_model_);
89        }
90        else if("MUX2" == model_name_)
91        {
92            return new MUX2(instance_name_, tech_model_);
93        }
94        else if("XOR2" == model_name_)
95        {
96            return new XOR2(instance_name_, tech_model_);
97        }
98        else if("DFFQ" == model_name_)
99        {
100            return new DFFQ(instance_name_, tech_model_);
101        }
102        else if("LATQ" == model_name_)
103        {
104            return new LATQ(instance_name_, tech_model_);
105        }
106        else if("ADDF" == model_name_)
107        {
108            return new ADDF(instance_name_, tech_model_);
109        }
110        else if("OR2" == model_name_)
111        {
112            return new OR2(instance_name_, tech_model_);
113        }
114        else if("AND2" == model_name_)
115        {
116            return new AND2(instance_name_, tech_model_);
117        }
118        else if("BUF" == model_name_)
119        {
120            return new BUF(instance_name_, tech_model_);
121        }
122        else if("TestModel" == model_name_)
123        {
124            return new TestModel(instance_name_, tech_model_);
125        }
126        else if("RippleAdder" == model_name_)
127        {
128            return new RippleAdder(instance_name_, tech_model_);
129        }
130        else if("Multiplexer" == model_name_)
131        {
132            return new Multiplexer(instance_name_, tech_model_);
133        }
134        else if("OR" == model_name_)
135        {
136            return new OR(instance_name_, tech_model_);
137        }
138        else if("MultiplexerCrossbar" == model_name_)
139        {
140            return new MultiplexerCrossbar(instance_name_, tech_model_);
141        }
142        else if("Decoder" == model_name_)
143        {
144            return new Decoder(instance_name_, tech_model_);
145        }
146        else if("DFFRAM" == model_name_)
147        {
148            return new DFFRAM(instance_name_, tech_model_);
149        }
150        else if("MatrixArbiter" == model_name_)
151        {
152            return new MatrixArbiter(instance_name_, tech_model_);
153        }
154        else if("SeparableAllocator" == model_name_)
155        {
156            return new SeparableAllocator(instance_name_, tech_model_);
157        }
158        else if("Router" == model_name_)
159        {
160            return new Router(instance_name_, tech_model_);
161        }
162        else if("OpticalLinkBackendTx" == model_name_)
163        {
164            return new OpticalLinkBackendTx(instance_name_, tech_model_);
165        }
166        else if("OpticalLinkBackendRx" == model_name_)
167        {
168            return new OpticalLinkBackendRx(instance_name_, tech_model_);
169        }
170        else if("SWMRLink" == model_name_)
171        {
172            return new SWMRLink(instance_name_, tech_model_);
173        }
174        else if("SWSRLink" == model_name_)
175        {
176            return new SWSRLink(instance_name_, tech_model_);
177        }
178        else if("LaserSource" == model_name_)
179        {
180            return new LaserSource(instance_name_, tech_model_);
181        }
182        else if("ThrottledLaserSource" == model_name_)
183        {
184            return new ThrottledLaserSource(instance_name_, tech_model_);
185        }
186        else if("RingModulator" == model_name_)
187        {
188            return new RingModulator(instance_name_, tech_model_);
189        }
190        else if("RingDetector" == model_name_)
191        {
192            return new RingDetector(instance_name_, tech_model_);
193        }
194        else if("RepeatedLink" == model_name_)
195        {
196            return new RepeatedLink(instance_name_, tech_model_);
197        }
198        else if("BroadcastHTree" == model_name_)
199        {
200            return new BroadcastHTree(instance_name_, tech_model_);
201        }
202        else if("ElectricalMesh" == model_name_)
203        {
204            return new ElectricalMesh(instance_name_, tech_model_);
205        }
206        else if("ElectricalClos" == model_name_)
207        {
208            return new ElectricalClos(instance_name_, tech_model_);
209        }
210        else if("PhotonicClos" == model_name_)
211        {
212            return new PhotonicClos(instance_name_, tech_model_);
213        }
214        else
215        {
216            const String& error_msg = "[Error] Invalid model name (" + model_name_ + ")";
217            throw Exception(error_msg);
218            return NULL;
219        }
220        return NULL;
221    }
222
223    StdCell* ModelGen::createStdCell(const String& std_cell_name_, const String& instance_name_, const TechModel* tech_model_)
224    {
225        Log::printLine("ModelGen::createStdCell -> " + std_cell_name_);
226
227        if("INV" == std_cell_name_)
228        {
229            return new INV(instance_name_, tech_model_);
230        }
231        else if("NAND2" == std_cell_name_)
232        {
233            return new NAND2(instance_name_, tech_model_);
234        }
235        else if("NOR2" == std_cell_name_)
236        {
237            return new NOR2(instance_name_, tech_model_);
238        }
239        else if("MUX2" == std_cell_name_)
240        {
241            return new MUX2(instance_name_, tech_model_);
242        }
243        else if("XOR2" == std_cell_name_)
244        {
245            return new XOR2(instance_name_, tech_model_);
246        }
247        else if("DFFQ" == std_cell_name_)
248        {
249            return new DFFQ(instance_name_, tech_model_);
250        }
251        else if("LATQ" == std_cell_name_)
252        {
253            return new LATQ(instance_name_, tech_model_);
254        }
255        else if("ADDF" == std_cell_name_)
256        {
257            return new ADDF(instance_name_, tech_model_);
258        }
259        else if("OR2" == std_cell_name_)
260        {
261            return new OR2(instance_name_, tech_model_);
262        }
263        else if("AND2" == std_cell_name_)
264        {
265            return new AND2(instance_name_, tech_model_);
266        }
267        else if("BUF" == std_cell_name_)
268        {
269            return new BUF(instance_name_, tech_model_);
270        }
271        else
272        {
273            const String& error_msg = "[Error] Invalid Standard Cell name (" + std_cell_name_ + ")";
274            throw Exception(error_msg);
275            return NULL;
276        }
277        return NULL;
278    }
279
280    ElectricalModel* ModelGen::createRAM(const String& ram_name_, const String& instance_name_, const TechModel* tech_model_)
281    {
282        Log::printLine("ModelGen::createRAM -> " + ram_name_);
283
284        if("DFFRAM" == ram_name_)
285        {
286            return new DFFRAM(instance_name_, tech_model_);
287        }
288        else
289        {
290            const String& error_msg = "[Error] Invalid RAM name (" + ram_name_ + ")";
291            throw Exception(error_msg);
292            return NULL;
293        }
294        return NULL;
295    }
296
297    ElectricalModel* ModelGen::createCrossbar(const String& crossbar_name_, const String& instance_name_, const TechModel* tech_model_)
298    {
299        Log::printLine("ModelGen::createCrossbar -> " + crossbar_name_);
300
301        if("MultiplexerCrossbar" == crossbar_name_)
302        {
303            return new MultiplexerCrossbar(instance_name_, tech_model_);
304        }
305        else
306        {
307            const String& error_msg = "[Error] Invalid Crossbar name (" + crossbar_name_ + ")";
308            throw Exception(error_msg);
309            return NULL;
310        }
311        return NULL;
312    }
313    //-----------------------------------------------------------------
314
315    void ModelGen::printAvailableModels()
316    {
317        // TODO: Need more descriptions
318        cout << "INV NAND2 NOR2 MUX2 XOR2 DFFQ LATQ ADDF OR2 AND2 BUF" << endl;
319        cout << "RippleAdder Multiplexer OR RepeatedLink BroadcastHTree" << endl;
320        cout << "MultiplexerCrossbar Decoder DFFRAM MatrixArbiter SeparableAllocator Router" << endl;
321        cout << "OpticalLinkBackendTx OpticalLinkBackendRx SWMRLink SWSRLink" << endl;
322        cout << "LaserSource ThrottledLaserSource RingModulator RingDetector" << endl;
323        cout << "ElectricalMesh ElectricalClos PhotonicClos" << endl;
324        return;
325    }
326} // namespace DSENT
327
328