From d6884db439746cb78b128d7d9437a87ae7f66497 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 27 Jun 2008 11:36:25 -0400 Subject: [PATCH] Support . --- Changes | 2 ++ bin/verilator | 6 ++++++ include/verilated.cpp | 32 ++++++++++++++++++++++++++------ include/verilated.h | 7 ++++++- src/V3AstNodes.h | 10 +++++++--- src/V3Signed.cpp | 4 ++++ src/V3Unknown.cpp | 2 +- src/V3Width.cpp | 5 +++++ src/verilog.l | 1 + src/verilog.y | 4 ++++ test_regress/t/t_sys_rand.pl | 17 +++++++++++++++++ test_regress/t/t_sys_rand.v | 36 ++++++++++++++++++++++++++++++++++++ 12 files changed, 115 insertions(+), 11 deletions(-) create mode 100755 test_regress/t/t_sys_rand.pl create mode 100644 test_regress/t/t_sys_rand.v diff --git a/Changes b/Changes index ef682d4ed..f0a261d92 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks! *** Support $feof, $fflush. [Holger Waechtler] +*** Support $random. + * Verilator 3.665 2008/06/25 **** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair] diff --git a/bin/verilator b/bin/verilator index 50e8cd037..ccea2366f 100755 --- a/bin/verilator +++ b/bin/verilator @@ -1569,6 +1569,12 @@ $setup, $setuphold, $skew, $timeskew, $width All specify blocks and timing checks are ignored. +=item $random + +$random does not support the optional argument to set the seed. Use the +srand function in C to accomplish this, and note there is only one random +number generator (not one per module). + =item $readmemb, $readmemh Read memory commands should work properly. Note Verilator and the Verilog diff --git a/include/verilated.cpp b/include/verilated.cpp index a94ee996d..1cab28774 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -80,23 +80,43 @@ IData VL_RAND32() { #endif } -IData VL_RAND_RESET_I(int outBits) { +IData VL_RANDOM_I(int obits) { + return VL_RAND32() & VL_MASK_I(obits); +} + +QData VL_RANDOM_Q(int obits) { + QData data = ((QData)VL_RAND32()<fileline(), new AstConst(nodep->fileline(),numbx), new AstRand(nodep->fileline(), - nodep->width()))))); + nodep->width(), true))))); // Add inits in front of other statement. // In the future, we should stuff the initp into the module's constructor. AstNode* afterp = m_modp->stmtsp()->unlinkFrBackWithNext(); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 7f0b527d8..2fb43dddb 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -362,6 +362,11 @@ private: } } } + virtual void visit(AstRand* nodep, AstNUser* vup) { + if (vup->c()->prelim()) { + nodep->width(32,32); // Says the spec + } + } virtual void visit(AstTime* nodep, AstNUser*) { nodep->width(64,64); } diff --git a/src/verilog.l b/src/verilog.l index c1c2d01f8..b633baa90 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -141,6 +141,7 @@ escid \\[^ \t\f\r\n]+ "$hold" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;} "$nochange" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;} "$period" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;} + "$random" {yylval.fileline = CRELINE(); return yD_RANDOM;} "$readmemb" {yylval.fileline = CRELINE(); return yD_READMEMB;} "$readmemh" {yylval.fileline = CRELINE(); return yD_READMEMH;} "$realtime" {yylval.fileline = CRELINE(); return yD_TIME;} diff --git a/src/verilog.y b/src/verilog.y index 2789ed574..089d6705f 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -235,6 +235,7 @@ class AstSenTree; %token yD_ISUNKNOWN "$isunknown" %token yD_ONEHOT "$onehot" %token yD_ONEHOT0 "$onehot0" +%token yD_RANDOM "$random" %token yD_READMEMB "$readmemb" %token yD_READMEMH "$readmemh" %token yD_SIGNED "$signed" @@ -1085,6 +1086,9 @@ exprNoStr: expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); } | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); } | yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); } | yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); } + | yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")\n"); } + | yD_RANDOM '(' ')' { $$ = new AstRand($1); } + | yD_RANDOM { $$ = new AstRand($1); } | yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); } | yD_TIME { $$ = new AstTime($1); } | yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); } diff --git a/test_regress/t/t_sys_rand.pl b/test_regress/t/t_sys_rand.pl new file mode 100755 index 000000000..e2a0c97fa --- /dev/null +++ b/test_regress/t/t_sys_rand.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +compile ( + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_sys_rand.v b/test_regress/t/t_sys_rand.v new file mode 100644 index 000000000..80287feac --- /dev/null +++ b/test_regress/t/t_sys_rand.v @@ -0,0 +1,36 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2008 by Wilson Snyder. + +module t; + + reg [31:0] lastrand; + reg [31:0] thisrand; + + integer same = 0; + integer i; + +`define TRIES 20 + + initial begin + // There's a 1^32 chance of the numbers being the same twice, + // so we'll allow one failure + lastrand = $random; + for (i=0; i<`TRIES; i=i+1) begin + thisrand = $random; +`ifdef TEST_VERBOSE + $write("Random = %x\n", thisrand); +`endif + if (thisrand == lastrand) same=same+1; + lastrand = thisrand; + end + if (same > 1) begin + $write("%%Error: Too many similar numbers: %d\n", same); + $stop; + end + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule