Parse multi-dimension packed arrays to pform.
This commit is contained in:
parent
5d35ad8a0d
commit
950e7a632c
4
PExpr.cc
4
PExpr.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2011 Stephen Williams <steve@icarus.com>
|
* Copyright (c) 1998-2012 Stephen Williams <steve@icarus.com>
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -346,7 +346,7 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||||
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||||
net->set_file(get_file());
|
net->set_file(get_file());
|
||||||
net->set_lineno(get_lineno());
|
net->set_lineno(get_lineno());
|
||||||
net->set_range(0, 0, SR_NET, true);
|
net->set_range_scalar(SR_NET);
|
||||||
scope->wires[name] = net;
|
scope->wires[name] = net;
|
||||||
if (warn_implicit) {
|
if (warn_implicit) {
|
||||||
cerr << get_fileline() << ": warning: implicit "
|
cerr << get_fileline() << ": warning: implicit "
|
||||||
|
|
|
||||||
69
PWire.cc
69
PWire.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -28,8 +28,7 @@ PWire::PWire(perm_string n,
|
||||||
ivl_variable_type_t dt)
|
ivl_variable_type_t dt)
|
||||||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||||
signed_(false), isint_(false),
|
signed_(false), isint_(false),
|
||||||
port_msb_(0), port_lsb_(0), port_set_(false),
|
port_set_(false), net_set_(false), is_scalar_(false),
|
||||||
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
|
|
||||||
error_cnt_(0), lidx_(0), ridx_(0), enum_type_(0), struct_type_(0),
|
error_cnt_(0), lidx_(0), ridx_(0), enum_type_(0), struct_type_(0),
|
||||||
discipline_(0)
|
discipline_(0)
|
||||||
{
|
{
|
||||||
|
|
@ -149,8 +148,9 @@ bool PWire::get_scalar() const
|
||||||
return is_scalar_;
|
return is_scalar_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
|
void PWire::set_range_scalar(PWSRType type)
|
||||||
{
|
{
|
||||||
|
is_scalar_ = true;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SR_PORT:
|
case SR_PORT:
|
||||||
if (port_set_) {
|
if (port_set_) {
|
||||||
|
|
@ -158,10 +158,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
|
||||||
<< "'' has already been declared a port." << endl;
|
<< "'' has already been declared a port." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
} else {
|
} else {
|
||||||
port_msb_ = m;
|
|
||||||
port_lsb_ = l;
|
|
||||||
port_set_ = true;
|
port_set_ = true;
|
||||||
is_scalar_ = is_scalar;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -171,10 +168,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
|
||||||
<< "'' has already been declared." << endl;
|
<< "'' has already been declared." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
} else {
|
} else {
|
||||||
net_msb_ = m;
|
|
||||||
net_lsb_ = l;
|
|
||||||
net_set_ = true;
|
net_set_ = true;
|
||||||
is_scalar_ = is_scalar;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -191,13 +185,58 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
port_msb_ = m;
|
|
||||||
port_lsb_ = l;
|
|
||||||
port_set_ = true;
|
port_set_ = true;
|
||||||
net_msb_ = m;
|
|
||||||
net_lsb_ = l;
|
|
||||||
net_set_ = true;
|
net_set_ = true;
|
||||||
is_scalar_ = is_scalar;
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PWire::set_range(const list<PWire::range_t>&rlist, PWSRType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case SR_PORT:
|
||||||
|
if (port_set_) {
|
||||||
|
cerr << get_fileline() << ": error: Port ``" << name_
|
||||||
|
<< "'' has already been declared a port." << endl;
|
||||||
|
error_cnt_ += 1;
|
||||||
|
} else {
|
||||||
|
port_ = rlist;
|
||||||
|
port_set_ = true;
|
||||||
|
is_scalar_ = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SR_NET:
|
||||||
|
if (net_set_) {
|
||||||
|
cerr << get_fileline() << ": error: Net ``" << name_
|
||||||
|
<< "'' has already been declared." << endl;
|
||||||
|
error_cnt_ += 1;
|
||||||
|
} else {
|
||||||
|
net_ = rlist;
|
||||||
|
net_set_ = true;
|
||||||
|
is_scalar_ = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SR_BOTH:
|
||||||
|
if (port_set_ || net_set_) {
|
||||||
|
if (port_set_) {
|
||||||
|
cerr << get_fileline() << ": error: Port ``" << name_
|
||||||
|
<< "'' has already been declared a port." << endl;
|
||||||
|
error_cnt_ += 1;
|
||||||
|
}
|
||||||
|
if (net_set_) {
|
||||||
|
cerr << get_fileline() << ": error: Net ``" << name_
|
||||||
|
<< "'' has already been declared." << endl;
|
||||||
|
error_cnt_ += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port_ = rlist;
|
||||||
|
port_set_ = true;
|
||||||
|
net_ = rlist;
|
||||||
|
net_set_ = true;
|
||||||
|
is_scalar_ = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
PWire.h
24
PWire.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __PWire_H
|
#ifndef __PWire_H
|
||||||
#define __PWire_H
|
#define __PWire_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2009,2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
# include "svector.h"
|
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
|
|
||||||
#ifdef HAVE_IOSFWD
|
#ifdef HAVE_IOSFWD
|
||||||
|
|
@ -51,6 +51,11 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
|
||||||
* the wire name.
|
* the wire name.
|
||||||
*/
|
*/
|
||||||
class PWire : public LineInfo {
|
class PWire : public LineInfo {
|
||||||
|
public:
|
||||||
|
struct range_t {
|
||||||
|
PExpr*msb;
|
||||||
|
PExpr*lsb;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PWire(perm_string name,
|
PWire(perm_string name,
|
||||||
|
|
@ -75,7 +80,8 @@ class PWire : public LineInfo {
|
||||||
bool set_data_type(ivl_variable_type_t dt);
|
bool set_data_type(ivl_variable_type_t dt);
|
||||||
ivl_variable_type_t get_data_type() const;
|
ivl_variable_type_t get_data_type() const;
|
||||||
|
|
||||||
void set_range(PExpr*msb, PExpr*lsb, PWSRType type, bool is_scalar);
|
void set_range_scalar(PWSRType type);
|
||||||
|
void set_range(const std::list<range_t>&ranges, PWSRType type);
|
||||||
|
|
||||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||||
|
|
||||||
|
|
@ -101,12 +107,14 @@ class PWire : public LineInfo {
|
||||||
bool isint_; // original type of integer
|
bool isint_; // original type of integer
|
||||||
|
|
||||||
// These members hold expressions for the bit width of the
|
// These members hold expressions for the bit width of the
|
||||||
// wire. If they do not exist, the wire is 1 bit wide.
|
// wire. If they do not exist, the wire is 1 bit wide. If they
|
||||||
PExpr*port_msb_;
|
// do exist, they represent the packed dimensions of the
|
||||||
PExpr*port_lsb_;
|
// bit. The first item in the list is the first range, and so
|
||||||
|
// on. For example "reg [3:0][7:0] ..." will contains the
|
||||||
|
// range_t object for [3:0] first and [7:0] last.
|
||||||
|
std::list<range_t>port_;
|
||||||
bool port_set_;
|
bool port_set_;
|
||||||
PExpr*net_msb_;
|
std::list<range_t>net_;
|
||||||
PExpr*net_lsb_;
|
|
||||||
bool net_set_;
|
bool net_set_;
|
||||||
bool is_scalar_;
|
bool is_scalar_;
|
||||||
unsigned error_cnt_;
|
unsigned error_cnt_;
|
||||||
|
|
|
||||||
68
elab_sig.cc
68
elab_sig.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -890,29 +890,31 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
|
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
|
||||||
bool bad_lsb = false, bad_msb = false;
|
bool bad_lsb = false, bad_msb = false;
|
||||||
/* If they exist get the port definition MSB and LSB */
|
/* If they exist get the port definition MSB and LSB */
|
||||||
if (port_set_ && port_msb_ != 0) {
|
if (port_set_ && !port_.empty()) {
|
||||||
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1, true);
|
assert(port_.size() == 1);
|
||||||
|
PWire::range_t rng = port_.front();
|
||||||
|
NetExpr*texpr = elab_and_eval(des, scope, rng.msb, -1, true);
|
||||||
|
|
||||||
if (! eval_as_long(pmsb, texpr)) {
|
if (! eval_as_long(pmsb, texpr)) {
|
||||||
cerr << port_msb_->get_fileline() << ": error: "
|
cerr << rng.msb->get_fileline() << ": error: "
|
||||||
"Range expressions must be constant." << endl;
|
"Range expressions must be constant." << endl;
|
||||||
cerr << port_msb_->get_fileline() << " : "
|
cerr << rng.msb->get_fileline() << " : "
|
||||||
"This MSB expression violates the rule: "
|
"This MSB expression violates the rule: "
|
||||||
<< *port_msb_ << endl;
|
<< *rng.msb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
bad_msb = true;
|
bad_msb = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete texpr;
|
delete texpr;
|
||||||
|
|
||||||
texpr = elab_and_eval(des, scope, port_lsb_, -1, true);
|
texpr = elab_and_eval(des, scope, rng.lsb, -1, true);
|
||||||
|
|
||||||
if (! eval_as_long(plsb, texpr)) {
|
if (! eval_as_long(plsb, texpr)) {
|
||||||
cerr << port_lsb_->get_fileline() << ": error: "
|
cerr << rng.lsb->get_fileline() << ": error: "
|
||||||
"Range expressions must be constant." << endl;
|
"Range expressions must be constant." << endl;
|
||||||
cerr << port_lsb_->get_fileline() << " : "
|
cerr << rng.lsb->get_fileline() << " : "
|
||||||
"This LSB expression violates the rule: "
|
"This LSB expression violates the rule: "
|
||||||
<< *port_lsb_ << endl;
|
<< *rng.lsb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
bad_lsb = true;
|
bad_lsb = true;
|
||||||
}
|
}
|
||||||
|
|
@ -923,49 +925,53 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
/* An implicit port can have a range so note that here. */
|
/* An implicit port can have a range so note that here. */
|
||||||
is_implicit_scalar = false;
|
is_implicit_scalar = false;
|
||||||
}
|
}
|
||||||
if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
|
if (!port_set_) assert(port_.empty());
|
||||||
if (port_msb_ == 0) assert(port_lsb_ == 0);
|
|
||||||
if (port_lsb_ == 0) assert(port_msb_ == 0);
|
if (net_.size() > 1) {
|
||||||
|
cerr << net_.back().msb->get_fileline() << ": sorry: "
|
||||||
|
<< "Multi-dimension packed arrays not supported."
|
||||||
|
<< endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* If they exist get the net/etc. definition MSB and LSB */
|
/* If they exist get the net/etc. definition MSB and LSB */
|
||||||
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
|
if (net_set_ && !net_.empty() && !bad_msb && !bad_lsb) {
|
||||||
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1, true);
|
PWire::range_t rng = net_.front();
|
||||||
|
NetExpr*texpr = elab_and_eval(des, scope, rng.msb, -1, true);
|
||||||
|
|
||||||
if (! eval_as_long(nmsb, texpr)) {
|
if (! eval_as_long(nmsb, texpr)) {
|
||||||
cerr << net_msb_->get_fileline() << ": error: "
|
cerr << rng.msb->get_fileline() << ": error: "
|
||||||
"Range expressions must be constant." << endl;
|
"Range expressions must be constant." << endl;
|
||||||
cerr << net_msb_->get_fileline() << " : "
|
cerr << rng.msb->get_fileline() << " : "
|
||||||
"This MSB expression violates the rule: "
|
"This MSB expression violates the rule: "
|
||||||
<< *net_msb_ << endl;
|
<< *rng.msb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
bad_msb = true;
|
bad_msb = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete texpr;
|
delete texpr;
|
||||||
|
|
||||||
texpr = elab_and_eval(des, scope, net_lsb_, -1, true);
|
texpr = elab_and_eval(des, scope, rng.lsb, -1, true);
|
||||||
|
|
||||||
if (! eval_as_long(nlsb, texpr)) {
|
if (! eval_as_long(nlsb, texpr)) {
|
||||||
cerr << net_lsb_->get_fileline() << ": error: "
|
cerr << rng.lsb->get_fileline() << ": error: "
|
||||||
"Range expressions must be constant." << endl;
|
"Range expressions must be constant." << endl;
|
||||||
cerr << net_lsb_->get_fileline() << " : "
|
cerr << rng.lsb->get_fileline() << " : "
|
||||||
"This LSB expression violates the rule: "
|
"This LSB expression violates the rule: "
|
||||||
<< *net_lsb_ << endl;
|
<< *rng.lsb << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
bad_lsb = true;
|
bad_lsb = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete texpr;
|
delete texpr;
|
||||||
}
|
}
|
||||||
if (!net_set_) assert(net_msb_ == 0 && net_lsb_ == 0);
|
if (!net_set_) assert(net_.empty());
|
||||||
if (net_msb_ == 0) assert(net_lsb_ == 0);
|
|
||||||
if (net_lsb_ == 0) assert(net_msb_ == 0);
|
|
||||||
|
|
||||||
/* We have a port size error */
|
/* We have a port size error */
|
||||||
if (port_set_ && net_set_ && (pmsb != nmsb || plsb != nlsb)) {
|
if (port_set_ && net_set_ && (pmsb != nmsb || plsb != nlsb)) {
|
||||||
|
|
||||||
/* Scalar port with a vector net/etc. definition */
|
/* Scalar port with a vector net/etc. definition */
|
||||||
if (port_msb_ == 0) {
|
if (port_.empty()) {
|
||||||
if (!gn_io_range_error_flag) {
|
if (!gn_io_range_error_flag) {
|
||||||
cerr << get_fileline()
|
cerr << get_fileline()
|
||||||
<< ": warning: Scalar port ``" << name_
|
<< ": warning: Scalar port ``" << name_
|
||||||
|
|
@ -982,8 +988,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vectored port with a scalar net/etc. definition */
|
/* Vectored port with a scalar net/etc. definition */
|
||||||
if (net_msb_ == 0) {
|
if (net_.empty()) {
|
||||||
cerr << port_msb_->get_fileline()
|
cerr << port_.front().msb->get_fileline()
|
||||||
<< ": error: Vectored port ``"
|
<< ": error: Vectored port ``"
|
||||||
<< name_ << "'' [" << pmsb << ":" << plsb
|
<< name_ << "'' [" << pmsb << ":" << plsb
|
||||||
<< "] has a scalar net declaration at "
|
<< "] has a scalar net declaration at "
|
||||||
|
|
@ -993,12 +999,12 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Both vectored, but they have different ranges. */
|
/* Both vectored, but they have different ranges. */
|
||||||
if (port_msb_ != 0 && net_msb_ != 0) {
|
if (!port_.empty() && !net_.empty()) {
|
||||||
cerr << port_msb_->get_fileline()
|
cerr << port_.front().msb->get_fileline()
|
||||||
<< ": error: Vectored port ``"
|
<< ": error: Vectored port ``"
|
||||||
<< name_ << "'' [" << pmsb << ":" << plsb
|
<< name_ << "'' [" << pmsb << ":" << plsb
|
||||||
<< "] has a net declaration [" << nmsb << ":"
|
<< "] has a net declaration [" << nmsb << ":"
|
||||||
<< nlsb << "] at " << net_msb_->get_fileline()
|
<< nlsb << "] at " << net_.front().msb->get_fileline()
|
||||||
<< " that does not match." << endl;
|
<< " that does not match." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
15
parse.y
15
parse.y
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -3931,12 +3931,19 @@ range
|
||||||
tmp->push_back($4);
|
tmp->push_back($4);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| range '[' expression ':' expression ']'
|
||||||
|
{ list<PExpr*>*tmp = $1;
|
||||||
|
tmp->push_back($3);
|
||||||
|
tmp->push_back($5);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
range_opt
|
range_opt
|
||||||
: range
|
: range
|
||||||
| { $$ = 0; }
|
| { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
dimensions_opt
|
dimensions_opt
|
||||||
: { $$ = 0; }
|
: { $$ = 0; }
|
||||||
| dimensions { $$ = $1; }
|
| dimensions { $$ = $1; }
|
||||||
|
|
|
||||||
82
pform.cc
82
pform.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -1480,6 +1480,20 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
||||||
delete init_expr;
|
delete init_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ranges_from_list(list<PWire::range_t>&rlist, const list<PExpr*>*range)
|
||||||
|
{
|
||||||
|
// There must be an even number of expressions in the
|
||||||
|
// range. The parser will assure that for us.
|
||||||
|
assert(range->size()%2 == 0);
|
||||||
|
list<PExpr*>::const_iterator rcur = range->begin();
|
||||||
|
while (rcur != range->end()) {
|
||||||
|
PWire::range_t rng;
|
||||||
|
rng.msb = *rcur; ++rcur;
|
||||||
|
rng.lsb = *rcur; ++rcur;
|
||||||
|
rlist.push_back(rng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function attaches a range to a given name. The function is
|
* This function attaches a range to a given name. The function is
|
||||||
* only called by the parser within the scope of the net declaration,
|
* only called by the parser within the scope of the net declaration,
|
||||||
|
|
@ -1500,11 +1514,12 @@ static void pform_set_net_range(perm_string name,
|
||||||
if (range == 0) {
|
if (range == 0) {
|
||||||
/* This is the special case that we really mean a
|
/* This is the special case that we really mean a
|
||||||
scalar. Set a fake range. */
|
scalar. Set a fake range. */
|
||||||
cur->set_range(0, 0, rt, true);
|
cur->set_range_scalar(rt);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(range->size() == 2);
|
list<PWire::range_t> rlist;
|
||||||
cur->set_range(range->front(), range->back(), rt, false);
|
ranges_from_list(rlist, range);
|
||||||
|
cur->set_range(rlist, rt);
|
||||||
}
|
}
|
||||||
cur->set_signed(signed_flag);
|
cur->set_signed(signed_flag);
|
||||||
|
|
||||||
|
|
@ -1515,15 +1530,14 @@ static void pform_set_net_range(perm_string name,
|
||||||
void pform_set_net_range(list<perm_string>*names,
|
void pform_set_net_range(list<perm_string>*names,
|
||||||
list<PExpr*>*range,
|
list<PExpr*>*range,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
ivl_variable_type_t dt,
|
ivl_variable_type_t dt)
|
||||||
PWSRType rt)
|
|
||||||
{
|
{
|
||||||
assert((range == 0) || (range->size() == 2));
|
assert((range == 0) || (range->size()%2 == 0));
|
||||||
|
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
for (list<perm_string>::iterator cur = names->begin()
|
||||||
; cur != names->end() ; ++ cur ) {
|
; cur != names->end() ; ++ cur ) {
|
||||||
perm_string txt = *cur;
|
perm_string txt = *cur;
|
||||||
pform_set_net_range(txt, range, signed_flag, dt, rt);
|
pform_set_net_range(txt, range, signed_flag, dt, SR_NET);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete names;
|
delete names;
|
||||||
|
|
@ -1884,17 +1898,12 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
cur->set_signed(signed_flag);
|
cur->set_signed(signed_flag);
|
||||||
|
|
||||||
if (range == 0) {
|
if (range == 0) {
|
||||||
cur->set_range(0, 0, (type == NetNet::IMPLICIT) ? SR_PORT :
|
cur->set_range_scalar((type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
|
||||||
SR_BOTH,
|
|
||||||
true);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(range->size() == 2);
|
list<PWire::range_t> rlist;
|
||||||
assert(range->front());
|
ranges_from_list(rlist, range);
|
||||||
assert(range->back());
|
cur->set_range(rlist, (type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
|
||||||
cur->set_range(range->front(), range->back(),
|
|
||||||
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pform_bind_attributes(cur->attributes, attr);
|
pform_bind_attributes(cur->attributes, attr);
|
||||||
|
|
@ -1981,7 +1990,7 @@ void pform_makewire(const vlltype&li, perm_string name,
|
||||||
<< " to " << dt << "." << endl;
|
<< " to " << dt << "." << endl;
|
||||||
}
|
}
|
||||||
ivl_assert(*cur, flag);
|
ivl_assert(*cur, flag);
|
||||||
cur->set_range(0, 0, SR_NET, true);
|
cur->set_range_scalar(SR_NET);
|
||||||
cur->set_signed(true);
|
cur->set_signed(true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2168,8 +2177,9 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
|
|
||||||
/* If there is a range involved, it needs to be set. */
|
/* If there is a range involved, it needs to be set. */
|
||||||
if (range) {
|
if (range) {
|
||||||
assert(range->size() == 2);
|
list<PWire::range_t> rlist;
|
||||||
curw->set_range(range->front(), range->back(), SR_PORT, false);
|
ranges_from_list(rlist, range);
|
||||||
|
curw->set_range(rlist, SR_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
|
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
|
||||||
|
|
@ -2458,9 +2468,12 @@ static void pform_set_reg_integer(perm_string name)
|
||||||
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||||
assert(cur);
|
assert(cur);
|
||||||
|
|
||||||
cur->set_range(new PENumber(new verinum(integer_width-1, integer_width)),
|
PWire::range_t rng;
|
||||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
rng.msb = new PENumber(new verinum(integer_width-1, integer_width));
|
||||||
SR_NET, false);
|
rng.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
list<PWire::range_t>rlist;
|
||||||
|
rlist.push_back(rng);
|
||||||
|
cur->set_range(rlist, SR_NET);
|
||||||
cur->set_signed(true);
|
cur->set_signed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2479,9 +2492,12 @@ static void pform_set_reg_time(perm_string name)
|
||||||
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||||
assert(cur);
|
assert(cur);
|
||||||
|
|
||||||
cur->set_range(new PENumber(new verinum(TIME_WIDTH-1, integer_width)),
|
PWire::range_t rng;
|
||||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
rng.msb = new PENumber(new verinum(TIME_WIDTH-1, integer_width));
|
||||||
SR_NET, false);
|
rng.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
list<PWire::range_t>rlist;
|
||||||
|
rlist.push_back(rng);
|
||||||
|
cur->set_range(rlist, SR_NET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_reg_time(list<perm_string>*names)
|
void pform_set_reg_time(list<perm_string>*names)
|
||||||
|
|
@ -2500,9 +2516,13 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_strin
|
||||||
assert(cur);
|
assert(cur);
|
||||||
|
|
||||||
cur->set_signed(signed_flag);
|
cur->set_signed(signed_flag);
|
||||||
cur->set_range(new PENumber(new verinum(width-1, integer_width)),
|
|
||||||
new PENumber(new verinum((uint64_t)0, integer_width)),
|
PWire::range_t rng;
|
||||||
SR_NET, false);
|
rng.msb = new PENumber(new verinum(width-1, integer_width));
|
||||||
|
rng.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
|
||||||
|
list<PWire::range_t>rlist;
|
||||||
|
rlist.push_back(rng);
|
||||||
|
cur->set_range(rlist, SR_NET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names)
|
void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names)
|
||||||
|
|
@ -2545,7 +2565,9 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
|
||||||
|
|
||||||
assert(enum_type->range.get() != 0);
|
assert(enum_type->range.get() != 0);
|
||||||
assert(enum_type->range->size() == 2);
|
assert(enum_type->range->size() == 2);
|
||||||
cur->set_range(enum_type->range->front(), enum_type->range->back(), SR_NET, false);
|
list<PWire::range_t>rlist;
|
||||||
|
ranges_from_list(rlist, enum_type->range.get());
|
||||||
|
cur->set_range(rlist, SR_NET);
|
||||||
cur->set_enumeration(enum_type);
|
cur->set_enumeration(enum_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
5
pform.h
5
pform.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __pform_H
|
#ifndef __pform_H
|
||||||
#define __pform_H
|
#define __pform_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -287,8 +287,7 @@ extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
||||||
extern void pform_set_net_range(list<perm_string>*names,
|
extern void pform_set_net_range(list<perm_string>*names,
|
||||||
list<PExpr*>*,
|
list<PExpr*>*,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
ivl_variable_type_t,
|
ivl_variable_type_t);
|
||||||
PWSRType rt = SR_NET);
|
|
||||||
extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r);
|
extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r);
|
||||||
extern void pform_set_reg_integer(list<perm_string>*names);
|
extern void pform_set_reg_integer(list<perm_string>*names);
|
||||||
extern void pform_set_reg_time(list<perm_string>*names);
|
extern void pform_set_reg_time(list<perm_string>*names);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -351,17 +351,23 @@ void PWire::dump(ostream&out, unsigned ind) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port_set_) {
|
if (port_set_) {
|
||||||
if (port_msb_ == 0) {
|
if (port_.empty()) {
|
||||||
out << " port<scalar>";
|
out << " port<scalar>";
|
||||||
} else {
|
} else {
|
||||||
out << " port[" << *port_msb_ << ":" << *port_lsb_ << "]";
|
out << " port";
|
||||||
|
for (list<PWire::range_t>::const_iterator cur = port_.begin()
|
||||||
|
; cur != port_.end() ; ++cur)
|
||||||
|
out << "[" << *cur->msb << ":" << *cur->lsb << "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (net_set_) {
|
if (net_set_) {
|
||||||
if (net_msb_ == 0) {
|
if (net_.empty()) {
|
||||||
out << " net<scalar>";
|
out << " net<scalar>";
|
||||||
} else {
|
} else {
|
||||||
out << " net[" << *net_msb_ << ":" << *net_lsb_ << "]";
|
out << " net";
|
||||||
|
for (list<PWire::range_t>::const_iterator cur = net_.begin()
|
||||||
|
; cur != net_.end() ; ++cur)
|
||||||
|
out << "[" << *cur->msb << ":" << *cur->lsb << "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue