diff options
Diffstat (limited to 'frontends/ast/ast.cc')
| -rw-r--r-- | frontends/ast/ast.cc | 66 | 
1 files changed, 42 insertions, 24 deletions
| diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 68b3327f9..57de725d8 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -2,11 +2,11 @@   *  yosys -- Yosys Open SYnthesis Suite   *   *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> - *   + *   *  Permission to use, copy, modify, and/or distribute this software for any   *  purpose with or without fee is hereby granted, provided that the above   *  copyright notice and this permission notice appear in all copies. - *   + *   *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES   *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF   *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -30,15 +30,6 @@  #include "libs/sha1/sha1.h"  #include "ast.h" -#include <sstream> -#include <stdarg.h> - -#if defined(__APPLE__) -#  include <cmath> -#else -#  include <math.h> -#endif -  YOSYS_NAMESPACE_BEGIN  using namespace AST; @@ -53,12 +44,12 @@ namespace AST {  // instanciate global variables (private API)  namespace AST_INTERNAL { -	bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; +	bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;  	AstNode *current_ast, *current_ast_mod;  	std::map<std::string, AstNode*> current_scope;  	const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;  	RTLIL::SigSpec ignoreThisSignalsInInitial; -	AstNode *current_top_block, *current_block, *current_block_child; +	AstNode *current_always, *current_top_block, *current_block, *current_block_child;  	AstModule *current_module;  } @@ -90,6 +81,7 @@ std::string AST::type2str(AstNodeType type)  	X(AST_IDENTIFIER)  	X(AST_PREFIX)  	X(AST_ASSERT) +	X(AST_ASSUME)  	X(AST_FCALL)  	X(AST_TO_BITS)  	X(AST_TO_SIGNED) @@ -132,6 +124,7 @@ std::string AST::type2str(AstNodeType type)  	X(AST_TERNARY)  	X(AST_MEMRD)  	X(AST_MEMWR) +	X(AST_MEMINIT)  	X(AST_TCALL)  	X(AST_ASSIGN)  	X(AST_CELL) @@ -144,6 +137,8 @@ std::string AST::type2str(AstNodeType type)  	X(AST_ASSIGN_LE)  	X(AST_CASE)  	X(AST_COND) +	X(AST_CONDX) +	X(AST_CONDZ)  	X(AST_DEFAULT)  	X(AST_FOR)  	X(AST_WHILE) @@ -156,6 +151,7 @@ std::string AST::type2str(AstNodeType type)  	X(AST_POSEDGE)  	X(AST_NEGEDGE)  	X(AST_EDGE) +	X(AST_PACKAGE)  #undef X  	default:  		log_abort(); @@ -327,7 +323,7 @@ static std::string id2vl(std::string txt)  	return txt;  } -// dump AST node as verilog pseudo-code +// dump AST node as Verilog pseudo-code  void AstNode::dumpVlog(FILE *f, std::string indent)  {  	bool first = true; @@ -499,7 +495,12 @@ void AstNode::dumpVlog(FILE *f, std::string indent)  		break;  	case AST_CASE: -		fprintf(f, "%s" "case (", indent.c_str()); +		if (!children.empty() && children[0]->type == AST_CONDX) +			fprintf(f, "%s" "casex (", indent.c_str()); +		else if (!children.empty() && children[0]->type == AST_CONDZ) +			fprintf(f, "%s" "casez (", indent.c_str()); +		else +			fprintf(f, "%s" "case (", indent.c_str());  		children[0]->dumpVlog(f, "");  		fprintf(f, ")\n");  		for (size_t i = 1; i < children.size(); i++) { @@ -510,6 +511,8 @@ void AstNode::dumpVlog(FILE *f, std::string indent)  		break;  	case AST_COND: +	case AST_CONDX: +	case AST_CONDZ:  		for (auto child : children) {  			if (child->type == AST_BLOCK) {  				fprintf(f, ":\n"); @@ -553,7 +556,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent)  		children[1]->dumpVlog(f, "");  		fprintf(f, "}}");  		break; -	 +  	if (0) { case AST_BIT_NOT:     txt = "~";  }  	if (0) { case AST_REDUCE_AND:  txt = "&";  }  	if (0) { case AST_REDUCE_OR:   txt = "|";  } @@ -697,7 +700,7 @@ AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signe  	for (size_t i = 0; i < 32; i++) {  		if (i < node->bits.size())  			node->integer |= (node->bits[i] == RTLIL::S1) << i; -		else if (is_signed) +		else if (is_signed && !node->bits.empty())  			node->integer |= (node->bits.back() == RTLIL::S1) << i;  	}  	node->range_valid = true; @@ -818,7 +821,7 @@ uint64_t AstNode::asInt(bool is_signed)  	}  	if (type == AST_REALVALUE) -		return realvalue; +		return uint64_t(realvalue);  	log_abort();  } @@ -829,7 +832,7 @@ double AstNode::asReal(bool is_signed)  	{  		RTLIL::Const val(bits); -		bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1; +		bool is_negative = is_signed && !val.bits.empty() && val.bits.back() == RTLIL::State::S1;  		if (is_negative)  			val = const_neg(val, val, false, false, val.bits.size()); @@ -892,7 +895,7 @@ static AstModule* process_module(AstNode *ast, bool defer)  	AstNode *ast_before_simplify = ast->clone();  	if (flag_dump_ast1) { -		log("Dumping verilog AST before simplification:\n"); +		log("Dumping Verilog AST before simplification:\n");  		ast->dumpAst(NULL, "    ");  		log("--- END OF AST DUMP ---\n");  	} @@ -902,13 +905,13 @@ static AstModule* process_module(AstNode *ast, bool defer)  		while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { }  		if (flag_dump_ast2) { -			log("Dumping verilog AST after simplification:\n"); +			log("Dumping Verilog AST after simplification:\n");  			ast->dumpAst(NULL, "    ");  			log("--- END OF AST DUMP ---\n");  		}  		if (flag_dump_vlog) { -			log("Dumping verilog AST (as requested by dump_vlog option):\n"); +			log("Dumping Verilog AST (as requested by dump_vlog option):\n");  			ast->dumpVlog(NULL, "    ");  			log("--- END OF AST DUMP ---\n");  		} @@ -957,6 +960,7 @@ static AstModule* process_module(AstNode *ast, bool defer)  	current_module->ast = ast_before_simplify;  	current_module->nolatches = flag_nolatches; +	current_module->nomeminit = flag_nomeminit;  	current_module->nomem2reg = flag_nomem2reg;  	current_module->mem2reg = flag_mem2reg;  	current_module->lib = flag_lib; @@ -968,13 +972,14 @@ static AstModule* process_module(AstNode *ast, bool defer)  }  // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire)  {  	current_ast = ast;  	flag_dump_ast1 = dump_ast1;  	flag_dump_ast2 = dump_ast2;  	flag_dump_vlog = dump_vlog;  	flag_nolatches = nolatches; +	flag_nomeminit = nomeminit;  	flag_nomem2reg = nomem2reg;  	flag_mem2reg = mem2reg;  	flag_lib = lib; @@ -992,6 +997,14 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump  			for (auto n : global_decls)  				(*it)->children.push_back(n->clone()); +			for (auto n : design->verilog_packages){ +				for (auto o : n->children) { +					AstNode *cloned_node = o->clone(); +					cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1); +					(*it)->children.push_back(cloned_node); +				} +			} +  			if (flag_icells && (*it)->str.substr(0, 2) == "\\$")  				(*it)->str = (*it)->str.substr(1); @@ -1009,6 +1022,9 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump  			design->add(process_module(*it, defer));  		} +		else if ((*it)->type == AST_PACKAGE){ +			design->verilog_packages.push_back((*it)->clone()); +		}  		else  			global_decls.push_back(*it);  	} @@ -1029,13 +1045,14 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R  	if (stripped_name.substr(0, 9) == "$abstract")  		stripped_name = stripped_name.substr(9); -	log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); +	log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());  	current_ast = NULL;  	flag_dump_ast1 = false;  	flag_dump_ast2 = false;  	flag_dump_vlog = false;  	flag_nolatches = nolatches; +	flag_nomeminit = nomeminit;  	flag_nomem2reg = nomem2reg;  	flag_mem2reg = mem2reg;  	flag_lib = lib; @@ -1102,6 +1119,7 @@ RTLIL::Module *AstModule::clone() const  	new_mod->ast = ast->clone();  	new_mod->nolatches = nolatches; +	new_mod->nomeminit = nomeminit;  	new_mod->nomem2reg = nomem2reg;  	new_mod->mem2reg = mem2reg;  	new_mod->lib = lib; | 
