Implemented indexed part selects
authorClifford Wolf <clifford@clifford.at>
Wed, 20 Nov 2013 12:05:27 +0000 (13:05 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 20 Nov 2013 12:05:27 +0000 (13:05 +0100)
README
frontends/verilog/lexer.l
frontends/verilog/parser.y
tests/simple/partsel.v [new file with mode: 0644]

diff --git a/README b/README
index aa68da253770bcf5b7951c68ba3dd81b6df315d6..a5e3d5974c3707edbbd18f799e373ac3ba0fc10f 100644 (file)
--- a/README
+++ b/README
@@ -291,9 +291,6 @@ Roadmap / Large-scale TODOs
    - VlogHammer: http://www.clifford.at/yosys/vloghammer.html
    - yosys-bigsim: https://github.com/cliffordwolf/yosys-bigsim
 
-- Missing Verilog-2005 features to be implemented soon:
-  - Indexed part selects
-
 - Technology mapping for real-world applications
    - Add "mini synth script" feature to techmap pass
    - Add const-folding via cell parameters to techmap pass
index fea383cf4d9346131a42149a8fa1ee4697e4eee0..353f0a79bde1624619a4f934e42f0b56857fc041 100644 (file)
@@ -249,6 +249,9 @@ supply1 { return TOK_SUPPLY1; }
 "<<<" { return OP_SSHL; }
 ">>>" { return OP_SSHR; }
 
+"+:" { return TOK_POS_INDEXED; }
+"-:" { return TOK_NEG_INDEXED; }
+
 "/*" { BEGIN(COMMENT); }
 <COMMENT>.    /* ignore comment body */
 <COMMENT>\n   /* ignore comment body */
index c4f386ce5c1df12e066bf8741327899d66c657ff..5dbf049005a56e5bac7d4a70bb98651962cf9e20 100644 (file)
@@ -104,6 +104,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
 %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR
 %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
 %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
+%token TOK_POS_INDEXED TOK_NEG_INDEXED
 
 %type <ast> wire_type range non_opt_range expr basic_expr concat_list rvalue lvalue lvalue_concat_list
 %type <string> opt_label tok_prim_wrapper hierarchical_id
@@ -336,6 +337,16 @@ non_opt_range:
                $$->children.push_back($2);
                $$->children.push_back($4);
        } |
+       '[' expr TOK_POS_INDEXED expr ']' {
+               $$ = new AstNode(AST_RANGE);
+               $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), $4), AstNode::mkconst_int(1, true)));
+               $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
+       } |
+       '[' expr TOK_NEG_INDEXED expr ']' {
+               $$ = new AstNode(AST_RANGE);
+               $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
+               $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), AstNode::mkconst_int(1, true)), $4));
+       } |
        '[' expr ']' {
                $$ = new AstNode(AST_RANGE);
                $$->children.push_back($2);
diff --git a/tests/simple/partsel.v b/tests/simple/partsel.v
new file mode 100644 (file)
index 0000000..acfc1ca
--- /dev/null
@@ -0,0 +1,5 @@
+module test001(input [2:0] idx, input [31:0] data, output [3:0] slice_up, slice_down);
+wire [5:0] offset = idx << 2;
+assign slice_up = data[offset +: 4];
+assign slice_down = data[offset + 3 -: 4];
+endmodule