diff options
-rw-r--r-- | backends/cxxrtl/cxxrtl_capi.h | 2 | ||||
-rw-r--r-- | frontends/verilog/Makefile.inc | 2 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 138 | ||||
-rw-r--r-- | passes/opt/opt_merge.cc | 4 | ||||
-rw-r--r-- | techlibs/achronix/synth_achronix.cc | 2 | ||||
-rw-r--r-- | techlibs/anlogic/cells_map.v | 38 | ||||
-rw-r--r-- | techlibs/anlogic/cells_sim.v | 45 | ||||
-rw-r--r-- | techlibs/anlogic/synth_anlogic.cc | 2 | ||||
-rw-r--r-- | techlibs/efinix/Makefile.inc | 2 | ||||
-rw-r--r-- | techlibs/efinix/cells_sim.v | 6 | ||||
-rw-r--r-- | techlibs/efinix/efinix_gbuf.cc | 119 | ||||
-rw-r--r-- | techlibs/efinix/gbuf_map.v | 3 | ||||
-rw-r--r-- | techlibs/efinix/synth_efinix.cc | 3 | ||||
-rw-r--r-- | tests/arch/anlogic/latches.ys | 26 | ||||
-rw-r--r-- | tests/various/integer_range_bad_syntax.ys | 6 | ||||
-rw-r--r-- | tests/various/integer_real_bad_syntax.ys | 6 | ||||
-rw-r--r-- | tests/various/logic_param_simple.ys | 9 | ||||
-rw-r--r-- | tests/various/signed.ys | 28 |
18 files changed, 179 insertions, 262 deletions
diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index 74257f0da..1f1942803 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -64,7 +64,7 @@ int cxxrtl_eval(cxxrtl_handle handle); // Commit the design, replacing the `curr` value of internal state and output wires with the `next` // value. // -// Return 1 if any of the `curr` values, 0 otherwise. +// Return 1 if any of the `curr` values were updated, 0 otherwise. int cxxrtl_commit(cxxrtl_handle handle); // Simulate the design to a fixed point. diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc index d5d5edd3d..2c923f0b7 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -6,7 +6,7 @@ GENFILES += frontends/verilog/verilog_lexer.cc frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y $(Q) mkdir -p $(dir $@) - $(P) $(BISON) -Werror=conflicts-sr,error=conflicts-rr -o $@ -d -r all -b frontends/verilog/verilog_parser $< + $(P) $(BISON) -Wall -Werror -o $@ -d -r all -b frontends/verilog/verilog_parser $< frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 0fdf2b516..63f0341d9 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -299,14 +299,14 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %left '+' '-' %left '*' '/' '%' %left OP_POW -%left OP_CAST -%right UNARY_OPS +%precedence OP_CAST +%precedence UNARY_OPS %define parse.error verbose %define parse.lac full -%nonassoc FAKE_THEN -%nonassoc TOK_ELSE +%precedence FAKE_THEN +%precedence TOK_ELSE %debug %locations @@ -333,7 +333,7 @@ design: typedef_decl design | package design | interface design | - /* empty */; + %empty; attr: { @@ -355,7 +355,7 @@ attr_opt: attr_opt ATTR_BEGIN opt_attr_list ATTR_END { SET_RULE_LOC(@$, @2, @$); }| - /* empty */; + %empty; defattr: DEFATTR_BEGIN { @@ -376,7 +376,7 @@ defattr: } DEFATTR_END; opt_attr_list: - attr_list | /* empty */; + attr_list | %empty; attr_list: attr_assign | @@ -449,13 +449,13 @@ module: }; module_para_opt: - '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | /* empty */; + '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | %empty; module_para_list: single_module_para | module_para_list ',' single_module_para; single_module_para: - /* empty */ | + %empty | attr TOK_PARAMETER { if (astbuf1) delete astbuf1; astbuf1 = new AstNode(AST_PARAMETER); @@ -471,13 +471,13 @@ single_module_para: single_param_decl; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')'; + '(' ')' | %empty | '(' module_args optional_comma ')'; module_args: module_arg | module_args ',' module_arg; optional_comma: - ',' | /* empty */; + ',' | %empty; module_arg_opt_assignment: '=' expr { @@ -497,7 +497,7 @@ module_arg_opt_assignment: } else frontend_verilog_yyerror("SystemVerilog interface in module port list cannot have a default value."); } | - /* empty */; + %empty; module_arg: TOK_ID { @@ -565,15 +565,10 @@ package: }; package_body: - package_body package_body_stmt - | // optional - ; + package_body package_body_stmt | %empty; package_body_stmt: - typedef_decl - | localparam_decl - | param_decl - ; + typedef_decl | localparam_decl | param_decl; interface: TOK_INTERFACE { @@ -599,7 +594,7 @@ interface: }; interface_body: - interface_body interface_body_stmt |; + interface_body interface_body_stmt | %empty; interface_body_stmt: param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | @@ -613,7 +608,7 @@ non_opt_delay: '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; }; delay: - non_opt_delay | /* empty */; + non_opt_delay | %empty; wire_type: { @@ -725,7 +720,7 @@ range: non_opt_range { $$ = $1; } | - /* empty */ { + %empty { $$ = NULL; }; @@ -742,7 +737,8 @@ module_body: module_body module_body_stmt | /* the following line makes the generate..endgenrate keywords optional */ module_body gen_stmt | - /* empty */; + module_body ';' | + %empty; module_body_stmt: task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt | @@ -842,28 +838,28 @@ dpi_function_arg: opt_dpi_function_args: '(' dpi_function_args ')' | - /* empty */; + %empty; dpi_function_args: dpi_function_args ',' dpi_function_arg | dpi_function_args ',' | dpi_function_arg | - /* empty */; + %empty; opt_automatic: TOK_AUTOMATIC | - /* empty */; + %empty; opt_signed: TOK_SIGNED { $$ = true; } | - /* empty */ { + %empty { $$ = false; }; task_func_args_opt: - '(' ')' | /* empty */ | '(' { + '(' ')' | %empty | '(' { albuf = nullptr; astbuf1 = nullptr; astbuf2 = nullptr; @@ -904,7 +900,7 @@ task_func_port: task_func_body: task_func_body behavioral_stmt | - /* empty */; + %empty; /*************************** specify parser ***************************/ @@ -913,7 +909,7 @@ specify_block: specify_item_list: specify_item specify_item_list | - /* empty */; + %empty; specify_item: specify_if '(' specify_edge expr TOK_SPECIFY_OPER specify_target ')' '=' specify_rise_fall ';' { @@ -1075,7 +1071,7 @@ specify_opt_triple: ',' specify_triple { $$ = $2; } | - /* empty */ { + %empty { $$ = nullptr; }; @@ -1083,7 +1079,7 @@ specify_if: TOK_IF '(' expr ')' { $$ = $3; } | - /* empty */ { + %empty { $$ = nullptr; }; @@ -1091,7 +1087,7 @@ specify_condition: TOK_SPECIFY_AND expr { $$ = $2; } | - /* empty */ { + %empty { $$ = nullptr; }; @@ -1124,7 +1120,7 @@ specify_target: specify_edge: TOK_POSEDGE { $$ = 'p'; } | TOK_NEGEDGE { $$ = 'n'; } | - { $$ = 0; }; + %empty { $$ = 0; }; specify_rise_fall: specify_triple { @@ -1231,7 +1227,7 @@ specparam_assignment: ignspec_id '=' ignspec_expr ; ignspec_opt_cond: - TOK_IF '(' ignspec_expr ')' | /* empty */; + TOK_IF '(' ignspec_expr ')' | %empty; path_declaration : simple_path_declaration ';' @@ -1282,9 +1278,7 @@ list_of_path_outputs : list_of_path_outputs ',' specify_output_terminal_descriptor ; opt_polarity_operator : - '+' - | '-' - | ; + '+' | '-' | %empty; // Good enough for the time being specify_input_terminal_descriptor : @@ -1331,36 +1325,36 @@ ignspec_id: param_signed: TOK_SIGNED { astbuf1->is_signed = true; - } | /* empty */; + } | TOK_UNSIGNED { + astbuf1->is_signed = false; + } | %empty; param_integer: TOK_INTEGER { - if (astbuf1->children.size() != 1) - frontend_verilog_yyerror("Internal error in param_integer - should not happen?"); astbuf1->children.push_back(new AstNode(AST_RANGE)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); astbuf1->is_signed = true; - } | /* empty */; + }; param_real: TOK_REAL { - if (astbuf1->children.size() != 1) - frontend_verilog_yyerror("Parameter already declared as integer, cannot set to real."); astbuf1->children.push_back(new AstNode(AST_REALVALUE)); - } | /* empty */; + }; param_range: range { if ($1 != NULL) { - if (astbuf1->children.size() != 1) - frontend_verilog_yyerror("integer/real parameters should not have a range."); astbuf1->children.push_back($1); } }; +param_integer_type: param_integer param_signed; +param_range_type: type_vec param_signed param_range; +param_implicit_type: param_signed param_range; + param_type: - param_signed param_integer param_real param_range | + param_integer_type | param_real | param_range_type | param_implicit_type | hierarchical_type_id { astbuf1->is_custom_type = true; astbuf1->children.push_back(new AstNode(AST_WIRETYPE)); @@ -1450,7 +1444,7 @@ enum_type: TOK_ENUM { enum_base_type: type_atom type_signing | type_vec type_signing range { if ($3) astbuf1->children.push_back($3); } - | /* nothing */ { astbuf1->is_reg = true; addRange(astbuf1); } + | %empty { astbuf1->is_reg = true; addRange(astbuf1); } ; type_atom: TOK_INTEGER { astbuf1->is_reg = true; addRange(astbuf1); } // 4-state signed @@ -1466,7 +1460,7 @@ type_vec: TOK_REG { astbuf1->is_reg = true; } // unsigned type_signing: TOK_SIGNED { astbuf1->is_signed = true; } | TOK_UNSIGNED { astbuf1->is_signed = false; } - | // optional + | %empty ; enum_name_list: enum_name_decl @@ -1490,7 +1484,7 @@ enum_name_decl: opt_enum_init: '=' basic_expr { $$ = $2; } // TODO: restrict this - | /* optional */ { $$ = NULL; } + | %empty { $$ = NULL; } ; enum_var_list: @@ -1531,14 +1525,14 @@ struct_union: struct_body: opt_packed '{' struct_member_list '}' ; -opt_packed: TOK_PACKED opt_signed_struct - | { frontend_verilog_yyerror("Only PACKED supported at this time"); } - ; +opt_packed: + TOK_PACKED opt_signed_struct | + %empty { frontend_verilog_yyerror("Only PACKED supported at this time"); }; opt_signed_struct: TOK_SIGNED { astbuf2->is_signed = true; } | TOK_UNSIGNED { astbuf2->is_signed = false; } - | // default is unsigned + | %empty // default is unsigned ; struct_member_list: struct_member @@ -1645,7 +1639,7 @@ wire_decl: } opt_supply_wires ';'; opt_supply_wires: - /* empty */ | + %empty | opt_supply_wires ',' TOK_ID { AstNode *wire_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-2)->clone(); AstNode *assign_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-1)->clone(); @@ -1876,13 +1870,13 @@ single_prim: } cell_parameter_list_opt: - '#' '(' cell_parameter_list ')' | /* empty */; + '#' '(' cell_parameter_list ')' | %empty; cell_parameter_list: cell_parameter | cell_parameter_list ',' cell_parameter; cell_parameter: - /* empty */ | + %empty | expr { AstNode *node = new AstNode(AST_PARASET); astbuf1->children.push_back(node); @@ -2040,7 +2034,7 @@ always_cond: '@' ATTR_BEGIN ')' | '@' '(' ATTR_END | '@' '*' | - /* empty */; + %empty; always_events: always_event | @@ -2070,7 +2064,7 @@ opt_label: ':' TOK_ID { $$ = $2; } | - /* empty */ { + %empty { $$ = NULL; }; @@ -2078,7 +2072,7 @@ opt_sva_label: TOK_SVA_LABEL ':' { $$ = $1; } | - /* empty */ { + %empty { $$ = NULL; }; @@ -2089,7 +2083,7 @@ opt_property: TOK_FINAL { $$ = false; } | - /* empty */ { + %empty { $$ = false; }; @@ -2500,7 +2494,7 @@ behavioral_stmt: }; unique_case_attr: - /* empty */ { + %empty { $$ = false; } | TOK_PRIORITY case_attr { @@ -2536,11 +2530,11 @@ opt_synopsys_attr: if (ast_stack.back()->attributes.count(ID::parallel_case) == 0) ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(1, false); } | - /* empty */; + %empty; behavioral_stmt_list: behavioral_stmt_list behavioral_stmt | - /* empty */; + %empty; optional_else: TOK_ELSE { @@ -2554,11 +2548,11 @@ optional_else: } behavioral_stmt { SET_AST_NODE_LOC(ast_stack.back(), @3, @3); } | - /* empty */ %prec FAKE_THEN; + %empty %prec FAKE_THEN; case_body: case_body case_item | - /* empty */; + %empty; case_item: { @@ -2581,7 +2575,7 @@ case_item: gen_case_body: gen_case_body gen_case_item | - /* empty */; + %empty; gen_case_item: { @@ -2665,11 +2659,11 @@ lvalue_concat_list: opt_arg_list: '(' arg_list optional_comma ')' | - /* empty */; + %empty; arg_list: arg_list2 | - /* empty */; + %empty; arg_list2: single_arg | @@ -2682,7 +2676,7 @@ single_arg: module_gen_body: module_gen_body gen_stmt_or_module_body_stmt | - /* empty */; + %empty; gen_stmt_or_module_body_stmt: gen_stmt | module_body_stmt | @@ -2761,7 +2755,7 @@ gen_stmt_block: }; opt_gen_else: - TOK_ELSE gen_stmt_block | /* empty */ %prec FAKE_THEN; + TOK_ELSE gen_stmt_block | %empty %prec FAKE_THEN; expr: basic_expr { diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index f03faa9cf..9086943dc 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -173,9 +173,7 @@ struct OptMergeWorker for (const auto &it : cell1->connections_) { if (cell1->output(it.first)) { - if (it.first == ID::Q && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") || - cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") || - cell1->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) { + if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) { // For the 'Q' output of state elements, // use the (* init *) attribute value auto &sig1 = conn1[it.first]; diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index ddd9822b9..b203828d2 100644 --- a/techlibs/achronix/synth_achronix.cc +++ b/techlibs/achronix/synth_achronix.cc @@ -144,12 +144,12 @@ struct SynthAchronixPass : public ScriptPass { run("opt -fast -mux_undef -undriven -fine -full"); run("memory_map"); run("opt -undriven -fine"); - run("dff2dffe -direct-match $_DFF_*"); run("opt -fine"); run("techmap -map +/techmap.v"); run("opt -full"); run("clean -purge"); run("setundef -undriven -zero"); + run("dfflegalize -cell $_DFF_P_ x"); if (retime || help_mode) run("abc -markgroups -dff -D 1", "(only if -retime)"); } diff --git a/techlibs/anlogic/cells_map.v b/techlibs/anlogic/cells_map.v index 0bcea9856..000256fb9 100644 --- a/techlibs/anlogic/cells_map.v +++ b/techlibs/anlogic/cells_map.v @@ -1,31 +1,17 @@ -module \$_DFF_N_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(1'b0)); endmodule -module \$_DFF_P_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(1'b0)); endmodule +module \$_DFFE_PN0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) ,.ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PN1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_NN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_NP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_PN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule +module \$_SDFFE_PN0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) ,.ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PN1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) , .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule - -module \$_DLATCH_N_ (E, D, Q); - wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; - input E, D; - output Q = !E ? D : Q; -endmodule - -module \$_DLATCH_P_ (E, D, Q); - wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; - input E, D; - output Q = E ? D : Q; -endmodule +module \$_DLATCH_NN0_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E) ,.ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DLATCH_NN1_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E), .ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DLATCH_NP0_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E), .ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DLATCH_NP1_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E), .ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule `ifndef NO_LUT module \$lut (A, Y); diff --git a/techlibs/anlogic/cells_sim.v b/techlibs/anlogic/cells_sim.v index 0fba43572..e8ecf4f03 100644 --- a/techlibs/anlogic/cells_sim.v +++ b/techlibs/anlogic/cells_sim.v @@ -10,9 +10,6 @@ module AL_MAP_SEQ ( parameter SRMUX = "SR"; //SR/INV parameter SRMODE = "SYNC"; //SYNC/ASYNC - wire clk_ce; - assign clk_ce = ce ? clk : 1'b0; - wire srmux; generate case (SRMUX) @@ -20,7 +17,7 @@ module AL_MAP_SEQ ( "INV": assign srmux = ~sr; default: assign srmux = sr; endcase - endgenerate + endgenerate wire regset; generate @@ -34,43 +31,45 @@ module AL_MAP_SEQ ( initial q = regset; generate - if (DFFMODE == "FF") + if (DFFMODE == "FF") begin - if (SRMODE == "ASYNC") + if (SRMODE == "ASYNC") begin - always @(posedge clk_ce, posedge srmux) + always @(posedge clk, posedge srmux) if (srmux) q <= regset; - else - q <= d; - end + else if (ce) + q <= d; + end else begin - always @(posedge clk_ce) + always @(posedge clk) if (srmux) q <= regset; - else - q <= d; + else if (ce) + q <= d; end end else begin // DFFMODE == "LATCH" - if (SRMODE == "ASYNC") + if (SRMODE == "ASYNC") begin - always @(clk_ce, srmux) + always @* if (srmux) q <= regset; - else - q <= d; - end + else if (~clk & ce) + q <= d; + end else begin - always @(clk_ce) - if (srmux) - q <= regset; - else - q <= d; + always @* + if (~clk) begin + if (srmux) + q <= regset; + else if (ce) + q <= d; + end end end endgenerate diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index d7475df86..d953fae5e 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -182,8 +182,8 @@ struct SynthAnlogicPass : public ScriptPass if (check_label("map_ffs")) { + run("dfflegalize -cell $_DFFE_P??P_ r -cell $_SDFFE_P??P_ r -cell $_DLATCH_N??_ r"); run("techmap -D NO_LUT -map +/anlogic/cells_map.v"); - run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); run("opt_expr -mux_undef"); run("simplemap"); } diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 69665982c..2a3a953e3 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,10 +1,10 @@ OBJS += techlibs/efinix/synth_efinix.o -OBJS += techlibs/efinix/efinix_gbuf.o OBJS += techlibs/efinix/efinix_fixcarry.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/gbuf_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams.txt)) diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index a74d1c571..22c7bc776 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -36,6 +36,7 @@ module EFX_FF( output reg Q, input D, input CE, + (* clkbuf_sink *) input CLK, input SR ); @@ -100,6 +101,7 @@ endmodule module EFX_GBUFCE( input CE, input I, + (* clkbuf_driver *) output O ); parameter CE_POLARITY = 1'b1; @@ -115,11 +117,13 @@ module EFX_RAM_5K( input [WRITE_WIDTH-1:0] WDATA, input [WRITE_ADDR_WIDTH-1:0] WADDR, input WE, + (* clkbuf_sink *) input WCLK, input WCLKE, output [READ_WIDTH-1:0] RDATA, input [READ_ADDR_WIDTH-1:0] RADDR, input RE, + (* clkbuf_sink *) input RCLK ); parameter READ_WIDTH = 20; @@ -172,4 +176,4 @@ module EFX_RAM_5K( (WRITE_WIDTH == 10) ? 9 : // 512x10 (WRITE_WIDTH == 5) ? 10 : -1; // 1024x5 -endmodule
\ No newline at end of file +endmodule diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc deleted file mode 100644 index ae191359a..000000000 --- a/techlibs/efinix/efinix_gbuf.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.com> - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/yosys.h" -#include "kernel/sigtools.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -static void handle_gbufs(Module *module) -{ - SigMap sigmap(module); - - pool<SigBit> clk_bits; - dict<SigBit, SigBit> rewrite_bits; - vector<pair<Cell*, SigBit>> pad_bits; - - for (auto cell : module->cells()) - { - if (cell->type == ID(EFX_FF)) { - for (auto bit : sigmap(cell->getPort(ID::CLK))) - clk_bits.insert(bit); - } - if (cell->type == ID(EFX_RAM_5K)) { - for (auto bit : sigmap(cell->getPort(ID(RCLK)))) - clk_bits.insert(bit); - for (auto bit : sigmap(cell->getPort(ID(WCLK)))) - clk_bits.insert(bit); - } - } - - for (auto wire : vector<Wire*>(module->wires())) - { - if (!wire->port_input) - continue; - - for (int index = 0; index < GetSize(wire); index++) - { - SigBit bit(wire, index); - SigBit canonical_bit = sigmap(bit); - - if (!clk_bits.count(canonical_bit)) - continue; - - Cell *c = module->addCell(NEW_ID, ID(EFX_GBUFCE)); - SigBit new_bit = module->addWire(NEW_ID); - c->setParam(ID(CE_POLARITY), State::S1); - c->setPort(ID::O, new_bit); - c->setPort(ID(CE), State::S1); - pad_bits.push_back(make_pair(c, bit)); - rewrite_bits[canonical_bit] = new_bit; - - log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit)); - } - } - - auto rewrite_function = [&](SigSpec &s) { - for (auto &bit : s) { - SigBit canonical_bit = sigmap(bit); - if (rewrite_bits.count(canonical_bit)) - bit = rewrite_bits.at(canonical_bit); - } - }; - - module->rewrite_sigspecs(rewrite_function); - - for (auto &it : pad_bits) - it.first->setPort(ID::I, it.second); -} - -struct EfinixGbufPass : public Pass { - EfinixGbufPass() : Pass("efinix_gbuf", "Efinix: insert global clock buffers") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" efinix_gbuf [options] [selection]\n"); - log("\n"); - log("Add Efinix global clock buffers to top module as needed.\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) override - { - log_header(design, "Executing efinix_gbuf pass (insert global clock buffers).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - break; - } - extra_args(args, argidx, design); - - Module *module = design->top_module(); - - if (module == nullptr) - log_cmd_error("No top module found.\n"); - - handle_gbufs(module); - } -} EfinixGbufPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/gbuf_map.v b/techlibs/efinix/gbuf_map.v new file mode 100644 index 000000000..43e0c9ac3 --- /dev/null +++ b/techlibs/efinix/gbuf_map.v @@ -0,0 +1,3 @@ +module \$__EFX_GBUF (input I, output O); + EFX_GBUFCE #(.CE_POLARITY(1'b1)) _TECHMAP_REPLACE_ (.I(I), .O(O), .CE(1'b1)); +endmodule diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index d994ae524..001b05945 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -202,7 +202,8 @@ struct SynthEfinixPass : public ScriptPass if (check_label("map_gbuf")) { - run("efinix_gbuf"); + run("clkbufmap -buf $__EFX_GBUF O:I"); + run("techmap -map +/efinix/gbuf_map.v"); run("efinix_fixcarry"); run("clean"); } diff --git a/tests/arch/anlogic/latches.ys b/tests/arch/anlogic/latches.ys index 8d66f77b3..34a3b14d0 100644 --- a/tests/arch/anlogic/latches.ys +++ b/tests/arch/anlogic/latches.ys @@ -3,31 +3,33 @@ design -save read hierarchy -top latchp proc -# Can't run any sort of equivalence check because latches are blown to LUTs -synth_anlogic +equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic +design -load postopt cd latchp # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT3 -select -assert-none t:AL_MAP_LUT3 %% t:* %D +select -assert-count 1 t:AL_MAP_SEQ +select -assert-count 1 t:AL_MAP_LUT1 +select -assert-none t:AL_MAP_SEQ t:AL_MAP_LUT1 %% t:* %D design -load read hierarchy -top latchn proc -# Can't run any sort of equivalence check because latches are blown to LUTs -synth_anlogic +equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic +design -load postopt cd latchn # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT3 -select -assert-none t:AL_MAP_LUT3 %% t:* %D +select -assert-count 1 t:AL_MAP_SEQ +select -assert-none t:AL_MAP_SEQ %% t:* %D design -load read hierarchy -top latchsr proc -# Can't run any sort of equivalence check because latches are blown to LUTs -synth_anlogic +equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic +design -load postopt cd latchsr # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT5 -select -assert-none t:AL_MAP_LUT5 %% t:* %D +select -assert-count 1 t:AL_MAP_SEQ +select -assert-count 2 t:AL_MAP_LUT3 +select -assert-none t:AL_MAP_SEQ t:AL_MAP_LUT3 %% t:* %D diff --git a/tests/various/integer_range_bad_syntax.ys b/tests/various/integer_range_bad_syntax.ys new file mode 100644 index 000000000..4f427211f --- /dev/null +++ b/tests/various/integer_range_bad_syntax.ys @@ -0,0 +1,6 @@ +logger -expect error "syntax error, unexpected" 1 +read_verilog -sv <<EOT +module test_integer_range(); +parameter integer [31:0] a = 0; +endmodule +EOT diff --git a/tests/various/integer_real_bad_syntax.ys b/tests/various/integer_real_bad_syntax.ys new file mode 100644 index 000000000..942d8de77 --- /dev/null +++ b/tests/various/integer_real_bad_syntax.ys @@ -0,0 +1,6 @@ +logger -expect error "syntax error, unexpected TOK_REAL" 1 +read_verilog -sv <<EOT +module test_integer_real(); +parameter integer real a = 0; +endmodule +EOT diff --git a/tests/various/logic_param_simple.ys b/tests/various/logic_param_simple.ys new file mode 100644 index 000000000..968564080 --- /dev/null +++ b/tests/various/logic_param_simple.ys @@ -0,0 +1,9 @@ +read_verilog -sv <<EOT +module test_logic_param(); +parameter logic a = 0; +parameter logic [31:0] e = 0; +parameter logic signed b = 0; +parameter logic unsigned c = 0; +parameter logic unsigned [31:0] d = 0; +endmodule +EOT diff --git a/tests/various/signed.ys b/tests/various/signed.ys new file mode 100644 index 000000000..2319a5da1 --- /dev/null +++ b/tests/various/signed.ys @@ -0,0 +1,28 @@ +# SV LRM A2.2.1 + +read_verilog -sv <<EOT +module test_signed(); +parameter integer signed a = 0; +parameter integer unsigned b = 0; + +endmodule +EOT + +design -reset +read_verilog -sv <<EOT +module test_signed(); +parameter logic signed [7:0] a = 0; +parameter logic unsigned [7:0] b = 0; + +endmodule +EOT + +design -reset +logger -expect error "syntax error, unexpected TOK_INTEGER" 1 +read_verilog -sv <<EOT +module test_signed(); +parameter signed integer a = 0; +parameter unsigned integer b = 0; + +endmodule +EOT |