ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ndr.h
Go to the documentation of this file.
1
20
21#ifndef ABC__base__ndr__ndr_h
22#define ABC__base__ndr__ndr_h
23
24
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33
34#include "abcOper.h"
35
36#ifndef _YOSYS_
38#endif
39
40#ifdef _WIN32
41#define inline __inline
42#endif
43
44/*
45 For the lack of a better name, this format is called New Data Representation (NDR).
46
47 NDR is designed as an interchange format to pass hierarchical word-level designs between the tools.
48 It is relatively simple, uses little memory, and can be easily converted into other ABC data-structures.
49
50 This tutorial discusses how to construct the NDR representation of a hierarchical word-level design.
51
52 First, all names used in the design (including the design name, module names, port names, net names,
53 instance names, etc) are hashed into 1-based integers called "name IDs". Nets are not explicitly represented.
54 The connectivity of a design object is established by specifying name IDs of the nets connected to the object.
55 Object inputs are name IDs of the driving nets; object outputs are name IDs of the driven nets.
56
57 The design is initialized using procedure Ndr_Create(), which takes the design name as an argument.
58 A module in the design is initialized using procedure Ndr_AddModule(), which takes the design and
59 the module name as arguments. Objects are added to a module in any order using procedure Ndr_AddObject().
60
61 Primary input and primary output objects should be explicitly created, as shown in the examples below.
62
63 Instances of known operators listed in file "abcOper.h" are assumed to have one output. The only known
64 issue due to this restriction concerns the adder, which produces the sum and the carry-out. To make sure the
65 adder instance has only one output, the carry-out has to be concatenated with the sum before the adder
66 instance is created in the NDR format.
67
68 Instances of hierarchical modules defined by the user can have multiple outputs.
69
70 Bit-slice and concatenation operators should be represented as separate objects.
71
72 If the ordering of inputs/outputs/flops of a module is not provided as a separate record in NDR format,
73 their ordering is determined by the order of their appearance in the NDR description of the module.
74
75 If left limit and right limit of a bit-range are equal, it is assumed that the range contains one bit
76
77 Word-level constants are represented as char-strings given in the same way as they would appear in a Verilog
78 file. For example, the 16-bit constant 10 is represented as a string "4'b1010" and is given as an argument
79 (char * pFunction) to the procedure Ndr_AddObject().
80
81 Currently two types of flops are supported: a simple flop with implicit clock and two fanins (data and init)
82 and a complex flop with 8 fanins (clock, data, reset, set, enable, async, sre, init), as shown in the examples below.
83
84 The initial value of a flop is represented by input "init", which can be driven by a constant or by a primary
85 input of the module. If it is a primary input, is it assumed that the flop is not initialized. If the input
86 "init" is not driven, it is assumed that the flop is initialized to 0.
87
88 Memory read and write ports are supported, as shown in the example below.
89
90 (to be continued)
91*/
92
96
97// record types
98typedef enum {
99 NDR_NONE = 0, // 0: unused
100 NDR_DESIGN, // 1: design (or library of modules)
101 NDR_MODULE, // 2: one module
102 NDR_OBJECT, // 3: object
103 NDR_INPUT, // 4: input
104 NDR_OUTPUT, // 5: output
105 NDR_OPERTYPE, // 6: operator type (buffer, shifter, adder, etc)
106 NDR_NAME, // 7: name
107 NDR_RANGE, // 8: bit range
108 NDR_FUNCTION, // 9: specified for some operators (PLAs, etc)
109 NDR_TARGET, // 10: target
110 NDR_UNKNOWN // 11: unknown
112
113
117
118// this is an internal procedure, which is not seen by the user
119typedef struct Ndr_Data_t_ Ndr_Data_t;
121{
122 int nSize;
123 int nCap;
124 unsigned char * pHead;
125 unsigned int * pBody;
126};
127
128static inline int Ndr_DataType( Ndr_Data_t * p, int i ) { assert( p->pHead[i] ); return (int)p->pHead[i]; }
129static inline int Ndr_DataSize( Ndr_Data_t * p, int i ) { return Ndr_DataType(p, i) > NDR_OBJECT ? 1 : p->pBody[i]; }
130static inline int Ndr_DataEntry( Ndr_Data_t * p, int i ) { return (int)p->pBody[i]; }
131static inline int * Ndr_DataEntryP( Ndr_Data_t * p, int i ) { return (int *)p->pBody + i; }
132static inline int Ndr_DataEnd( Ndr_Data_t * p, int i ) { return i + p->pBody[i]; }
133static inline void Ndr_DataAddTo( Ndr_Data_t * p, int i, int Add ) { assert(Ndr_DataType(p, i) <= NDR_OBJECT); p->pBody[i] += Add; }
134static inline void Ndr_DataPush( Ndr_Data_t * p, int Type, int Entry ) { p->pHead[p->nSize] = Type; p->pBody[p->nSize++] = Entry; }
135
136#define NDR_ALLOC(type, num) ((type *) malloc(sizeof(type) * (size_t)(num)))
137
141
142// iterates over modules in the design
143#define Ndr_DesForEachMod( p, Mod ) \
144 for ( Mod = 1; Mod < Ndr_DataEntry(p, 0); Mod += Ndr_DataSize(p, Mod) ) if (Ndr_DataType(p, Mod) != NDR_MODULE) {} else
145
146// iterates over objects in a module
147#define Ndr_ModForEachObj( p, Mod, Obj ) \
148 for ( Obj = Mod + 1; Obj < Ndr_DataEnd(p, Mod); Obj += Ndr_DataSize(p, Obj) ) if (Ndr_DataType(p, Obj) != NDR_OBJECT) {} else
149
150// iterates over records in an object
151#define Ndr_ObjForEachEntry( p, Obj, Ent ) \
152 for ( Ent = Obj + 1; Ent < Ndr_DataEnd(p, Obj); Ent += Ndr_DataSize(p, Ent) )
153
154// iterates over primary inputs of a module
155#define Ndr_ModForEachPi( p, Mod, Obj ) \
156 Ndr_ModForEachObj( p, Mod, Obj ) if ( !Ndr_ObjIsType(p, Obj, ABC_OPER_CI) ) {} else
157
158// iteraots over primary outputs of a module
159#define Ndr_ModForEachPo( p, Mod, Obj ) \
160 Ndr_ModForEachObj( p, Mod, Obj ) if ( !Ndr_ObjIsType(p, Obj, ABC_OPER_CO) ) {} else
161
162// iterates over internal nodes of a module
163#define Ndr_ModForEachNode( p, Mod, Obj ) \
164 Ndr_ModForEachObj( p, Mod, Obj ) if ( Ndr_ObjIsType(p, Obj, ABC_OPER_CI) || Ndr_ObjIsType(p, Obj, ABC_OPER_CO) ) {} else
165
166// iterates over target signals of a module
167#define Ndr_ModForEachTarget( p, Mod, Obj ) \
168 for ( Obj = Mod + 1; Obj < Ndr_DataEnd(p, Mod); Obj += Ndr_DataSize(p, Obj) ) if (Ndr_DataType(p, Obj) != NDR_TARGET) {} else
169
173
174
175static inline void Ndr_DataResize( Ndr_Data_t * p, int Add )
176{
177 if ( p->nSize + Add <= p->nCap )
178 return;
179 p->nCap = 2 * p->nCap > p->nSize + Add ? 2 * p->nCap : p->nSize + Add;
180 p->pHead = (unsigned char*)realloc( p->pHead, p->nCap );
181 p->pBody = (unsigned int *)realloc( p->pBody, 4*p->nCap );
182}
183static inline void Ndr_DataPushRange( Ndr_Data_t * p, int RangeLeft, int RangeRight, int fSignedness )
184{
185 if ( fSignedness )
186 {
187 Ndr_DataPush( p, NDR_RANGE, RangeLeft );
188 Ndr_DataPush( p, NDR_RANGE, RangeRight );
189 Ndr_DataPush( p, NDR_RANGE, fSignedness );
190 return;
191 }
192 if ( !RangeLeft && !RangeRight )
193 return;
194 if ( RangeLeft == RangeRight )
195 Ndr_DataPush( p, NDR_RANGE, RangeLeft );
196 else
197 {
198 Ndr_DataPush( p, NDR_RANGE, RangeLeft );
199 Ndr_DataPush( p, NDR_RANGE, RangeRight );
200 }
201}
202static inline void Ndr_DataPushArray( Ndr_Data_t * p, int Type, int nArray, int * pArray )
203{
204 if ( !nArray )
205 return;
206 assert( nArray > 0 );
207 Ndr_DataResize( p, nArray );
208 memset( p->pHead + p->nSize, Type, (size_t)nArray );
209 memcpy( p->pBody + p->nSize, pArray, (size_t)4*nArray );
210 p->nSize += nArray;
211}
212static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, char * pFunc )
213{
214 int nBuffInts;
215 int * pBuff;
216 if ( !pFunc )
217 return;
218 if ( ObjType == ABC_OPER_LUT )
219 {
220 //word Truth = (word)pFunc;
221 //Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
222 int nInts = (strlen(pFunc) + 1 + sizeof(int) - 1) / sizeof(int);
223 Ndr_DataPushArray( p, Type, nInts, (int *)&pFunc );
224 }
225 else
226 {
227 nBuffInts = ((int)strlen(pFunc) + 4) / 4;
228 pBuff = (int *)calloc( 1, 4*nBuffInts );
229 memcpy( pBuff, pFunc, strlen(pFunc) );
230 Ndr_DataPushArray( p, Type, nBuffInts, pBuff );
231 free( pBuff );
232 }
233}
234
238
239static inline int Ndr_ObjReadEntry( Ndr_Data_t * p, int Obj, int Type )
240{
241 int Ent;
242 Ndr_ObjForEachEntry( p, Obj, Ent )
243 if ( Ndr_DataType(p, Ent) == Type )
244 return Ndr_DataEntry(p, Ent);
245 return -1;
246}
247static inline int Ndr_ObjReadArray( Ndr_Data_t * p, int Obj, int Type, int ** ppStart )
248{
249 int Ent, Counter = 0; *ppStart = NULL;
250 Ndr_ObjForEachEntry( p, Obj, Ent )
251 if ( Ndr_DataType(p, Ent) == Type )
252 {
253 Counter++;
254 if ( *ppStart == NULL )
255 *ppStart = (int *)p->pBody + Ent;
256 }
257 else if ( *ppStart )
258 return Counter;
259 return Counter;
260}
261static inline int Ndr_ObjIsType( Ndr_Data_t * p, int Obj, int Type )
262{
263 int Ent;
264 Ndr_ObjForEachEntry( p, Obj, Ent )
265 if ( Ndr_DataType(p, Ent) == NDR_OPERTYPE )
266 return (int)(Ndr_DataEntry(p, Ent) == Type);
267 return -1;
268}
269static inline int Ndr_ObjReadBody( Ndr_Data_t * p, int Obj, int Type )
270{
271 int Ent;
272 Ndr_ObjForEachEntry( p, Obj, Ent )
273 if ( Ndr_DataType(p, Ent) == Type )
274 return Ndr_DataEntry(p, Ent);
275 return -1;
276}
277static inline int * Ndr_ObjReadBodyP( Ndr_Data_t * p, int Obj, int Type )
278{
279 int Ent;
280 Ndr_ObjForEachEntry( p, Obj, Ent )
281 if ( Ndr_DataType(p, Ent) == Type )
282 return Ndr_DataEntryP(p, Ent);
283 return NULL;
284}
285static inline void Ndr_ObjWriteRange( Ndr_Data_t * p, int Obj, FILE * pFile, int fSkipBin )
286{
287 int * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_RANGE, &pArray );
288 if ( (nArray == 0 || nArray == 1) && fSkipBin )
289 return;
290 if ( nArray == 3 && fSkipBin )
291 fprintf( pFile, "signed " );
292 else if ( nArray == 1 )
293 {
294 if ( fSkipBin )
295 fprintf( pFile, "[%d:%d]", pArray[0], pArray[0] );
296 else
297 fprintf( pFile, "[%d]", pArray[0] );
298 }
299 else if ( nArray == 0 )
300 {
301 if ( fSkipBin )
302 fprintf( pFile, "[%d:%d]", 0, 0 );
303 else
304 fprintf( pFile, "[%d]", 0 );
305 }
306 else
307 fprintf( pFile, "[%d:%d]", pArray[0], pArray[1] );
308}
309static inline char * Ndr_ObjReadOutName( Ndr_Data_t * p, int Obj, char ** pNames )
310{
311 return pNames[Ndr_ObjReadBody(p, Obj, NDR_OUTPUT)];
312}
313static inline char * Ndr_ObjReadInName( Ndr_Data_t * p, int Obj, char ** pNames )
314{
315 return pNames[Ndr_ObjReadBody(p, Obj, NDR_INPUT)];
316}
317
318static inline int Ndr_DataCiNum( Ndr_Data_t * p, int Mod )
319{
320 int Obj, Count = 0;
321 Ndr_ModForEachPi( p, Mod, Obj )
322 Count++;
323 return Count;
324}
325static inline int Ndr_DataCoNum( Ndr_Data_t * p, int Mod )
326{
327 int Obj, Count = 0;
328 Ndr_ModForEachPo( p, Mod, Obj )
329 Count++;
330 return Count;
331}
332static inline int Ndr_DataObjNum( Ndr_Data_t * p, int Mod )
333{
334 int Obj, Count = 0;
335 Ndr_ModForEachObj( p, Mod, Obj )
336 Count++;
337 return Count;
338}
339
340// to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames)
341static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod, char ** pNames, int fSimple )
342{
343 Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
344 int * pOuts = NDR_ALLOC( int, Ndr_DataCoNum(p, Mod) );
345 int i, k, Obj, nArray, * pArray, fFirst = 1;
346
347 fprintf( pFile, "\nmodule %s (\n ", pNames[Ndr_ObjReadEntry(p, Mod, NDR_NAME)] );
348
349 Ndr_ModForEachPi( p, Mod, Obj )
350 fprintf( pFile, "%s, ", Ndr_ObjReadOutName(p, Obj, pNames) );
351
352 fprintf( pFile, "\n " );
353
354 Ndr_ModForEachPo( p, Mod, Obj )
355 fprintf( pFile, "%s%s", fFirst ? "":", ", Ndr_ObjReadInName(p, Obj, pNames) ), fFirst = 0;
356
357 fprintf( pFile, "\n);\n\n" );
358
359 Ndr_ModForEachPi( p, Mod, Obj )
360 {
361 fprintf( pFile, " input " );
362 Ndr_ObjWriteRange( p, Obj, pFile, 1 );
363 fprintf( pFile, " %s;\n", Ndr_ObjReadOutName(p, Obj, pNames) );
364 }
365
366 i = 0;
367 Ndr_ModForEachPo( p, Mod, Obj )
368 {
369 fprintf( pFile, " output " );
370 Ndr_ObjWriteRange( p, Obj, pFile, 1 );
371 fprintf( pFile, " %s;\n", Ndr_ObjReadInName(p, Obj, pNames) );
372 pOuts[i++] = Ndr_ObjReadBody(p, Obj, NDR_INPUT);
373 }
374
375 fprintf( pFile, "\n" );
376
377 Ndr_ModForEachNode( p, Mod, Obj )
378 {
379 for ( k = 0; k < i; k++ )
380 if ( pOuts[k] == Ndr_ObjReadBody(p, Obj, NDR_OUTPUT) )
381 break;
382 if ( k < i )
383 continue;
384 if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' )
385 continue;
386 fprintf( pFile, " wire " );
387 Ndr_ObjWriteRange( p, Obj, pFile, 1 );
388 fprintf( pFile, " %s;\n", Ndr_ObjReadOutName(p, Obj, pNames) );
389 }
390 free( pOuts );
391
392 fprintf( pFile, "\n" );
393
394 Ndr_ModForEachNode( p, Mod, Obj )
395 {
396 int i, Type = Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE);
397 if ( Type >= 256 )
398 {
399 fprintf( pFile, " %s ", pNames[Ndr_ObjReadEntry(p, Type-256, NDR_NAME)] );
400 if ( Ndr_ObjReadBody(p, Obj, NDR_NAME) > 0 )
401 fprintf( pFile, "%s ", pNames[Ndr_ObjReadBody(p, Obj, NDR_NAME)] );
402 fprintf( pFile, "( " );
403 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
404 for ( i = 0; i < nArray; i++ )
405 fprintf( pFile, "%s%s ", pNames[pArray[i]], i==nArray-1 ? "":"," );
406 fprintf( pFile, ");\n" );
407 continue;
408 }
409 if ( Type == ABC_OPER_DFF )
410 {
411 fprintf( pFile, " %s ", "ABC_DFF" );
412 if ( Ndr_ObjReadBody(p, Obj, NDR_NAME) > 0 )
413 fprintf( pFile, "%s ", pNames[Ndr_ObjReadBody(p, Obj, NDR_NAME)] );
414 fprintf( pFile, "( " );
415 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
416 fprintf( pFile, ".q(%s), ", Ndr_ObjReadOutName(p, Obj, pNames) );
417 fprintf( pFile, ".d(%s), ", pNames[pArray[0]] );
418 fprintf( pFile, ".init(%s) ", pNames[pArray[1]] );
419 fprintf( pFile, ");\n" );
420 continue;
421 }
422 if ( Type == ABC_OPER_DFFRSE )
423 {
424 fprintf( pFile, " %s ", "ABC_DFFRSE" );
425 if ( Ndr_ObjReadBody(p, Obj, NDR_NAME) > 0 )
426 fprintf( pFile, "%s ", pNames[Ndr_ObjReadBody(p, Obj, NDR_NAME)] );
427 fprintf( pFile, "( " );
428 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
429 fprintf( pFile, ".q(%s), ", Ndr_ObjReadOutName(p, Obj, pNames) );
430 fprintf( pFile, ".d(%s), ", pNames[pArray[0]] );
431 fprintf( pFile, ".clk(%s), ", pNames[pArray[1]] );
432 fprintf( pFile, ".reset(%s), ", pNames[pArray[2]] );
433 fprintf( pFile, ".set(%s), ", pNames[pArray[3]] );
434 fprintf( pFile, ".enable(%s), ", pNames[pArray[4]] );
435 fprintf( pFile, ".async(%s), ", pNames[pArray[5]] );
436 fprintf( pFile, ".sre(%s), ", pNames[pArray[6]] );
437 fprintf( pFile, ".init(%s) ", pNames[pArray[7]] );
438 fprintf( pFile, ");\n" );
439 continue;
440 }
441 if ( Type == ABC_OPER_RAMR )
442 {
443 fprintf( pFile, " %s ", "ABC_READ" );
444 if ( Ndr_ObjReadBody(p, Obj, NDR_NAME) > 0 )
445 fprintf( pFile, "%s ", pNames[Ndr_ObjReadBody(p, Obj, NDR_NAME)] );
446 fprintf( pFile, "( " );
447 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
448 fprintf( pFile, ".data(%s), ", Ndr_ObjReadOutName(p, Obj, pNames) );
449 fprintf( pFile, ".mem_in(%s), ", pNames[pArray[0]] );
450 fprintf( pFile, ".addr(%s) ", pNames[pArray[1]] );
451 fprintf( pFile, ");\n" );
452 continue;
453 }
454 if ( Type == ABC_OPER_RAMW )
455 {
456 fprintf( pFile, " %s ", "ABC_WRITE" );
457 if ( Ndr_ObjReadBody(p, Obj, NDR_NAME) > 0 )
458 fprintf( pFile, "%s ", pNames[Ndr_ObjReadBody(p, Obj, NDR_NAME)] );
459 fprintf( pFile, "( " );
460 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
461 fprintf( pFile, ".mem_out(%s), ", Ndr_ObjReadOutName(p, Obj, pNames) );
462 fprintf( pFile, ".mem_in(%s), ", pNames[pArray[0]] );
463 fprintf( pFile, ".addr(%s), ", pNames[pArray[1]] );
464 fprintf( pFile, ".data(%s) ", pNames[pArray[2]] );
465 fprintf( pFile, ");\n" );
466 continue;
467 }
468 if ( fSimple )
469 {
470 if ( Ndr_ObjReadOutName(p, Obj, pNames)[0] == '1' )
471 continue;
472 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
473 fprintf( pFile, " %s ( %s", Abc_OperNameSimple(Type), Ndr_ObjReadOutName(p, Obj, pNames) );
474 if ( nArray == 0 )
475 fprintf( pFile, ", %s );\n", (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) );
476 else if ( nArray == 1 && Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE) == ABC_OPER_BIT_BUF )
477 fprintf( pFile, ", %s );\n", pNames[pArray[0]] );
478 else
479 {
480 for ( i = 0; i < nArray; i++ )
481 fprintf( pFile, ", %s", pNames[pArray[i]] );
482 fprintf( pFile, " );\n" );
483 }
484 continue;
485 }
486 fprintf( pFile, " assign %s = ", Ndr_ObjReadOutName(p, Obj, pNames) );
487 nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
488 if ( nArray == 0 )
489 fprintf( pFile, "%s;\n", (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) );
490 else if ( nArray == 1 && Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE) == ABC_OPER_BIT_BUF )
491 fprintf( pFile, "%s;\n", pNames[pArray[0]] );
492 else if ( Type == ABC_OPER_SLICE )
493 fprintf( pFile, "%s", pNames[pArray[0]] ),
494 Ndr_ObjWriteRange( p, Obj, pFile, 0 ),
495 fprintf( pFile, ";\n" );
496 else if ( Type == ABC_OPER_CONCAT )
497 {
498 fprintf( pFile, "{" );
499 for ( i = 0; i < nArray; i++ )
500 fprintf( pFile, "%s%s", pNames[pArray[i]], i==nArray-1 ? "":", " );
501 fprintf( pFile, "};\n" );
502 }
503 else if ( nArray == 1 )
504 fprintf( pFile, "%s %s;\n", Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)), pNames[pArray[0]] );
505 else if ( nArray == 2 )
506 fprintf( pFile, "%s %s %s;\n", pNames[pArray[0]], Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)), pNames[pArray[1]] );
507 else if ( nArray == 3 && Type == ABC_OPER_ARI_ADD )
508 fprintf( pFile, "%s + %s + %s;\n", pNames[pArray[0]], pNames[pArray[1]], pNames[pArray[2]] );
509 else if ( Type == ABC_OPER_BIT_MUX )
510 fprintf( pFile, "%s ? %s : %s;\n", pNames[pArray[0]], pNames[pArray[2]], pNames[pArray[1]] );
511 else
512 fprintf( pFile, "<cannot write operation %s>;\n", Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)) );
513 }
514
515 fprintf( pFile, "\nendmodule\n\n" );
516}
517
518// to write signal names, this procedure takes a mapping of name IDs into actual char-strings (pNames)
519static inline void Ndr_WriteVerilog( char * pFileName, void * pDesign, char ** pNames, int fSimple )
520{
521 Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int Mod;
522
523 FILE * pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
524 if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; }
525
526 Ndr_DesForEachMod( p, Mod )
527 Ndr_WriteVerilogModule( pFile, p, Mod, pNames, fSimple );
528
529 if ( pFileName ) fclose( pFile );
530}
531
532
536
537// creating a new module (returns pointer to the memory buffer storing the module info)
538static inline void * Ndr_Create( int Name )
539{
541 p->nSize = 0;
542 p->nCap = 16;
543 p->pHead = NDR_ALLOC( unsigned char, p->nCap );
544 p->pBody = NDR_ALLOC( unsigned int, p->nCap * 4 );
545 Ndr_DataPush( p, NDR_DESIGN, 0 );
546 Ndr_DataPush( p, NDR_NAME, Name );
547 Ndr_DataAddTo( p, 0, p->nSize );
548 assert( p->nSize == 2 );
549 assert( Name );
550 return p;
551}
552
553// creating a new module in an already started design
554// returns module ID to be used when adding objects to the module
555static inline int Ndr_AddModule( void * pDesign, int Name )
556{
557 Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
558 int Mod = p->nSize;
559 Ndr_DataResize( p, 6 );
560 Ndr_DataPush( p, NDR_MODULE, 0 );
561 Ndr_DataPush( p, NDR_NAME, Name );
562 Ndr_DataAddTo( p, Mod, p->nSize - Mod );
563 Ndr_DataAddTo( p, 0, p->nSize - Mod );
564 assert( (int)p->pBody[0] == p->nSize );
565 return Mod + 256;
566}
567
568// adding a new object (input/output/flop/intenal node) to an already started module
569// this procedure takes the design, the module ID, and the parameters of the boject
570// (please note that all objects should be added to a given module before starting a new module)
571static inline void Ndr_AddObject( void * pDesign, int ModuleId,
572 int ObjType, int InstName,
573 int RangeLeft, int RangeRight, int fSignedness,
574 int nInputs, int * pInputs,
575 int nOutputs, int * pOutputs,
576 char * pFunction )
577{
578 Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
579 int Mod = ModuleId - 256;
580 int Obj = p->nSize; assert( ObjType != 0 );
581 Ndr_DataResize( p, 6 );
582 Ndr_DataPush( p, NDR_OBJECT, 0 );
583 Ndr_DataPush( p, NDR_OPERTYPE, ObjType );
584 Ndr_DataPushRange( p, RangeLeft, RangeRight, fSignedness );
585 if ( InstName )
586 Ndr_DataPush( p, NDR_NAME, InstName );
587 Ndr_DataPushArray( p, NDR_INPUT, nInputs, pInputs );
588 Ndr_DataPushArray( p, NDR_OUTPUT, nOutputs, pOutputs );
589 Ndr_DataPushString( p, ObjType, NDR_FUNCTION, pFunction );
590 Ndr_DataAddTo( p, Obj, p->nSize - Obj );
591 Ndr_DataAddTo( p, Mod, p->nSize - Obj );
592 Ndr_DataAddTo( p, 0, p->nSize - Obj );
593 assert( (int)p->pBody[0] == p->nSize );
594}
595
596// deallocate the memory buffer
597static inline void Ndr_Delete( void * pDesign )
598{
599 Ndr_Data_t * p = (Ndr_Data_t *)pDesign;
600 if ( !p ) return;
601 free( p->pHead );
602 free( p->pBody );
603 free( p );
604}
605
606
610
611// file reading/writing
612static inline void * Ndr_Read( char * pFileName )
613{
614 Ndr_Data_t * p; int nFileSize, RetValue;
615 FILE * pFile = fopen( pFileName, "rb" );
616 if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for reading.\n", pFileName ); return NULL; }
617 // check file size
618 fseek( pFile, 0, SEEK_END );
619 nFileSize = ftell( pFile );
620 if ( nFileSize % 5 != 0 )
621 return NULL;
622 assert( nFileSize % 5 == 0 );
623 rewind( pFile );
624 // create structure
625 p = NDR_ALLOC( Ndr_Data_t, 1 );
626 p->nSize = p->nCap = nFileSize / 5;
627 p->pHead = NDR_ALLOC( unsigned char, p->nCap );
628 p->pBody = NDR_ALLOC( unsigned int, p->nCap * 4 );
629 RetValue = (int)fread( p->pBody, 4, p->nCap, pFile );
630 RetValue = (int)fread( p->pHead, 1, p->nCap, pFile );
631 assert( p->nSize == (int)p->pBody[0] );
632 fclose( pFile );
633 //printf( "Read the design from file \"%s\".\n", pFileName );
634 return p;
635}
636static inline void Ndr_Write( char * pFileName, void * pDesign )
637{
638 Ndr_Data_t * p = (Ndr_Data_t *)pDesign; int RetValue;
639 FILE * pFile = fopen( pFileName, "wb" );
640 if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for writing.\n", pFileName ? pFileName : "stdout" ); return; }
641 RetValue = (int)fwrite( p->pBody, 4, p->pBody[0], pFile );
642 RetValue = (int)fwrite( p->pHead, 1, p->pBody[0], pFile );
643 fclose( pFile );
644 //printf( "Dumped the design into file \"%s\".\n", pFileName );
645}
646
647
651
652// This testing procedure creates and writes into a Verilog file
653// the following design composed of one module
654
655// module add10 ( input [3:0] a, output [3:0] s );
656// wire [3:0] const10 = 4'b1010;
657// assign s = a + const10;
658// endmodule
659
660static inline void Ndr_ModuleTest()
661{
662 // name IDs
663 int NameIdA = 2;
664 int NameIdS = 3;
665 int NameIdC = 4;
666 // array of fanins of node s
667 int Fanins[2] = { NameIdA, NameIdC };
668 // map name IDs into char strings
669 //char * ppNames[5] = { NULL, "add10", "a", "s", "const10" };
670
671 // create a new module
672 void * pDesign = Ndr_Create( 1 );
673
674 int ModuleID = Ndr_AddModule( pDesign, 1 );
675
676 // add objects to the modele
677 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdA, NULL ); // no fanins
678 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONST, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, (char*)"4'b1010" ); // no fanins
679 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 3, 0, 0, 2, Fanins, 1, &NameIdS, NULL ); // fanins are a and const10
680 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdS, 0, NULL, NULL ); // fanin is a
681
682 // write Verilog for verification
683 //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
684 Ndr_Write( (char*)"add4.ndr", pDesign );
685 Ndr_Delete( pDesign );
686}
687
688
689
690// This testing procedure creates and writes into a Verilog file
691// the following design composed of one adder divided into two
692
693// module add8 ( input [7:0] a, input [7:0] b, output [7:0] s, output co );
694// wire [3:0] a0 = a[3:0];
695// wire [3:0] b0 = b[3:0];
696
697// wire [7:4] a1 = a[7:4];
698// wire [7:4] b1 = b[7:4];
699
700// wire [4:0] r0 = a0 + b0;
701// wire [3:0] s0 = r0[3:0];
702// wire rco = r0[4];
703
704// wire [4:0] r1 = a1 + b1 + rco;
705// wire [3:0] s1 = r1[3:0];
706// assign co = r1[4];
707
708// assign s = {s1, s0};
709// endmodule
710
711static inline void Ndr_ModuleTestAdder()
712{
713/*
714 // map name IDs into char strings
715 char * ppNames[20] = { NULL,
716 "a", "b", "s", "co", // 1, 2, 3, 4
717 "a0", "a1", "b0", "b1", // 5, 6, 7, 8
718 "r0", "s0", "rco", // 9, 10, 11
719 "r1", "s1", "add8" // 12, 13, 14
720 };
721*/
722 // fanins
723 int FaninA = 1;
724 int FaninB = 2;
725 int FaninS = 3;
726 int FaninCO = 4;
727
728 int FaninA0 = 5;
729 int FaninA1 = 6;
730 int FaninB0 = 7;
731 int FaninB1 = 8;
732
733 int FaninR0 = 9;
734 int FaninS0 = 10;
735 int FaninRCO = 11;
736
737 int FaninR1 = 12;
738 int FaninS1 = 13;
739
740 int Fanins1[2] = { FaninA0, FaninB0 };
741 int Fanins2[3] = { FaninA1, FaninB1, FaninRCO };
742 int Fanins3[4] = { FaninS1, FaninS0 };
743
744 // create a new module
745 void * pDesign = Ndr_Create( 14 );
746
747 int ModuleID = Ndr_AddModule( pDesign, 14 );
748
749 // add objects to the modele
750 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 7, 0, 0, 0, NULL, 1, &FaninA, NULL ); // no fanins
751 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 7, 0, 0, 0, NULL, 1, &FaninB, NULL ); // no fanins
752
753 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninA, 1, &FaninA0, NULL ); // wire [3:0] a0 = a[3:0];
754 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninB, 1, &FaninB0, NULL ); // wire [3:0] b0 = a[3:0];
755
756 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 7, 4, 0, 1, &FaninA, 1, &FaninA1, NULL ); // wire [7:4] a1 = a[7:4];
757 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 7, 4, 0, 1, &FaninB, 1, &FaninB1, NULL ); // wire [7:4] b1 = b[7:4];
758
759 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 4, 0, 0, 2, Fanins1, 1, &FaninR0, NULL ); // wire [4:0] r0 = a0 + b0;
760 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninR0, 1, &FaninS0, NULL ); // wire [3:0] s0 = r0[3:0];
761 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 4, 4, 0, 1, &FaninR0, 1, &FaninRCO, NULL ); // wire rco = r0[4];
762
763 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 4, 0, 0, 3, Fanins2, 1, &FaninR1, NULL ); // wire [4:0] r1 = a1 + b1 + rco;
764 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninR1, 1, &FaninS1, NULL ); // wire [3:0] s1 = r1[3:0];
765 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 4, 4, 0, 1, &FaninR1, 1, &FaninCO, NULL ); // assign co = r1[4];
766
767 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONCAT, 0, 7, 0, 0, 2, Fanins3, 1, &FaninS, NULL ); // s = {s1, s0};
768
769 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 7, 0, 0, 1, &FaninS, 0, NULL, NULL );
770 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &FaninCO, 0, NULL, NULL );
771
772 // write Verilog for verification
773 //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
774 Ndr_Write( (char*)"add8.ndr", pDesign );
775 Ndr_Delete( pDesign );
776
777}
778
779// This testing procedure creates and writes into a Verilog file
780// the following hierarchical design composed of two modules
781
782// module mux21w ( input sel, input [3:0] d1, input [3:0] d0, output [3:0] out );
783// assign out = sel ? d1 : d0;
784// endmodule
785
786// module mux41w ( input [1:0] sel, input [15:0] d, output [3:0] out );
787// wire [3:0] t0, t1;
788// wire [3:0] d0 = d[3:0];
789// wire [3:0] d1 = d[7:4];
790// wire [3:0] d2 = d[11:8];
791// wire [3:0] d3 = d[15:12];
792// wire sel0 = sel[0];
793// wire sel1 = sel[1];
794// mux21w i0 ( sel0, d1, d0, t0 );
795// mux21w i1 ( sel0, d3, d2, t1 );
796// mux21w i2 ( sel1, t1, t0, out );
797// endmodule
798
799static inline void Ndr_ModuleTestHierarchy()
800{
801/*
802 // map name IDs into char strings
803 char * ppNames[20] = { NULL,
804 "mux21w", "mux41w", // 1, 2
805 "sel", "d", "out", // 3, 4, 5
806 "d0", "d1", "d2", "d3", // 6, 7, 8, 9
807 "sel0", "sel1", // 10, 11,
808 "t0", "t1", // 12, 13
809 "i0", "i1", "i2" // 14, 15, 16
810 };
811*/
812 // fanins
813 int FaninSel = 3;
814 int FaninSel0 = 10;
815 int FaninSel1 = 11;
816 int FaninD = 4;
817 int FaninD0 = 6;
818 int FaninD1 = 7;
819 int FaninD2 = 8;
820 int FaninD3 = 9;
821 int FaninT0 = 12;
822 int FaninT1 = 13;
823 int FaninOut = 5;
824 int Fanins1[3] = { FaninSel, FaninD1, FaninD0 };
825 int Fanins3[3][3] = { {FaninSel0, FaninD1, FaninD0 },
826 {FaninSel0, FaninD3, FaninD2 },
827 {FaninSel1, FaninT1, FaninT0 } };
828
829 // create a new module
830 void * pDesign = Ndr_Create( 2 );
831
832 int Module21, Module41;
833
834 Module21 = Ndr_AddModule( pDesign, 1 );
835
836 Ndr_AddObject( pDesign, Module21, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &FaninSel, NULL );
837 Ndr_AddObject( pDesign, Module21, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &FaninD1, NULL );
838 Ndr_AddObject( pDesign, Module21, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &FaninD0, NULL );
839 Ndr_AddObject( pDesign, Module21, ABC_OPER_BIT_MUX, 0, 3, 0, 0, 3, Fanins1, 1, &FaninOut, NULL );
840 Ndr_AddObject( pDesign, Module21, ABC_OPER_CO, 0, 3, 0, 0, 1, &FaninOut, 0, NULL, NULL );
841
842 Module41 = Ndr_AddModule( pDesign, 2 );
843
844 Ndr_AddObject( pDesign, Module41, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &FaninSel, NULL );
845 Ndr_AddObject( pDesign, Module41, ABC_OPER_CI, 0, 15,0, 0, 0, NULL, 1, &FaninD, NULL );
846
847 Ndr_AddObject( pDesign, Module41, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninD, 1, &FaninD0, NULL );
848 Ndr_AddObject( pDesign, Module41, ABC_OPER_SLICE, 0, 7, 4, 0, 1, &FaninD, 1, &FaninD1, NULL );
849 Ndr_AddObject( pDesign, Module41, ABC_OPER_SLICE, 0, 11,8, 0, 1, &FaninD, 1, &FaninD2, NULL );
850 Ndr_AddObject( pDesign, Module41, ABC_OPER_SLICE, 0, 15,12,0, 1, &FaninD, 1, &FaninD3, NULL );
851
852 Ndr_AddObject( pDesign, Module41, ABC_OPER_SLICE, 0, 0, 0, 0, 1, &FaninSel, 1, &FaninSel0, NULL );
853 Ndr_AddObject( pDesign, Module41, ABC_OPER_SLICE, 0, 1, 1, 0, 1, &FaninSel, 1, &FaninSel1, NULL );
854
855 Ndr_AddObject( pDesign, Module41, Module21, 14, 3, 0, 0, 3, Fanins3[0], 1, &FaninT0, NULL );
856 Ndr_AddObject( pDesign, Module41, Module21, 15, 3, 0, 0, 3, Fanins3[1], 1, &FaninT1, NULL );
857 Ndr_AddObject( pDesign, Module41, Module21, 16, 3, 0, 0, 3, Fanins3[2], 1, &FaninOut, NULL );
858 Ndr_AddObject( pDesign, Module41, ABC_OPER_CO, 0, 3, 0, 0, 1, &FaninOut, 0, NULL, NULL );
859
860 // write Verilog for verification
861 //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
862 Ndr_Write( (char*)"mux41w.ndr", pDesign );
863 Ndr_Delete( pDesign );
864}
865
866
867// This testing procedure creates and writes into a Verilog file
868// the following design with read/write memory ports
869
870// module test ( input clk, input [8:0] raddr, input [8:0] waddr, input [31:0] data, input [16383:0] mem_init, output out );
871//
872// wire [31:0] read1, read2;
873//
874// wire [16383:0] mem_fo1, mem_fo2, mem_fi1, mem_fi2;
875//
876// ABC_FF i_reg1 ( .q(mem_fo1), .d(mem_fi1), .init(mem_init) );
877// ABC_FF i_reg2 ( .q(mem_fo2), .d(mem_fi2), .init(mem_init) );
878//
879// ABC_WRITE i_write1 ( .mem_out(mem_fi1), .mem_in(mem_fo1), .addr(waddr), .data(data) );
880// ABC_WRITE i_write2 ( .mem_out(mem_fi2), .mem_in(mem_fo2), .addr(waddr), .data(data) );
881//
882// ABC_READ i_read1 ( .data(read1), .mem_in(mem_fi1), .addr(raddr) );
883// ABC_READ i_read2 ( .data(read2), .mem_in(mem_fi2), .addr(raddr) );
884//
885// assign out = read1 != read2;
886//endmodule
887
888static inline void Ndr_ModuleTestMemory()
889{
890/*
891 // map name IDs into char strings
892 char * ppNames[20] = { NULL,
893 "clk", "raddr", "waddr", "data", "mem_init", "out", // 1, 2, 3, 4, 5, 6
894 "read1", "read2", // 7. 8
895 "mem_fo1", "mem_fo2", "mem_fi1", "mem_fi2", // 9, 10, 11, 12
896 "i_reg1", "i_reg2", // 13, 14
897 "i_read1", "i_read2", // 15, 16
898 "i_write1", "i_write2", "memtest" // 17, 18, 19
899 };
900*/
901 // inputs
902 int NameIdClk = 1;
903 int NameIdRaddr = 2;
904 int NameIdWaddr = 3;
905 int NameIdData = 4;
906 int NameIdMemInit = 5;
907 // flops
908 int NameIdFF1 = 9;
909 int NameIdFF2 = 10;
910 int FaninsFF1[2] = { 11, 5 };
911 int FaninsFF2[2] = { 12, 5 };
912 // writes
913 int NameIdWrite1 = 11;
914 int NameIdWrite2 = 12;
915 int FaninsWrite1[3] = { 9, 3, 4 };
916 int FaninsWrite2[3] = { 10, 3, 4 };
917 // reads
918 int NameIdRead1 = 7;
919 int NameIdRead2 = 8;
920 int FaninsRead1[2] = { 11, 2 };
921 int FaninsRead2[2] = { 12, 2 };
922 // compare
923 int NameIdComp = 6;
924 int FaninsComp[2] = { 7, 8 };
925
926 // create a new module
927 void * pDesign = Ndr_Create( 19 ); // create design named "memtest"
928
929 int ModuleID = Ndr_AddModule( pDesign, 19 ); // create module named "memtest"
930
931 // add objects to the module
932 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdClk, NULL );
933 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 8, 0, 0, 0, NULL, 1, &NameIdRaddr, NULL );
934 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 8, 0, 0, 0, NULL, 1, &NameIdWaddr, NULL );
935 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 31, 0, 0, 0, NULL, 1, &NameIdData, NULL );
936 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 16383, 0, 0, 0, NULL, 1, &NameIdMemInit, NULL );
937
938 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdComp, 0, NULL, NULL );
939
940 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_DFF, 13, 16383, 0, 0, 2, FaninsFF1, 1, &NameIdFF1, NULL );
941 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_DFF, 14, 16383, 0, 0, 2, FaninsFF2, 1, &NameIdFF2, NULL );
942
943 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_RAMW, 17, 16383, 0, 0, 3, FaninsWrite1, 1, &NameIdWrite1, NULL );
944 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_RAMW, 18, 16383, 0, 0, 3, FaninsWrite2, 1, &NameIdWrite2, NULL );
945
946 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_RAMR, 15, 31, 0, 0, 2, FaninsRead1, 1, &NameIdRead1, NULL );
947 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_RAMR, 16, 31, 0, 0, 2, FaninsRead2, 1, &NameIdRead2, NULL );
948
949 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_COMP_NOTEQU, 0, 0, 0, 0, 2, FaninsComp, 1, &NameIdComp, NULL );
950
951 // write Verilog for verification
952 //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
953 Ndr_Write( (char*)"memtest.ndr", pDesign );
954 Ndr_Delete( pDesign );
955}
956
957// This testing procedure creates and writes into a Verilog file
958// the following design composed of one word-level flop
959
960// module flop ( input [3:0] data, input clk, input reset, input set, input enable, input async, input sre, input [3:0] init, output [3:0] q );
961// ABC_DFFRSE reg1 ( .d(data), .clk(clk), .reset(reset), .set(set), .enable(enable), .async(async), .sre(sre), .init(init), .q(q) ) ;
962// endmodule
963
964static inline void Ndr_ModuleTestFlop()
965{
966 // map name IDs into char strings
967 //char * ppNames[12] = { NULL, "flop", "data", "clk", "reset", "set", "enable", "async", "sre", "init", "q" };
968 // name IDs
969 int NameIdData = 2;
970 int NameIdClk = 3;
971 int NameIdReset = 4;
972 int NameIdSet = 5;
973 int NameIdEnable = 6;
974 int NameIdAsync = 7;
975 int NameIdSre = 8;
976 int NameIdInit = 9;
977 int NameIdQ = 10;
978 // array of fanins of node s
979 int Fanins[8] = { NameIdData, NameIdClk, NameIdReset, NameIdSet, NameIdEnable, NameIdAsync, NameIdSre, NameIdInit };
980
981 // create a new module
982 void * pDesign = Ndr_Create( 1 );
983
984 int ModuleID = Ndr_AddModule( pDesign, 1 );
985
986 // add objects to the modele
987 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdData, NULL );
988 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdClk, NULL );
989 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdReset, NULL );
990 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdSet, NULL );
991 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdEnable, NULL );
992 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdAsync, NULL );
993 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdSre, NULL );
994 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdInit, NULL );
995
996 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_DFFRSE, 0, 3, 0, 0, 8, Fanins, 1, &NameIdQ, NULL );
997
998 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdQ, 0, NULL, NULL );
999
1000 // write Verilog for verification
1001 //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
1002 Ndr_Write( (char*)"flop.ndr", pDesign );
1003 Ndr_Delete( pDesign );
1004}
1005
1006
1007// This testing procedure creates and writes into a Verilog file
1008// the following design composed of one selector
1009
1010// module sel ( input [3:0] c, input [2:0] d0, input [2:0] d1, input [2:0] d2, input [2:0] d3, input [2:0] out );
1011// wire [2:0] s7 ;
1012// always @( c or d0 or d1 or d2 or d3 )
1013// begin
1014// case ( c )
1015// 4'b0001 : s7 = d0 ;
1016// 4'b0010 : s7 = d1 ;
1017// 4'b0100 : s7 = d2 ;
1018// 4'b1000 : s7 = d3 ;
1019// endcase
1020// end
1021// assign out = s7 ;
1022// endmodule
1023
1024static inline void Ndr_ModuleTestSelSel()
1025{
1026 // map name IDs into char strings
1027 //char * ppNames[12] = { NULL, "sel", "c", "d0", "d1", "d2", "d3", "out" };
1028 // name IDs
1029 int NameIdC = 2;
1030 int NameIdD0 = 3;
1031 int NameIdD1 = 4;
1032 int NameIdD2 = 5;
1033 int NameIdD3 = 6;
1034 int NameIdOut = 7;
1035 // array of fanins of node s
1036 int Fanins[8] = { NameIdC, NameIdD0, NameIdD1, NameIdD2, NameIdD3 };
1037
1038 // create a new module
1039 void * pDesign = Ndr_Create( 1 );
1040
1041 int ModuleID = Ndr_AddModule( pDesign, 1 );
1042
1043 // add objects to the modele
1044 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 3, 0, 0, 0, NULL, 1, &NameIdC, NULL );
1045 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdD0, NULL );
1046 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdD1, NULL );
1047 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdD2, NULL );
1048 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdD3, NULL );
1049
1050 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_SEL, 0, 2, 0, 0, 5, Fanins, 1, &NameIdOut, NULL );
1051
1052 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 2, 0, 0, 1, &NameIdOut,0, NULL, NULL );
1053
1054 // write Verilog for verification
1055 //Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 );
1056 Ndr_Write( (char*)"sel.ndr", pDesign );
1057 Ndr_Delete( pDesign );
1058}
1059
1060// This testing procedure creates and writes into a Verilog file
1061// the following design composed of one decoder
1062
1063// module dec ( input [1:0] in, output [3:0] out );
1064// wire out0 = ~in[1] & ~in[0] ;
1065// wire out1 = ~in[1] & in[0] ;
1066// wire out2 = in[1] & ~in[0] ;
1067// wire out3 = in[1] & in[0] ;
1068// assign out = { out3, out2, out1, out0 } ;
1069// endmodule
1070
1071static inline void Ndr_ModuleTestDec()
1072{
1073 // map name IDs into char strings
1074 //char * ppNames[12] = { NULL, "dec", "in", "out" };
1075 // name IDs
1076 int NameIdIn = 2;
1077 int NameIdOut = 3;
1078
1079 // create a new module
1080 void * pDesign = Ndr_Create( 1 );
1081
1082 int ModuleID = Ndr_AddModule( pDesign, 1 );
1083
1084 // add objects to the modele
1085 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL );
1086 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_DEC, 0, 3, 0, 0, 1, &NameIdIn, 1, &NameIdOut, NULL );
1087 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
1088
1089 Ndr_Write( (char*)"dec.ndr", pDesign );
1090 Ndr_Delete( pDesign );
1091}
1092
1093// This testing procedure creates and writes into a Verilog file
1094// the following design composed of one adder/subtractor
1095
1096// module addsub ( input mode, input cin, input [2:0] a, input [2:0] b, output [3:0] out );
1097// assign out = mode ? a+b+cin : a-b-cin ;
1098// endmodule
1099
1100static inline void Ndr_ModuleTestAddSub()
1101{
1102 // map name IDs into char strings
1103 //char * ppNames[12] = { NULL, "addsub", "mode", "cin", "a", "b", "out" };
1104 // name IDs
1105 int NameIdInMode = 2;
1106 int NameIdInCin = 3;
1107 int NameIdInA = 4;
1108 int NameIdInB = 5;
1109 int NameIdOut = 6;
1110 int Fanins[8] = { 2, 3, 4, 5 };
1111
1112 // create a new module
1113 void * pDesign = Ndr_Create( 1 );
1114
1115 int ModuleID = Ndr_AddModule( pDesign, 1 );
1116
1117 // add objects to the modele
1118 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdInMode, NULL );
1119 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdInCin, NULL );
1120 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdInA, NULL );
1121 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdInB, NULL );
1122 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADDSUB, 0, 3, 0, 0, 4, Fanins, 1, &NameIdOut, NULL );
1123 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
1124
1125 Ndr_Write( (char*)"addsub.ndr", pDesign );
1126 Ndr_Delete( pDesign );
1127}
1128
1129// This testing procedure creates and writes into a Verilog file
1130// the following design composed of one lookup table with function of AND2
1131
1132// module lut_test ( input [1:0] in, output out );
1133// assign out = LUT #(TT=4'h8) lut_inst { in[0], in[1], out } ;
1134// endmodule
1135
1136static inline void Ndr_ModuleTestLut()
1137{
1138 // map name IDs into char strings
1139 //char * ppNames[12] = { NULL, "lut_test", "in", "out" };
1140 // name IDs
1141 int NameIdIn = 2;
1142 int NameIdOut = 3;
1143
1144 // create a new module
1145 void * pDesign = Ndr_Create( 1 );
1146
1147 int ModuleID = Ndr_AddModule( pDesign, 1 );
1148
1149 unsigned pTruth[2] = { 0x88888888, 0x88888888 };
1150
1151 // add objects to the modele
1152 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL );
1153 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)pTruth );
1154 Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
1155
1156 Ndr_Write( (char*)"lut_test.ndr", pDesign );
1157 Ndr_Delete( pDesign );
1158}
1159
1160#ifndef _YOSYS_
1162#endif
1163
1164#endif
1165
1169
@ ABC_OPER_DFF
Definition abcOper.h:142
@ ABC_OPER_LUT
Definition abcOper.h:127
@ ABC_OPER_CI
Definition abcOper.h:45
@ ABC_OPER_DFFRSE
Definition abcOper.h:143
@ ABC_OPER_RAMW
Definition abcOper.h:134
@ ABC_OPER_SEL_SEL
Definition abcOper.h:92
@ ABC_OPER_CONCAT
Definition abcOper.h:147
@ ABC_OPER_BIT_MUX
Definition abcOper.h:65
@ ABC_OPER_RAMR
Definition abcOper.h:133
@ ABC_OPER_CONST
Definition abcOper.h:153
@ ABC_OPER_SEL_DEC
Definition abcOper.h:96
@ ABC_OPER_SLICE
Definition abcOper.h:146
@ ABC_OPER_ARI_ADDSUB
Definition abcOper.h:155
@ ABC_OPER_COMP_NOTEQU
Definition abcOper.h:117
@ ABC_OPER_BIT_BUF
Definition abcOper.h:55
@ ABC_OPER_CO
Definition abcOper.h:46
@ ABC_OPER_ARI_ADD
Definition abcOper.h:99
#define ABC_NAMESPACE_HEADER_END
#define ABC_NAMESPACE_HEADER_START
NAMESPACES ///.
Cube * p
Definition exorList.c:222
Ndr_RecordType_t
INCLUDES ///.
Definition ndr.h:98
@ NDR_RANGE
Definition ndr.h:107
@ NDR_NONE
Definition ndr.h:99
@ NDR_INPUT
Definition ndr.h:103
@ NDR_FUNCTION
Definition ndr.h:108
@ NDR_DESIGN
Definition ndr.h:100
@ NDR_OBJECT
Definition ndr.h:102
@ NDR_MODULE
Definition ndr.h:101
@ NDR_NAME
Definition ndr.h:106
@ NDR_OPERTYPE
Definition ndr.h:105
@ NDR_OUTPUT
Definition ndr.h:104
@ NDR_TARGET
Definition ndr.h:109
@ NDR_UNKNOWN
Definition ndr.h:110
#define Ndr_ModForEachObj(p, Mod, Obj)
Definition ndr.h:147
#define NDR_ALLOC(type, num)
Definition ndr.h:136
struct Ndr_Data_t_ Ndr_Data_t
BASIC TYPES ///.
Definition ndr.h:119
#define Ndr_DesForEachMod(p, Mod)
ITERATORS ///.
Definition ndr.h:143
#define Ndr_ModForEachPo(p, Mod, Obj)
Definition ndr.h:159
#define Ndr_ObjForEachEntry(p, Obj, Ent)
Definition ndr.h:151
#define Ndr_ModForEachPi(p, Mod, Obj)
Definition ndr.h:155
#define Ndr_ModForEachNode(p, Mod, Obj)
Definition ndr.h:163
int nSize
Definition ndr.h:122
unsigned int * pBody
Definition ndr.h:125
int nCap
Definition ndr.h:123
unsigned char * pHead
Definition ndr.h:124
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * calloc()
char * memset()
int strlen()
VOID_HACK free()
VOID_HACK rewind()
char * realloc()
#define SEEK_END
Definition zconf.h:392