📄 verilog2c++.cc
字号:
/* * Copyright (c) 2000-2002 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 <string>#include <cstdlib>#include <cstdio>#include <typeinfo>#include <fstream>#include <iostream>#include "Verilog.hh"namespace moe{ static void printProgress(ostream& ostr,double ratio) { if( ratio<0 ) ostr << "...."; else { ostr << "\b\b\b\b" << setw(3) << int(ratio) << '%';ostr.flush(); } } static void printNet(ostream& ostr,int indent,const Verilog::Net* net) { if( net->sign() ) { if( net->width()<=32 ) ostr << setw(indent) << "" << " int32_t "; else if( net->width()<=64 ) ostr << setw(indent) << "" << " int64_t "; else ostr << setw(indent) << "" << " IntN<" << setw(3) << net->width() << "> "; } else { if( net->width()<=32 ) ostr << setw(indent) << "" << "uint32_t "; else if( net->width()<=64 ) ostr << setw(indent) << "" << "uint64_t "; else ostr << setw(indent) << "" << "UIntN<" << setw(3) << net->width() << "> "; } ostr << 'n' << (uint)net; if( net->isArray() ) ostr << '[' << net->depth() << ']'; ostr << ";"; } static void printPort(ostream& ostr,int indent,const Verilog::Net* net,const string& name) { if( net->width()<=32 ) ostr << setw(indent) << "" << "uint32_t& "; else if( net->width()<=64 ) ostr << setw(indent) << "" << "uint64_t& "; else ostr << setw(indent) << "" << "UIntN<" << setw(3) << net->width() << ">& "; ostr << name << "() { return "; // hhstr.form("n%08X",i->second); ostr << 'n' << (uint)net; ostr << "; }"; } static void printClass(ostream& ostr,unsigned int width,int indent=0) { if( width<=32 ) ostr << setw(indent) << "" << "uint32_t "; else if( width<=64 ) ostr << setw(indent) << "" << "uint64_t "; else ostr << setw(indent) << "" << "UIntN<" << setw(3) << width << "> "; } static void printPort(ostream& ostr,unsigned int width,int indent=0) { if( width<=32 ) ostr << setw(indent) << "" << "uint32_t& "; else if( width<=64 ) ostr << setw(indent) << "" << "uint64_t& "; else ostr << setw(indent) << "" << "UIntN<" << setw(3) << width << ">& "; } static void printCast(ostream& ostr,unsigned int width) { if( width<=32 ) ostr << "uint32_t"; else if( width<=64 ) ostr << "uint64_t"; else ostr << "UIntN<" << setw(3) << width << ">"; } static void printRef(ostream& ostr,unsigned int width) { if( width<=32 ) ostr << "uint32_t"; else if( width<=64 ) ostr << "uint64_t"; else ostr << "const UIntN<" << setw(3) << width << ">&"; } static void printSignMask(ostream& ostr,unsigned int cast,unsigned int width) { if( cast<=32 ) ostr << (0xFFFFFFFFUL<<(width-1)) << "UL"; else if( cast<=64 ) ostr << (0xFFFFFFFFFFFFFFFFULL<<(width-1)) << "ULL"; else ostr << "SignMask(" << (width-1) << ')'; } static void printMask(ostream& ostr,unsigned int width, unsigned int msb,unsigned int lsb) { if( width<=32 ) ostr << ((0xFFFFFFFFUL>>(32-(msb-lsb+1)))<<lsb) << "UL"; else if( width<=64 ) ostr << ((0xFFFFFFFFFFFFFFFFULL>>(64-(msb-lsb+1)))<<lsb) << "ULL"; else ostr << "Mask(" << msb << ',' << lsb << ')'; } static void printMask(ostream& ostr,unsigned int width) { if( width<=32 ) ostr << (0xFFFFFFFFUL>>(32-width)) << "UL"; else if( width<=64 ) ostr << (0xFFFFFFFFFFFFFFFFULL>>(64-width)) << "ULL"; else ostr << "Mask(" << width << ')'; } static uint64_t calcConstant(const string& num) { uint64_t ret =0; int i; for( i=0;i<num.size();i++ ) { ret =ret<<1; if( num[i]=='1' ) ret |=1; } return ret; } //////////////////////////////////////////////////////////////////////// class Convert : public Verilog { //////////////////////////////////////////////////////////////////////// class RightExpression : public Callback { bool comm_; ostream& ostr_; unsigned int cast_; public: RightExpression(): comm_(true), ostr_(std::cout), cast_(32) {} RightExpression(bool comm,ostream& ostr,unsigned int cast): comm_(comm), ostr_(ostr), cast_(cast) {} ~RightExpression(){} void trap(const Number* self) { { if( self->width()<=32 ) ostr_ << self->calcConstant() << "UL"; else if( self->width()<=64 ) ostr_ << self->calcConstant() << "ULL"; else ostr_ << '\"' << self->value() << '\"'; } if( self->isPartial() ) { ostr_ << ','; if( self->width()<=32 ) ostr_ << calcConstant( self->mask() ) << "UL"; else if( self->width()<=64 ) ostr_ << calcConstant( self->mask() ) << "ULL"; else ostr_ << "Constant(" << self->mask() << ')'; } } void trap(const Identifier* self) { if( self->net()->isArray() ) { // ostr_.form("n%08X",self->net()); ostr_ << 'n' << (uint)self->net(); ostr_ << '['; self->idx()->callback( *this ); ostr_ << '-' << self->net()->sa()->calcConstant(); ostr_ << ']'; } else { if( self->idx()!=NULL ) { ostr_ << "EmVer::Index("; // ostr_.form("n%08X",self->net()); ostr_ << 'n' << (uint)self->net(); ostr_ << ','; ostr_ << self->idx()->calcConstant(); ostr_ << '-' << self->net()->lsb()->calcConstant(); ostr_ << ')'; } else if( self->msb()!=NULL && self->lsb()!=NULL ) { ostr_ << "EmVer::Part("; // ostr_.form("n%08X",self->net()); ostr_ << 'n' << (uint)self->net(); ostr_ << ','; if( self->net()->width() <=32 ) { ostr_ << self->lsb()->calcConstant(); ostr_ << '-' << self->net()->lsb()->calcConstant(); ostr_ << ','; // ostr_.form("0x%08XUL",0xFFFFFFFFUL>> ostr_ << (0xFFFFFFFFUL>> (31-(self->msb()->calcConstant()-self->lsb()->calcConstant()))) << "UL"; } else if( self->net()->width() <=64 ) { ostr_ << self->lsb()->calcConstant(); ostr_ << '-' << self->net()->lsb()->calcConstant(); ostr_ << ','; // ostr_.form("0x%016lXULL",0xFFFFFFFFFFFFFFFFULL>> ostr_ << (0xFFFFFFFFFFFFFFFFULL>> (63-(self->msb()->calcConstant()-self->lsb()->calcConstant()))) << "ULL"; } else { ostr_ << self->lsb()->calcConstant(); ostr_ << '-' << self->net()->lsb()->calcConstant(); ostr_ << ','; ostr_ << self->msb()->calcConstant(); ostr_ << '-' << self->lsb()->calcConstant(); } ostr_ << ')'; } else // ostr_.form("n%08X",self->net()); ostr_ << 'n' << (uint)self->net(); } } void trap(const Concat* self) { int cast=self->width(); if( self->repeat()!=NULL ) { ostr_ << "EmVer::Repeat("; ostr_ << self->repeat()->calcConstant(); ostr_ << ','; cast /=self->repeat()->calcConstant(); } if( self->list().size()==1 ) { printCast(ostr_,cast); ostr_ << '('; self->list().front()->callback( *this ); ostr_ << ')'; } else { { vector<Expression*>::const_iterator i; for( i=self->list().begin();i!=self->list().end();++i ) { if( (*i)!=self->list().back() ) { ostr_ << "EmVer::Concat("; printCast(ostr_,cast); ostr_ << '('; (*i)->callback( *this ); ostr_ << ')'; ostr_ << ','; } else { printCast(ostr_,cast); ostr_ << '('; (*i)->callback( *this ); ostr_ << ')'; } } } { vector<Expression*>::const_reverse_iterator i; int sum =0; for( i=self->list().rbegin();i!=self->list().rend();++i ) { if( (*i)!=self->list().front() ) { sum +=(*i)->width(); ostr_ << ','; ostr_ << sum; ostr_ << ')'; } } } } if( self->repeat()!=NULL ) { ostr_ << ','; ostr_ << cast; ostr_ << ')'; } } void trap(const Event* self) { std::cerr << " a event expression in this statement is failure profit. \n"; } //////////////////////////////////// void trap(const Unary* self) { switch( self->operation() ) { case Expression::ArithmeticMinus: ostr_ << "(-"; self->value()->callback( *this ); ostr_ << ')'; break; case Expression::BitwiseNegation: ostr_ << "((~"; self->value()->callback( *this ); ostr_ << ')'; ostr_ << "&"; printMask(ostr_,self->value()->width(),self->value()->width()-1,0); ostr_ << ')'; break; case Expression::LogicalNegation: ostr_ << "(!"; self->value()->callback( *this ); ostr_ << ')'; break; case Expression::ReductionAND: case Expression::ReductionOR: case Expression::ReductionXOR: case Expression::ReductionNAND: case Expression::ReductionNOR: case Expression::ReductionNXOR: ostr_ << "EmVer::" << self->opName(); ostr_ << '('; self->value()->callback( *this ); ostr_ << ','; printMask(ostr_,self->value()->width(),self->value()->width()-1,0); ostr_ << ')'; break; case Expression::CastSigned: ostr_ << "EmVer::SignExt"; ostr_ << '('; self->value()->callback( *this ); ostr_ << ','; printSignMask(ostr_,cast_,self->value()->width()); ostr_ << ')'; break; case Expression::CastUnsigned: break; } } //////////////////////////////////// void trap(const Binary* self) { switch( self->operation() ) { case Expression::ArithmeticMultiply: case Expression::ArithmeticDivide: case Expression::ArithmeticModulus: case Expression::ArithmeticAdd: case Expression::ArithmeticMinus: ostr_ << '('; /* if( self->width()!=self->left()->width() ) { ostr_ << '('; printCast(ostr_,self->width()); ostr_ << ')'; } */ ostr_ << '('; printCast(ostr_,cast_); ostr_ << ')'; self->left()->callback( *this ); switch( self->operation() ) { case Expression::ArithmeticMultiply: ostr_ << '*'; break; case Expression::ArithmeticDivide: ostr_ << '/'; break; case Expression::ArithmeticModulus: ostr_ << '%'; break; case Expression::ArithmeticAdd: ostr_ << '+'; break; case Expression::ArithmeticMinus: ostr_ << '-'; break; } /* if( self->width()!=self->right()->width() ) { ostr_ << '('; printCast(ostr_,self->width()); ostr_ << ')'; } */ ostr_ << '('; printCast(ostr_,cast_); ostr_ << ')'; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::BitwiseXOR: ostr_ << '('; self->left()->callback( *this ); ostr_ << '^'; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::BitwiseAND: ostr_ << '('; self->left()->callback( *this ); ostr_ << '&'; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::BitwiseOR: ostr_ << '('; self->left()->callback( *this ); ostr_ << '|'; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::BitwiseNOR: ostr_ << "((~("; self->left()->callback( *this ); ostr_ << '|'; self->right()->callback( *this ); ostr_ << "))"; ostr_ << "&"; printMask(ostr_,self->width(),self->width()-1,0); ostr_ << ')'; break; case Expression::BitwiseNXOR: ostr_ << "((~("; self->left()->callback( *this ); ostr_ << '^'; self->right()->callback( *this ); ostr_ << "))"; ostr_ << "&"; printMask(ostr_,self->width(),self->width()-1,0); ostr_ << ')'; break; case Expression::LeftShift: ostr_ << "(("; self->left()->callback( *this ); ostr_ << "<<"; self->right()->callback( *this ); ostr_ << ')'; // ostr_ << "&"; // printMask(ostr_,self->width(),self->width()-1,0); ostr_ << ')'; break; case Expression::RightShift: ostr_ << '('; self->left()->callback( *this ); ostr_ << ">>"; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::LogicalEquality: ostr_ << '('; self->left()->callback( *this ); ostr_ << "=="; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::LogicalInequality: ostr_ << '('; self->left()->callback( *this ); ostr_ << "!="; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::LogicalOR: ostr_ << '('; self->left()->callback( *this ); ostr_ << "||"; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::LogicalAND: ostr_ << '('; self->left()->callback( *this ); ostr_ << "&&"; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::LessThan: ostr_ << '('; self->left()->callback( *this ); ostr_ << "<"; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::GreaterThan: ostr_ << '('; self->left()->callback( *this ); ostr_ << ">"; self->right()->callback( *this ); ostr_ << ')'; break; case Expression::LessEqual:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -