[logo] 
 
Home
News
Activity
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  BugVise
  CovVise
  Force-Gate-Sim
  Gspice
  IPC::Locker
  Rsvn
  Schedule::Load
  SVN::S4
  Synopsys-modes
  SystemPerl
  Verilog-Pli
  Voneline
  Vregs
General Info
  Papers

slices.diff

Byron Bradley, 01/19/2010 01:59 pm

Download (30.9 kB)

b/src/Makefile_obj.in
206 206
	V3Premit.o \
207 207
	V3Scope.o \
208 208
	V3Signed.o \
209
	V3Slice.o \
209 210
	V3Split.o \
210 211
	V3SplitAs.o \
211 212
	V3Stats.o \
b/src/V3Ast.h
1229 1229
	:AstNodeBiop(fl, fromp, bitp) {}
1230 1230
    ASTNODE_BASE_FUNCS(NodeSel)
1231 1231
    AstNode* fromp()		const { return op1p()->castNode(); }	// op1 = Extracting what (NULL=TBD during parsing)
1232
    void fromp(AstNode* nodep)	      { setOp1p(nodep); }
1232 1233
    AstNode* bitp()		const { return op2p()->castNode(); }	// op2 = Msb selection expression
1234
    void bitp(AstNode* nodep)	      { setOp2p(nodep); }
1233 1235
    int	     bitConst()	const;
1234 1236
};
1235 1237

  
b/src/V3AstNodes.cpp
258 258
    return entries;
259 259
}
260 260

  
261
uint32_t AstVar::dimensions() const {
262
    // How many array dimensions does this Var have?
263
    uint32_t dim = 0;
264
    for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) {
265
	dtypep = dtypep->skipRefp();  // Skip AstRefDType/AstTypedef, or return same node
266
	if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
267
	    dim += 1;
268
	    dtypep = adtypep->dtypep();
269
	}
270
	else {
271
	    // AstBasicDType - nothing below, 1
272
	    break;
273
	}
274
    }
275
    return dim;
276
}
277

  
261 278
// Special operators
262 279
int AstArraySel::dimension(AstNode* nodep) {
263 280
    // How many dimensions is this reference from the base variable?
......
445 462
    if (name()!="") os<<"  "<<AstNode::quoteName(name());
446 463
}
447 464

  
465
void AstArraySel::dump(ostream& str) {
466
    this->AstNode::dump(str);
467
    str<<" [start:"<<start()<<"] [length:"<<length()<<"]";
468
}
448 469
void AstAttrOf::dump(ostream& str) {
449 470
    this->AstNode::dump(str);
450 471
    str<<" ["<<attrType().ascii()<<"]";
b/src/V3AstNodes.h
401 401
struct AstArraySel : public AstNodeSel {
402 402
    // Parents: math|stmt
403 403
    // Children: varref|arraysel, math
404
private:
405
    unsigned m_start;
406
    unsigned m_length;
407
public:
404 408
    AstArraySel(FileLine* fl, AstNode* fromp, AstNode* bitp)
405
	:AstNodeSel(fl, fromp, bitp) {
409
	:AstNodeSel(fl, fromp, bitp), m_start(0), m_length(1) {
406 410
	if (fromp) widthSignedFrom(fromp);
407 411
    }
408 412
    AstArraySel(FileLine* fl, AstNode* fromp, int bit)
409
	:AstNodeSel(fl, fromp, new AstConst(fl,bit)) {
413
	:AstNodeSel(fl, fromp, new AstConst(fl,bit)), m_start(0), m_length(1) {
410 414
	if (fromp) widthSignedFrom(fromp);
411 415
    }
412 416
    ASTNODE_NODE_FUNCS(ArraySel, ARRAYSEL)
......
422 426
    virtual V3Hash sameHash() const { return V3Hash(); }
423 427
    virtual bool same(AstNode* samep) const { return true; }
424 428
    virtual int instrCount() const { return widthInstrs(); }
429
    unsigned length()                { return m_length; }
430
    void     length(unsigned length) { m_length = length; }
431
    void     start(unsigned start) { m_start = start; }
432
    unsigned start(void)           { return m_start; }
425 433
    // Special operators
426 434
    static int dimension(AstNode* nodep); ///< How many dimensions is this reference from the base variable?
427 435
    static AstNode* baseFromp(AstNode* nodep);	///< What is the base variable (or const) this dereferences?
436
    virtual void dump(ostream& str);
428 437
};
429 438

  
430 439
struct AstWordSel : public AstNodeSel {
......
603 612
    AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); }	// op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
604 613
    AstBasicDType* basicp() const { return dtypep()->basicp(); }  // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
605 614
    AstNodeDType* dtypeDimensionp(int depth) const;
615
    uint32_t	dimensions() const;
606 616
    AstNode* 	initp()		const { return op3p()->castNode(); }	// op3 = Initial value that never changes (static const)
607 617
    void	initp(AstNode* nodep) { setOp3p(nodep); }
608 618
    void	addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
b/src/V3Delayed.cpp
158 158
	    arrayselp = lhsp->castArraySel();
159 159
	}
160 160
	if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
161
	UASSERT(arrayselp->length() == 1, "ArraySel with length!=1 should have been removed in V3Slice");
161 162

  
162 163
	UINFO(4,"AssignDlyArray: "<<nodep<<endl);
163 164
	//
b/src/V3Expand.cpp
239 239
	return true;
240 240
    }
241 241
    bool expandWide (AstNodeAssign* nodep, AstArraySel* rhsp) {
242
	UASSERT(rhsp->length() == 1, "ArraySel with length!=1 should have been removed in V3Slice");
242 243
	UINFO(8,"    Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
243 244
	for (int w=0; w<nodep->widthWords(); w++) {
244 245
	    addWordAssign(nodep, w, newAstWordSelClone (rhsp, w));
b/src/V3Slice.cpp
1
//*************************************************************************
2
// DESCRIPTION: Verilator: Parse module/signal name references
3
//
4
// Code available from: http://www.veripool.org/verilator
5
//
6
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
7
//
8
//*************************************************************************
9
//
10
// Copyright 2003-2010 by Wilson Snyder.  This program is free software; you can
11
// redistribute it and/or modify it under the terms of either the GNU
12
// Lesser General Public License Version 3 or the Perl Artistic License
13
// Version 2.0.
14
//
15
// Verilator is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
// GNU General Public License for more details.
19
//
20
//*************************************************************************
21
// Slice TRANSFORMATIONS:
22
//	Top-down traversal (SliceVisitor):
23
//	  NODEASSIGN
24
//	    ARRAYSEL
25
//	      Compare the dimensions to the Var to check for implicit slices.
26
//	      Using ->length() calculate the number of clones needed.
27
//	    VARREF
28
//	      Check the dimensions of the Var for an implicit slice.
29
//	      Replace with ArraySel nodes if needed.
30
//	    SEL, EXTEND
31
//	      We might be assigning a 1-D packed array to a 2-D packed array,
32
//	      this is unsupported.
33
//	    SliceCloneVisitor (called if this node is a slice):
34
//	      NODEASSIGN
35
//	        Clone and iterate the clone:
36
//		  ARRAYSEL
37
//		    Modify bitp() for the new value and set ->length(1)
38
//*************************************************************************
39

40
#include "config_build.h"
41
#include "verilatedos.h"
42
#include <cstdio>
43
#include <cstdarg>
44
#include <unistd.h>
45

  
46
#include "V3Global.h"
47
#include "V3Slice.h"
48
#include "V3Ast.h"
49
#include <vector>
50

  
51
class SliceCloneVisitor : public AstNVisitor {
52
private:
53
    // NODE STATE
54
    // Inputs:
55
    //  AstArraySel::user1p()	    -> AstVarRef. The VarRef that the final ArraySel points to
56
    //  AstNodeAssign::user2()	    -> int. The number of clones needed for this assign
57

  
58
    // STATE
59
    std::vector<std::vector<unsigned> >	    m_selBits;	    // Indexes of the ArraySel we are expanding
60
    int					    m_vecIdx;	    // Current vector index
61
    unsigned				    m_depth;	    // Number of ArraySel's from the VarRef
62
    AstVarRef*				    m_refp;	    // The VarRef under this ArraySel
63

  
64
    // METHODS
65
    virtual void visit(AstArraySel* nodep, AstNUser*) {
66
	if (!nodep->backp()->castArraySel()) {
67
	    // This is the top of an ArraySel, setup
68
	    m_refp = nodep->user1p()->castNode()->castVarRef();
69
	    m_vecIdx += 1;
70
	    if (m_vecIdx == m_selBits.size()) {
71
		m_selBits.push_back(std::vector<unsigned>());
72
		AstVar* varp = m_refp->varp();
73
		int dimensions = varp->dimensions();
74
		for (int i = 0; i < dimensions; ++i) {
75
		    m_selBits[m_vecIdx].push_back(0);
76
		}
77
	    }
78
	}
79
	nodep->iterateChildren(*this);
80
	if (nodep->fromp()->castVarRef()) {
81
	    m_depth = 0;
82
	} else {
83
	    ++m_depth;
84
	}
85
	// Check if m_selBits has overflowed
86
	if (m_selBits[m_vecIdx][m_depth] >= nodep->length()) {
87
	    m_selBits[m_vecIdx][m_depth] = 0;
88
	    if (m_depth + 1 < m_selBits[m_vecIdx].size())
89
		m_selBits[m_vecIdx][m_depth+1] += 1;
90
	}
91
	// Reassign the bitp()
92
	if (nodep->length() > 1) {
93
	    if (AstConst* bitp = nodep->bitp()->castConst()) {
94
		unsigned idx = nodep->start() + m_selBits[m_vecIdx][m_depth];
95
		AstNode* constp = new AstConst(bitp->fileline(), V3Number(bitp->fileline(), bitp->castConst()->num().width(), idx));
96
		bitp->replaceWith(constp);
97
	    } else {
98
		nodep->v3error("Unsupported: Only constants supported in slices");
99
	    }
100
	}
101
	if (!nodep->backp()->castArraySel()) {
102
	    // Top ArraySel, increment m_selBits
103
	    m_selBits[m_vecIdx][0] += 1;
104
	}
105
	nodep->length(1);
106
    }
107

  
108
    virtual void visit(AstNodeAssign* nodep, AstNUser*) {
109
	m_selBits.clear();
110
	UINFO(4, "Cloning "<<nodep->user2()<<" times: "<<nodep<<endl);
111
	for (int i = 0; i < nodep->user2(); ++i) {
112
	    // Clone the node and iterate over the clone
113
	    m_vecIdx = -1;
114
	    AstNodeAssign* clonep = nodep->cloneTree(false)->castNodeAssign();
115
	    clonep->iterateChildren(*this);
116
	    nodep->addNextHere(clonep);
117
	}
118
	nodep->unlinkFrBack(false)->deleteTree(); nodep = NULL;
119
    }
120

  
121
    virtual void visit(AstNode* nodep, AstNUser*) {
122
	// Default: Just iterate
123
	nodep->iterateChildren(*this);
124
    }
125
public:
126
    // CONSTUCTORS
127
    SliceCloneVisitor(AstNodeAssign* assignp) {
128
	assignp->accept(*this);
129
    }
130
    virtual ~SliceCloneVisitor() {}
131
};
132

  
133
class SliceVisitor : public AstNVisitor {
134
private:
135
    // NODE STATE
136
    // Cleared on netlist
137
    //  AstNodeAssign::user1()	    -> bool.  True if find is complete
138
    //  AstNodeAssign::user2()	    -> int. The number of clones needed for this assign
139
    //  AstArraySel::user1p()	    -> AstVarRef. The VarRef that the final ArraySel points to
140
    AstUser1InUse	m_inuser1;
141
    AstUser2InUse	m_inuser2;
142

  
143
    // STATE
144
    AstNode*		    m_assign;	    // The assignment we are under
145
    AstNodeVarRef*	    m_lhspVarRef;   // Var on the LHS
146
    bool		    m_extend;	    // True if we have found an extend node
147

  
148
    // METHODS
149
    virtual void visit(AstVarRef* nodep, AstNUser*) {
150
	// The LHS/RHS of an Assign may be to a Var that is an array. In this
151
	// case we need to create a slice accross the entire Var
152
	if (m_assign && !nodep->backp()->castArraySel()) {
153
	    uint32_t dimensions = nodep->varp()->dimensions();
154
	    if (dimensions > 0) {
155
		AstNode* newp = insertImplicit(nodep->cloneTree(false), 1, dimensions);
156
		nodep->replaceWith(newp); nodep = NULL;
157
		newp->iterateChildren(*this);
158
	    }
159
	}
160
    }
161

  
162
    // Find out how many explicit dimensions are in a given ArraySel.
163
    unsigned explicitDimensions(AstArraySel* nodep) {
164
	unsigned dim = 0;
165
	AstNode* fromp = nodep;
166
	AstArraySel* selp;
167
	do {
168
	    selp = fromp->castArraySel();
169
	    if (!selp) {
170
		nodep->user1p(fromp->castVarRef());
171
		selp = NULL;
172
	    } else {
173
		fromp = selp->fromp();
174
		if (fromp)
175
		    ++dim;
176
	    }
177
	} while (fromp && selp);
178
	UASSERT(m_assign->user1p(), "Couldn't find VarRef under the ArraySel");
179
	return dim;
180
    }
181

  
182
    AstNode* insertImplicit(AstVarRef* nodep, unsigned start, unsigned count) {
183
	// Insert any implicit slices as explicit slices (ArraySel nodes).
184
	// Return a new pointer to replace fromp() in the ArraySel.
185
	AstVarRef* fromp = nodep;
186
	UASSERT(fromp, "NULL VarRef passed to insertImplicit");
187
	AstVar* varp = fromp->varp();
188
	// Get the DType and insert a new ArraySel
189
	AstArraySel* topp = NULL;
190
	AstArraySel* bottomp = NULL;
191
	for (unsigned i = start; i < start + count; ++i) {
192
	    AstNodeDType* dtypep = varp->dtypeDimensionp(i-1);
193
	    AstArrayDType* adtypep = dtypep->castArrayDType();
194
	    UASSERT(adtypep, "insertImplicit tried to expand an array without an ArrayDType");
195
	    vlsint32_t msb = adtypep->msb();
196
	    vlsint32_t lsb = adtypep->lsb();
197
	    if (lsb > msb) {
198
		// Below code assumes big bit endian; just works out if we swap
199
		int x = msb; msb = lsb; lsb = x;
200
	    }
201
	    AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, new AstConst(nodep->fileline(),lsb));
202
	    newp->start(lsb);
203
	    newp->length(msb - lsb + 1);
204
	    if (!topp)
205
		topp = newp;
206
	    fromp = newp->fromp()->unlinkFrBack()->castVarRef();
207

  
208
	    if (bottomp)
209
		bottomp->fromp(newp);
210
	    bottomp = newp;
211
	}
212
	bottomp->fromp(fromp);
213
	return topp;
214
    }
215

  
216
    int countClones(AstArraySel* nodep) {
217
	// Count how many clones we need to make from this ArraySel
218
	int clones = 1;
219
	AstNode* fromp = nodep;
220
	AstArraySel* selp;
221
	do {
222
	    selp = fromp->castArraySel();
223
	    fromp = (selp) ? selp->fromp() : NULL;
224
	    if (fromp && selp)
225
		clones *= selp->length();
226
	} while (fromp && selp);
227
	return clones;
228
    }
229

  
230
    virtual void visit(AstExtend* nodep, AstNUser*) {
231
	m_extend = true;
232
	if (m_assign && m_assign->user2() > 1) {
233
	    m_assign->v3error("Unsupported: Assignment between packed arrays of different dimensions");
234
	}
235
	nodep->iterateChildren(*this);
236
    }
237

  
238
    virtual void visit(AstArraySel* nodep, AstNUser*) {
239
	if (!m_assign)
240
	    return;
241
	unsigned dim = explicitDimensions(nodep);
242
	AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
243
	unsigned implicit = refp->varp()->dimensions() - dim;
244
	if (implicit > 0) {
245
	    AstNode* backp = refp->backp();
246
	    AstNode* newp = insertImplicit(refp->cloneTree(false), dim+1, implicit);
247
	    backp->castArraySel()->fromp()->replaceWith(newp);
248
	}
249
	int clones = countClones(nodep);
250
	if (m_assign->user2() > 0 && m_assign->user2() != clones) {
251
	    m_assign->v3error("Slices of arrays in assignments must have the same unpacked dimensions");
252
	} else if (m_assign->user2() == 0) {
253
	    if (m_extend && clones > 1) {
254
		m_assign->v3error("Unsupported: Assignment between packed arrays of different dimensions");
255
	    }
256
	    if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhspVarRef->varp() && !m_assign->castAssignDly()) {
257
	        // LHS Var != RHS Var for a non-delayed assignment
258
		m_assign->v3error("Unsupported: Slices in a non-delayed assignment with the same Var on both sides");
259
	    }
260
	    m_assign->user2(clones);
261
	}
262
    }
263

  
264
    virtual void visit(AstSel* nodep, AstNUser*) {
265
	m_extend = true;
266
	if (m_assign && m_assign->user2() > 1) {
267
	    m_assign->v3error("Unsupported: Assignment between packed arrays of different dimensions");
268
	}
269
	nodep->iterateChildren(*this);
270
    }
271

  
272
    // Return the first AstVarRef under the node
273
    AstVarRef* findVarRefRecurse(AstNode* nodep)
274
    {
275
	AstVarRef* refp;
276
	if (refp = nodep->castVarRef())
277
	    return refp;
278
	if (nodep->op1p()) {
279
	    refp = findVarRefRecurse(nodep->op1p());
280
	    if (refp) return refp;
281
	}
282
	if (nodep->op2p()) {
283
	    refp = findVarRefRecurse(nodep->op2p());
284
	    if (refp) return refp;
285
	}
286
	if (nodep->op3p()) {
287
	    refp = findVarRefRecurse(nodep->op3p());
288
	    if (refp) return refp;
289
	}
290
	if (nodep->op3p()) {
291
	    refp = findVarRefRecurse(nodep->op3p());
292
	    if (refp) return refp;
293
	}
294
	if (nodep->nextp()) {
295
	    refp = findVarRefRecurse(nodep->nextp());
296
	    if (refp) return refp;
297
	}
298
	return NULL;
299
    }
300

  
301
    void findImplicit(AstNodeAssign* nodep) {
302
	UASSERT(!m_assign, "Found a NodeAssign under another NodeAssign");
303
	m_assign = nodep;
304
	m_extend = false;
305
	nodep->user1(true);
306
	// Record the LHS Var so we can check if the Var on the RHS is the same
307
	m_lhspVarRef = findVarRefRecurse(nodep->lhsp());
308
	UASSERT(m_lhspVarRef, "Couldn't find a VarRef on the LHSP of an Assign");
309
	// Iterate children looking for ArraySel nodes. From that we get the number of elements
310
	// in the array so we know how many times we need to clone this assignment.
311
	nodep->iterateChildren(*this);
312
	if (nodep->user2() > 1) {
313
	    SliceCloneVisitor scv(nodep);
314
	}
315
	m_assign = NULL;
316
    }
317

  
318
    virtual void visit(AstNodeAssign* nodep, AstNUser*) {
319
	if (!nodep->user1()) {
320
	    // Hasn't been searched for implicit slices yet
321
	    findImplicit(nodep);
322
	}
323
    }
324

  
325
    virtual void visit(AstNode* nodep, AstNUser*) {
326
	// Default: Just iterate
327
	nodep->iterateChildren(*this);
328
    }
329

  
330
public:
331
    // CONSTUCTORS
332
    SliceVisitor(AstNetlist* rootp) {
333
	m_assign = NULL;
334
	m_lhspVarRef = NULL;
335
	AstNode::user1ClearTree();
336
	AstNode::user2ClearTree();
337
	rootp->accept(*this);
338
    }
339
    virtual ~SliceVisitor() {}
340
};
341

  
342
//######################################################################
343
// Link class functions
344

  
345
void V3Slice::expandAll(AstNetlist* rootp) {
346
    UINFO(4,__FUNCTION__<<": "<<endl);
347
    SliceVisitor visitor(rootp);
348
}
b/src/V3Slice.h
1
// -*- C++ -*-
2
//*************************************************************************
3
// DESCRIPTION: Verilator: Link modules/signals together
4
//
5
// Code available from: http://www.veripool.org/verilator
6
//
7
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
8
//
9
//*************************************************************************
10
//
11
// Copyright 2003-2009 by Wilson Snyder.  This program is free software; you can
12
// redistribute it and/or modify it under the terms of either the GNU
13
// Lesser General Public License Version 3 or the Perl Artistic License
14
// Version 2.0.
15
//
16
// Verilator is distributed in the hope that it will be useful,
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
// GNU General Public License for more details.
20
//
21
//*************************************************************************
22

23
#ifndef _V3LINKSLICE_H_
24
#define _V3LINKSLICE_H_ 1
25
#include "config_build.h"
26
#include "verilatedos.h"
27
#include "V3Error.h"
28
#include "V3Ast.h"
29

  
30
//============================================================================
31

  
32
class V3Slice {
33
public:
34
    static void expandAll(AstNetlist* nodep);
35
};
36

  
37
#endif // Guard
b/src/V3WidthSel.cpp
80 80
	//UINFO(9,"SCD\n"); if (debug()>=9) nodep->backp()->dumpTree(cout,"-selcheck: ");
81 81
	AstNodeDType* ddtypep = varp->dtypeDimensionp(dimension);
82 82
	if (AstArrayDType* adtypep = ddtypep->castArrayDType()) {
83
	    if (rangedSelect) {
84
		nodep->v3error("Illegal bit select; can't bit extract from arrayed dimension: "<<varp->prettyName());
85
		return NULL;
86
	    }
87 83
	    return adtypep;
88 84
	}
89 85
	else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
......
247 243
	vlsint32_t msb = msbp->castConst()->toSInt();
248 244
	vlsint32_t lsb = lsbp->castConst()->toSInt();
249 245
	AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, msb!=lsb);
250
	if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
246
	if (AstArrayDType* adtypep = ddtypep->castArrayDType()) {
247
	    if (msb!=lsb) {
248
		AstArraySel* newp = new AstArraySel	(nodep->fileline(),
249
						     fromp, lsbp);
250
		newp->start(lsb);
251
		newp->length((msb - lsb) + 1);
252
		nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL;
253
	    } else {
254
		nodep->v3error("Illegal bit select; can't bit extract from arrayed dimension: "<<varp->prettyName());
255
	    }
256
	} else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
251 257
	    if (adtypep) {} // Unused
252 258
	    if (varp->basicp()->rangep() && varp->basicp()->rangep()->littleEndian()) {
253 259
		// Below code assumes big bit endian; just works out if we swap
b/src/Verilator.cpp
74 74
#include "V3Premit.h"
75 75
#include "V3Scope.h"
76 76
#include "V3Signed.h"
77
#include "V3Slice.h"
77 78
#include "V3Split.h"
78 79
#include "V3SplitAs.h"
79 80
#include "V3Stats.h"
......
280 281
    V3Unroll::unrollAll(v3Global.rootp());
281 282
    v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("unroll.tree"));
282 283

  
284
    // Expand slices of arrays
285
    V3Slice::expandAll(v3Global.rootp());
286
    v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("slices.tree"));
287

  
283 288
    // Convert case statements to if() blocks.  Must be after V3Unknown
284 289
    V3Case::caseAll(v3Global.rootp());
285 290
    v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("case.tree"));
b/test_regress/t/t_mem_multi_ref_bad.pl
12 12
	 nc=>0,  # Need to get it not to give the prompt
13 13
	 expect=>
14 14
q{%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dimn
15
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal range select; variable already selected, or bad dimension
15 16
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dim0
17
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension
16 18
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dim1
17
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit select; can't bit extract from arrayed dimension: dim2
18
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit select; can't bit extract from arrayed dimension: dim2
19
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit select; can't bit extract from arrayed dimension: dim0nv
19
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension
20
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal \+: or -: select; variable already selected, or bad dimension
20 21
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dim0nv
22
.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension
21 23
.*%Error: Exiting due to.*},
22 24
	 );
23 25

  
24 26
ok(1);
25 27
1;
26

  
b/test_regress/t/t_mem_packed_assign.pl
1
#!/usr/bin/perl
2
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
4
#
5
# Copyright 2003 by Wilson Snyder. This program is free software; you can
6
# redistribute it and/or modify it under the terms of either the GNU
7
# Lesser General Public License Version 3 or the Perl Artistic License
8
# Version 2.0.
9

  
10
compile (
11
         v_flags => ["--lint-only"],
12
	 fails=>1,
13
	 expect=>
14
'%Error: t/t_mem_packed_assign.v:\d+: Unsupported: Assignment between packed arrays of different dimensions
15
%Error: t/t_mem_packed_assign.v:\d+: Unsupported: Assignment between packed arrays of different dimensions
16
%Error: Exiting due to.*',
17
	 );
18

  
19
ok(1);
20
1;
b/test_regress/t/t_mem_packed_assign.v
1
// DESCRIPTION: Verilator: Verilog Test module
2
//
3
// This file ONLY is placed into the Public Domain, for any use,
4
// without warranty, 2009 by Wilson Snyder.
5

  
6
module t (/*AUTOARG*/
7
   // Inputs
8
   clk
9
   );
10

  
11
   /* verilator lint_off WIDTH */
12

  
13
   input clk;
14

  
15
   integer cyc; initial cyc = 0;
16
   logic [31:0] arr_c; initial arr_c = 0;
17
   logic [7:0] [3:0] arr;
18

  
19
   logic [31:0] arr2_c; initial arr2_c = 0;
20
   logic [7:0] [3:0] arr2;
21
   assign arr2_c = arr2;
22

  
23
   always @ (posedge clk) begin
24
      cyc <= cyc + 1;
25
      arr_c <= arr_c + 1;
26
      arr2 <= arr2 + 1;
27
      $write("cyc%0d c:%0x a0:%0x a1:%0x a2:%0x a3:%0x\n", cyc, arr_c, arr[0], arr[1], arr[2], arr[3]);
28
      if (cyc==99) begin
29
	 $write("*-* All Finished *-*\n");
30
	 $finish;
31
      end
32
   end
33

  
34
   /* verilator lint_on WIDTH */
35

  
36
endmodule
b/test_regress/t/t_mem_slice.pl
1
#!/usr/bin/perl
2
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
4
#
5
# Copyright 2003 by Wilson Snyder. This program is free software; you can
6
# redistribute it and/or modify it under the terms of either the GNU
7
# Lesser General Public License Version 3 or the Perl Artistic License
8
# Version 2.0.
9

  
10
compile (
11
	 v_flags => [],
12
	 );
13

  
14
execute (
15
	 check_finished=>1,
16
     );
17

  
18
ok(1);
19
1;
b/test_regress/t/t_mem_slice.v
1
// DESCRIPTION: Verilator: Verilog Test module
2
//
3
// This file ONLY is placed into the Public Domain, for any use,
4
// without warranty, 2009 by Wilson Snyder.
5

  
6
module t (/*AUTOARG*/
7
   // Inputs
8
   clk
9
   );
10

  
11
   input clk;
12

  
13
   logic       use_AnB;
14
   logic [1:0] active_command [8:0];
15
   logic [1:0] command_A      [8:0];
16
   logic [1:0] command_B      [8:0];
17

  
18
   logic [1:0] active_command2 [8:0];
19
   logic [1:0] command_A2      [8:0];
20
   logic [1:0] command_B2      [8:0];
21

  
22
   logic [1:0] active_command3 [1:0][2:0][3:0];
23
   logic [1:0] command_A3      [1:0][2:0][3:0];
24
   logic [1:0] command_B3      [1:0][2:0][3:0];
25

  
26
   logic [8:0] pipe1	      [7:0];
27
   logic [8:0] pipe1_input;
28

  
29
   integer cyc;
30

  
31
   assign active_command[8:0] = (use_AnB) ? command_A[8:0] : command_B[8:0];
32
   assign active_command2 = (use_AnB) ? command_A2 : command_B2;
33
   assign active_command3[1:0][2:0][3:0] = (use_AnB) ?  command_A3[1:0][2:0][3:0] : command_B3[1:0][2:0][3:0];
34

  
35
   always @ (posedge clk) begin
36
      pipe1_input <= pipe1_input + 1;
37
      pipe1[0]    <= pipe1_input;
38
      pipe1[7:1]  <= pipe1[6:0];
39
   end
40

  
41
   logic [3:0][13:0] iq_read_data [15:0];
42
   logic [3:0][13:0] iq_data;
43
   logic [3:0]       sel;
44

  
45
   assign iq_data = iq_read_data[sel];
46

  
47
   always @ (posedge clk) begin
48
      sel = sel + 1;
49
   end
50

  
51
   initial begin
52
      cyc = 0;
53
      use_AnB = 0;
54
      for (int i = 0; i < 7; ++i) begin
55
	 command_A[i] = 2'b00;
56
	 command_B[i] = 2'b11;
57
	 command_A2[i] = 2'b00;
58
	 command_B2[i] = 2'b11;
59
	 pipe1_input = 9'b0;
60
      end
61
      for (int i = 0; i < 2; ++i) begin
62
	 for (int j = 0; j < 3; ++j) begin
63
	    for (int k = 0; k < 4; ++k) begin
64
	       command_A3[i][j][k] = 2'b00;
65
	       command_B3[i][j][k] = 2'b11;
66
	    end
67
	 end
68
      end
69
   end
70

  
71
   always @ (posedge clk) begin
72
      use_AnB <= ~use_AnB;
73
      cyc <= cyc + 1;
74
      if (use_AnB) begin
75
	 if (active_command[3] != 2'b00) begin
76
	    $stop;
77
	 end
78
	 if (active_command2[3] != 2'b00) begin
79
	    $stop;
80
	 end
81
	 if (active_command3[0][1][2] != 2'b00) begin
82
	    $stop;
83
	 end
84
      end
85
      if (!use_AnB) begin
86
	 if (active_command[3] != 2'b11) begin
87
	    $stop;
88
	 end
89
	 if (active_command2[3] != 2'b11) begin
90
	    $stop;
91
	 end
92
	 if (active_command3[3][1][2] != 2'b11) begin
93
	    $stop;
94
	 end
95
      end
96
   end
97

  
98
   logic [8:0] last_pipe;
99
   always @(posedge clk) begin
100
      if (cyc < 3) begin
101
	 last_pipe <= pipe1[0];
102
      end
103
      else begin
104
	 if (last_pipe + 1 != pipe1[0]) begin
105
	    $stop;
106
	 end
107
	 else begin
108
	    last_pipe <= pipe1[0];
109
	 end
110
      end
111
      if (cyc > 10) begin
112
	 $write("*-* All Finished *-*\n");
113
	 $finish;
114
      end
115
   end
116

  
117
endmodule : t
b/test_regress/t/t_mem_slice_bad.pl
1
#!/usr/bin/perl
2
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
4
#
5
# Copyright 2008 by Wilson Snyder. This program is free software; you can
6
# redistribute it and/or modify it under the terms of either the GNU
7
# Lesser General Public License Version 3 or the Perl Artistic License
8
# Version 2.0.
9

  
10
compile (
11
	 v_flags2 => ["--lint-only"],
12
	 fails=>1,
13
	 expect=>
14
'%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions
15
%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions
16
%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions
17
%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions
18
%Error: t/t_mem_slice_bad.v:\d+: Unsupported: Slices in a non-delayed assignment with the same Var on both sides
19
%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions
20
%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions
21
%Error: Exiting due to.*',
22
	 ) if $Self->{v3};
23

  
24
ok(1);
25
1;
b/test_regress/t/t_mem_slice_bad.v
1
// DESCRIPTION: Verilator: Verilog Test module
2
//
3
// This file ONLY is placed into the Public Domain, for any use,
4
// without warranty, 2009 by Wilson Snyder.
5

  
6
module t (/*AUTOARG*/
7
   // Inputs
8
   clk
9
   );
10

  
11
   input clk;
12

  
13
   logic       use_AnB;
14

  
15
   logic [1:0] active_command  [8:0];
16
   logic [1:0] command_A       [8:0];
17
   logic [1:0] command_B       [8:0];
18

  
19
   logic [1:0] active_command2 [8:0];
20
   logic [1:0] command_A2      [7:0];
21
   logic [1:0] command_B2      [8:0];
22

  
23
   logic [1:0] active_command3 [1:0][2:0][3:0];
24
   logic [1:0] command_A3      [1:0][2:0][3:0];
25
   logic [1:0] command_B3      [1:0][2:0][3:0];
26

  
27
   logic [1:0] active_command4 [8:0];
28
   logic [1:0] command_A4      [7:0];
29

  
30
   logic [1:0] active_command5 [8:0];
31
   logic [1:0] command_A5      [7:0];
32

  
33
   // Single dimension assign
34
   assign active_command[3:0] = (use_AnB) ? command_A[7:0] : command_B[7:0];
35
   // Assignment of entire arrays
36
   assign active_command2 = (use_AnB) ? command_A2 : command_B2;
37
   // Multi-dimension assign
38
   assign active_command3[1:0][2:0][3:0] = (use_AnB) ?  command_A3[1:0][2:0][3:0] : command_B3[1:0][1:0][3:0];
39

  
40
   // Supported: Delayed assigment with RHS Var == LHS Var
41
   logic [7:0] arrd [7:0];
42
   always_ff @(posedge clk) arrd[7:4] <= arrd[3:0];
43

  
44
   // Unsupported: Non-delayed assigment with RHS Var == LHS Var
45
   logic [7:0] arr [7:0];
46
   assign arr[7:4] = arr[3:0];
47

  
48
   // Delayed assign
49
   always @(posedge clk) begin
50
      active_command4[7:0] <= command_A4[8:0];
51
   end
52

  
53
   // Combinational assign
54
   always_comb begin
55
      active_command5[8:0] = command_A5[7:0];
56
   end
57

  
58
endmodule : t