mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Implemented more real arithmetic
This commit is contained in:
		
							parent
							
								
									442a8e2875
								
							
						
					
					
						commit
						fc7b6d172a
					
				
					 1 changed files with 70 additions and 27 deletions
				
			
		| 
						 | 
					@ -1348,7 +1348,9 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
					} else
 | 
										} else
 | 
				
			||||||
					if (children.size() == 0)
 | 
										if (children.size() == 0)
 | 
				
			||||||
						newNode = current_scope[str]->children[0]->clone();
 | 
											newNode = current_scope[str]->children[0]->clone();
 | 
				
			||||||
				}
 | 
									} else
 | 
				
			||||||
 | 
									if (current_scope[str]->children[0]->isConst())
 | 
				
			||||||
 | 
										newNode = current_scope[str]->children[0]->clone();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
 | 
								else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
 | 
				
			||||||
				newNode = mkconst_int(0, sign_hint, width_hint);
 | 
									newNode = mkconst_int(0, sign_hint, width_hint);
 | 
				
			||||||
| 
						 | 
					@ -1391,6 +1393,9 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
			if (children[0]->type == AST_CONSTANT) {
 | 
								if (children[0]->type == AST_CONSTANT) {
 | 
				
			||||||
				RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
 | 
									RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
 | 
				
			||||||
				newNode = mkconst_bits(y.bits, false);
 | 
									newNode = mkconst_bits(y.bits, false);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
								if (children[0]->isConst()) {
 | 
				
			||||||
 | 
									newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; }
 | 
							if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; }
 | 
				
			||||||
| 
						 | 
					@ -1399,6 +1404,12 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
				RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits),
 | 
									RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits),
 | 
				
			||||||
						children[0]->is_signed, children[1]->is_signed, -1);
 | 
											children[0]->is_signed, children[1]->is_signed, -1);
 | 
				
			||||||
				newNode = mkconst_bits(y.bits, false);
 | 
									newNode = mkconst_bits(y.bits, false);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
								if (children[0]->isConst() && children[1]->isConst()) {
 | 
				
			||||||
 | 
									if (type == AST_LOGIC_AND)
 | 
				
			||||||
 | 
										newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1);
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (0) { case AST_SHIFT_LEFT:   const_func = RTLIL::const_shl;  }
 | 
							if (0) { case AST_SHIFT_LEFT:   const_func = RTLIL::const_shl;  }
 | 
				
			||||||
| 
						 | 
					@ -1410,6 +1421,10 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
				RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
 | 
									RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
 | 
				
			||||||
						RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint);
 | 
											RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint);
 | 
				
			||||||
				newNode = mkconst_bits(y.bits, sign_hint);
 | 
									newNode = mkconst_bits(y.bits, sign_hint);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
								if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) {
 | 
				
			||||||
 | 
									newNode = new AstNode(AST_REALVALUE);
 | 
				
			||||||
 | 
									newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (0) { case AST_LT:  const_func = RTLIL::const_lt; }
 | 
							if (0) { case AST_LT:  const_func = RTLIL::const_lt; }
 | 
				
			||||||
| 
						 | 
					@ -1426,6 +1441,19 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
				RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed),
 | 
									RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed),
 | 
				
			||||||
						children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
 | 
											children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
 | 
				
			||||||
				newNode = mkconst_bits(y.bits, false);
 | 
									newNode = mkconst_bits(y.bits, false);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
								if (children[0]->isConst() && children[1]->isConst()) {
 | 
				
			||||||
 | 
									switch (type) {
 | 
				
			||||||
 | 
									case AST_LT:  newNode = mkconst_int(children[0]->asReal(sign_hint) <  children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_LE:  newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_EQ:  newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_NE:  newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_GE:  newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									case AST_GT:  newNode = mkconst_int(children[0]->asReal(sign_hint) >  children[1]->asReal(sign_hint), false, 1);
 | 
				
			||||||
 | 
									default: log_abort();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (0) { case AST_ADD: const_func = RTLIL::const_add; }
 | 
							if (0) { case AST_ADD: const_func = RTLIL::const_add; }
 | 
				
			||||||
| 
						 | 
					@ -1433,21 +1461,20 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
		if (0) { case AST_MUL: const_func = RTLIL::const_mul; }
 | 
							if (0) { case AST_MUL: const_func = RTLIL::const_mul; }
 | 
				
			||||||
		if (0) { case AST_DIV: const_func = RTLIL::const_div; }
 | 
							if (0) { case AST_DIV: const_func = RTLIL::const_div; }
 | 
				
			||||||
		if (0) { case AST_MOD: const_func = RTLIL::const_mod; }
 | 
							if (0) { case AST_MOD: const_func = RTLIL::const_mod; }
 | 
				
			||||||
 | 
								if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
 | 
				
			||||||
 | 
									RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
 | 
				
			||||||
 | 
											children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
 | 
				
			||||||
 | 
									newNode = mkconst_bits(y.bits, sign_hint);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
			if (children[0]->isConst() && children[1]->isConst()) {
 | 
								if (children[0]->isConst() && children[1]->isConst()) {
 | 
				
			||||||
				if (children[0]->isConst() + children[1]->isConst() > 2) {
 | 
									newNode = new AstNode(AST_REALVALUE);
 | 
				
			||||||
					newNode = new AstNode(AST_REALVALUE);
 | 
									switch (type) {
 | 
				
			||||||
					switch (type) {
 | 
									case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break;
 | 
				
			||||||
					case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break;
 | 
									case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break;
 | 
				
			||||||
					case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break;
 | 
									case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break;
 | 
				
			||||||
					case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break;
 | 
									case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break;
 | 
				
			||||||
					case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break;
 | 
									case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break;
 | 
				
			||||||
					case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break;
 | 
									default: log_abort();
 | 
				
			||||||
					default: log_abort();
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
 | 
					 | 
				
			||||||
							children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
 | 
					 | 
				
			||||||
					newNode = mkconst_bits(y.bits, sign_hint);
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -1456,29 +1483,45 @@ skip_dynamic_range_lvalue_expansion:;
 | 
				
			||||||
			if (children[0]->type == AST_CONSTANT) {
 | 
								if (children[0]->type == AST_CONSTANT) {
 | 
				
			||||||
				RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
 | 
									RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
 | 
				
			||||||
				newNode = mkconst_bits(y.bits, sign_hint);
 | 
									newNode = mkconst_bits(y.bits, sign_hint);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
								if (children[0]->isConst()) {
 | 
				
			||||||
 | 
									newNode = new AstNode(AST_REALVALUE);
 | 
				
			||||||
 | 
									if (type == AST_POS)
 | 
				
			||||||
 | 
										newNode->realvalue = +children[0]->asReal(sign_hint);
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										newNode->realvalue = -children[0]->asReal(sign_hint);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case AST_TERNARY:
 | 
							case AST_TERNARY:
 | 
				
			||||||
			if (children[0]->type == AST_CONSTANT) {
 | 
								if (children[0]->isConst()) {
 | 
				
			||||||
				bool found_sure_true = false;
 | 
									bool found_sure_true = false;
 | 
				
			||||||
				bool found_maybe_true = false;
 | 
									bool found_maybe_true = false;
 | 
				
			||||||
				for (auto &bit : children[0]->bits) {
 | 
									if (children[0]->type == AST_CONSTANT) {
 | 
				
			||||||
					if (bit == RTLIL::State::S1)
 | 
										for (auto &bit : children[0]->bits) {
 | 
				
			||||||
						found_sure_true = true;
 | 
											if (bit == RTLIL::State::S1)
 | 
				
			||||||
					if (bit > RTLIL::State::S1)
 | 
												found_sure_true = true;
 | 
				
			||||||
						found_maybe_true = true;
 | 
											if (bit > RTLIL::State::S1)
 | 
				
			||||||
 | 
												found_maybe_true = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										found_sure_true = children[0]->asReal(false) != 0;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				AstNode *choice = NULL;
 | 
									AstNode *choice = NULL;
 | 
				
			||||||
				if (found_sure_true)
 | 
									if (found_sure_true)
 | 
				
			||||||
					choice = children[1];
 | 
										choice = children[1];
 | 
				
			||||||
				else if (!found_maybe_true)
 | 
									else if (!found_maybe_true)
 | 
				
			||||||
					choice = children[2];
 | 
										choice = children[2];
 | 
				
			||||||
				if (choice != NULL && choice->type == AST_CONSTANT) {
 | 
									if (choice != NULL) {
 | 
				
			||||||
					RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
 | 
										if (choice->type == AST_CONSTANT) {
 | 
				
			||||||
					if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
 | 
											RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
 | 
				
			||||||
						newNode = mkconst_str(y.bits);
 | 
											if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
 | 
				
			||||||
					else
 | 
												newNode = mkconst_str(y.bits);
 | 
				
			||||||
						newNode = mkconst_bits(y.bits, sign_hint);
 | 
											else
 | 
				
			||||||
 | 
												newNode = mkconst_bits(y.bits, sign_hint);
 | 
				
			||||||
 | 
										} else
 | 
				
			||||||
 | 
										if (choice->isConst()) {
 | 
				
			||||||
 | 
											newNode = choice->clone();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				} else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
 | 
									} else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
 | 
				
			||||||
					RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
 | 
										RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
 | 
				
			||||||
					RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
 | 
										RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue