mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Further improve handling of zero-length SVA consecutive repetition
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
		
							parent
							
								
									3e67497ec2
								
							
						
					
					
						commit
						24e6401617
					
				
					 1 changed files with 108 additions and 69 deletions
				
			
		|  | @ -1138,7 +1138,98 @@ struct VerificSvaImporter | |||
| 		log_abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	int parse_sequence(SvaFsm &fsm, int start_node, Net *net, int past_start_node = -1) | ||||
| 	bool check_zero_consecutive_repeat(Net *net) | ||||
| 	{ | ||||
| 		Instance *inst = net_to_ast_driver(net); | ||||
| 
 | ||||
| 		if (inst == nullptr) | ||||
| 			return false; | ||||
| 
 | ||||
| 		if (inst->Type() != PRIM_SVA_CONSECUTIVE_REPEAT) | ||||
| 			return false; | ||||
| 
 | ||||
| 		const char *sva_low_s = inst->GetAttValue("sva:low"); | ||||
| 		int sva_low = atoi(sva_low_s); | ||||
| 
 | ||||
| 		return sva_low == 0; | ||||
| 	} | ||||
| 
 | ||||
| 	int parse_consecutive_repeat(SvaFsm &fsm, int start_node, Net *net, bool add_pre_delay, bool add_post_delay) | ||||
| 	{ | ||||
| 		Instance *inst = net_to_ast_driver(net); | ||||
| 
 | ||||
| 		log_assert(inst->Type() == PRIM_SVA_CONSECUTIVE_REPEAT); | ||||
| 
 | ||||
| 		const char *sva_low_s = inst->GetAttValue("sva:low"); | ||||
| 		const char *sva_high_s = inst->GetAttValue("sva:high"); | ||||
| 
 | ||||
| 		int sva_low = atoi(sva_low_s); | ||||
| 		int sva_high = atoi(sva_high_s); | ||||
| 		bool sva_inf = !strcmp(sva_high_s, "$"); | ||||
| 
 | ||||
| 		Net *body_net = inst->GetInput(); | ||||
| 
 | ||||
| 		if (add_pre_delay || add_post_delay) | ||||
| 			log_assert(sva_low == 0); | ||||
| 
 | ||||
| 		if (sva_low == 0) { | ||||
| 			if (!add_pre_delay && !add_post_delay) | ||||
| 				parser_error("Possibly zero-length consecutive repeat must follow or precede a delay of at least one cycle", inst); | ||||
| 			sva_low++; | ||||
| 		} | ||||
| 
 | ||||
| 		int node = fsm.createNode(start_node); | ||||
| 		start_node = node; | ||||
| 
 | ||||
| 		if (add_pre_delay) { | ||||
| 			node = fsm.createNode(start_node); | ||||
| 			fsm.createEdge(start_node, node); | ||||
| 		} | ||||
| 
 | ||||
| 		int prev_node = node; | ||||
| 		node = parse_sequence(fsm, node, body_net); | ||||
| 
 | ||||
| 		for (int i = 1; i < sva_low; i++) | ||||
| 		{ | ||||
| 			int next_node = fsm.createNode(); | ||||
| 			fsm.createEdge(node, next_node); | ||||
| 
 | ||||
| 			prev_node = node; | ||||
| 			node = parse_sequence(fsm, next_node, body_net); | ||||
| 		} | ||||
| 
 | ||||
| 		if (sva_inf) | ||||
| 		{ | ||||
| 			log_assert(prev_node >= 0); | ||||
| 			fsm.createEdge(node, prev_node); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			for (int i = sva_low; i < sva_high; i++) | ||||
| 			{ | ||||
| 				int next_node = fsm.createNode(); | ||||
| 				fsm.createEdge(node, next_node); | ||||
| 
 | ||||
| 				prev_node = node; | ||||
| 				node = parse_sequence(fsm, next_node, body_net); | ||||
| 
 | ||||
| 				fsm.createLink(prev_node, node); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (add_post_delay) { | ||||
| 			int next_node = fsm.createNode(); | ||||
| 			fsm.createEdge(node, next_node); | ||||
| 			node = next_node; | ||||
| 		} | ||||
| 
 | ||||
| 		if (add_pre_delay || add_post_delay) | ||||
| 			fsm.createLink(start_node, node); | ||||
| 
 | ||||
| 		return node; | ||||
| 	} | ||||
| 
 | ||||
| 	int parse_sequence(SvaFsm &fsm, int start_node, Net *net) | ||||
| 	{ | ||||
| 		if (check_expression(net)) { | ||||
| 			int node = fsm.createNode(); | ||||
|  | @ -1182,29 +1273,29 @@ struct VerificSvaImporter | |||
| 			int sva_high = atoi(sva_high_s); | ||||
| 			bool sva_inf = !strcmp(sva_high_s, "$"); | ||||
| 
 | ||||
| 			int node = parse_sequence(fsm, start_node, inst->GetInput1()); | ||||
| 			int past_node = -1; | ||||
| 			int node = -1; | ||||
| 			bool past_add_delay = false; | ||||
| 
 | ||||
| 			Net *next_net = inst->GetInput2(); | ||||
| 			Instance *next_inst = net_to_ast_driver(next_net); | ||||
| 			if (check_zero_consecutive_repeat(inst->GetInput1()) && sva_low > 0) { | ||||
| 				node = parse_consecutive_repeat(fsm, start_node, inst->GetInput1(), false, true); | ||||
| 				sva_low--, sva_high--; | ||||
| 			} else { | ||||
| 				node = parse_sequence(fsm, start_node, inst->GetInput1()); | ||||
| 			} | ||||
| 
 | ||||
| 			if (next_inst != nullptr && next_inst->Type() == PRIM_SVA_CONSECUTIVE_REPEAT && sva_low > 0) { | ||||
| 				past_node = fsm.createNode(); | ||||
| 				log_dump(past_node); | ||||
| 			if (check_zero_consecutive_repeat(inst->GetInput2()) && sva_low > 0) { | ||||
| 				past_add_delay = true; | ||||
| 				sva_low--, sva_high--; | ||||
| 			} | ||||
| 
 | ||||
| 			for (int i = 0; i < sva_low; i++) { | ||||
| 				int next_node = fsm.createNode(); | ||||
| 				fsm.createEdge(node, next_node); | ||||
| 				if (past_node >= 0 && i == sva_low-1) | ||||
| 					fsm.createLink(node, past_node); | ||||
| 				node = next_node; | ||||
| 			} | ||||
| 
 | ||||
| 			if (sva_inf) | ||||
| 			{ | ||||
| 				if (past_node >= 0) | ||||
| 					fsm.createLink(node, past_node); | ||||
| 				fsm.createEdge(node, node); | ||||
| 			} | ||||
| 			else | ||||
|  | @ -1214,73 +1305,21 @@ struct VerificSvaImporter | |||
| 					int next_node = fsm.createNode(); | ||||
| 					fsm.createEdge(node, next_node); | ||||
| 					fsm.createLink(node, next_node); | ||||
| 					if (past_node >= 0) | ||||
| 						fsm.createLink(node, past_node); | ||||
| 					node = next_node; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			node = parse_sequence(fsm, node, inst->GetInput2(), past_node); | ||||
| 			if (past_add_delay) | ||||
| 				node = parse_consecutive_repeat(fsm, node, inst->GetInput2(), true, false); | ||||
| 			else | ||||
| 				node = parse_sequence(fsm, node, inst->GetInput2()); | ||||
| 
 | ||||
| 			return node; | ||||
| 		} | ||||
| 
 | ||||
| 		if (inst->Type() == PRIM_SVA_CONSECUTIVE_REPEAT) | ||||
| 		{ | ||||
| 			const char *sva_low_s = inst->GetAttValue("sva:low"); | ||||
| 			const char *sva_high_s = inst->GetAttValue("sva:high"); | ||||
| 
 | ||||
| 			int sva_low = atoi(sva_low_s); | ||||
| 			int sva_high = atoi(sva_high_s); | ||||
| 			bool sva_inf = !strcmp(sva_high_s, "$"); | ||||
| 
 | ||||
| 			Net *body_net = inst->GetInput(); | ||||
| 
 | ||||
| 			bool bypass = false; | ||||
| 
 | ||||
| 			if (sva_low == 0) { | ||||
| 				if (past_start_node == -1) | ||||
| 					parser_error("Possibly zero-length consecutive repeat must follow a delay of at least one cycle", inst); | ||||
| 				bypass = true; | ||||
| 				sva_low++; | ||||
| 			} | ||||
| 
 | ||||
| 			int node = fsm.createNode(start_node); | ||||
| 			int prev_node = node; | ||||
| 			node = parse_sequence(fsm, node, body_net); | ||||
| 
 | ||||
| 			for (int i = 1; i < sva_low; i++) | ||||
| 			{ | ||||
| 				int next_node = fsm.createNode(); | ||||
| 				fsm.createEdge(node, next_node); | ||||
| 
 | ||||
| 				prev_node = node; | ||||
| 				node = parse_sequence(fsm, next_node, body_net); | ||||
| 			} | ||||
| 
 | ||||
| 			if (sva_inf) | ||||
| 			{ | ||||
| 				log_assert(prev_node >= 0); | ||||
| 				fsm.createEdge(node, prev_node); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				for (int i = sva_low; i < sva_high; i++) | ||||
| 				{ | ||||
| 					int next_node = fsm.createNode(); | ||||
| 					fsm.createEdge(node, next_node); | ||||
| 
 | ||||
| 					prev_node = node; | ||||
| 					node = parse_sequence(fsm, next_node, body_net); | ||||
| 
 | ||||
| 					fsm.createLink(prev_node, node); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (bypass) | ||||
| 				fsm.createLink(past_start_node, node); | ||||
| 
 | ||||
| 			return node; | ||||
| 			return parse_consecutive_repeat(fsm, start_node, net, false, false); | ||||
| 		} | ||||
| 
 | ||||
| 		if (inst->Type() == PRIM_SVA_NON_CONSECUTIVE_REPEAT || inst->Type() == PRIM_SVA_GOTO_REPEAT) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue