📄 verilog.cc
字号:
/* * Copyright (C) 2000-2001 moe * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */#include "Verilog.hh"FILE* verilog_input;string verilog_file;string verilog_comment;moe::Verilog* source_;namespace moe{ static char* opName_[] = { "ArithmeticAdd", "ArithmeticMinus", "ArithmeticMultiply", "ArithmeticDivide", "ArithmeticModulus", "ArithmeticLeftShift", "ArithmeticRightShift", "ArithmeticPower", "LeftShift", "RightShift", "LessThan", "GreaterThan", "LessEqual", "GreaterEqual", "CaseEquality", "CaseInequality", "LogicalNegation", "LogicalAND", "LogicalOR", "LogicalEquality", "LogicalInequality", "BitwiseAND", "BitwiseOR", "BitwiseNOR", "BitwiseNXOR", "BitwiseXOR", "BitwiseNegation", "ReductionAND", "ReductionNAND", "ReductionNOR", "ReductionNXOR", "ReductionXOR", "ReductionOR", "CastUnsigned", "CastSigned" }; static char* opToken_[] = { "+", // ArithmeticAdd, "-", // ArithmeticMinus, "*", // ArithmeticMultiply, "/", // ArithmeticDivide, "%%", // ArithmeticModulus, "<<<", // ArithmeticLeftShift, ">>>", // ArithmeticRightShift, "**", // ArithmeticPower, "<<", // LeftShift, ">>", // RightShift, "<", // LessThan, ">", // GreaterThan, "<=", // LessEqual, ">=", // GreaterEqual, "===", // CaseEquality, "!==", // CaseInequality, "!", // LogicalNegation, "&&", // LogicalAND, "||", // LogicalOR, "==", // LogicalEquality, "!=", // LogicalInequality, "&", // BitwiseAND, "|", // BitwiseOR, "~|", // BitwiseNOR, "~^", // BitwiseNXOR, "^", // BitwiseXOR, "~", // BitwiseNegation, "&", // ReductionAND, "~&", // ReductionNAND, "~|", // ReductionNOR, "~^", // ReductionNXOR, "^", // ReductionXOR, "|", // ReductionOR, "$unsigned", // CastUnsigned, "$signed", // CastSigned }; static void printName(ostream& ostr,const string& name) { ostr << name; if( name.c_str()[0]=='\\' ) ostr << ' '; } //////////////////////////////////////////////////////////////////////// // Verilog::Number //////////////////////////////////// Verilog::Number::Number(const char* text): text_(text) { static const char* BIN_NUM ="01XZ"; static const char* OCT_NUM ="01234567XZ"; static const char* HEX_NUM ="0123456789ABCDEFXZ"; vector<char> bits; const char* ptr; int base; unsigned int width; ptr =strchr(text,'\''); if( ptr!=NULL ) { ptr =text; width =0; for( ;*ptr!='\'';ptr++ ) if( isdigit(*ptr) ) { width *=10; width +=int(*ptr-'0'); } if( width==0 ) width =32; ptr++; if( *ptr!=0 ) { if( *ptr=='b' || *ptr=='B' ) base =2; else if( *ptr=='o' || *ptr=='O' ) base =8; else if( *ptr=='h' || *ptr=='H' ) base =16; else base =10; } else base =10; } else { width =32; base =10; ptr =text; } int i; unsigned long val; if( base==10 ) { val =0; for( ;*ptr!=0;ptr++ ) if( isdigit(*ptr) ) { val *=10; val +=int(*ptr-'0'); } for(i=0;i<width;i++) bits.push_back( ((val>>i)&1) ? '1' : '0' ); } else { i =0; char* idx; ptr =text+strlen(text)-1; for( ;*ptr!='\'';ptr-- ) { switch( base ) { case 2: idx =index(BIN_NUM,toupper(*ptr)); if( idx!=NULL ) if( bits.size()<width ) bits.push_back( *idx ); break; case 8: idx =index(OCT_NUM,toupper(*ptr)); if( idx!=NULL ) { val =int(idx-OCT_NUM); if( val < 8 ) for( i=0;i<3;i++ ) if( bits.size()<width ) bits.push_back( ((val>>i)&1) ? '1' : '0' ); else for( i=0;i<3;i++ ) if( bits.size()<width ) bits.push_back( *idx ); } break; case 16: idx =index(HEX_NUM,toupper(*ptr)); if( idx!=NULL ) { val =int(idx-HEX_NUM); if( val < 16 ) for( i=0;i<4;i++ ) if( bits.size()<width ) bits.push_back( ((val>>i)&1) ? '1' : '0' ); else for( i=0;i<4;i++ ) if( bits.size()<width ) bits.push_back( *idx ); } break; } if( ptr==text ) break; } } for( i=bits.size();i<width;i++ ) bits.push_back( '0' ); for( i=width-1;i>=0;i-- ) bitset_ +=bits[i]; if( isPartial() ) { string::iterator i; string tmp =bitset_; for( i=tmp.begin();i!=tmp.end();++i ) if( ((*i)=='X') || ((*i)=='Z') || ((*i)=='?') ) (*i) ='0'; value_ =tmp; tmp =bitset_; for( i=tmp.begin();i!=tmp.end();++i ) if( ((*i)=='1') || ((*i)=='0') ) (*i) ='1'; else (*i) ='0'; mask_ =tmp; } else { value_ =bitset_; } width_ =bitset_.size(); } bool Verilog::Number::isPartial() const { if( bitset_.find('X')!=string::npos ) return( true ); if( bitset_.find('?')!=string::npos ) return( true ); if( bitset_.find('Z')!=string::npos ) return( true ); return( false ); } uint64_t Verilog::Number::calcConstant() const { uint64_t ret =0; int i; for( i=0;i<bitset_.size();i++ ) { ret =ret<<1; if( bitset_[i]=='1' ) ret |=1; } return ret; } void Verilog::Number::toXML(std::ostream& ostr) const { ostr << bitset_; } void Verilog::Number::toVerilog(std::ostream& ostr) const { ostr << text_; } void Verilog::Number::link(const map<string,Net*>& net,Module* mod) { /** string tmp =bitset_; string::iterator i; { for( i=tmp.begin();i!=tmp.end();++i ) if( ((*i)=='X') ||((*i)=='Z') ) (*i)='0'; value_ =mod->newNet(tmp.c_str(),Net::CONSTANT,width()-1,0,Net::PRIVATE,0,0); } if( isPartial() ) { tmp =bitset_; for( i=tmp.begin();i!=tmp.end();++i ) if( ((*i)=='1') ||((*i)=='0') ) (*i)='1'; else if( ((*i)=='X') ||((*i)=='Z') ) (*i)='0'; mask_ =mod->newNet(tmp.c_str(),Net::MASK,width()-1,0,Net::PRIVATE,0,0); } **/ } void Verilog::Number::callback(Callback& cb) const { cb.trap( this ); } //////////////////////////////////////////////////////////////////////// // Verilog::Identifier //////////////////////////////////// Verilog::Identifier::~Identifier() { delete msb_; delete lsb_; delete idx_; } void Verilog::Identifier::toXML(std::ostream& ostr) const { ostr << name_; if( idx_!=NULL ) { ostr << '['; idx_->toXML(ostr); ostr << ']'; } else if( msb_!=NULL && lsb_!=NULL ) { ostr << '['; msb_->toXML(ostr); ostr << ':'; lsb_->toXML(ostr); ostr << ']'; } } void Verilog::Identifier::toVerilog(std::ostream& ostr) const { printName( ostr,name_ ); if( idx_!=NULL ) { ostr << '['; idx_->toVerilog(ostr); ostr << ']'; } else if( msb_!=NULL && lsb_!=NULL ) { ostr << '['; msb_->toVerilog(ostr); ostr << ':'; lsb_->toVerilog(ostr); ostr << ']'; } } bool Verilog::Identifier::isPartial() const { if( idx_!=NULL ) { return true; } else if( msb_!=NULL && lsb_!=NULL ) { if( net_!=NULL ) { if( net_->msb()!=NULL && net_->lsb()!=NULL ) { if( (msb_->calcConstant()==net_->msb()->calcConstant()) && (lsb_->calcConstant()==net_->lsb()->calcConstant()) ) return false; else return true; } else { return true; } } else { std::cerr << " can't estimate. " << name_ << " is not linked.\n"; return true; } } else return false; } unsigned int Verilog::Identifier::width() const { if( idx_!=NULL ) { if( net_->isArray() ) return net_->width(); else return 1; } else if( msb_!=NULL && lsb_!=NULL ) { return (msb_->calcConstant()-lsb_->calcConstant()+1); } else { return net_->width(); } } void Verilog::Identifier::link(const map<string,Net*>& net,Module* mod) { if( msb_!=NULL ) msb_->link(net,mod); if( lsb_!=NULL ) lsb_->link(net,mod); if( idx_!=NULL ) idx_->link(net,mod); // HIDENTIFIER // DIDENTIFIER bool hie=false; if( (name_.c_str()[0]!='\\')&& (name_.c_str()[0]!='`') ) if( name_.find(".")!=string::npos ) { hie =true; name_ ='\\' + name_; } { int i; while( (i=name_.find(".\\"))!=string::npos ) name_.replace(i,2,"."); } map<string,Net*>::const_iterator i =net.find(name_); if( i!=net.end() ) { net_ =i->second; } else { if( name_.c_str()[0]=='`' ) { std::cerr << "not defined identifier : " << name_ << std::endl; } else if( !hie ) { std::cerr << "implicit identifier : " << name_ << std::endl; net_ =mod->newNet( name_.c_str(),Verilog::Net::IMPLICIT ); } } } Verilog::Expression* Verilog::Identifier::clone(const string& hname) const { Verilog::Identifier* ret =new Identifier(); if( name_.c_str()[0]=='`' ) // global defined name ret->name_ =name_; else ret->name_ =hname + name_; ret->msb_ =(msb_!=NULL) ? msb_->clone(hname) : NULL; ret->lsb_ =(lsb_!=NULL) ? lsb_->clone(hname) : NULL; ret->idx_ =(idx_!=NULL) ? idx_->clone(hname) : NULL; return ret; } Verilog::Expression* Verilog::Identifier::clone() const { Verilog::Identifier* ret =new Identifier(); ret->name_ =name_; ret->msb_ =(msb_!=NULL) ? msb_->clone() : NULL; ret->lsb_ =(lsb_!=NULL) ? lsb_->clone() : NULL; ret->idx_ =(idx_!=NULL) ? idx_->clone() : NULL; return ret; } void Verilog::Identifier::chain(set<const Net*>& ev) const { if( net_!=NULL ) ev.insert(net_); if( msb_!=NULL ) msb_->chain(ev); if( lsb_!=NULL ) lsb_->chain(ev); if( idx_!=NULL ) idx_->chain(ev); } void Verilog::Identifier::chain(set<const Expression*>& ev) const { ev.insert((Expression*)this); if( msb_!=NULL ) msb_->chain(ev); if( lsb_!=NULL ) lsb_->chain(ev); if( idx_!=NULL ) idx_->chain(ev); } void Verilog::Identifier::callback(Callback& cb) const { cb.trap( this ); } //////////////////////////////////////////////////////////////////////// // Verilog::Concat
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -