aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
authorclairexen <claire@symbioticeda.com>2020-07-01 16:40:20 +0200
committerGitHub <noreply@github.com>2020-07-01 16:40:20 +0200
commit8ce4f8790ecf33f7df19e0fb54a749abe026831d (patch)
tree20d18b6f47cb74be76d91568cfc0e0f51a47f1dd /frontends
parentb1707407a0912fe44ecf83f6f8e64b13a1c4daee (diff)
parent429d37ff41b5a058fdd0b70f23a55170a973c369 (diff)
downloadyosys-8ce4f8790ecf33f7df19e0fb54a749abe026831d.tar.gz
yosys-8ce4f8790ecf33f7df19e0fb54a749abe026831d.tar.bz2
yosys-8ce4f8790ecf33f7df19e0fb54a749abe026831d.zip
Merge pull request #2179 from splhack/static-cast
Support SystemVerilog Static Cast
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc1
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/genrtlil.cc24
-rw-r--r--frontends/ast/simplify.cc8
-rw-r--r--frontends/verilog/verilog_lexer.l2
-rw-r--r--frontends/verilog/verilog_parser.y19
6 files changed, 55 insertions, 0 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 03fd272da..9520ae32c 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -95,6 +95,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_TO_SIGNED)
X(AST_TO_UNSIGNED)
X(AST_SELFSZ)
+ X(AST_CAST_SIZE)
X(AST_CONCAT)
X(AST_REPLICATE)
X(AST_BIT_NOT)
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 46864a4e1..9a5aa15f9 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -76,6 +76,7 @@ namespace AST
AST_TO_SIGNED,
AST_TO_UNSIGNED,
AST_SELFSZ,
+ AST_CAST_SIZE,
AST_CONCAT,
AST_REPLICATE,
AST_BIT_NOT,
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 9546558aa..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;
@@ -1289,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;
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index c819924a0..c4df5c0a0 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -950,6 +950,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
case AST_TO_SIGNED:
case AST_TO_UNSIGNED:
case AST_SELFSZ:
+ case AST_CAST_SIZE:
case AST_CONCAT:
case AST_REPLICATE:
case AST_REDUCE_AND:
@@ -3487,6 +3488,13 @@ replace_fcall_later:;
}
}
break;
+ case AST_CAST_SIZE:
+ if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) {
+ int width = children[0]->bitsAsConst().as_int();
+ RTLIL::Const val = children[1]->bitsAsConst(width);
+ newNode = mkconst_bits(val.bits, children[1]->is_signed);
+ }
+ break;
case AST_CONCAT:
string_op = !children.empty();
for (auto it = children.begin(); it != children.end(); it++) {
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index 028106381..f2241066f 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -517,6 +517,8 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
"<<<" { return OP_SSHL; }
">>>" { return OP_SSHR; }
+"'" { return OP_CAST; }
+
"::" { return TOK_PACKAGESEP; }
"++" { return TOK_INCREMENT; }
"--" { return TOK_DECREMENT; }
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 96d9299fe..0fdf2b516 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -299,6 +299,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%left '+' '-'
%left '*' '/' '%'
%left OP_POW
+%left OP_CAST
%right UNARY_OPS
%define parse.error verbose
@@ -3042,6 +3043,24 @@ basic_expr:
$$ = new AstNode(AST_LOGIC_NOT, $3);
SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
+ } |
+ TOK_SIGNED OP_CAST '(' expr ')' {
+ if (!sv_mode)
+ frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode.");
+ $$ = new AstNode(AST_TO_SIGNED, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
+ } |
+ TOK_UNSIGNED OP_CAST '(' expr ')' {
+ if (!sv_mode)
+ frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode.");
+ $$ = new AstNode(AST_TO_UNSIGNED, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
+ } |
+ basic_expr OP_CAST '(' expr ')' {
+ if (!sv_mode)
+ frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode.");
+ $$ = new AstNode(AST_CAST_SIZE, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
};
concat_list: