From 12bd12e11272b7a9e52b3a56785a0d78401b998c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 6 Jan 2009 11:57:25 -0500 Subject: [PATCH] Support bufif0, bufif1, notif0, notif1 --- bin/verilator | 5 +-- src/verilog.l | 8 ++--- src/verilog.y | 36 +++++++++++++++++-- .../t/{t_tristate.cpp => t_tri_gate.cpp} | 20 +++++++++-- test_regress/t/{t_tristate.v => t_tri_gate.v} | 13 ++++++- test_regress/t/t_tri_gate_bufif0.pl | 24 +++++++++++++ test_regress/t/t_tri_gate_bufif1.pl | 24 +++++++++++++ .../t/{t_tristate.pl => t_tri_gate_cond.pl} | 10 ++++-- test_regress/t/t_tri_gate_notif0.pl | 24 +++++++++++++ test_regress/t/t_tri_gate_notif1.pl | 24 +++++++++++++ test_regress/t/t_tri_inout.cpp | 2 ++ test_regress/t/t_tri_inout.pl | 6 ++-- test_regress/t/t_tri_pullup.cpp | 2 ++ test_regress/t/t_tri_pullup.pl | 6 ++-- test_regress/t/t_tri_select.cpp | 2 ++ test_regress/t/t_tri_select.pl | 6 ++-- 16 files changed, 188 insertions(+), 24 deletions(-) rename test_regress/t/{t_tristate.cpp => t_tri_gate.cpp} (70%) rename test_regress/t/{t_tristate.v => t_tri_gate.v} (78%) create mode 100755 test_regress/t/t_tri_gate_bufif0.pl create mode 100755 test_regress/t/t_tri_gate_bufif1.pl rename test_regress/t/{t_tristate.pl => t_tri_gate_cond.pl} (68%) create mode 100755 test_regress/t/t_tri_gate_notif0.pl create mode 100755 test_regress/t/t_tri_gate_notif1.pl diff --git a/bin/verilator b/bin/verilator index 15e5fd593..fe012d5e9 100755 --- a/bin/verilator +++ b/bin/verilator @@ -1507,8 +1507,9 @@ Will be converted to output driver__en; // True if driven from this module output driver__enout; // Value being driven from this module -Pullup and pulldown are also supported. External logic will be needed to -combine these signals with any external drivers. +Pullup, pulldown, bufif0, bufif1, notif0, notif1 are also supported. +External logic will be needed to combine these signals with any external +drivers. Tristate drivers are not supported inside functions and tasks; a inout there will be considered a two state variable that is read and written diff --git a/src/verilog.l b/src/verilog.l index 3e8b741e1..4b6082798 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -182,6 +182,8 @@ escid \\[^ \t\f\r\n]+ "assign" {yylval.fileline = CRELINE(); return yASSIGN;} "begin" {yylval.fileline = CRELINE(); return yBEGIN;} "buf" {yylval.fileline = CRELINE(); return yBUF;} + "bufif0" {yylval.fileline = CRELINE(); return yBUFIF0;} + "bufif1" {yylval.fileline = CRELINE(); return yBUFIF1;} "case" {yylval.fileline = CRELINE(); return yCASE;} "casex" {yylval.fileline = CRELINE(); return yCASEX;} "casez" {yylval.fileline = CRELINE(); return yCASEZ;} @@ -209,6 +211,8 @@ escid \\[^ \t\f\r\n]+ "negedge" {yylval.fileline = CRELINE(); return yNEGEDGE;} "nor" {yylval.fileline = CRELINE(); return yNOR;} "not" {yylval.fileline = CRELINE(); return yNOT;} + "notif0" {yylval.fileline = CRELINE(); return yNOTIF0;} + "notif1" {yylval.fileline = CRELINE(); return yNOTIF1;} "or" {yylval.fileline = CRELINE(); return yOR;} "output" {yylval.fileline = CRELINE(); return yOUTPUT;} "parameter" {yylval.fileline = CRELINE(); return yPARAMETER;} @@ -242,8 +246,6 @@ escid \\[^ \t\f\r\n]+ "$writeh" {yyerrorf("Unsupported: Use $write with %%x format instead: %s",yytext);} "$writeo" {yyerrorf("Unsupported: Use $write with %%o format instead: %s",yytext);} /* Generic unsupported warnings */ - "bufif0" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} - "bufif1" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "cmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "deassign" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "endprimitive" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} @@ -258,8 +260,6 @@ escid \\[^ \t\f\r\n]+ "large" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "medium" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "nmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} - "notif0" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} - "notif1" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "pmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "primitive" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} "pull0" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);} diff --git a/src/verilog.y b/src/verilog.y index 1dd9452e7..817722a18 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -164,6 +164,8 @@ class AstSenTree; %token yAUTOMATIC "automatic" %token yBEGIN "begin" %token yBUF "buf" +%token yBUFIF0 "bufif0" +%token yBUFIF1 "bufif1" %token yCASE "case" %token yCASEX "casex" %token yCASEZ "casez" @@ -200,6 +202,8 @@ class AstSenTree; %token yNEGEDGE "negedge" %token yNOR "nor" %token yNOT "not" +%token yNOTIF0 "notif0" +%token yNOTIF1 "notif1" %token yOR "or" %token yOUTPUT "output" %token yPARAMETER "parameter" @@ -1249,8 +1253,12 @@ commaVRDListE: // Gate declarations gateDecl: - yBUF delayE gateBufList ';' { $$ = $3; } - | yNOT delayE gateNotList ';' { $$ = $3; } + yBUF delayE gateBufList ';' { $$ = $3; } + | yBUFIF0 delayE gateBufif0List ';' { $$ = $3; } + | yBUFIF1 delayE gateBufif1List ';' { $$ = $3; } + | yNOT delayE gateNotList ';' { $$ = $3; } + | yNOTIF0 delayE gateNotif0List ';' { $$ = $3; } + | yNOTIF1 delayE gateNotif1List ';' { $$ = $3; } | yAND delayE gateAndList ';' { $$ = $3; } | yNAND delayE gateNandList ';' { $$ = $3; } | yOR delayE gateOrList ';' { $$ = $3; } @@ -1265,10 +1273,26 @@ gateBufList: gateBuf { $$ = $1; } | gateBufList ',' gateBuf { $$ = $1->addNext($3); } ; +gateBufif0List: + gateBufif0 { $$ = $1; } + | gateBufif0List ',' gateBufif0 { $$ = $1->addNext($3); } + ; +gateBufif1List: + gateBufif1 { $$ = $1; } + | gateBufif1List ',' gateBufif1 { $$ = $1->addNext($3); } + ; gateNotList: gateNot { $$ = $1; } | gateNotList ',' gateNot { $$ = $1->addNext($3); } ; +gateNotif0List: + gateNotif0 { $$ = $1; } + | gateNotif0List ',' gateNotif0 { $$ = $1->addNext($3); } + ; +gateNotif1List: + gateNotif1 { $$ = $1; } + | gateNotif1List ',' gateNotif1 { $$ = $1->addNext($3); } + ; gateAndList: gateAnd { $$ = $1; } | gateAndList ',' gateAnd { $$ = $1->addNext($3); } @@ -1304,8 +1328,16 @@ gatePulldownList: gateBuf: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); } ; +gateBufif0: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), $6)); } + ; +gateBufif1: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, $6, new AstConst($3,V3Number($3,"1'bz")))); } + ; gateNot: gateIdE instRangeE '(' varRefDotBit ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); } ; +gateNotif0: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), new AstNot($3, $6))); } + ; +gateNotif1: gateIdE instRangeE '(' varRefDotBit ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstNot($3,$6), new AstConst($3,V3Number($3,"1'bz")))); } + ; gateAnd: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); $$->allowImplicit(true); } ; gateNand: gateIdE instRangeE '(' varRefDotBit ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); $$->allowImplicit(true); } diff --git a/test_regress/t/t_tristate.cpp b/test_regress/t/t_tri_gate.cpp similarity index 70% rename from test_regress/t/t_tristate.cpp rename to test_regress/t/t_tri_gate.cpp index 193d85e04..da9fc384a 100644 --- a/test_regress/t/t_tristate.cpp +++ b/test_regress/t/t_tri_gate.cpp @@ -1,9 +1,21 @@ // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks -#include "Vt_tristate.h" +#ifdef T_COND +# include "Vt_tri_gate_cond.h" +#elif defined(T_BUFIF0) +# include "Vt_tri_gate_bufif0.h" +#elif defined(T_BUFIF1) +# include "Vt_tri_gate_bufif1.h" +#elif defined(T_NOTIF0) +# include "Vt_tri_gate_notif0.h" +#elif defined(T_NOTIF1) +# include "Vt_tri_gate_notif1.h" +#else +# error "Unknown test" +#endif -Vt_tristate *tb = NULL; +VM_PREFIX* tb = NULL; double sc_time_stamp() { return 0; @@ -26,7 +38,9 @@ bool check() { int main() { bool pass = true; - tb = new Vt_tristate("tb"); + + Verilated::debug(0); + tb = new VM_PREFIX ("tb"); // loop through every possibility and check the result for (tb->SEL=0; tb->SEL<2; tb->SEL++) { diff --git a/test_regress/t/t_tristate.v b/test_regress/t/t_tri_gate.v similarity index 78% rename from test_regress/t/t_tristate.v rename to test_regress/t/t_tri_gate.v index c14a6b62b..4980854ba 100644 --- a/test_regress/t/t_tristate.v +++ b/test_regress/t/t_tri_gate.v @@ -4,7 +4,6 @@ module top (input SEL, input[1:0] A, output Z, output Y, output X, output W); assign Z = ( SEL) ? A[1] : 1'bz; tbuf tbuf(.A(A[0]), .OE(!SEL), .Z(Z)); -// assign Z = (!SEL) ? A[0] : 1'bz; tbuf mux0[1:0](.A(A), .OE({SEL,!SEL}), .Z(Y)); @@ -18,7 +17,19 @@ module pass (input[1:0] A, input SEL, output Z); endmodule module tbuf (input A, input OE, output Z); +`ifdef T_BUFIF0 + bufif0 (Z, A, !OE); +`elsif T_BUFIF1 + bufif1 (Z, A, OE); +`elsif T_NOTIF0 + notif0 (Z, !A, !OE); +`elsif T_NOTIF1 + notif1 (Z, !A, OE); +`elsif T_COND assign Z = (OE) ? A : 1'bz; +`else + `error "Unknown test name" +`endif endmodule module mux (input[1:0] A, input SEL, output Z); diff --git a/test_regress/t/t_tri_gate_bufif0.pl b/test_regress/t/t_tri_gate_bufif0.pl new file mode 100755 index 000000000..3b488ca0f --- /dev/null +++ b/test_regress/t/t_tri_gate_bufif0.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# General Public License or the Perl Artistic License. + +top_filename("t/t_tri_gate.v"); + +compile ( + make_top_shell => 0, + make_main => 0, + v_flags2 => ['+define+T_BUFIF0',], + make_flags => 'CPPFLAGS_ADD=-DT_BUFIF0', + verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], + ) if $Self->{v3}; + +execute ( + check_finished=>1, + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_tri_gate_bufif1.pl b/test_regress/t/t_tri_gate_bufif1.pl new file mode 100755 index 000000000..94c1ac788 --- /dev/null +++ b/test_regress/t/t_tri_gate_bufif1.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# General Public License or the Perl Artistic License. + +top_filename("t/t_tri_gate.v"); + +compile ( + make_top_shell => 0, + make_main => 0, + v_flags2 => ['+define+T_BUFIF1',], + make_flags => 'CPPFLAGS_ADD=-DT_BUFIF1', + verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], + ) if $Self->{v3}; + +execute ( + check_finished=>1, + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_tristate.pl b/test_regress/t/t_tri_gate_cond.pl similarity index 68% rename from test_regress/t/t_tristate.pl rename to test_regress/t/t_tri_gate_cond.pl index a2959d48c..693e4260d 100755 --- a/test_regress/t/t_tristate.pl +++ b/test_regress/t/t_tri_gate_cond.pl @@ -6,15 +6,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # redistribute it and/or modify it under the terms of either the GNU # General Public License or the Perl Artistic License. +top_filename("t/t_tri_gate.v"); + compile ( make_top_shell => 0, make_main => 0, - v_flags2 => ["--exe t/$Last_Self->{name}.cpp"], - ) if $Last_Self->{v3}; + v_flags2 => ['+define+T_COND',], + make_flags => 'CPPFLAGS_ADD=-DT_COND', + verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], + ) if $Self->{v3}; execute ( check_finished=>1, - ) if $Last_Self->{v3}; + ) if $Self->{v3}; ok(1); 1; diff --git a/test_regress/t/t_tri_gate_notif0.pl b/test_regress/t/t_tri_gate_notif0.pl new file mode 100755 index 000000000..0a03f7119 --- /dev/null +++ b/test_regress/t/t_tri_gate_notif0.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# General Public License or the Perl Artistic License. + +top_filename("t/t_tri_gate.v"); + +compile ( + make_top_shell => 0, + make_main => 0, + v_flags2 => ['+define+T_NOTIF0',], + make_flags => 'CPPFLAGS_ADD=-DT_NOTIF0', + verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], + ) if $Self->{v3}; + +execute ( + check_finished=>1, + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_tri_gate_notif1.pl b/test_regress/t/t_tri_gate_notif1.pl new file mode 100755 index 000000000..17845cb6b --- /dev/null +++ b/test_regress/t/t_tri_gate_notif1.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# General Public License or the Perl Artistic License. + +top_filename("t/t_tri_gate.v"); + +compile ( + make_top_shell => 0, + make_main => 0, + v_flags2 => ['+define+T_NOTIF1',], + make_flags => 'CPPFLAGS_ADD=-DT_NOTIF1', + verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], + ) if $Self->{v3}; + +execute ( + check_finished=>1, + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_tri_inout.cpp b/test_regress/t/t_tri_inout.cpp index 4581e5e15..fca375e97 100644 --- a/test_regress/t/t_tri_inout.cpp +++ b/test_regress/t/t_tri_inout.cpp @@ -31,6 +31,8 @@ bool check() { int main() { bool pass = true; + + Verilated::debug(0); tb = new Vt_tri_inout("tb"); // loop through every possibility and check the result diff --git a/test_regress/t/t_tri_inout.pl b/test_regress/t/t_tri_inout.pl index a2959d48c..af7f39ed0 100755 --- a/test_regress/t/t_tri_inout.pl +++ b/test_regress/t/t_tri_inout.pl @@ -9,12 +9,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di compile ( make_top_shell => 0, make_main => 0, - v_flags2 => ["--exe t/$Last_Self->{name}.cpp"], - ) if $Last_Self->{v3}; + v_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], + ) if $Self->{v3}; execute ( check_finished=>1, - ) if $Last_Self->{v3}; + ) if $Self->{v3}; ok(1); 1; diff --git a/test_regress/t/t_tri_pullup.cpp b/test_regress/t/t_tri_pullup.cpp index 182c0f271..d0731f4c5 100644 --- a/test_regress/t/t_tri_pullup.cpp +++ b/test_regress/t/t_tri_pullup.cpp @@ -35,6 +35,8 @@ bool check() { int main() { bool pass = true; + + Verilated::debug(0); tb = new Vt_tri_pullup("tb"); // loop through every possibility and check the result diff --git a/test_regress/t/t_tri_pullup.pl b/test_regress/t/t_tri_pullup.pl index 9a4056310..26df29436 100755 --- a/test_regress/t/t_tri_pullup.pl +++ b/test_regress/t/t_tri_pullup.pl @@ -9,12 +9,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di compile ( make_top_shell => 0, make_main => 0, - v_flags2 => ["--exe t/$Last_Self->{name}.cpp --debug"], - ) if $Last_Self->{v3}; + v_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp --debug"], + ) if $Self->{v3}; execute ( check_finished=>1, - ) if $Last_Self->{v3}; + ) if $Self->{v3}; ok(1); 1; diff --git a/test_regress/t/t_tri_select.cpp b/test_regress/t/t_tri_select.cpp index eb1984db5..ce8d4225e 100644 --- a/test_regress/t/t_tri_select.cpp +++ b/test_regress/t/t_tri_select.cpp @@ -31,6 +31,8 @@ bool check() { int main() { bool pass = true; + + Verilated::debug(0); tb = new Vt_tri_select("tb"); // loop through every possibility and check the result diff --git a/test_regress/t/t_tri_select.pl b/test_regress/t/t_tri_select.pl index 9a4056310..26df29436 100755 --- a/test_regress/t/t_tri_select.pl +++ b/test_regress/t/t_tri_select.pl @@ -9,12 +9,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di compile ( make_top_shell => 0, make_main => 0, - v_flags2 => ["--exe t/$Last_Self->{name}.cpp --debug"], - ) if $Last_Self->{v3}; + v_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp --debug"], + ) if $Self->{v3}; execute ( check_finished=>1, - ) if $Last_Self->{v3}; + ) if $Self->{v3}; ok(1); 1;