diff --git a/Makefile b/Makefile index 2a3a6ab..0345e0f 100644 --- a/Makefile +++ b/Makefile @@ -11,4 +11,4 @@ clean: rm -rf bin test: - (cd test/relong; ./run.sh) + (cd test && ./run-all.sh) diff --git a/test/lex/cond.sv b/test/lex/cond.sv new file mode 100644 index 0000000..44a884f --- /dev/null +++ b/test/lex/cond.sv @@ -0,0 +1,139 @@ +module top; + +integer x = 0; +integer y = 1; + +`define GOOD \ + $display("%x %x %d", x, y, `__LINE__); \ + x += 1; $display(x); + +`define BAD \ + $display("FAIL line ", `__LINE__); + +initial begin + + `include "cond.vh" + $display(`RESULT); + `include "cond.vh" + $display(`RESULT); + `include "cond.vh" + $display(`RESULT); + `undef INCLUDED + `include "cond.vh" + $display(`RESULT); + `include "cond.vh" + $display(`RESULT); + + `define A + `define C + + `ifdef A + `GOOD + `endif + `ifndef A + `BAD + `endif + + `ifdef B + `BAD + `endif + `ifndef B + `GOOD + `endif + + `ifdef A + `GOOD + `else + `BAD + `endif + + `ifdef B + `BAD + `define A + `else + `GOOD + `endif + + `ifndef A + `BAD + `elsif B + `BAD + `elsif A + `GOOD + `else + `BAD + `endif + + `ifndef B + `GOOD + `elsif A + `BAD + `elsif B + `BAD + `else + `BAD + `endif + + `ifdef B + `BAD + `elsif A + `GOOD + `else + `BAD + `endif + + `ifdef B + `BAD + `elsif A + `GOOD + `elsif B + `BAD + `else + `BAD + `endif + + `ifdef B + `BAD + `elsif A + `GOOD + `elsif C + `BAD + `else + `BAD + `endif + + `ifdef A + `ifdef B + `BAD + `ifdef B + `BAD + `else + `BAD + `endif + `BAD + `else + `ifdef C + `GOOD + `ifndef C + `BAD + `else + `GOOD + `endif + `else + `BAD + `endif + `endif + `GOOD + `else + `BAD + `ifdef B + `BAD + `else + `BAD + `endif + `BAD + `endif + +end + +endmodule diff --git a/test/lex/cond.v b/test/lex/cond.v new file mode 100644 index 0000000..c0c9520 --- /dev/null +++ b/test/lex/cond.v @@ -0,0 +1,2 @@ +// use iverilog as reference +`include "cond.sv" diff --git a/test/lex/cond.vh b/test/lex/cond.vh new file mode 100644 index 0000000..a7b2d3a --- /dev/null +++ b/test/lex/cond.vh @@ -0,0 +1,8 @@ +`undef RESULT + +`ifndef INCLUDED +`define INCLUDED +`define RESULT 1 +`else +`define RESULT 0 +`endif diff --git a/test/lex/macro.sv b/test/lex/macro.sv new file mode 100644 index 0000000..79488bc --- /dev/null +++ b/test/lex/macro.sv @@ -0,0 +1,146 @@ +`define NUMBER_01 42 +`define NUMBER_02 (42) +`define NUMBER_03 (21 * 2) +`define NUMBER_04 21 * 2 +`define NUMBER_05 21 *\ +2 +`define NUMBER_06 21 *\ + 2 +`define NUMBER_07 21 * /* foo */ 2 +`define NUMBER_08 21 *\ + /* foo */\ + 2 +`define NUMBER_09 21 *\ + /* foo */ 2 +`define NUMBER_10 4 * \ +10 + \ +2 +`define NUMBER_11 42 // +`define NUMBER_12 21 */* foo */2//foo +`define NUMBER_13 21 *\ + // foo \ + 2 + +`define STRING_01 "foo\nbar" +`define STRING_02 " foo \n bar " + +`define STRING_COMMAS_01 "test" +`define STRING_COMMAS_02 "%s", "test" +`define STRING_COMMAS_03 "%s%s", "te", "st" +`define STRING_COMMAS_04 "%s%s%s", "t", "e", "st" +`define STRING_COMMAS_05 "%s%s%s", \ + "t", "e", "st" \ + // FOO + +`define MACRO_A_01(str="bar") str, str +`define MACRO_A_02(str= "bar") str, str +`define MACRO_A_03(str = "bar") str, str +`define MACRO_A_04( str = "bar") str, str +`define MACRO_A_05( str = "bar" ) str, str +`define MACRO_A_06( str += "bar" ) str, str +`define MACRO_A_07( str + = "bar" ) str, str + +`define MACRO_B(s=) \ + $display(`MACRO_A_01(s));\ + $display(`MACRO_A_02(s));\ + $display(`MACRO_A_03(s));\ + $display(`MACRO_A_04(s));\ + $display(`MACRO_A_05(s));\ + $display(`MACRO_A_06(s));\ + $display(`MACRO_A_07(s));\ + $display(`MACRO_A_01( s));\ + $display(`MACRO_A_02( s));\ + $display(`MACRO_A_03( s));\ + $display(`MACRO_A_04( s));\ + $display(`MACRO_A_05( s));\ + $display(`MACRO_A_06( s));\ + $display(`MACRO_A_07( s));\ + $display(`MACRO_A_01 (s));\ + $display(`MACRO_A_02 (s));\ + $display(`MACRO_A_03 (s));\ + $display(`MACRO_A_04 (s));\ + $display(`MACRO_A_05 (s));\ + $display(`MACRO_A_06 (s));\ + $display(`MACRO_A_07 (s));\ + $display(`MACRO_A_01 (s ));\ + $display(`MACRO_A_02 (s ));\ + $display(`MACRO_A_03 (s ));\ + $display(`MACRO_A_04 (s ));\ + $display(`MACRO_A_05 (s ));\ + $display(`MACRO_A_06 (s ));\ + $display(`MACRO_A_07 (s ));\ + $display(`MACRO_A_01(\ + s\ + ));\ + $display(`MACRO_A_02(\ + s\ + ));\ + $display(`MACRO_A_03(\ + s\ + ));\ + $display(`MACRO_A_04(\ + s\ + ));\ + $display(`MACRO_A_05(\ + s\ + ));\ + $display(`MACRO_A_06(\ + s\ + ));\ + $display(`MACRO_A_07(\ + s\ + )); + +`define MACRO_C(a, b=1) a, b + +`define MACRO_D(display) $display(display); + +`define MACRO_E(s) $display("s", `"s", `"ss"); + +`define MACRO_F(t) $display(`"s t = `\`"t`\`""); + +module top; +initial begin + + $display("%d", `NUMBER_01); + $display("%d", `NUMBER_02); + $display("%d", `NUMBER_03); + $display("%d", `NUMBER_04); + $display("%d", `NUMBER_05); + $display("%d", `NUMBER_06); + $display("%d", `NUMBER_07); + $display("%d", `NUMBER_08); + $display("%d", `NUMBER_09); + $display("%d", `NUMBER_10); + $display("%d", `NUMBER_11); + $display("%d", `NUMBER_12); + $display("%d", `NUMBER_13); + + $display("%s", `STRING_01); + $display("%s", `STRING_02); + + $display(`STRING_COMMAS_01); + $display(`STRING_COMMAS_02); + $display(`STRING_COMMAS_03); + $display(`STRING_COMMAS_04); + $display(`STRING_COMMAS_05); + + `MACRO_B(); + `MACRO_B("foo"); + + $display(`MACRO_C("foo")); + $display(`MACRO_C("foo",)); + $display(`MACRO_C("foo",2)); + + `MACRO_D("display"); + + `MACRO_E(foo); + `MACRO_E(display); + + `MACRO_F(foo); + `MACRO_F(display); + +end +endmodule diff --git a/test/lex/macro.v b/test/lex/macro.v new file mode 100644 index 0000000..08b13c9 --- /dev/null +++ b/test/lex/macro.v @@ -0,0 +1,18 @@ +module top; +initial begin + repeat (13) $display(42); + repeat (1) $display("foo\nbar"); + repeat (1) $display(" foo \n bar "); + repeat (5) $display("test"); + repeat (35) $display("bar", "bar"); + repeat (35) $display("foo", "foo"); + $display("foo", 1); + $display("foo", 1); + $display("foo", 2); + $display("display"); + $display("s", "foo", "ss"); + $display("s", "display", "ss"); + $display("s foo = \"foo\""); + $display("s display = \"display\""); +end +endmodule diff --git a/test/lex/run.sh b/test/lex/run.sh new file mode 100755 index 0000000..0dc63aa --- /dev/null +++ b/test/lex/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +NO_SEPARATE_TBS=1 +source ../lib/runner.sh diff --git a/test/lib/empty.v b/test/lib/empty.v new file mode 100644 index 0000000..e69de29 diff --git a/test/lib/runner.sh b/test/lib/runner.sh new file mode 100644 index 0000000..5c2f16b --- /dev/null +++ b/test/lib/runner.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +SCRIPT_DIR=`dirname "${BASH_SOURCE[0]}"` +SV2V="$SCRIPT_DIR/../../bin/sv2v" + +assertExists() { + file=$1 + [ -f "$file" ] + assertTrue "$file does not exist" $? +} + +# USAGE: simulate [ ...] +simulate() { + # arguments + sim_vcd="$1"; shift + sim_log="$1"; shift + sim_top="$1"; shift + # compile the files + sim_prog="$SHUNIT_TMPDIR/simprog.exe" + iverilog \ + -o "$sim_prog" \ + -g2005 \ + -DTEST_VCD="\"$sim_vcd\"" \ + -DTEST_TOP=$sim_top \ + "$SCRIPT_DIR/tb_dumper.v" \ + "$@" + assertTrue "iverilog on $1 failed" $? + # run the simulation + $sim_prog > $sim_log + assertTrue "simulating $1 failed" $? + # remove the date from the VCD + sed -i.orig -e "1,3d" "$sim_vcd" + # remove the "opened file..." prompt from the log + sed -i.orig -e "1,1d" "$sim_log" +} + +assertConverts() { + ac_file="$1" + ac_temp="$SHUNIT_TMPDIR/ac-conv-temp.v" + $SV2V "$ac_file" 2> /dev/null > "$ac_temp" + assertTrue "1st conversion of $ac_file failed" $? + $SV2V "$ac_temp" 2> /dev/null > /dev/null + assertTrue "2nd conversion of $ac_file failed" $? +} + +simpleTest() { + sv="$1" + ve="$2" + if [ -z ${NO_SEPARATE_TBS} ]; then + tb="$3" + else + tb="$SCRIPT_DIR/empty.v" + fi + + assertNotNull "SystemVerilog file not specified" $sv + assertNotNull "Verilog file not specified" $ve + assertNotNull "Testbench not specified" $tb + + assertExists $sv + assertExists $ve + assertExists $tb + + assertConverts "$sv" + assertConverts "$ve" + assertConverts "$tb" + + # convert the SystemVerilog source file + cv="$SHUNIT_TMPDIR/conv.v" + $SV2V $sv 2> /dev/null > $cv + assertTrue "conversion failed" $? + assertExists $cv + + ref_vcd="$SHUNIT_TMPDIR/ref.vcd" + gen_vcd="$SHUNIT_TMPDIR/gen.vcd" + ref_log="$SHUNIT_TMPDIR/ref.log" + gen_log="$SHUNIT_TMPDIR/gen.log" + + # simulate and compare the two files + simulate "$ref_vcd" "$ref_log" top "$ve" "$tb" + simulate "$gen_vcd" "$gen_log" top "$cv" "$tb" + diff "$ref_vcd" "$gen_vcd" > /dev/null + assertTrue "VCDs are different" $? + output=`diff "$ref_log" "$gen_log"` + assertTrue "Simulation outputs differ:\n$output" $? +} + +runTest() { + test="$1" + simpleTest "${test}.sv" "${test}.v" "${test}_tb.v" +} + +suite() { + for test in `ls *.sv | sed -e "s_\.sv\\\$__"`; do + eval "test_$test() { runTest \"$test\"; }" + suite_addTest "test_$test" + done +} + +. shunit2 + diff --git a/test/relong/tb_dumper.v b/test/lib/tb_dumper.v similarity index 100% rename from test/relong/tb_dumper.v rename to test/lib/tb_dumper.v diff --git a/test/relong/README.md b/test/relong/README.md index daa267a..5c6285d 100644 --- a/test/relong/README.md +++ b/test/relong/README.md @@ -7,6 +7,8 @@ done. The `inline_concat` files were modified to remove a stray trailing semicolon. +`array.v` previously had a custom implementation of `$clog2`, which was removed. + Each test case (say, "foo") is comprised of the following files: 1. `foo.sv`: original SystemVerilog diff --git a/test/relong/run.sh b/test/relong/run.sh index 086c2dd..8f8457f 100755 --- a/test/relong/run.sh +++ b/test/relong/run.sh @@ -1,81 +1,2 @@ #!/bin/sh - -SV2V=../../bin/sv2v - -assertExists() { - file=$1 - [ -f "$file" ] - assertTrue "$file does not exist" $? -} - -# USAGE: simulate [ ...] -simulate() { - # arguments - sim_outfile="$1"; shift - sim_top="$1"; shift - # compile the files - sim_prog="$SHUNIT_TMPDIR/simprog.exe" - iverilog \ - -o "$sim_prog" \ - -g2005 \ - -DTEST_VCD="\"$sim_outfile\"" \ - -DTEST_TOP=$sim_top \ - "tb_dumper.v" \ - "$@" - assertTrue "iverilog on $1 failed" $? - # run the simulation - $sim_prog > /dev/null - assertTrue "simulating $1 failed" $? - # remove the date from the VCD - sed -i.orig -e "1,3d" "$sim_outfile" -} - -assertConverts() { - ac_file="$1" - ac_temp="$SHUNIT_TMPDIR/ac-conv-temp.v" - $SV2V "$ac_file" 2> /dev/null > "$ac_temp" - assertTrue "1st conversion of $ac_file failed" $? - $SV2V "$ac_temp" 2> /dev/null > /dev/null - assertTrue "2nd conversion of $ac_file failed" $? -} - -runTest() { - test=$1 - assertNotNull "test not specified" $test - - sv="$test.sv" - ve="$test.v" - tb="${test}_tb.v" - - assertExists $sv - assertExists $ve - assertExists $tb - - assertConverts "$sv" - assertConverts "$ve" - assertConverts "$tb" - - # convert the SystemVerilog source file - cv="$SHUNIT_TMPDIR/conv-$test.v" - $SV2V $sv 2> /dev/null > $cv - assertTrue "conversion failed" $? - assertExists $cv - - ref_vcd="$SHUNIT_TMPDIR/ref.vcd" - gen_vcd="$SHUNIT_TMPDIR/gen.vcd" - - # simulate and compare the two files - simulate "$ref_vcd" top "$ve" "$tb" - simulate "$gen_vcd" top "$cv" "$tb" - diff "$ref_vcd" "$gen_vcd" > /dev/null - assertTrue "VCDs are different" $? -} - -suite() { - for test in `ls *.sv | sed -e "s_\.sv\\\$__"`; do - eval "test_$test() { runTest \"$test\"; }" - suite_addTest "test_$test" - done -} - -. shunit2 +source ../lib/runner.sh diff --git a/test/run-all.sh b/test/run-all.sh new file mode 100755 index 0000000..cf9a227 --- /dev/null +++ b/test/run-all.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +cd `dirname "${BASH_SOURCE[0]}"` + +for script in `ls */run.sh`; do + suite=`dirname $script` + echo "--------------------" + echo "SUITE: $suite" + echo "--------------------" + (cd $suite; ./run.sh) +done