diff --git a/Changes b/Changes index 0e3940bd5..d8c85fdab 100644 --- a/Changes +++ b/Changes @@ -31,6 +31,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix error on parameters with dotted references, bug1146. [Johan Bjork] +**** Fix wreal not handling continuous assign, bug1150. [J Briquet] + * Verilator 3.900 2017-01-15 diff --git a/src/V3Ast.h b/src/V3Ast.h index 0814afb0a..864ff075d 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -427,6 +427,7 @@ public: SUPPLY0, SUPPLY1, WIRE, + WREAL, IMPLICITWIRE, TRIWIRE, TRI0, @@ -448,13 +449,13 @@ public: static const char* names[] = { "?","GPARAM","LPARAM","GENVAR", "VAR","INPUT","OUTPUT","INOUT", - "SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE", + "SUPPLY0","SUPPLY1","WIRE","WREAL","IMPLICITWIRE", "TRIWIRE","TRI0","TRI1", "PORT", "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP", "IFACEREF"}; return names[m_e]; } - bool isSignal() const { return (m_e==WIRE || m_e==IMPLICITWIRE + bool isSignal() const { return (m_e==WIRE || m_e==WREAL || m_e==IMPLICITWIRE || m_e==TRIWIRE || m_e==TRI0 || m_e==TRI1 || m_e==SUPPLY0 || m_e==SUPPLY1 diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 525a6157f..428b248c4 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -195,6 +195,8 @@ string AstVar::verilogKwd() const { return "tri"; } else if (varType()==AstVarType::WIRE) { return "wire"; + } else if (varType()==AstVarType::WREAL) { + return "wreal"; } else { return dtypep()->name(); } diff --git a/src/verilog.y b/src/verilog.y index 0b3f3ec3f..a2c120b3c 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -934,13 +934,13 @@ portDirNetE: // IEEE: part of port, optional net type and/or direction // // Per spec, if direction given default the nettype. // // The higher level rule may override this VARDTYPE with one later in the parse. | port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } - | port_direction { VARDECL(PORT); } net_type { VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET - | net_type { } // net_type calls VARNET + | port_direction { VARDECL(PORT); } net_type { VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARDECL + | net_type { } // net_type calls VARDECL ; port_declNetE: // IEEE: part of port_declaration, optional net type /* empty */ { } - | net_type { } // net_type calls VARNET + | net_type { } // net_type calls VARDECL ; portSig: @@ -1209,6 +1209,8 @@ net_type: // ==IEEE: net_type //UNSUP yWAND { VARDECL(WAND); } | yWIRE { VARDECL(WIRE); } //UNSUP yWOR { VARDECL(WOR); } + // // VAMS - somewhat hackish + | yWREAL { VARDECL(WREAL); } ; varGParamReset: @@ -1291,8 +1293,6 @@ non_integer_type: // ==IEEE: non_integer_type yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } | yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } //UNSUP ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::FLOAT); } - // // VAMS - somewhat hackish - | yWREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); VARDECL(WIRE); } ; signingE: // IEEE: signing - plus empty @@ -3803,6 +3803,10 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange return NULL; } AstVarType type = GRAMMARP->m_varIO; + if (GRAMMARP->m_varDecl == AstVarType::WREAL) { + // dtypep might not be null, might be implicit LOGIC before we knew better + dtypep = new AstBasicDType(fileline,AstBasicDTypeKwd::DOUBLE); + } if (!dtypep) { // Created implicitly dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT); } else { // May make new variables with same type, so clone diff --git a/test_regress/t/t_vams_wreal.v b/test_regress/t/t_vams_wreal.v index 091c792c2..63e0b4eaf 100644 --- a/test_regress/t/t_vams_wreal.v +++ b/test_regress/t/t_vams_wreal.v @@ -9,20 +9,75 @@ module t (/*autoarg*/ // Outputs aout, // Inputs - in + clk, in ); + input clk; + input [15:0] in; output aout; wreal aout; + integer cyc=0; + + real vin; + real gnd; + wire out; + within_range within_range (/*AUTOINST*/ + // Interfaces + .vin (vin), + .gnd (gnd), + // Outputs + .out (out)); + parameter real lsb = 1; // verilator lint_off WIDTH assign aout = $itor(in) * lsb; - - initial begin - $write("*-* All Finished *-*\n"); - $finish; + // verilator lint_on WIDTH + + always @ (posedge clk) begin + cyc <= cyc + 1; +`ifdef TEST_VERBOSE + $write("[%0t] cyc==%0d aout=%d (%f-%f=%f)\n",$time, cyc, out, vin, gnd, within_range.in_int); +`endif + if (cyc==0) begin + // Setup + gnd = 0.0; + vin = 0.2; + end + else if (cyc==2) begin + if (out != 0) $stop; + end + else if (cyc==3) begin + gnd = 0.0; + vin = 0.6; + end + else if (cyc==4) begin + if (out != 1) $stop; + end + else if (cyc==5) begin + gnd = 0.6; + vin = 0.8; + end + else if (cyc==6) begin + if (out != 0) $stop; + end + else if (cyc==99) begin + $write("*-* All Finished *-*\n"); + $finish; + end end endmodule + +module within_range + (input wreal vin, + input wreal gnd, + output out); + + parameter real V_MIN = 0.5; + parameter real V_MAX = 10; + + wreal in_int = vin - gnd; + wire out = (V_MIN <= in_int && in_int <= V_MAX); +endmodule