aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast/genrtlil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/ast/genrtlil.cc')
-rw-r--r--frontends/ast/genrtlil.cc29
1 files changed, 28 insertions, 1 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index d4e9baa5f..e878d0dd2 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -814,6 +814,16 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
children.at(0)->detectSignWidthWorker(sub_width_hint, sign_hint);
break;
+ case AST_CAST_SIZE:
+ while (children.at(0)->simplify(true, false, false, 1, -1, false, false)) { }
+ if (children.at(0)->type != AST_CONSTANT)
+ log_file_error(filename, location.first_line, "Static cast with non constant expression!\n");
+ children.at(1)->detectSignWidthWorker(width_hint, sign_hint);
+ width_hint = children.at(0)->bitsAsConst().as_int();
+ if (width_hint <= 0)
+ log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n");
+ break;
+
case AST_CONCAT:
for (auto child : children) {
sub_width_hint = 0;
@@ -991,6 +1001,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_MODPORT:
case AST_MODPORTMEMBER:
case AST_TYPEDEF:
+ case AST_STRUCT:
+ case AST_UNION:
break;
case AST_INTERFACEPORT: {
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
@@ -1055,7 +1067,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (!range_valid)
log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str());
- if (!(range_left >= range_right || (range_left == -1 && range_right == 0)))
+ if (!(range_left + 1 >= range_right))
log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
@@ -1065,6 +1077,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
wire->port_input = is_input;
wire->port_output = is_output;
wire->upto = range_swapped;
+ wire->is_signed = is_signed;
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -1286,6 +1299,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
return sig;
}
+ // changing the size of signal can be done directly using RTLIL::SigSpec
+ case AST_CAST_SIZE: {
+ RTLIL::SigSpec size = children[0]->genRTLIL();
+ RTLIL::SigSpec sig = children[1]->genRTLIL();
+ if (!size.is_fully_const())
+ log_file_error(filename, location.first_line, "Static cast with non constant expression!\n");
+ int width = size.as_int();
+ if (width <= 0)
+ log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n");
+ sig.extend_u0(width, sign_hint);
+ is_signed = sign_hint;
+ return sig;
+ }
+
// concatenation of signals can be done directly using RTLIL::SigSpec
case AST_CONCAT: {
RTLIL::SigSpec sig;