diff options
Diffstat (limited to 'frontends')
| -rw-r--r-- | frontends/ast/ast.h | 1 | ||||
| -rw-r--r-- | frontends/ast/simplify.cc | 57 | ||||
| -rw-r--r-- | frontends/verific/verific.cc | 12 | 
3 files changed, 68 insertions, 2 deletions
| diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6d556fae2..b8f24ee14 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -257,6 +257,7 @@ namespace AST  		bool mem2reg_check(pool<AstNode*> &mem2reg_set);  		void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);  		void meminfo(int &mem_width, int &mem_size, int &addr_bits); +		bool detect_latch(const std::string &var);  		// additional functionality for evaluating constant functions  		struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 6970135d0..5f026dfed 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2136,6 +2136,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  				use_case_method = true;  		} +		if (!use_case_method && current_always->detect_latch(children[0]->str)) +			use_case_method = true; +  		if (use_case_method)  		{  			// big case block @@ -4204,6 +4207,60 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)  		addr_bits++;  } +bool AstNode::detect_latch(const std::string &var) +{ +	switch (type) +	{ +	case AST_ALWAYS: +		for (auto &c : children) +		{ +			switch (c->type) +			{ +			case AST_POSEDGE: +			case AST_NEGEDGE: +				return false; +			case AST_BLOCK: +				if (!c->detect_latch(var)) +					return false; +				break; +			default: +				log_abort(); +			} +		} +		return true; +	case AST_BLOCK: +		for (auto &c : children) +			if (!c->detect_latch(var)) +				return false; +		return true; +	case AST_CASE: +		{ +			bool r = true; +			for (auto &c : children) { +				if (c->type == AST_COND) { +					if (c->children.at(1)->detect_latch(var)) +						return true; +					r = false; +				} +				if (c->type == AST_DEFAULT) { +					if (c->children.at(0)->detect_latch(var)) +						return true; +					r = false; +				} +			} +			return r; +		} +	case AST_ASSIGN_EQ: +	case AST_ASSIGN_LE: +		if (children.at(0)->type == AST_IDENTIFIER && +				children.at(0)->children.empty() && children.at(0)->str == var) +			return false; +		return true; +	default: +		return true; +	} +} +  bool AstNode::has_const_only_constructs(bool &recommend_const_eval)  {  	if (type == AST_FOR) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cb0368fd5..a22a8a93d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1262,7 +1262,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se  		if (inst->Type() == OPER_READ_PORT)  		{ -			RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name())); +			RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name()), nullptr); +			if (!memory) +				log_error("Memory net '%s' missing, possibly no driver, use verific -flatten.\n", inst->GetInput()->Name()); +  			int numchunks = int(inst->OutputSize()) / memory->width;  			int chunksbits = ceil_log2(numchunks); @@ -1289,7 +1292,9 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se  		if (inst->Type() == OPER_WRITE_PORT || inst->Type() == OPER_CLOCKED_WRITE_PORT)  		{ -			RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name())); +			RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name()), nullptr); +			if (!memory) +				log_error("Memory net '%s' missing, possibly no driver, use verific -flatten.\n", inst->GetInput()->Name());  			int numchunks = int(inst->Input2Size()) / memory->width;  			int chunksbits = ceil_log2(numchunks); @@ -2175,6 +2180,9 @@ struct VerificPass : public Pass {  			RuntimeFlags::SetVar("vhdl_support_variable_slice", 1);  			RuntimeFlags::SetVar("vhdl_ignore_assertion_statements", 0); +			RuntimeFlags::SetVar("veri_preserve_assignments", 1); +			RuntimeFlags::SetVar("vhdl_preserve_assignments", 1); +  			// Workaround for VIPER #13851  			RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1); | 
