diff options
Diffstat (limited to 'tests')
148 files changed, 4322 insertions, 101 deletions
diff --git a/tests/aiger/.gitignore b/tests/aiger/.gitignore new file mode 100644 index 00000000..9a26bb8f --- /dev/null +++ b/tests/aiger/.gitignore @@ -0,0 +1 @@ +/*_ref.v diff --git a/tests/aiger/and_.aag b/tests/aiger/and_.aag new file mode 100644 index 00000000..cadd505f --- /dev/null +++ b/tests/aiger/and_.aag @@ -0,0 +1,8 @@ +aag 3 2 0 1 1 +2 +4 +6 +6 2 4 +i0 pi0 +i1 pi1 +o0 po0 diff --git a/tests/aiger/and_.aig b/tests/aiger/and_.aig new file mode 100644 index 00000000..13c7a0c1 --- /dev/null +++ b/tests/aiger/and_.aig @@ -0,0 +1,5 @@ +aig 3 2 0 1 1 +6 +i0 pi0 +i1 pi1 +o0 po0 diff --git a/tests/aiger/buffer.aag b/tests/aiger/buffer.aag new file mode 100644 index 00000000..211106ed --- /dev/null +++ b/tests/aiger/buffer.aag @@ -0,0 +1,5 @@ +aag 1 1 0 1 0 +2 +2 +i0 pi0 +o0 po0 diff --git a/tests/aiger/buffer.aig b/tests/aiger/buffer.aig new file mode 100644 index 00000000..01df6f1c --- /dev/null +++ b/tests/aiger/buffer.aig @@ -0,0 +1,4 @@ +aig 1 1 0 1 0 +2 +i0 pi0 +o0 po0 diff --git a/tests/aiger/cnt1.aag b/tests/aiger/cnt1.aag new file mode 100644 index 00000000..75598862 --- /dev/null +++ b/tests/aiger/cnt1.aag @@ -0,0 +1,4 @@ +aag 1 0 1 0 0 1 +2 3 +2 +b0 po0 diff --git a/tests/aiger/cnt1.aig b/tests/aiger/cnt1.aig new file mode 100644 index 00000000..6fcf6252 --- /dev/null +++ b/tests/aiger/cnt1.aig @@ -0,0 +1,4 @@ +aig 1 0 1 0 0 1 +3 +2 +b0 po0 diff --git a/tests/aiger/cnt1e.aag b/tests/aiger/cnt1e.aag new file mode 100644 index 00000000..35cd5a48 --- /dev/null +++ b/tests/aiger/cnt1e.aag @@ -0,0 +1,9 @@ +aag 5 1 1 0 3 1 +2 +4 10 +4 +6 5 3 +8 4 2 +10 9 7 +b0 AIGER_NEVER +i0 po0 diff --git a/tests/aiger/cnt1e.aig b/tests/aiger/cnt1e.aig new file mode 100644 index 00000000..7284dd42 --- /dev/null +++ b/tests/aiger/cnt1e.aig @@ -0,0 +1,5 @@ +aig 5 1 1 0 3 1 +10 +4 +i0 po0 +b0 AIGER_NEVER diff --git a/tests/aiger/empty.aag b/tests/aiger/empty.aag new file mode 100644 index 00000000..40c0f00c --- /dev/null +++ b/tests/aiger/empty.aag @@ -0,0 +1 @@ +aag 0 0 0 0 0 diff --git a/tests/aiger/empty.aig b/tests/aiger/empty.aig new file mode 100644 index 00000000..a28373cd --- /dev/null +++ b/tests/aiger/empty.aig @@ -0,0 +1 @@ +aig 0 0 0 0 0 diff --git a/tests/aiger/false.aag b/tests/aiger/false.aag new file mode 100644 index 00000000..bab4a06a --- /dev/null +++ b/tests/aiger/false.aag @@ -0,0 +1,3 @@ +aag 0 0 0 1 0 +0 +o0 po0 diff --git a/tests/aiger/false.aig b/tests/aiger/false.aig new file mode 100644 index 00000000..4dc442d7 --- /dev/null +++ b/tests/aiger/false.aig @@ -0,0 +1,3 @@ +aig 0 0 0 1 0 +0 +o0 po0 diff --git a/tests/aiger/halfadder.aag b/tests/aiger/halfadder.aag new file mode 100644 index 00000000..5bf54d38 --- /dev/null +++ b/tests/aiger/halfadder.aag @@ -0,0 +1,14 @@ +aag 7 2 0 2 3 +2 +4 +6 +12 +6 13 15 +12 2 4 +14 3 5 +i0 x +i1 y +o0 s +o1 c +c +half adder diff --git a/tests/aiger/halfadder.aig b/tests/aiger/halfadder.aig new file mode 100644 index 00000000..83727ee6 --- /dev/null +++ b/tests/aiger/halfadder.aig @@ -0,0 +1,9 @@ +aig 5 2 0 2 3 +10 +6 +i0 x +i1 y +o0 s +o1 c +c +half adder diff --git a/tests/aiger/inverter.aag b/tests/aiger/inverter.aag new file mode 100644 index 00000000..428bad9e --- /dev/null +++ b/tests/aiger/inverter.aag @@ -0,0 +1,5 @@ +aag 1 1 0 1 0 +2 +3 +i0 pi0 +o0 po0 diff --git a/tests/aiger/inverter.aig b/tests/aiger/inverter.aig new file mode 100644 index 00000000..5bec90ae --- /dev/null +++ b/tests/aiger/inverter.aig @@ -0,0 +1,4 @@ +aig 1 1 0 1 0 +3 +i0 pi0 +o0 po0 diff --git a/tests/aiger/notcnt1.aag b/tests/aiger/notcnt1.aag new file mode 100644 index 00000000..e92815f2 --- /dev/null +++ b/tests/aiger/notcnt1.aag @@ -0,0 +1,4 @@ +aag 1 0 1 0 0 1 +2 3 +3 +b0 AIGER_NEVER diff --git a/tests/aiger/notcnt1.aig b/tests/aiger/notcnt1.aig new file mode 100644 index 00000000..f8a667f1 --- /dev/null +++ b/tests/aiger/notcnt1.aig @@ -0,0 +1,4 @@ +aig 1 0 1 0 0 1 +3 +3 +b0 AIGER_NEVER diff --git a/tests/aiger/notcnt1e.aag b/tests/aiger/notcnt1e.aag new file mode 100644 index 00000000..2ed645d8 --- /dev/null +++ b/tests/aiger/notcnt1e.aag @@ -0,0 +1,9 @@ +aag 5 1 1 0 3 1 +2 +4 10 +5 +6 5 3 +8 4 2 +10 9 7 +b0 AIGER_NEVER +i0 pi0 diff --git a/tests/aiger/notcnt1e.aig b/tests/aiger/notcnt1e.aig new file mode 100644 index 00000000..fd7e9450 --- /dev/null +++ b/tests/aiger/notcnt1e.aig @@ -0,0 +1,5 @@ +aig 5 1 1 0 3 1 +10 +5 +i0 pi0 +b0 AIGER_NEVER diff --git a/tests/aiger/or_.aag b/tests/aiger/or_.aag new file mode 100644 index 00000000..0f619dba --- /dev/null +++ b/tests/aiger/or_.aag @@ -0,0 +1,8 @@ +aag 3 2 0 1 1 +2 +4 +7 +6 3 5 +i0 pi0 +i1 pi1 +o0 po0 diff --git a/tests/aiger/or_.aig b/tests/aiger/or_.aig new file mode 100644 index 00000000..05168751 --- /dev/null +++ b/tests/aiger/or_.aig @@ -0,0 +1,5 @@ +aig 3 2 0 1 1 +7 +i0 pi0 +i1 pi1 +o0 po0 diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh new file mode 100755 index 00000000..4fbffcdc --- /dev/null +++ b/tests/aiger/run-test.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +set -e + +OPTIND=1 +abcprog="berkeley-abc" # default to built-in version of abc +while getopts "A:" opt +do + case "$opt" in + A) abcprog="$OPTARG" ;; + esac +done +shift "$((OPTIND-1))" + +# NB: *.aag and *.aig must contain a symbol table naming the primary +# inputs and outputs, otherwise ABC and Yosys will name them +# arbitrarily (and inconsistently with each other). + +for aag in *.aag; do + # Since ABC cannot read *.aag, read the *.aig instead + # (which would have been created by the reference aig2aig utility, + # available from http://fmv.jku.at/aiger/) + echo "Checking $aag." + $abcprog -q "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v" + ../../yosys -qp " +read_verilog ${aag%.*}_ref.v +prep +design -stash gold +read_aiger -clk_name clock $aag +prep +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -seq 16 miter +" +done + +for aig in *.aig; do + echo "Checking $aig." + $abcprog -q "read -c $aig; write ${aig%.*}_ref.v" + ../../yosys -qp " +read_verilog ${aig%.*}_ref.v +prep +design -stash gold +read_aiger -clk_name clock $aig +prep +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -seq 16 miter +" +done diff --git a/tests/aiger/toggle-re.aag b/tests/aiger/toggle-re.aag new file mode 100644 index 00000000..b662bb38 --- /dev/null +++ b/tests/aiger/toggle-re.aag @@ -0,0 +1,14 @@ +aag 7 2 1 2 4 +2 +4 +6 8 +6 +7 +8 4 10 +10 13 15 +12 2 6 +14 3 7 +i0 enable +i1 reset +o0 Q +o1 !Q diff --git a/tests/aiger/toggle-re.aig b/tests/aiger/toggle-re.aig new file mode 100644 index 00000000..9d6730f2 --- /dev/null +++ b/tests/aiger/toggle-re.aig @@ -0,0 +1,8 @@ +aig 7 2 1 2 4 +14 +6 +7 +i0 enable +i1 reset +o0 Q +o1 !Q diff --git a/tests/aiger/toggle.aag b/tests/aiger/toggle.aag new file mode 100644 index 00000000..b1a1582d --- /dev/null +++ b/tests/aiger/toggle.aag @@ -0,0 +1,6 @@ +aag 1 0 1 2 0 +2 3 +2 +3 +o0 po0 +o1 po1 diff --git a/tests/aiger/toggle.aig b/tests/aiger/toggle.aig new file mode 100644 index 00000000..68b41763 --- /dev/null +++ b/tests/aiger/toggle.aig @@ -0,0 +1,6 @@ +aig 1 0 1 2 0 +3 +2 +3 +o0 po0 +o1 po1 diff --git a/tests/aiger/true.aag b/tests/aiger/true.aag new file mode 100644 index 00000000..66a9eab4 --- /dev/null +++ b/tests/aiger/true.aag @@ -0,0 +1,3 @@ +aag 0 0 0 1 0 +1 +o0 po0 diff --git a/tests/aiger/true.aig b/tests/aiger/true.aig new file mode 100644 index 00000000..f9bad600 --- /dev/null +++ b/tests/aiger/true.aig @@ -0,0 +1,3 @@ +aig 0 0 0 1 0 +1 +o0 po0 diff --git a/tests/arch/run-test.sh b/tests/arch/run-test.sh new file mode 100755 index 00000000..5292d161 --- /dev/null +++ b/tests/arch/run-test.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +echo "Running syntax check on arch sim models" +for arch in ../../techlibs/*; do + find $arch -name cells_sim.v | while read path; do + echo -n "Test $path ->" + iverilog -t null -I$arch $path + echo " ok" + done +done + +for path in "../../techlibs/common/simcells.v" "../../techlibs/common/simlib.v"; do + echo -n "Test $path ->" + iverilog -t null $path + echo " ok" +done diff --git a/tests/asicworld/code_hdl_models_misc1.v b/tests/asicworld/code_hdl_models_misc1.v deleted file mode 100644 index e3d9d5d6..00000000 --- a/tests/asicworld/code_hdl_models_misc1.v +++ /dev/null @@ -1,22 +0,0 @@ -module misc1 (a,b,c,d,y); -input a, b,c,d; -output y; - -wire net1,net2,net3; - -supply1 vdd; -supply0 vss; - -// y = !((a+b+c).d) - -pmos p1 (vdd,net1,a); -pmos p2 (net1,net2,b); -pmos p3 (net2,y,c); -pmos p4 (vdd,y,d); - -nmos n1 (vss,net3,a); -nmos n2 (vss,net3,b); -nmos n3 (vss,net3,c); -nmos n4 (net3,y,d); - -endmodule diff --git a/tests/asicworld/code_hdl_models_mux21_switch.v b/tests/asicworld/code_hdl_models_mux21_switch.v deleted file mode 100644 index 519c07fc..00000000 --- a/tests/asicworld/code_hdl_models_mux21_switch.v +++ /dev/null @@ -1,22 +0,0 @@ -//----------------------------------------------------- -// Design Name : mux21_switch -// File Name : mux21_switch.v -// Function : 2:1 Mux using Switch Primitives -// Coder : Deepak Kumar Tala -//----------------------------------------------------- -module mux21_switch (out, ctrl, in1, in2); - - output out; - input ctrl, in1, in2; - wire w; - - supply1 power; - supply0 ground; - - pmos N1 (w, power, ctrl); - nmos N2 (w, ground, ctrl); - - cmos C1 (out, in1, w, ctrl); - cmos C2 (out, in2, ctrl, w); - -endmodule diff --git a/tests/asicworld/code_hdl_models_nand_switch.v b/tests/asicworld/code_hdl_models_nand_switch.v deleted file mode 100644 index 1ccdd3a7..00000000 --- a/tests/asicworld/code_hdl_models_nand_switch.v +++ /dev/null @@ -1,14 +0,0 @@ -module nand_switch(a,b,out); -input a,b; -output out; - -supply0 vss; -supply1 vdd; -wire net1; - -pmos p1 (vdd,out,a); -pmos p2 (vdd,out,b); -nmos n1 (vss,net1,a); -nmos n2 (net1,out,b); - -endmodule
\ No newline at end of file diff --git a/tests/asicworld/code_hdl_models_t_gate_switch.v b/tests/asicworld/code_hdl_models_t_gate_switch.v deleted file mode 100644 index 5a7e0eaf..00000000 --- a/tests/asicworld/code_hdl_models_t_gate_switch.v +++ /dev/null @@ -1,11 +0,0 @@ -module t_gate_switch (L,R,nC,C); - inout L; - inout R; - input nC; - input C; - - //Syntax: keyword unique_name (drain. source, gate); - pmos p1 (L,R,nC); - nmos p2 (L,R,C); - -endmodule diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh index d5708c45..c22ab692 100755 --- a/tests/asicworld/run-test.sh +++ b/tests/asicworld/run-test.sh @@ -11,4 +11,4 @@ do done shift "$((OPTIND-1))" -exec ${MAKE:-make} -f ../tools/autotest.mk $seed EXTRA_FLAGS="-e" *.v +exec ${MAKE:-make} -f ../tools/autotest.mk $seed EXTRA_FLAGS+="-e" *.v diff --git a/tests/asicworld/xfirrtl b/tests/asicworld/xfirrtl new file mode 100644 index 00000000..08bf4ccd --- /dev/null +++ b/tests/asicworld/xfirrtl @@ -0,0 +1,23 @@ +# This file contains the names of verilog files to exclude from verilog to FIRRTL regression tests due to known failures. +code_hdl_models_arbiter.v error: reg rst; cannot be driven by primitives or continuous assignment. +code_hdl_models_clk_div_45.v yosys issue: 2nd PMUXTREE pass yields: ERROR: Negative edge clock on FF clk_div_45.$procdff$49. +code_hdl_models_d_ff_gates.v combinational loop +code_hdl_models_d_latch_gates.v combinational loop +code_hdl_models_dff_async_reset.v $adff +code_hdl_models_tff_async_reset.v $adff +code_hdl_models_uart.v $adff +code_tidbits_asyn_reset.v $adff +code_tidbits_reg_seq_example.v $adff +code_verilog_tutorial_always_example.v empty module +code_verilog_tutorial_escape_id.v make_id issues (name begins with a digit) +code_verilog_tutorial_explicit.v firrtl backend bug (empty module) +code_verilog_tutorial_first_counter.v error: reg rst; cannot be driven by primitives or continuous assignment. +code_verilog_tutorial_fsm_full.v error: reg reset; cannot be driven by primitives or continuous assignment. +code_verilog_tutorial_if_else.v empty module (everything is under 'always @ (posedge clk)') +[code_verilog_tutorial_n_out_primitive.v empty module +code_verilog_tutorial_parallel_if.v empty module (everything is under 'always @ (posedge clk)') +code_verilog_tutorial_simple_function.v empty module (no hardware) +code_verilog_tutorial_simple_if.v empty module (everything is under 'always @ (posedge clk)') +code_verilog_tutorial_task_global.v empty module (everything is under 'always @ (posedge clk)') +code_verilog_tutorial_v2k_reg.v empty module +code_verilog_tutorial_which_clock.v $adff diff --git a/tests/errors/syntax_err01.v b/tests/errors/syntax_err01.v new file mode 100644 index 00000000..68e9b1d5 --- /dev/null +++ b/tests/errors/syntax_err01.v @@ -0,0 +1,4 @@ +module a; +integer [31:0]w; +endmodule + diff --git a/tests/errors/syntax_err02.v b/tests/errors/syntax_err02.v new file mode 100644 index 00000000..c72e976a --- /dev/null +++ b/tests/errors/syntax_err02.v @@ -0,0 +1,7 @@ +module a; +task to ( + input integer [3:0]x +); +endtask +endmodule + diff --git a/tests/errors/syntax_err03.v b/tests/errors/syntax_err03.v new file mode 100644 index 00000000..6eec44ad --- /dev/null +++ b/tests/errors/syntax_err03.v @@ -0,0 +1,7 @@ +module a; +task to ( + input [3]x +); +endtask +endmodule + diff --git a/tests/errors/syntax_err04.v b/tests/errors/syntax_err04.v new file mode 100644 index 00000000..d488e5db --- /dev/null +++ b/tests/errors/syntax_err04.v @@ -0,0 +1,4 @@ +module a; +wire [3]x; +endmodule + diff --git a/tests/errors/syntax_err05.v b/tests/errors/syntax_err05.v new file mode 100644 index 00000000..8a1f1153 --- /dev/null +++ b/tests/errors/syntax_err05.v @@ -0,0 +1,4 @@ +module a; +input x[2:0]; +endmodule + diff --git a/tests/errors/syntax_err06.v b/tests/errors/syntax_err06.v new file mode 100644 index 00000000..b35a1dea --- /dev/null +++ b/tests/errors/syntax_err06.v @@ -0,0 +1,6 @@ +module a; +initial +begin : label1 +end: label2 +endmodule + diff --git a/tests/errors/syntax_err07.v b/tests/errors/syntax_err07.v new file mode 100644 index 00000000..62bcc6b3 --- /dev/null +++ b/tests/errors/syntax_err07.v @@ -0,0 +1,6 @@ +module a; +wire [5:0]x; +wire [3:0]y; +assign y = (4)55; +endmodule + diff --git a/tests/errors/syntax_err08.v b/tests/errors/syntax_err08.v new file mode 100644 index 00000000..d41bfd6c --- /dev/null +++ b/tests/errors/syntax_err08.v @@ -0,0 +1,6 @@ +module a; +wire [5:0]x; +wire [3:0]y; +assign y = x 55; +endmodule + diff --git a/tests/errors/syntax_err09.v b/tests/errors/syntax_err09.v new file mode 100644 index 00000000..1e472eb9 --- /dev/null +++ b/tests/errors/syntax_err09.v @@ -0,0 +1,3 @@ +module a(input wire x = 1'b0); +endmodule + diff --git a/tests/errors/syntax_err10.v b/tests/errors/syntax_err10.v new file mode 100644 index 00000000..d3280405 --- /dev/null +++ b/tests/errors/syntax_err10.v @@ -0,0 +1,3 @@ +module a; +parameter integer [2:0]x=0; +endmodule diff --git a/tests/errors/syntax_err11.v b/tests/errors/syntax_err11.v new file mode 100644 index 00000000..f3cde9df --- /dev/null +++ b/tests/errors/syntax_err11.v @@ -0,0 +1,3 @@ +module a; +parameter integer real x=0; +endmodule diff --git a/tests/errors/syntax_err12.v b/tests/errors/syntax_err12.v new file mode 100644 index 00000000..f9b5d5b0 --- /dev/null +++ b/tests/errors/syntax_err12.v @@ -0,0 +1,7 @@ +interface iface; +endinterface + +module a ( + iface x = 1'b0 +); +endmodule diff --git a/tests/errors/syntax_err13.v b/tests/errors/syntax_err13.v new file mode 100644 index 00000000..b5c942fc --- /dev/null +++ b/tests/errors/syntax_err13.v @@ -0,0 +1,4 @@ +module a #(p = 0) +(); +endmodule + diff --git a/tests/liberty/.gitignore b/tests/liberty/.gitignore new file mode 100644 index 00000000..e6ec49c4 --- /dev/null +++ b/tests/liberty/.gitignore @@ -0,0 +1,2 @@ +*.log +test.ys diff --git a/tests/liberty/busdef.lib b/tests/liberty/busdef.lib new file mode 100644 index 00000000..b5e3d50b --- /dev/null +++ b/tests/liberty/busdef.lib @@ -0,0 +1,81 @@ +/********************************************/ +/* */ +/* Supergate cell library for Bench marking */ +/* */ +/* Symbiotic EDA GmbH / Moseley Instruments */ +/* Niels A. Moseley */ +/* */ +/* Process: none */ +/* */ +/* Date : 02-11-2018 */ +/* Version: 1.0 */ +/* */ +/********************************************/ + +library(supergate) { + technology (cmos); + revision : 1.0; + + time_unit : "1ps"; + pulling_resistance_unit : "1kohm"; + voltage_unit : "1V"; + current_unit : "1uA"; + + capacitive_load_unit(1,ff); + + default_inout_pin_cap : 7.0; + default_input_pin_cap : 7.0; + default_output_pin_cap : 0.0; + default_fanout_load : 1.0; + + default_wire_load_capacitance : 0.1; + default_wire_load_resistance : 1.0e-3; + default_wire_load_area : 0.0; + + nom_process : 1.0; + nom_temperature : 25.0; + nom_voltage : 1.2; + + delay_model : generic_cmos; + + type( IO_bus_3_to_0 ) { + base_type : array ; + data_type : bit ; + bit_width : 4; + bit_from : 3 ; + bit_to : 0 ; + downto : true ; + } + + cell (SRAM) { + area : 1 ; + memory() { + type : ram; + address_width : 4; + word_width : 4; + } + pin(CE1) { + direction : input; + capacitance : 0.021; + max_transition : 1.024; + switch_pin : true; + } + bus(I1) { + bus_type : IO_bus_3_to_0 ; + direction : input; + pin (I1[3:0]) { + timing() { + related_pin : "CE1" ; + timing_type : setup_rising ; + rise_constraint (scalar) { + values("0.0507786"); + } + fall_constraint (scalar) { + values("0.0507786"); + } + } + } + } + } + +} /* end */ diff --git a/tests/liberty/normal.lib b/tests/liberty/normal.lib new file mode 100644 index 00000000..4621194d --- /dev/null +++ b/tests/liberty/normal.lib @@ -0,0 +1,359 @@ +/********************************************/ +/* */ +/* Supergate cell library for Bench marking */ +/* */ +/* Symbiotic EDA GmbH / Moseley Instruments */ +/* Niels A. Moseley */ +/* */ +/* Process: none */ +/* */ +/* Date : 02-11-2018 */ +/* Version: 1.0 */ +/* */ +/********************************************/ + +library(supergate) { + technology (cmos); + revision : 1.0; + + time_unit : "1ps"; + pulling_resistance_unit : "1kohm"; + voltage_unit : "1V"; + current_unit : "1uA"; + + capacitive_load_unit(1,ff); + + default_inout_pin_cap : 7.0; + default_input_pin_cap : 7.0; + default_output_pin_cap : 0.0; + default_fanout_load : 1.0; + + default_wire_load_capacitance : 0.1; + default_wire_load_resistance : 1.0e-3; + default_wire_load_area : 0.0; + + nom_process : 1.0; + nom_temperature : 25.0; + nom_voltage : 1.2; + + delay_model : generic_cmos; + + /* Inverter */ + cell (inv) { + area : 1; + pin(A) { + direction : input; + } + + pin(Y) { + direction : output; + function : "A'"; + } + } + + /* tri-state inverter */ + cell (tri_inv) { + area : 4; + pin(A) { + direction : input; + } + pin(S) { + direction : input; + } + pin(Z) { + direction : output; + function : "A'"; + three_State : "S'"; + } + } + + cell (buffer) { + area : 5; + pin(A) { + direction : input; + } + pin(Y) { + direction : output; + function : "A"; + } + } + + /* 2-input NAND gate */ + cell (nand2) { + area : 3; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(Y) { + direction: output; + function : "(A * B)'"; + } + } + + /* 2-input NOR gate */ + cell (nor2) { + area : 3; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(Y) { + direction: output; + function : "(A + B)'"; + } + } + + /* 2-input XOR */ + cell (xor2) { + area : 6; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(Y) { + direction: output; + function : "(A *B') + (A' * B)"; + } + } + + /* 2-input inverting MUX */ + cell (imux2) { + area : 5; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(S) { + direction : input; + } + pin(Y) { + direction: output; + function : "( (A * S) + (B * S') )'"; + } + } + + /* D-type flip-flop with asynchronous reset and preset */ + cell (dff) { + area : 6; + ff("IQ", "IQN") { + next_state : "D"; + clocked_on : "CLK"; + clear : "RESET"; + preset : "PRESET"; + clear_preset_var1 : L; + clear_preset_var2 : L; + } + pin(D) { + direction : input; + } + pin(CLK) { + direction : input; + } + pin(RESET) { + direction : input; + } + pin(PRESET) { + direction : input; + } + pin(Q) { + direction: output; + function : "IQ"; + timing() { + timing_type : rising_edge; + intrinsic_rise : 65; + intrinsic_fall : 65; + rise_resistance : 0; + fall_resistance : 0; + related_pin : "CLK"; + } + timing () { + timing_type : clear; + timing_sense : positive_unate; + intrinsic_fall : 75; + related_pin : "RESET"; + } + timing () { + timing_type : preset; + timing_sense : negative_unate; + intrinsic_rise : 75; + related_pin : "PRESET"; + } + } + pin(QN) { + direction: output; + function : "IQN"; + timing() { + timing_type : rising_edge; + intrinsic_rise : 65; + intrinsic_fall : 65; + rise_resistance : 0; + fall_resistance : 0; + related_pin : "CLK"; + } + timing () { + timing_type : preset; + timing_sense : negative_unate; + intrinsic_rise : 75; + related_pin : "RESET"; + } + timing () { + timing_type : clear; + timing_sense : positive_unate; + intrinsic_fall : 75; + related_pin : "PRESET"; + } + } + } + + /* Latch */ + cell(latch) { + area : 5; + latch ("IQ","IQN") { + enable : "G"; + data_in : "D"; + } + + pin(D) { + direction : input; + } + pin(G) { + direction : input; + } + + pin(Q) { + direction : output; + function : "IQ"; + internal_node : "Q"; + + timing() { + timing_type : rising_edge; + intrinsic_rise : 65; + intrinsic_fall : 65; + rise_resistance : 0; + fall_resistance : 0; + related_pin : "G"; + } + + timing() { + timing_sense : positive_unate; + intrinsic_rise : 65; + intrinsic_fall : 65; + rise_resistance : 0; + fall_resistance : 0; + related_pin : "D"; + } + } + + pin(QN) { + direction : output; + function : "IQN"; + internal_node : "QN"; + + timing() { + timing_type : rising_edge; + intrinsic_rise : 65; + intrinsic_fall : 65; + rise_resistance : 0; + fall_resistance : 0; + related_pin : "G"; + } + + timing() { + timing_sense : negative_unate; + intrinsic_rise : 65; + intrinsic_fall : 65; + rise_resistance : 0; + fall_resistance : 0; + related_pin : "D"; + } + } + } + + /* 3 input AND-OR-INVERT gate */ + cell (aoi211) { + area : 3; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(C) { + direction : input; + } + pin(Y) { + direction: output; + function : "((A * B) + C)'"; + } + } + + + /* 3 input OR-AND-INVERT gate */ + cell (oai211) { + area : 3; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(C) { + direction : input; + } + pin(Y) { + direction: output; + function : "((A + B) * C)'"; + } + } + + /* half adder */ + cell (halfadder) { + area : 5; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(C) { + direction : output; + function : "(A * B)"; + } + pin(Y) { + direction: output; + function : "(A *B') + (A' * B)"; + } + } + + /* full adder */ + cell (fulladder) { + area : 8; + pin(A) { + direction : input; + } + pin(B) { + direction : input; + } + pin(CI) { + direction : input; + } + pin(CO) { + direction : output; + function : "(((A * B)+(B * CI))+(CI * A))"; + } + pin(Y) { + direction: output; + function : "((A^B)^CI)"; + } + } + +} /* end */ diff --git a/tests/liberty/processdefs.lib b/tests/liberty/processdefs.lib new file mode 100644 index 00000000..37a6bbaf --- /dev/null +++ b/tests/liberty/processdefs.lib @@ -0,0 +1,48 @@ +/********************************************/ +/* */ +/* Supergate cell library for Bench marking */ +/* */ +/* Symbiotic EDA GmbH / Moseley Instruments */ +/* Niels A. Moseley */ +/* */ +/* Process: none */ +/* */ +/* Date : 25-03-2019 */ +/* Version: 1.0 */ +/* */ +/********************************************/ + +library(processdefs) { + technology (cmos); + revision : 1.0; + + time_unit : "1ps"; + pulling_resistance_unit : "1kohm"; + voltage_unit : "1V"; + current_unit : "1uA"; + + capacitive_load_unit(1,ff); + + default_inout_pin_cap : 7.0; + default_input_pin_cap : 7.0; + default_output_pin_cap : 0.0; + default_fanout_load : 1.0; + + default_wire_load_capacitance : 0.1; + default_wire_load_resistance : 1.0e-3; + default_wire_load_area : 0.0; + + nom_process : 1.0; + nom_temperature : 25.0; + nom_voltage : 1.2; + + delay_model : generic_cmos; + + define_cell_area(bond_pads,pad_slots) + input_voltage(cmos) { + vil : 0.3 * VDD ; + vih : 0.7 * VDD ; + vimin : -0.5 ; + vimax : VDD + 0.5 ; + } +} diff --git a/tests/liberty/run-test.sh b/tests/liberty/run-test.sh new file mode 100755 index 00000000..7e2ed237 --- /dev/null +++ b/tests/liberty/run-test.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +for x in *.lib; do + echo "Running $x.." + echo "read_verilog small.v" > test.ys + echo "synth -top small" >> test.ys + echo "dfflibmap -liberty ${x}" >> test.ys + ../../yosys -ql ${x%.lib}.log -s test.ys +done diff --git a/tests/liberty/semicolextra.lib b/tests/liberty/semicolextra.lib new file mode 100644 index 00000000..6a7fa77c --- /dev/null +++ b/tests/liberty/semicolextra.lib @@ -0,0 +1,48 @@ +/* + + Test case for https://www.reddit.com/r/yosys/comments/b5texg/yosys_fails_to_parse_apparentlycorrect_liberty/ + + fall_constraint (SETUP_HOLD) formatting. + +*/ + +library(supergate) { + technology (cmos); + revision : 1.0; + + cell (DFF) { + cell_footprint : dff; + area : 50; + pin(D) { + direction : input; + capacitance : 0.002; + timing() { + related_pin : "CK"; + timing_type : setup_rising; + + fall_constraint (SETUP_HOLD) { values ("0.4000, 0.3000, 0.2000, 0.1000, 0.0000", \ + "0.4000, 0.3000, 0.2000, 0.1000, 0.000", \ + "0.5000, 0.4000, 0.3000, 0.2000, 0.0000", \ + "0.7000, 0.6000, 0.5000, 0.4000, 0.2000", \ + "1.0000, 1.0000, 0.9000, 0.8000, 0.6000"); }; + } + } + + pin(CK) { + direction : input; + clock : true; + capacitance : 0.00290; + } + + ff(IQ,IQN) { + clocked_on : "CK"; + next_state : "D"; + } + pin(Q) { + direction : output; + capacitance : 0.003; + max_capacitance : 0.3; + } + cell_leakage_power : 0.3; + } +} diff --git a/tests/liberty/semicolmissing.lib b/tests/liberty/semicolmissing.lib new file mode 100644 index 00000000..f7c20750 --- /dev/null +++ b/tests/liberty/semicolmissing.lib @@ -0,0 +1,72 @@ +/********************************************/ +/* */ +/* Supergate cell library for Bench marking */ +/* */ +/* Symbiotic EDA GmbH / Moseley Instruments */ +/* Niels A. Moseley */ +/* */ +/* Process: none */ +/* */ +/* Date : 24-03-2019 */ +/* Version: 1.0 */ +/* Version: 1.1 - Removed semicolons in */ +/* full adder */ +/* */ +/********************************************/ + +/* + semi colon is missing in full-adder specification + some TSMC liberty files are formatted this way.. +*/ + +library(supergate) { + technology (cmos); + revision : 1.0; + + time_unit : "1ps"; + pulling_resistance_unit : "1kohm"; + voltage_unit : "1V"; + current_unit : "1uA"; + + capacitive_load_unit(1,ff); + + default_inout_pin_cap : 7.0; + default_input_pin_cap : 7.0; + default_output_pin_cap : 0.0; + default_fanout_load : 1.0; + + default_wire_load_capacitance : 0.1; + default_wire_load_resistance : 1.0e-3; + default_wire_load_area : 0.0; + + nom_process : 1.0; + nom_temperature : 25.0; + nom_voltage : 1.2; + + delay_model : generic_cmos; + + /* full adder */ + cell (fulladder) { + area : 8 + pin(A) { + direction : input + } + pin(B) { + direction : input + } + pin(CI) { + direction : input + } + pin(CO) { + direction : output + function : "(((A * B)+(B * CI))+(CI * A))" + } + pin(Y) { + direction: output + function : "((A^B)^CI)" + } + } + +} /* end */ + + diff --git a/tests/liberty/small.v b/tests/liberty/small.v new file mode 100644 index 00000000..bd94be4f --- /dev/null +++ b/tests/liberty/small.v @@ -0,0 +1,16 @@ +/** small, meaningless design to test loading of liberty files */ + +module small +( + input clk, + output reg[7:0] count +); + +initial count = 0; + +always @ (posedge clk) +begin + count <= count + 1'b1; +end + +endmodule diff --git a/tests/lut/.gitignore b/tests/lut/.gitignore new file mode 100644 index 00000000..397b4a76 --- /dev/null +++ b/tests/lut/.gitignore @@ -0,0 +1 @@ +*.log diff --git a/tests/lut/check_map.ys b/tests/lut/check_map.ys new file mode 100644 index 00000000..46854e82 --- /dev/null +++ b/tests/lut/check_map.ys @@ -0,0 +1,6 @@ +simplemap +equiv_opt -assert techmap -D LUT_WIDTH=4 -map +/cmp2lut.v +design -load postopt +equiv_opt -assert techmap -D LUT_WIDTH=4 -map +/gate2lut.v +design -load postopt +select -assert-count 0 t:* t:$lut %d diff --git a/tests/lut/map_and.v b/tests/lut/map_and.v new file mode 100644 index 00000000..68ae33fd --- /dev/null +++ b/tests/lut/map_and.v @@ -0,0 +1,5 @@ +module top(...); + input a, b; + output y; + assign y = a&b; +endmodule diff --git a/tests/lut/map_cmp.v b/tests/lut/map_cmp.v new file mode 100644 index 00000000..5e413f89 --- /dev/null +++ b/tests/lut/map_cmp.v @@ -0,0 +1,29 @@ +module top(...); + input [3:0] a; + + output o1_1 = 4'b1010 <= a; + output o1_2 = 4'b1010 < a; + output o1_3 = 4'b1010 >= a; + output o1_4 = 4'b1010 > a; + output o1_5 = 4'b1010 == a; + output o1_6 = 4'b1010 != a; + + output o2_1 = a <= 4'b1010; + output o2_2 = a < 4'b1010; + output o2_3 = a >= 4'b1010; + output o2_4 = a > 4'b1010; + output o2_5 = a == 4'b1010; + output o2_6 = a != 4'b1010; + + output o3_1 = 4'sb0101 <= $signed(a); + output o3_2 = 4'sb0101 < $signed(a); + output o3_3 = 4'sb0101 >= $signed(a); + output o3_4 = 4'sb0101 > $signed(a); + output o3_5 = 4'sb0101 == $signed(a); + output o3_6 = 4'sb0101 != $signed(a); + + output o4_1 = $signed(a) <= 4'sb0000; + output o4_2 = $signed(a) < 4'sb0000; + output o4_3 = $signed(a) >= 4'sb0000; + output o4_4 = $signed(a) > 4'sb0000; +endmodule diff --git a/tests/lut/map_mux.v b/tests/lut/map_mux.v new file mode 100644 index 00000000..ccecf302 --- /dev/null +++ b/tests/lut/map_mux.v @@ -0,0 +1,5 @@ +module top(...); + input a, b, s; + output y; + assign y = s?a:b; +endmodule diff --git a/tests/lut/map_not.v b/tests/lut/map_not.v new file mode 100644 index 00000000..38599741 --- /dev/null +++ b/tests/lut/map_not.v @@ -0,0 +1,5 @@ +module top(...); + input a; + output y; + assign y = ~a; +endmodule diff --git a/tests/lut/map_or.v b/tests/lut/map_or.v new file mode 100644 index 00000000..8b8c5518 --- /dev/null +++ b/tests/lut/map_or.v @@ -0,0 +1,5 @@ +module top(...); + input a, b; + output y; + assign y = a|b; +endmodule diff --git a/tests/lut/map_xor.v b/tests/lut/map_xor.v new file mode 100644 index 00000000..708a0578 --- /dev/null +++ b/tests/lut/map_xor.v @@ -0,0 +1,5 @@ +module top(...); + input a, b; + output y; + assign y = a^b; +endmodule diff --git a/tests/lut/run-test.sh b/tests/lut/run-test.sh new file mode 100755 index 00000000..207417fa --- /dev/null +++ b/tests/lut/run-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +for x in *.v; do + echo "Running $x.." + ../../yosys -q -s check_map.ys -l ${x%.v}.log $x +done diff --git a/tests/memories/firrtl_938.v b/tests/memories/firrtl_938.v new file mode 100644 index 00000000..af5efcd2 --- /dev/null +++ b/tests/memories/firrtl_938.v @@ -0,0 +1,22 @@ +module top +( + input [7:0] data_a, + input [6:1] addr_a, + input we_a, clk, + output reg [7:0] q_a +); + // Declare the RAM variable + reg [7:0] ram[63:0]; + + // Port A + always @ (posedge clk) + begin + if (we_a) + begin + ram[addr_a] <= data_a; + q_a <= data_a; + end + q_a <= ram[addr_a]; + end + +endmodule diff --git a/tests/memories/issue00335.v b/tests/memories/issue00335.v new file mode 100644 index 00000000..f3b6e5df --- /dev/null +++ b/tests/memories/issue00335.v @@ -0,0 +1,28 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-rd-clk \clk + +module ram2 (input clk, + input sel, + input we, + input [SIZE-1:0] adr, + input [63:0] dat_i, + output reg [63:0] dat_o); + parameter SIZE = 5; // Address size + + reg [63:0] mem [0:(1 << SIZE)-1]; + integer i; + + initial begin + for (i = 0; i < (1<<SIZE) - 1; i = i + 1) + mem[i] <= 0; + end + + always @(posedge clk) + if (sel) begin + if (~we) + dat_o <= mem[adr]; + else + mem[adr] <= dat_i; + end +endmodule diff --git a/tests/memories/issue00710.v b/tests/memories/issue00710.v new file mode 100644 index 00000000..7a5fad1c --- /dev/null +++ b/tests/memories/issue00710.v @@ -0,0 +1,17 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-rd-clk \clk + +module top(input clk, input we, re, reset, input [7:0] addr, wdata, output reg [7:0] rdata); + +reg [7:0] bram[0:255]; +(* keep *) reg dummy; + +always @(posedge clk) + if (reset) + dummy <= 1'b0; + else if (re) + rdata <= bram[addr]; + else if (we) + bram[addr] <= wdata; +endmodule diff --git a/tests/memories/read_two_mux.v b/tests/memories/read_two_mux.v new file mode 100644 index 00000000..4f2e7e1c --- /dev/null +++ b/tests/memories/read_two_mux.v @@ -0,0 +1,16 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 +// expect-no-rd-clk + +module top(input clk, input we, re, reset, input [7:0] addr, wdata, output reg [7:0] rdata); + +reg [7:0] bram[0:255]; +(* keep *) reg dummy; + +always @(posedge clk) begin + rdata <= re ? (reset ? 8'b0 : bram[addr]) : rdata; + if (we) + bram[addr] <= wdata; +end + +endmodule diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh index 734a9668..8d1a8b41 100755 --- a/tests/memories/run-test.sh +++ b/tests/memories/run-test.sh @@ -4,17 +4,19 @@ set -e OPTIND=1 seed="" # default to no seed specified -while getopts "S:" opt +abcopt="" +while getopts "A:S:" opt do case "$opt" in + A) abcopt="-A $OPTARG" ;; S) seed="-S $OPTARG" ;; esac done shift "$((OPTIND-1))" -bash ../tools/autotest.sh $seed -G *.v +bash ../tools/autotest.sh $abcopt $seed -G *.v -for f in `egrep -l 'expect-(wr|rd)-ports' *.v`; do +for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do echo -n "Testing expectations for $f .." ../../yosys -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem" $f if grep -q expect-wr-ports $f; then @@ -25,6 +27,14 @@ for f in `egrep -l 'expect-(wr|rd)-ports' *.v`; do grep -q "parameter \\\\RD_PORTS $(gawk '/expect-rd-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected number of read ports."; false; } fi + if grep -q expect-rd-clk $f; then + grep -q "connect \\\\RD_CLK \\$(gawk '/expect-rd-clk/ { print $3; }' $f)\$" ${f%.v}.dmp || + { echo " ERROR: Unexpected read clock."; false; } + fi + if grep -q expect-no-rd-clk $f; then + grep -q "connect \\\\RD_CLK 1'x\$" ${f%.v}.dmp || + { echo " ERROR: Expected no read clock."; false; } + fi echo " ok." done diff --git a/tests/opt/.gitignore b/tests/opt/.gitignore new file mode 100644 index 00000000..397b4a76 --- /dev/null +++ b/tests/opt/.gitignore @@ -0,0 +1 @@ +*.log diff --git a/tests/opt/opt_expr_cmp.v b/tests/opt/opt_expr_cmp.v new file mode 100644 index 00000000..5aff4b80 --- /dev/null +++ b/tests/opt/opt_expr_cmp.v @@ -0,0 +1,40 @@ +module top(...); + input [3:0] a; + + output o1_1 = 4'b0000 > a; + output o1_2 = 4'b0000 <= a; + output o1_3 = 4'b1111 < a; + output o1_4 = 4'b1111 >= a; + output o1_5 = a < 4'b0000; + output o1_6 = a >= 4'b0000; + output o1_7 = a > 4'b1111; + output o1_8 = a <= 4'b1111; + + output o2_1 = 4'sb0000 > $signed(a); + output o2_2 = 4'sb0000 <= $signed(a); + output o2_3 = $signed(a) < 4'sb0000; + output o2_4 = $signed(a) >= 4'sb0000; + + output o3_1 = 4'b0100 > a; + output o3_2 = 4'b0100 <= a; + output o3_3 = a < 4'b0100; + output o3_4 = a >= 4'b0100; + + output o4_1 = 5'b10000 > a; + output o4_2 = 5'b10000 >= a; + output o4_3 = 5'b10000 < a; + output o4_4 = 5'b10000 <= a; + output o4_5 = a < 5'b10000; + output o4_6 = a <= 5'b10000; + output o4_7 = a > 5'b10000; + output o4_8 = a >= 5'b10000; + + output o5_1 = 5'b10100 > a; + output o5_2 = 5'b10100 >= a; + output o5_3 = 5'b10100 < a; + output o5_4 = 5'b10100 <= a; + output o5_5 = a < 5'b10100; + output o5_6 = a <= 5'b10100; + output o5_7 = a > 5'b10100; + output o5_8 = a >= 5'b10100; +endmodule diff --git a/tests/opt/opt_expr_cmp.ys b/tests/opt/opt_expr_cmp.ys new file mode 100644 index 00000000..214ce8b1 --- /dev/null +++ b/tests/opt/opt_expr_cmp.ys @@ -0,0 +1,4 @@ +read_verilog opt_expr_cmp.v +equiv_opt -assert opt_expr -fine +design -load postopt +select -assert-count 0 t:$gt t:$ge t:$lt t:$le diff --git a/tests/opt/opt_ff.v b/tests/opt/opt_ff.v new file mode 100644 index 00000000..a01b64b6 --- /dev/null +++ b/tests/opt/opt_ff.v @@ -0,0 +1,21 @@ +module top( + input clk, + input rst, + input [2:0] a, + output [1:0] b +); + reg [2:0] b_reg; + initial begin + b_reg <= 3'b0; + end + + assign b = b_reg[1:0]; + always @(posedge clk or posedge rst) begin + if(rst) begin + b_reg <= 3'b0; + end else begin + b_reg <= a; + end + end +endmodule + diff --git a/tests/opt/opt_ff.ys b/tests/opt/opt_ff.ys new file mode 100644 index 00000000..704c7acf --- /dev/null +++ b/tests/opt/opt_ff.ys @@ -0,0 +1,3 @@ +read_verilog opt_ff.v +synth_ice40 +ice40_unlut diff --git a/tests/opt/opt_lut.v b/tests/opt/opt_lut.v new file mode 100644 index 00000000..b13db367 --- /dev/null +++ b/tests/opt/opt_lut.v @@ -0,0 +1,18 @@ +module top( + input [8:0] a, + input [8:0] b, + output [8:0] o1, + output [2:0] o2, + input [2:0] c, + input [2:0] d, + output [2:0] o3, + output [2:0] o4, + input s +); + +assign o1 = (s ? 0 : a + b); +assign o2 = (s ? a : a - b); +assign o3 = (s ? 4'b1111 : d + c); +assign o4 = (s ? d : c - d); + +endmodule diff --git a/tests/opt/opt_lut.ys b/tests/opt/opt_lut.ys new file mode 100644 index 00000000..59b12c35 --- /dev/null +++ b/tests/opt/opt_lut.ys @@ -0,0 +1,4 @@ +read_verilog opt_lut.v +synth_ice40 +ice40_unlut +equiv_opt -map +/ice40/cells_sim.v -assert opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 diff --git a/tests/opt/opt_lut_elim.il b/tests/opt/opt_lut_elim.il new file mode 100644 index 00000000..75675d98 --- /dev/null +++ b/tests/opt/opt_lut_elim.il @@ -0,0 +1,19 @@ +module \test + wire input 1 \i + + wire output 2 \o1 + cell $lut $1 + parameter \LUT 16'0110100110010110 + parameter \WIDTH 4 + connect \A { \i 3'000 } + connect \Y \o1 + end + + wire output 2 \o2 + cell $lut $2 + parameter \LUT 16'0110100010010110 + parameter \WIDTH 4 + connect \A { \i 3'000 } + connect \Y \o2 + end +end diff --git a/tests/opt/opt_lut_elim.ys b/tests/opt/opt_lut_elim.ys new file mode 100644 index 00000000..8e5e23ae --- /dev/null +++ b/tests/opt/opt_lut_elim.ys @@ -0,0 +1,3 @@ +read_ilang opt_lut_elim.il +opt_lut +select -assert-count 0 t:$lut diff --git a/tests/opt/opt_lut_port.il b/tests/opt/opt_lut_port.il new file mode 100644 index 00000000..7eb71890 --- /dev/null +++ b/tests/opt/opt_lut_port.il @@ -0,0 +1,18 @@ +module $1 + wire width 4 input 2 \_0_ + wire output 4 \_1_ + wire input 3 \_2_ + wire output 1 \o + cell $lut \_3_ + parameter \LUT 16'0011000000000011 + parameter \WIDTH 4 + connect \A { \_0_ [3] \o 2'00 } + connect \Y \_1_ + end + cell $lut \_4_ + parameter \LUT 4'0001 + parameter \WIDTH 4 + connect \A { 3'000 \_2_ } + connect \Y \o + end +end diff --git a/tests/opt/opt_lut_port.ys b/tests/opt/opt_lut_port.ys new file mode 100644 index 00000000..3cb4ecb2 --- /dev/null +++ b/tests/opt/opt_lut_port.ys @@ -0,0 +1,3 @@ +read_ilang opt_lut_port.il +opt_lut +select -assert-count 2 t:$lut diff --git a/tests/opt/run-test.sh b/tests/opt/run-test.sh new file mode 100755 index 00000000..44ce7e67 --- /dev/null +++ b/tests/opt/run-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +for x in *.ys; do + echo "Running $x.." + ../../yosys -ql ${x%.ys}.log $x +done diff --git a/tests/sat/counters-repeat.v b/tests/sat/counters-repeat.v new file mode 100644 index 00000000..2ea45499 --- /dev/null +++ b/tests/sat/counters-repeat.v @@ -0,0 +1,38 @@ +// coverage for repeat loops outside of constant functions + +module counter1(clk, rst, ping); + input clk, rst; + output ping; + reg [31:0] count; + + always @(posedge clk) begin + if (rst) + count <= 0; + else + count <= count + 1; + end + + assign ping = &count; +endmodule + +module counter2(clk, rst, ping); + input clk, rst; + output ping; + reg [31:0] count; + + integer i; + reg carry; + + always @(posedge clk) begin + carry = 1; + i = 0; + repeat (32) begin + count[i] <= !rst & (count[i] ^ carry); + carry = count[i] & carry; + i = i+1; + end + end + + assign ping = &count; +endmodule + diff --git a/tests/sat/counters-repeat.ys b/tests/sat/counters-repeat.ys new file mode 100644 index 00000000..b3dcfe08 --- /dev/null +++ b/tests/sat/counters-repeat.ys @@ -0,0 +1,10 @@ + +read_verilog counters-repeat.v +proc; opt + +expose -shared counter1 counter2 +miter -equiv -make_assert -make_outputs counter1 counter2 miter + +cd miter; flatten; opt +sat -verify -prove-asserts -tempinduct -set-at 1 in_rst 1 -seq 1 -show-inputs -show-outputs + diff --git a/tests/simple/arrays02.sv b/tests/simple/arrays02.sv new file mode 100644 index 00000000..76c2a738 --- /dev/null +++ b/tests/simple/arrays02.sv @@ -0,0 +1,16 @@ +module uut_arrays02(clock, we, addr, wr_data, rd_data); + +input clock, we; +input [3:0] addr, wr_data; +output [3:0] rd_data; +reg [3:0] rd_data; + +reg [3:0] memory [16]; + +always @(posedge clock) begin + if (we) + memory[addr] <= wr_data; + rd_data <= memory[addr]; +end + +endmodule diff --git a/tests/simple/attrib01_module.v b/tests/simple/attrib01_module.v new file mode 100644 index 00000000..adef34f5 --- /dev/null +++ b/tests/simple/attrib01_module.v @@ -0,0 +1,21 @@ +module bar(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output reg out; + + always @(posedge clk) + if (rst) out <= 1'd0; + else out <= ~inp; + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output wire out; + + bar bar_instance (clk, rst, inp, out); +endmodule + diff --git a/tests/simple/attrib02_port_decl.v b/tests/simple/attrib02_port_decl.v new file mode 100644 index 00000000..3505e726 --- /dev/null +++ b/tests/simple/attrib02_port_decl.v @@ -0,0 +1,25 @@ +module bar(clk, rst, inp, out); + (* this_is_clock = 1 *) + input wire clk; + (* this_is_reset = 1 *) + input wire rst; + input wire inp; + (* an_output_register = 1*) + output reg out; + + always @(posedge clk) + if (rst) out <= 1'd0; + else out <= ~inp; + +endmodule + +module foo(clk, rst, inp, out); + (* this_is_the_master_clock *) + input wire clk; + input wire rst; + input wire inp; + output wire out; + + bar bar_instance (clk, rst, inp, out); +endmodule + diff --git a/tests/simple/attrib03_parameter.v b/tests/simple/attrib03_parameter.v new file mode 100644 index 00000000..562d225c --- /dev/null +++ b/tests/simple/attrib03_parameter.v @@ -0,0 +1,28 @@ +module bar(clk, rst, inp, out); + + (* bus_width *) + parameter WIDTH = 2; + + (* an_attribute_on_localparam = 55 *) + localparam INCREMENT = 5; + + input wire clk; + input wire rst; + input wire [WIDTH-1:0] inp; + output reg [WIDTH-1:0] out; + + always @(posedge clk) + if (rst) out <= 0; + else out <= inp + INCREMENT; + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire [7:0] inp; + output wire [7:0] out; + + bar # (.WIDTH(8)) bar_instance (clk, rst, inp, out); +endmodule + diff --git a/tests/simple/attrib04_net_var.v b/tests/simple/attrib04_net_var.v new file mode 100644 index 00000000..8b552340 --- /dev/null +++ b/tests/simple/attrib04_net_var.v @@ -0,0 +1,32 @@ +module bar(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output reg out; + + (* this_is_a_prescaler *) + reg [7:0] counter; + + (* temp_wire *) + wire out_val; + + always @(posedge clk) + counter <= counter + 1; + + assign out_val = inp ^ counter[4]; + + always @(posedge clk) + if (rst) out <= 1'd0; + else out <= out_val; + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output wire out; + + bar bar_instance (clk, rst, inp, out); +endmodule + diff --git a/tests/simple/attrib05_port_conn.v.DISABLED b/tests/simple/attrib05_port_conn.v.DISABLED new file mode 100644 index 00000000..e20e6631 --- /dev/null +++ b/tests/simple/attrib05_port_conn.v.DISABLED @@ -0,0 +1,21 @@ +module bar(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output reg out; + + always @(posedge clk) + if (rst) out <= 1'd0; + else out <= ~inp; + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output wire out; + + bar bar_instance ( (* clock_connected *) clk, rst, (* this_is_the_input *) inp, out); +endmodule + diff --git a/tests/simple/attrib06_operator_suffix.v b/tests/simple/attrib06_operator_suffix.v new file mode 100644 index 00000000..e21173c5 --- /dev/null +++ b/tests/simple/attrib06_operator_suffix.v @@ -0,0 +1,23 @@ +module bar(clk, rst, inp_a, inp_b, out); + input wire clk; + input wire rst; + input wire [7:0] inp_a; + input wire [7:0] inp_b; + output reg [7:0] out; + + always @(posedge clk) + if (rst) out <= 0; + else out <= inp_a + (* ripple_adder *) inp_b; + +endmodule + +module foo(clk, rst, inp_a, inp_b, out); + input wire clk; + input wire rst; + input wire [7:0] inp_a; + input wire [7:0] inp_b; + output wire [7:0] out; + + bar bar_instance (clk, rst, inp_a, inp_b, out); +endmodule + diff --git a/tests/simple/attrib07_func_call.v.DISABLED b/tests/simple/attrib07_func_call.v.DISABLED new file mode 100644 index 00000000..f55ef231 --- /dev/null +++ b/tests/simple/attrib07_func_call.v.DISABLED @@ -0,0 +1,21 @@ +function [7:0] do_add; + input [7:0] inp_a; + input [7:0] inp_b; + + do_add = inp_a + inp_b; + +endfunction + +module foo(clk, rst, inp_a, inp_b, out); + input wire clk; + input wire rst; + input wire [7:0] inp_a; + input wire [7:0] inp_b; + output wire [7:0] out; + + always @(posedge clk) + if (rst) out <= 0; + else out <= do_add (* combinational_adder *) (inp_a, inp_b); + +endmodule + diff --git a/tests/simple/attrib08_mod_inst.v b/tests/simple/attrib08_mod_inst.v new file mode 100644 index 00000000..c5a32234 --- /dev/null +++ b/tests/simple/attrib08_mod_inst.v @@ -0,0 +1,22 @@ +module bar(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output reg out; + + always @(posedge clk) + if (rst) out <= 1'd0; + else out <= ~inp; + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output wire out; + + (* my_module_instance = 99 *) + bar bar_instance (clk, rst, inp, out); +endmodule + diff --git a/tests/simple/attrib09_case.v b/tests/simple/attrib09_case.v new file mode 100644 index 00000000..8551bf9d --- /dev/null +++ b/tests/simple/attrib09_case.v @@ -0,0 +1,26 @@ +module bar(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire [1:0] inp; + output reg [1:0] out; + + always @(inp) + (* full_case, parallel_case *) + case(inp) + 2'd0: out <= 2'd3; + 2'd1: out <= 2'd2; + 2'd2: out <= 2'd1; + 2'd3: out <= 2'd0; + endcase + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire [1:0] inp; + output wire [1:0] out; + + bar bar_instance (clk, rst, inp, out); +endmodule + diff --git a/tests/simple/defvalue.sv b/tests/simple/defvalue.sv new file mode 100644 index 00000000..b0a087ec --- /dev/null +++ b/tests/simple/defvalue.sv @@ -0,0 +1,22 @@ +module top(input clock, input [3:0] delta, output [3:0] cnt1, cnt2); + cnt #(1) foo (.clock, .cnt(cnt1), .delta); + cnt #(2) bar (.clock, .cnt(cnt2)); +endmodule + +module cnt #( + parameter integer initval = 0 +) ( + input clock, + output logic [3:0] cnt = initval, +`ifdef __ICARUS__ + input [3:0] delta +`else + input [3:0] delta = 10 +`endif +); +`ifdef __ICARUS__ + assign (weak0, weak1) delta = 10; +`endif + always @(posedge clock) + cnt <= cnt + delta; +endmodule diff --git a/tests/simple/dff_init.v b/tests/simple/dff_init.v new file mode 100644 index 00000000..375ea5c4 --- /dev/null +++ b/tests/simple/dff_init.v @@ -0,0 +1,54 @@ +module dff0_test(n1, n1_inv, clk); + input clk; + output n1; + reg n1 = 32'd0; + output n1_inv; + always @(posedge clk) + n1 <= n1_inv; + assign n1_inv = ~n1; +endmodule + +module dff1_test(n1, n1_inv, clk); + input clk; + (* init = 32'd1 *) + output n1; + reg n1 = 32'd1; + output n1_inv; + always @(posedge clk) + n1 <= n1_inv; + assign n1_inv = ~n1; +endmodule + +module dff0a_test(n1, n1_inv, clk); + input clk; + (* init = 32'd0 *) // Must be consistent with reg initialiser below + output n1; + reg n1 = 32'd0; + output n1_inv; + always @(posedge clk) + n1 <= n1_inv; + assign n1_inv = ~n1; +endmodule + +module dff1a_test(n1, n1_inv, clk); + input clk; + (* init = 32'd1 *) // Must be consistent with reg initialiser below + output n1; + reg n1 = 32'd1; + output n1_inv; + always @(posedge clk) + n1 <= n1_inv; + assign n1_inv = ~n1; +endmodule + +module dff_test_997 (y, clk, wire4); +// https://github.com/YosysHQ/yosys/issues/997 + output wire [1:0] y; + input clk; + input signed wire4; + reg [1:0] reg10 = 0; + always @(posedge clk) begin + reg10 <= wire4; + end + assign y = reg10; +endmodule diff --git a/tests/simple/forloops.v b/tests/simple/forloops.v new file mode 100644 index 00000000..8665222d --- /dev/null +++ b/tests/simple/forloops.v @@ -0,0 +1,25 @@ +module forloops01 (input clk, a, b, output reg [3:0] p, q, x, y); + integer k; + always @(posedge clk) begin + for (k=0; k<2; k=k+1) + p[2*k +: 2] = {a, b} ^ {2{k}}; + x <= k + {a, b}; + end + always @* begin + for (k=0; k<4; k=k+1) + q[k] = {~a, ~b, a, b} >> k[1:0]; + y = k - {a, b}; + end +endmodule + +module forloops02 (input clk, a, b, output reg [3:0] q, x, output [3:0] y); + integer k; + always @* begin + for (k=0; k<4; k=k+1) + q[k] = {~a, ~b, a, b} >> k[1:0]; + end + always @* begin + x = k + {a, b}; + end + assign y = k - {a, b}; +endmodule diff --git a/tests/simple/generate.v b/tests/simple/generate.v index 24eb4462..0e353ad9 100644 --- a/tests/simple/generate.v +++ b/tests/simple/generate.v @@ -90,5 +90,72 @@ generate endcase end endgenerate +endmodule + +// ------------------------------------------ + +module gen_test4(a, b); + +input [3:0] a; +output [3:0] b; + +genvar i; +generate + for (i=0; i < 3; i=i+1) begin : foo + localparam PREV = i - 1; + wire temp; + if (i == 0) + assign temp = a[0]; + else + assign temp = foo[PREV].temp & a[i]; + assign b[i] = temp; + end +endgenerate +endmodule + +// ------------------------------------------ + +module gen_test5(input_bits, out); + +parameter WIDTH = 256; +parameter CHUNK = 4; + +input [WIDTH-1:0] input_bits; +output out; + +genvar step, i, j; +generate + for (step = 1; step <= WIDTH; step = step * CHUNK) begin : steps + localparam PREV = step / CHUNK; + localparam DIM = WIDTH / step; + for (i = 0; i < DIM; i = i + 1) begin : outer + localparam LAST_START = i * CHUNK; + for (j = 0; j < CHUNK; j = j + 1) begin : inner + wire temp; + if (step == 1) + assign temp = input_bits[i]; + else if (j == 0) + assign temp = steps[PREV].outer[LAST_START].val; + else + assign temp + = steps[step].outer[i].inner[j-1].temp + & steps[PREV].outer[LAST_START + j].val; + end + wire val; + assign val = steps[step].outer[i].inner[CHUNK - 1].temp; + end + end +endgenerate +assign out = steps[WIDTH].outer[0].val; +endmodule +// ------------------------------------------ + +module gen_test6(output [3:0] o); +generate + genvar i; + for (i = 3; i >= 0; i = i-1) begin + assign o[i] = 1'b0; + end +endgenerate endmodule diff --git a/tests/simple/hierdefparam.v b/tests/simple/hierdefparam.v index ff92c38b..c9368ca7 100644 --- a/tests/simple/hierdefparam.v +++ b/tests/simple/hierdefparam.v @@ -1,3 +1,5 @@ +`default_nettype none + module hierdefparam_top(input [7:0] A, output [7:0] Y); generate begin:foo hierdefparam_a mod_a(.A(A), .Y(Y)); diff --git a/tests/simple/implicit_ports.v b/tests/simple/implicit_ports.v new file mode 100644 index 00000000..8b0a6f38 --- /dev/null +++ b/tests/simple/implicit_ports.v @@ -0,0 +1,16 @@ +// Test implicit port connections +module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result); + assign cout = cin; + assign result = a + b; +endmodule + +module named_ports(input [2:0] a, b, output [2:0] alu_result, output cout); + wire cin = 1; + alu alu ( + .a(a), + .b, // Implicit connection is equivalent to .b(b) + .cin(), // Explicitely unconnected + .cout(cout), + .result(alu_result) + ); +endmodule diff --git a/tests/simple/localparam_attr.v b/tests/simple/localparam_attr.v new file mode 100644 index 00000000..2ef76c71 --- /dev/null +++ b/tests/simple/localparam_attr.v @@ -0,0 +1,11 @@ +module uut_localparam_attr (I, O); + +(* LOCALPARAM_ATTRIBUTE = "attribute_content" *) +localparam WIDTH = 1; + +input wire [WIDTH-1:0] I; +output wire [WIDTH-1:0] O; + +assign O = I; + +endmodule diff --git a/tests/simple/mem2reg.v b/tests/simple/mem2reg.v index 9839fd4a..10042678 100644 --- a/tests/simple/mem2reg.v +++ b/tests/simple/mem2reg.v @@ -92,3 +92,25 @@ module mem2reg_test5(input ctrl, output out); assign out = bar[foo[0]]; endmodule +// ------------------------------------------------------ + +module mem2reg_test6 (din, dout); + input wire [3:0] din; + output reg [3:0] dout; + + reg [1:0] din_array [1:0]; + reg [1:0] dout_array [1:0]; + + always @* begin + din_array[0] = din[0 +: 2]; + din_array[1] = din[2 +: 2]; + + dout_array[0] = din_array[0]; + dout_array[1] = din_array[1]; + + {dout_array[0][1], dout_array[0][0]} = dout_array[0][0] + dout_array[1][0]; + + dout[0 +: 2] = dout_array[0]; + dout[2 +: 2] = dout_array[1]; + end +endmodule diff --git a/tests/simple/param_attr.v b/tests/simple/param_attr.v new file mode 100644 index 00000000..34d63a34 --- /dev/null +++ b/tests/simple/param_attr.v @@ -0,0 +1,11 @@ +module uut_param_attr (I, O); + +(* PARAMETER_ATTRIBUTE = "attribute_content" *) +parameter WIDTH = 1; + +input wire [WIDTH-1:0] I; +output wire [WIDTH-1:0] O; + +assign O = I; + +endmodule diff --git a/tests/simple/peepopt.v b/tests/simple/peepopt.v new file mode 100644 index 00000000..1bf42789 --- /dev/null +++ b/tests/simple/peepopt.v @@ -0,0 +1,13 @@ +module peepopt_shiftmul_0 #(parameter N=3, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output [W-1:0] o); +assign o = i[s*W+:W]; +endmodule + +module peepopt_shiftmul_1 (output y, input [2:0] w); +assign y = 1'b1 >> (w * (3'b110)); +endmodule + +module peepopt_muldiv_0(input [1:0] i, output [1:0] o); +wire [3:0] t; +assign t = i * 3; +assign o = t / 3; +endmodule diff --git a/tests/simple/retime.v b/tests/simple/retime.v new file mode 100644 index 00000000..30b6087d --- /dev/null +++ b/tests/simple/retime.v @@ -0,0 +1,6 @@ +module retime_test(input clk, input [7:0] a, output z); + reg [7:0] ff = 8'hF5; + always @(posedge clk) + ff <= {ff[6:0], ^a}; + assign z = ff[7]; +endmodule diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh index aaa1cf94..967ac49f 100755 --- a/tests/simple/run-test.sh +++ b/tests/simple/run-test.sh @@ -17,4 +17,5 @@ if ! which iverilog > /dev/null ; then exit 1 fi -exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v +shopt -s nullglob +exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.{sv,v} diff --git a/tests/simple/task_func.v b/tests/simple/task_func.v index fa50c1d5..f6e902f6 100644 --- a/tests/simple/task_func.v +++ b/tests/simple/task_func.v @@ -120,3 +120,22 @@ module task_func_test04(input [7:0] in, output [7:0] out1, out2, out3, out4); assign out3 = test3(in); assign out4 = test4(in); endmodule + +// ------------------------------------------------------------------- + +// https://github.com/YosysHQ/yosys/issues/857 +module task_func_test05(data_in,data_out,clk); + output reg data_out; + input data_in; + input clk; + + task myTask; + output out; + input in; + out = in; + endtask + + always @(posedge clk) begin + myTask(data_out,data_in); + end +endmodule diff --git a/tests/simple/wandwor.v b/tests/simple/wandwor.v new file mode 100644 index 00000000..34404aa2 --- /dev/null +++ b/tests/simple/wandwor.v @@ -0,0 +1,36 @@ +module wandwor_test0 (A, B, C, D, X, Y, Z); + input A, B, C, D; + output wor X; + output wand Y; + output Z; + + assign X = A, X = B, Y = C, Y = D; + foo foo_0 (C, D, X); + foo foo_1 (A, B, Y); + foo foo_2 (X, Y, Z); +endmodule + +module wandwor_test1 (A, B, C, D, X, Y, Z); + input [3:0] A, B, C, D; + output wor [3:0] X; + output wand [3:0] Y; + output Z; + + bar bar_inst ( + .I0({A, B}), + .I1({B, A}), + .O({X, Y}) + ); + + assign X = C, X = D; + assign Y = C, Y = D; + assign Z = ^{X,Y}; +endmodule + +module foo(input I0, I1, output O); + assign O = I0 ^ I1; +endmodule + +module bar(input [7:0] I0, I1, output [7:0] O); + assign O = I0 + I1; +endmodule diff --git a/tests/simple/xfirrtl b/tests/simple/xfirrtl new file mode 100644 index 00000000..ba61a447 --- /dev/null +++ b/tests/simple/xfirrtl @@ -0,0 +1,27 @@ +# This file contains the names of verilog files to exclude from verilog to FIRRTL regression tests due to known failures. +arraycells.v inst id[0] of +dff_different_styles.v +dff_init.v Initial value not supported +generate.v combinational loop +hierdefparam.v inst id[0] of +i2c_master_tests.v $adff +macros.v drops modules +mem2reg.v drops modules +mem_arst.v $adff +memory.v $adff +multiplier.v inst id[0] of +muxtree.v drops modules +omsp_dbg_uart.v $adff +operators.v $pow +partsel.v drops modules +process.v drops modules +realexpr.v drops modules +retime.v Initial value (11110101) for (retime_test.ff) not supported +scopes.v original verilog issues ( -x where x isn't declared signed) +sincos.v $adff +specify.v no code (empty module generates error +subbytes.v $adff +task_func.v drops modules +values.v combinational loop +vloghammer.v combinational loop +wreduce.v original verilog issues ( -x where x isn't declared signed) diff --git a/tests/sva/basic01.sv b/tests/sva/basic01.sv index 74ab9343..d5ad497d 100644 --- a/tests/sva/basic01.sv +++ b/tests/sva/basic01.sv @@ -6,7 +6,7 @@ module top (input logic clock, ctrl); write <= ctrl; ready <= write; end - + a_rw: assert property ( @(posedge clock) !(read && write) ); `ifdef FAIL a_wr: assert property ( @(posedge clock) write |-> ready ); diff --git a/tests/sva/extnets.sv b/tests/sva/extnets.sv new file mode 100644 index 00000000..47312de7 --- /dev/null +++ b/tests/sva/extnets.sv @@ -0,0 +1,22 @@ +module top(input i, output o); + A A(); + B B(); + assign A.i = i; + assign o = B.o; + always @* assert(o == i); +endmodule + +module A; + wire i, y; +`ifdef FAIL + assign B.x = i; +`else + assign B.x = !i; +`endif + assign y = !B.y; +endmodule + +module B; + wire x, y, o; + assign y = x, o = A.y; +endmodule diff --git a/tests/svinterfaces/.gitignore b/tests/svinterfaces/.gitignore new file mode 100644 index 00000000..a5b7927d --- /dev/null +++ b/tests/svinterfaces/.gitignore @@ -0,0 +1,8 @@ +/a.out +/dut_result.txt +/reference_result.txt +/*.diff +/*.log_stderr +/*.log_stdout +/*_ref_syn.v +/*_syn.v diff --git a/tests/svinterfaces/run-test.sh b/tests/svinterfaces/run-test.sh new file mode 100755 index 00000000..86567d1c --- /dev/null +++ b/tests/svinterfaces/run-test.sh @@ -0,0 +1,6 @@ +#/bin/bash -e + + + +./runone.sh svinterface1 +./runone.sh svinterface_at_top diff --git a/tests/svinterfaces/runone.sh b/tests/svinterfaces/runone.sh new file mode 100755 index 00000000..54cf5f2e --- /dev/null +++ b/tests/svinterfaces/runone.sh @@ -0,0 +1,44 @@ +#!/bin/bash + + +TESTNAME=$1 + +STDOUTFILE=${TESTNAME}.log_stdout +STDERRFILE=${TESTNAME}.log_stderr + +echo "" > $STDOUTFILE +echo "" > $STDERRFILE + +echo -n "Test: ${TESTNAME} -> " + +set -e + +$PWD/../../yosys -p "read_verilog -sv ${TESTNAME}.sv ; hierarchy -check -top TopModule ; synth ; write_verilog ${TESTNAME}_syn.v" >> $STDOUTFILE 2>> $STDERRFILE +$PWD/../../yosys -p "read_verilog -sv ${TESTNAME}_ref.v ; hierarchy -check -top TopModule ; synth ; write_verilog ${TESTNAME}_ref_syn.v" >> $STDOUTFILE 2>> $STDERRFILE + +rm -f a.out reference_result.txt dut_result.txt + +iverilog -g2012 ${TESTNAME}_syn.v +iverilog -g2012 ${TESTNAME}_ref_syn.v + +set +e +iverilog -g2012 ${TESTNAME}_tb.v ${TESTNAME}_ref_syn.v +./a.out +mv output.txt reference_result.txt +if [ -f ${TESTNAME}_wrapper.v ] ; then + iverilog -g2012 ${TESTNAME}_tb_wrapper.v ${TESTNAME}_syn.v +else + iverilog -g2012 ${TESTNAME}_tb.v ${TESTNAME}_syn.v +fi +./a.out +mv output.txt dut_result.txt + +diff reference_result.txt dut_result.txt > ${TESTNAME}.diff +RET=$? +if [ "$RET" != "0" ] ; then + echo "ERROR!" + exit -1 +fi + +echo "ok" +exit 0 diff --git a/tests/svinterfaces/svinterface1.sv b/tests/svinterfaces/svinterface1.sv new file mode 100644 index 00000000..6d60b488 --- /dev/null +++ b/tests/svinterfaces/svinterface1.sv @@ -0,0 +1,117 @@ + + +module TopModule( + input logic clk, + input logic rst, + output logic [21:0] outOther, + input logic [1:0] sig, + input logic flip, + output logic [1:0] sig_out, + output logic [15:0] passThrough); + + MyInterface #(.WIDTH(4)) MyInterfaceInstance(); + + SubModule1 u_SubModule1 ( + .clk(clk), + .rst(rst), + .u_MyInterface(MyInterfaceInstance), + .outOther(outOther), + .sig (sig) + ); + + assign sig_out = MyInterfaceInstance.mysig_out; + + + assign MyInterfaceInstance.setting = flip; + + assign passThrough = MyInterfaceInstance.passThrough; + +endmodule + +interface MyInterface #( + parameter WIDTH = 3)( + ); + + logic setting; + logic [WIDTH-1:0] other_setting; + + logic [1:0] mysig_out; + + logic [15:0] passThrough; + + modport submodule1 ( + input setting, + output other_setting, + output mysig_out, + output passThrough + ); + + modport submodule2 ( + input setting, + output other_setting, + input mysig_out, + output passThrough + ); + +endinterface + + +module SubModule1( + input logic clk, + input logic rst, + MyInterface.submodule1 u_MyInterface, + input logic [1:0] sig, + output logic [21:0] outOther + + ); + + always_ff @(posedge clk or posedge rst) + if(rst) + u_MyInterface.mysig_out <= 0; + else begin + if(u_MyInterface.setting) + u_MyInterface.mysig_out <= sig; + else + u_MyInterface.mysig_out <= ~sig; + end + + MyInterface #(.WIDTH(22)) MyInterfaceInstanceInSub(); + + SubModule2 u_SubModule2 ( + .clk(clk), + .rst(rst), + .u_MyInterfaceInSub2(u_MyInterface), + .u_MyInterfaceInSub3(MyInterfaceInstanceInSub) + ); + + assign outOther = MyInterfaceInstanceInSub.other_setting; + + assign MyInterfaceInstanceInSub.setting = 0; + assign MyInterfaceInstanceInSub.mysig_out = sig; + +endmodule + +module SubModule2( + + input logic clk, + input logic rst, + MyInterface.submodule2 u_MyInterfaceInSub2, + MyInterface.submodule2 u_MyInterfaceInSub3 + + ); + + always_comb begin + if (u_MyInterfaceInSub3.mysig_out == 2'b00) + u_MyInterfaceInSub3.other_setting[21:0] = 1000; + else if (u_MyInterfaceInSub3.mysig_out == 2'b01) + u_MyInterfaceInSub3.other_setting[21:0] = 2000; + else if (u_MyInterfaceInSub3.mysig_out == 2'b10) + u_MyInterfaceInSub3.other_setting[21:0] = 3000; + else + u_MyInterfaceInSub3.other_setting[21:0] = 4000; + end + + assign u_MyInterfaceInSub2.passThrough[7:0] = 124; + assign u_MyInterfaceInSub2.passThrough[15:8] = 200; + +endmodule diff --git a/tests/svinterfaces/svinterface1_ref.v b/tests/svinterfaces/svinterface1_ref.v new file mode 100644 index 00000000..b119f403 --- /dev/null +++ b/tests/svinterfaces/svinterface1_ref.v @@ -0,0 +1,107 @@ + +module TopModule( + input logic clk, + input logic rst, + input logic [1:0] sig, + input logic flip, + output logic [15:0] passThrough, + output logic [21:0] outOther, + output logic [1:0] sig_out); + + + logic MyInterfaceInstance_setting; + logic [3:0] MyInterfaceInstance_other_setting; + logic [1:0] MyInterfaceInstance_mysig_out; + + SubModule1 u_SubModule1 ( + .clk(clk), + .rst(rst), + .u_MyInterface_setting(MyInterfaceInstance_setting), + .u_MyInterface_mysig_out(MyInterfaceInstance_mysig_out), + .u_MyInterface_other_setting(MyInterfaceInstance_other_setting), + .outOther(outOther), + .passThrough (passThrough), + .sig (sig) + ); + + assign sig_out = MyInterfaceInstance_mysig_out; + + + assign MyInterfaceInstance_setting = flip; + +endmodule + + +module SubModule1( + input logic clk, + input logic rst, + input logic u_MyInterface_setting, + output logic [3:0] u_MyInterface_other_setting, + output logic [1:0] u_MyInterface_mysig_out, + output logic [21:0] outOther, + input logic [1:0] sig, + output logic [15:0] passThrough + ); + + always @(posedge clk or posedge rst) + if(rst) + u_MyInterface_mysig_out <= 0; + else begin + if(u_MyInterface_setting) + u_MyInterface_mysig_out <= sig; + else + u_MyInterface_mysig_out <= ~sig; + end + + logic MyInterfaceInstanceInSub_setting; + logic [21:0] MyInterfaceInstanceInSub_other_setting; + logic [1:0] MyInterfaceInstanceInSub_mysig_out; + + + SubModule2 u_SubModule2 ( + .clk(clk), + .rst(rst), + .u_MyInterfaceInSub2_setting(u_MyInterface_setting), + .u_MyInterfaceInSub2_mysig_out(u_MyInterface_mysig_out), + .u_MyInterfaceInSub2_other_setting(u_MyInterface_other_setting), + .u_MyInterfaceInSub3_setting(MyInterfaceInstanceInSub_setting), + .u_MyInterfaceInSub3_mysig_out(MyInterfaceInstanceInSub_mysig_out), + .u_MyInterfaceInSub3_other_setting(MyInterfaceInstanceInSub_other_setting), + .passThrough (passThrough) + ); + assign outOther = MyInterfaceInstanceInSub_other_setting; + + assign MyInterfaceInstanceInSub_setting = 0; + assign MyInterfaceInstanceInSub_mysig_out = sig; + +endmodule + +module SubModule2( + + input logic clk, + input logic rst, + input logic u_MyInterfaceInSub2_setting, + output logic [3:0] u_MyInterfaceInSub2_other_setting, + input logic [1:0] u_MyInterfaceInSub2_mysig_out, + input logic u_MyInterfaceInSub3_setting, + output logic [21:0] u_MyInterfaceInSub3_other_setting, + input logic [1:0] u_MyInterfaceInSub3_mysig_out, + output logic [15:0] passThrough + + ); + + always @(u_MyInterfaceInSub3_mysig_out) begin + if (u_MyInterfaceInSub3_mysig_out == 2'b00) + u_MyInterfaceInSub3_other_setting[21:0] = 1000; + else if (u_MyInterfaceInSub3_mysig_out == 2'b01) + u_MyInterfaceInSub3_other_setting[21:0] = 2000; + else if (u_MyInterfaceInSub3_mysig_out == 2'b10) + u_MyInterfaceInSub3_other_setting[21:0] = 3000; + else + u_MyInterfaceInSub3_other_setting[21:0] = 4000; + end + + assign passThrough[7:0] = 124; + assign passThrough[15:8] = 200; + +endmodule diff --git a/tests/svinterfaces/svinterface1_tb.v b/tests/svinterfaces/svinterface1_tb.v new file mode 100644 index 00000000..44c3b5f6 --- /dev/null +++ b/tests/svinterfaces/svinterface1_tb.v @@ -0,0 +1,57 @@ +`timescale 1ns/10ps + +module svinterface1_tb; + + + logic clk; + logic rst; + logic [21:0] outOther; + logic [1:0] sig; + logic [1:0] sig_out; + logic flip; + logic [15:0] passThrough; + integer outfile; + + TopModule u_dut ( + .clk(clk), + .rst(rst), + .outOther(outOther), + .sig(sig), + .flip(flip), + .passThrough(passThrough), + .sig_out(sig_out) + ); + + initial begin + clk = 0; + while(1) begin + clk = ~clk; + #50; + end + end + + initial begin + outfile = $fopen("output.txt"); + rst = 1; + sig = 0; + flip = 0; + @(posedge clk); + #(2); + rst = 0; + @(posedge clk); + for(int j=0;j<2;j++) begin + for(int i=0;i<20;i++) begin + #(2); + flip = j; + sig = i; + @(posedge clk); + end + end + $finish; + end + + always @(negedge clk) begin + $fdisplay(outfile, "%d %d %d", outOther, sig_out, passThrough); + end + +endmodule diff --git a/tests/svinterfaces/svinterface_at_top.sv b/tests/svinterfaces/svinterface_at_top.sv new file mode 100644 index 00000000..b5aa8c8f --- /dev/null +++ b/tests/svinterfaces/svinterface_at_top.sv @@ -0,0 +1,125 @@ + + +module TopModule( + input logic clk, + input logic rst, + output logic [21:0] outOther, + input logic [1:0] sig, + input logic flip, + output logic [1:0] sig_out, + MyInterface.submodule1 interfaceInstanceAtTop, + output logic [15:0] passThrough); + + MyInterface #(.WIDTH(4)) MyInterfaceInstance(); + + SubModule1 u_SubModule1 ( + .clk(clk), + .rst(rst), + .u_MyInterface(MyInterfaceInstance), + .u_MyInterfaceFromTop(interfaceInstanceAtTop), + .outOther(outOther), + .sig (sig) + ); + + assign sig_out = MyInterfaceInstance.mysig_out; + + + assign MyInterfaceInstance.setting = flip; + + assign passThrough = MyInterfaceInstance.passThrough; + +endmodule + +interface MyInterface #( + parameter WIDTH = 3)( + ); + + logic setting; + logic [WIDTH-1:0] other_setting; + + logic [1:0] mysig_out; + + logic [15:0] passThrough; + + modport submodule1 ( + input setting, + output other_setting, + output mysig_out, + output passThrough + ); + + modport submodule2 ( + input setting, + output other_setting, + input mysig_out, + output passThrough + ); + +endinterface + + +module SubModule1( + input logic clk, + input logic rst, + MyInterface.submodule1 u_MyInterface, + MyInterface.submodule1 u_MyInterfaceFromTop, + input logic [1:0] sig, + output logic [21:0] outOther + + ); + + + always_ff @(posedge clk or posedge rst) + if(rst) + u_MyInterface.mysig_out <= 0; + else begin + if(u_MyInterface.setting) + u_MyInterface.mysig_out <= sig; + else + u_MyInterface.mysig_out <= ~sig; + end + + MyInterface #(.WIDTH(22)) MyInterfaceInstanceInSub(); + + SubModule2 u_SubModule2 ( + .clk(clk), + .rst(rst), + .u_MyInterfaceFromTopDown(u_MyInterfaceFromTop), + .u_MyInterfaceInSub2(u_MyInterface), + .u_MyInterfaceInSub3(MyInterfaceInstanceInSub) + ); + + assign outOther = MyInterfaceInstanceInSub.other_setting; + + assign MyInterfaceInstanceInSub.setting = 0; + assign MyInterfaceInstanceInSub.mysig_out = sig; + +endmodule + +module SubModule2( + + input logic clk, + input logic rst, + MyInterface.submodule2 u_MyInterfaceInSub2, + MyInterface.submodule1 u_MyInterfaceFromTopDown, + MyInterface.submodule2 u_MyInterfaceInSub3 + + ); + + assign u_MyInterfaceFromTopDown.mysig_out = u_MyInterfaceFromTop.setting ? 10 : 20; + + always_comb begin + if (u_MyInterfaceInSub3.mysig_out == 2'b00) + u_MyInterfaceInSub3.other_setting[21:0] = 1000; + else if (u_MyInterfaceInSub3.mysig_out == 2'b01) + u_MyInterfaceInSub3.other_setting[21:0] = 2000; + else if (u_MyInterfaceInSub3.mysig_out == 2'b10) + u_MyInterfaceInSub3.other_setting[21:0] = 3000; + else + u_MyInterfaceInSub3.other_setting[21:0] = 4000; + end + + assign u_MyInterfaceInSub2.passThrough[7:0] = 124; + assign u_MyInterfaceInSub2.passThrough[15:8] = 200; + +endmodule diff --git a/tests/svinterfaces/svinterface_at_top_ref.v b/tests/svinterfaces/svinterface_at_top_ref.v new file mode 100644 index 00000000..7b54a26d --- /dev/null +++ b/tests/svinterfaces/svinterface_at_top_ref.v @@ -0,0 +1,120 @@ + +module TopModule( + input logic clk, + input logic rst, + input logic [1:0] sig, + input logic flip, + output logic [15:0] passThrough, + output logic [21:0] outOther, + input logic interfaceInstanceAtTop_setting, + output logic [2:0] interfaceInstanceAtTop_other_setting, + output logic [1:0] interfaceInstanceAtTop_mysig_out, + output logic [15:0] interfaceInstanceAtTop_passThrough, + output logic [1:0] sig_out); + + + logic MyInterfaceInstance_setting; + logic [3:0] MyInterfaceInstance_other_setting; + logic [1:0] MyInterfaceInstance_mysig_out; + + SubModule1 u_SubModule1 ( + .clk(clk), + .rst(rst), + .u_MyInterface_setting(MyInterfaceInstance_setting), + .u_MyInterface_mysig_out(MyInterfaceInstance_mysig_out), + .u_MyInterface_other_setting(MyInterfaceInstance_other_setting), + .u_MyInterfaceFromTop_setting(interfaceInstanceAtTop_setting), + .u_MyInterfaceFromTop_other_setting(interfaceInstanceAtTop_other_setting), + .u_MyInterfaceFromTop_mysig_out(interfaceInstanceAtTop_mysig_out), + .u_MyInterfaceFromTop_passThrough(interfaceInstanceAtTop_passThrough), + .outOther(outOther), + .passThrough (passThrough), + .sig (sig) + ); + + assign sig_out = MyInterfaceInstance_mysig_out; + + + assign MyInterfaceInstance_setting = flip; + +endmodule + + +module SubModule1( + input logic clk, + input logic rst, + input logic u_MyInterface_setting, + output logic [3:0] u_MyInterface_other_setting, + output logic [1:0] u_MyInterface_mysig_out, + output logic [21:0] outOther, + input logic [1:0] sig, + input logic u_MyInterfaceFromTop_setting, + output logic [2:0] u_MyInterfaceFromTop_other_setting, + output logic [1:0] u_MyInterfaceFromTop_mysig_out, + output logic [14:0] u_MyInterfaceFromTop_passThrough, + output logic [15:0] passThrough + ); + + always @(posedge clk or posedge rst) + if(rst) + u_MyInterface_mysig_out <= 0; + else begin + if(u_MyInterface_setting) + u_MyInterface_mysig_out <= sig; + else + u_MyInterface_mysig_out <= ~sig; + end + + logic MyInterfaceInstanceInSub_setting; + logic [21:0] MyInterfaceInstanceInSub_other_setting; + logic [1:0] MyInterfaceInstanceInSub_mysig_out; + + assign u_MyInterfaceFromTop_mysig_out = u_MyInterfaceFromTop_setting ? 10 : 20; + + SubModule2 u_SubModule2 ( + .clk(clk), + .rst(rst), + .u_MyInterfaceInSub2_setting(u_MyInterface_setting), + .u_MyInterfaceInSub2_mysig_out(u_MyInterface_mysig_out), + .u_MyInterfaceInSub2_other_setting(u_MyInterface_other_setting), + .u_MyInterfaceInSub3_setting(MyInterfaceInstanceInSub_setting), + .u_MyInterfaceInSub3_mysig_out(MyInterfaceInstanceInSub_mysig_out), + .u_MyInterfaceInSub3_other_setting(MyInterfaceInstanceInSub_other_setting), + .passThrough (passThrough) + ); + assign outOther = MyInterfaceInstanceInSub_other_setting; + + assign MyInterfaceInstanceInSub_setting = 0; + assign MyInterfaceInstanceInSub_mysig_out = sig; + +endmodule + +module SubModule2( + + input logic clk, + input logic rst, + input logic u_MyInterfaceInSub2_setting, + output logic [3:0] u_MyInterfaceInSub2_other_setting, + input logic [1:0] u_MyInterfaceInSub2_mysig_out, + input logic u_MyInterfaceInSub3_setting, + output logic [21:0] u_MyInterfaceInSub3_other_setting, + input logic [1:0] u_MyInterfaceInSub3_mysig_out, + output logic [15:0] passThrough + + ); + + always @(u_MyInterfaceInSub3_mysig_out) begin + if (u_MyInterfaceInSub3_mysig_out == 2'b00) + u_MyInterfaceInSub3_other_setting[21:0] = 1000; + else if (u_MyInterfaceInSub3_mysig_out == 2'b01) + u_MyInterfaceInSub3_other_setting[21:0] = 2000; + else if (u_MyInterfaceInSub3_mysig_out == 2'b10) + u_MyInterfaceInSub3_other_setting[21:0] = 3000; + else + u_MyInterfaceInSub3_other_setting[21:0] = 4000; + end + + assign passThrough[7:0] = 124; + assign passThrough[15:8] = 200; + +endmodule diff --git a/tests/svinterfaces/svinterface_at_top_tb.v b/tests/svinterfaces/svinterface_at_top_tb.v new file mode 100644 index 00000000..bf37a148 --- /dev/null +++ b/tests/svinterfaces/svinterface_at_top_tb.v @@ -0,0 +1,68 @@ +`timescale 1ns/10ps + +module svinterface_at_top_tb; + + + logic clk; + logic rst; + logic [21:0] outOther; + logic [1:0] sig; + logic [1:0] sig_out; + logic flip; + logic [15:0] passThrough; + integer outfile; + + logic interfaceInstanceAtTop_setting; + logic [2:0] interfaceInstanceAtTop_other_setting; + logic [1:0] interfaceInstanceAtTop_mysig_out; + logic [15:0] interfaceInstanceAtTop_passThrough; + + + TopModule u_dut ( + .clk(clk), + .rst(rst), + .outOther(outOther), + .sig(sig), + .flip(flip), + .passThrough(passThrough), + .interfaceInstanceAtTop_setting(interfaceInstanceAtTop_setting), + .interfaceInstanceAtTop_other_setting(interfaceInstanceAtTop_other_setting), + .interfaceInstanceAtTop_mysig_out(interfaceInstanceAtTop_mysig_out), + .interfaceInstanceAtTop_passThrough(interfaceInstanceAtTop_passThrough), + .sig_out(sig_out) + ); + + initial begin + clk = 0; + while(1) begin + clk = ~clk; + #50; + end + end + + initial begin + outfile = $fopen("output.txt"); + rst = 1; + interfaceInstanceAtTop_setting = 0; + sig = 0; + flip = 0; + @(posedge clk); + #(2); + rst = 0; + @(posedge clk); + for(int j=0;j<2;j++) begin + for(int i=0;i<20;i++) begin + #(2); + flip = j; + sig = i; + @(posedge clk); + end + end + $finish; + end + + always @(negedge clk) begin + $fdisplay(outfile, "%d %d %d %d", outOther, sig_out, passThrough, interfaceInstanceAtTop_mysig_out); + end + +endmodule diff --git a/tests/svinterfaces/svinterface_at_top_tb_wrapper.v b/tests/svinterfaces/svinterface_at_top_tb_wrapper.v new file mode 100644 index 00000000..b344a7b8 --- /dev/null +++ b/tests/svinterfaces/svinterface_at_top_tb_wrapper.v @@ -0,0 +1,68 @@ +`timescale 1ns/10ps + +module svinterface_at_top_tb_wrapper; + + + logic clk; + logic rst; + logic [21:0] outOther; + logic [1:0] sig; + logic [1:0] sig_out; + logic flip; + logic [15:0] passThrough; + integer outfile; + + logic interfaceInstanceAtTop_setting; + logic [2:0] interfaceInstanceAtTop_other_setting; + logic [1:0] interfaceInstanceAtTop_mysig_out; + logic [15:0] interfaceInstanceAtTop_passThrough; + + + TopModule u_dut ( + .clk(clk), + .rst(rst), + .outOther(outOther), + .sig(sig), + .flip(flip), + .passThrough(passThrough), + .\interfaceInstanceAtTop.setting (interfaceInstanceAtTop_setting), + .\interfaceInstanceAtTop.other_setting (interfaceInstanceAtTop_other_setting), + .\interfaceInstanceAtTop.mysig_out (interfaceInstanceAtTop_mysig_out), + .\interfaceInstanceAtTop.passThrough (interfaceInstanceAtTop_passThrough), + .sig_out(sig_out) + ); + + initial begin + clk = 0; + while(1) begin + clk = ~clk; + #50; + end + end + + initial begin + outfile = $fopen("output.txt"); + rst = 1; + sig = 0; + interfaceInstanceAtTop_setting = 0; + flip = 0; + @(posedge clk); + #(2); + rst = 0; + @(posedge clk); + for(int j=0;j<2;j++) begin + for(int i=0;i<20;i++) begin + #(2); + flip = j; + sig = i; + @(posedge clk); + end + end + $finish; + end + + always @(negedge clk) begin + $fdisplay(outfile, "%d %d %d %d", outOther, sig_out, passThrough, interfaceInstanceAtTop_mysig_out); + end + +endmodule diff --git a/tests/svinterfaces/svinterface_at_top_wrapper.v b/tests/svinterfaces/svinterface_at_top_wrapper.v new file mode 100644 index 00000000..64f906c0 --- /dev/null +++ b/tests/svinterfaces/svinterface_at_top_wrapper.v @@ -0,0 +1,33 @@ +`timescale 1ns/10ps + +module svinterface_at_top_wrapper( + input logic clk, + input logic rst, + output logic [21:0] outOther, + input logic [1:0] sig, + output logic [1:0] sig_out, + input logic flip, + output logic [15:0] passThrough, + + input logic interfaceInstanceAtTop_setting, + output logic [2:0] interfaceInstanceAtTop_other_setting, + output logic [1:0] interfaceInstanceAtTop_mysig_out, + output logic [15:0] interfaceInstanceAtTop_passThrough, + ); + + + TopModule u_dut ( + .clk(clk), + .rst(rst), + .outOther(outOther), + .sig(sig), + .flip(flip), + .passThrough(passThrough), + .\interfaceInstanceAtTop.setting(interfaceInstanceAtTop_setting), + .\interfaceInstanceAtTop.other_setting(interfaceInstanceAtTop_other_setting), + .\interfaceInstanceAtTop.mysig_out(interfaceInstanceAtTop_mysig_out), + .\interfaceInstanceAtTop.passThrough(interfaceInstanceAtTop_passThrough), + .sig_out(sig_out) + ); + +endmodule diff --git a/tests/tools/autotest.mk b/tests/tools/autotest.mk index c6867892..e0f2bcdc 100644 --- a/tests/tools/autotest.mk +++ b/tests/tools/autotest.mk @@ -1,7 +1,7 @@ -EXTRA_FLAGS= -SEED= - +# Don't bother defining default values for SEED and EXTRA_FLAGS. +# Their "natural" default values should be sufficient, +# and they may be overridden in the environment. ifneq ($(strip $(SEED)),) SEEDOPT=-S$(SEED) endif diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index d6216244..6bece9b3 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -7,8 +7,8 @@ use_modelsim=false verbose=false keeprunning=false makejmode=false -frontend="verilog" -backend_opts="-noattr -noexpr" +frontend="verilog -noblackbox" +backend_opts="-noattr -noexpr -siminit" autotb_opts="" include_opts="" xinclude_opts="" @@ -17,12 +17,19 @@ scriptfiles="" scriptopt="" toolsdir="$(cd $(dirname $0); pwd)" warn_iverilog_git=false +# The following are used in verilog to firrtl regression tests. +# Typically these will be passed as environment variables: +#EXTRA_FLAGS="--firrtl2verilog 'java -cp /.../firrtl/utils/bin/firrtl.jar firrtl.Driver'" +# The tests are skipped if firrtl2verilog is the empty string (the default). +firrtl2verilog="" +xfirrtl="../xfirrtl" +abcprog="berkeley-abc" if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdata ]; then ( set -ex; ${CC:-gcc} -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1 fi -while getopts xmGl:wkjvref:s:p:n:S:I: opt; do +while getopts xmGl:wkjvref:s:p:n:S:I:A:-: opt; do case "$opt" in x) use_xsim=true ;; @@ -43,7 +50,7 @@ while getopts xmGl:wkjvref:s:p:n:S:I: opt; do r) backend_opts="$backend_opts -norename" ;; e) - backend_opts="$( echo " $backend_opts " | sed 's, -noexpr ,,; s,^ ,,; s, $,,;'; )" ;; + backend_opts="$( echo " $backend_opts " | sed 's, -noexpr , ,; s,^ ,,; s, $,,;'; )" ;; f) frontend="$OPTARG" ;; s) @@ -59,14 +66,38 @@ while getopts xmGl:wkjvref:s:p:n:S:I: opt; do include_opts="$include_opts -I $OPTARG" xinclude_opts="$xinclude_opts -i $OPTARG" minclude_opts="$minclude_opts +incdir+$OPTARG" ;; + A) + abcprog="$OPTARG" ;; + -) + case "${OPTARG}" in + xfirrtl) + xfirrtl="${!OPTIND}" + OPTIND=$(( $OPTIND + 1 )) + ;; + firrtl2verilog) + firrtl2verilog="${!OPTIND}" + OPTIND=$(( $OPTIND + 1 )) + ;; + *) + if [ "$OPTERR" == 1 ] && [ "${optspec:0:1}" != ":" ]; then + echo "Unknown option --${OPTARG}" >&2 + fi + ;; + esac;; *) - echo "Usage: $0 [-x|-m] [-G] [-w] [-k] [-j] [-v] [-r] [-e] [-l libs] [-f frontend] [-s script] [-p cmdstring] [-n iters] [-S seed] [-I incdir] verilog-files\n" >&2 + echo "Usage: $0 [-x|-m] [-G] [-w] [-k] [-j] [-v] [-r] [-e] [-l libs] [-f frontend] [-s script] [-p cmdstring] [-n iters] [-S seed] [-I incdir] [--xfirrtl FIRRTL test exclude file] [--firrtl2verilog command to generate verilog from firrtl] verilog-files\n" >&2 exit 1 esac done compile_and_run() { exe="$1"; output="$2"; shift 2 + if [ "${2##*.}" == "sv" ]; then + language_gen="-g2012" + else + language_gen="-g2005" + fi + if $use_modelsim; then altver=$( ls -v /opt/altera/ | grep '^[0-9]' | tail -n1; ) /opt/altera/$altver/modelsim_ase/bin/vlib work @@ -77,7 +108,7 @@ compile_and_run() { /opt/Xilinx/Vivado/$xilver/bin/xvlog $xinclude_opts -d outfile=\"$output\" "$@" /opt/Xilinx/Vivado/$xilver/bin/xelab -R work.testbench else - iverilog $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@" + iverilog $language_gen $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@" vvp -n "$exe" fi } @@ -86,8 +117,9 @@ shift $((OPTIND - 1)) for fn do - bn=${fn%.v} - if [ "$bn" == "$fn" ]; then + bn=${fn%.*} + ext=${fn##*.} + if [[ "$ext" != "v" ]] && [[ "$ext" != "sv" ]] && [[ "$ext" != "aag" ]] && [[ "$ext" != "aig" ]]; then echo "Invalid argument: $fn" >&2 exit 1 fi @@ -100,6 +132,10 @@ do echo -n "Test: $bn " fi + if [ "$ext" == sv ]; then + frontend="$frontend -sv" + fi + rm -f ${bn}.{err,log,skip} mkdir -p ${bn}.out rm -rf ${bn}.out/* @@ -108,16 +144,27 @@ do cd ${bn}.out fn=$(basename $fn) bn=$(basename $bn) + refext=v - egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.v + rm -f ${bn}_ref.fir + if [[ "$ext" == "v" ]]; then + egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext} + elif [[ "$ext" == "aig" ]] || [[ "$ext" == "aag" ]]; then + $abcprog -c "read_aiger ../${fn}; write ${bn}_ref.${refext}" + else + refext=$ext + cp ../${fn} ${bn}_ref.${refext} + fi if [ ! -f ../${bn}_tb.v ]; then - "$toolsdir"/../../yosys -f "$frontend $include_opts" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.v + "$toolsdir"/../../yosys -f "$frontend $include_opts -D_AUTOTB" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.${refext} else cp ../${bn}_tb.v ${bn}_tb.v fi if $genvcd; then sed -i 's,// \$dump,$dump,g' ${bn}_tb.v; fi - compile_and_run ${bn}_tb_ref ${bn}_out_ref ${bn}_tb.v ${bn}_ref.v $libs + compile_and_run ${bn}_tb_ref ${bn}_out_ref ${bn}_tb.v ${bn}_ref.${refext} $libs \ + "$toolsdir"/../../techlibs/common/simlib.v \ + "$toolsdir"/../../techlibs/common/simcells.v if $genvcd; then mv testbench.vcd ${bn}_ref.vcd; fi test_count=0 @@ -132,22 +179,29 @@ do test_count=$(( test_count + 1 )) } - if [ "$frontend" = "verific" -o "$frontend" = "verific_gates" ] && grep -q VERIFIC-SKIP ${bn}_ref.v; then + if [ "$frontend" = "verific" -o "$frontend" = "verific_gates" ] && grep -q VERIFIC-SKIP ${bn}_ref.${refext}; then touch ../${bn}.skip return fi if [ -n "$scriptfiles" ]; then - test_passes -f "$frontend $include_opts" ${bn}_ref.v $scriptfiles + test_passes -f "$frontend $include_opts" ${bn}_ref.${refext} $scriptfiles elif [ -n "$scriptopt" ]; then - test_passes -f "$frontend $include_opts" -p "$scriptopt" ${bn}_ref.v + test_passes -f "$frontend $include_opts" -p "$scriptopt" ${bn}_ref.${refext} elif [ "$frontend" = "verific" ]; then - test_passes -p "verific -vlog2k ${bn}_ref.v; verific -import -all; opt; memory;;" + test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -all; opt; memory;;" elif [ "$frontend" = "verific_gates" ]; then - test_passes -p "verific -vlog2k ${bn}_ref.v; verific -import -gates -all; opt; memory;;" + test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -gates -all; opt; memory;;" else - test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.v - test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.v + test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.${refext} + test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.${refext} + if [ -n "$firrtl2verilog" ]; then + if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then + "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt; memory; opt; fsm; opt -full -fine; pmuxtree" ${bn}_ref.${refext} + $firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v + test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v + fi + fi fi touch ../${bn}.log } @@ -160,14 +214,18 @@ do ( set -ex; body; ) > ${bn}.err 2>&1 fi + did_firrtl="" + if [ -f ${bn}.out/${bn}_ref.fir ]; then + did_firrtl="+FIRRTL " + fi if [ -f ${bn}.log ]; then mv ${bn}.err ${bn}.log - echo "${status_prefix}-> ok" + echo "${status_prefix}${did_firrtl}-> ok" elif [ -f ${bn}.skip ]; then mv ${bn}.err ${bn}.skip echo "${status_prefix}-> skip" else - echo "${status_prefix}-> ERROR!" + echo "${status_prefix}${did_firrtl}-> ERROR!" if $warn_iverilog_git; then echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of Icarus Verilog." fi diff --git a/tests/various/.gitignore b/tests/various/.gitignore index 397b4a76..7b3e8c68 100644 --- a/tests/various/.gitignore +++ b/tests/various/.gitignore @@ -1 +1,2 @@ -*.log +/*.log +/*.out diff --git a/tests/various/attrib05_port_conn.v b/tests/various/attrib05_port_conn.v new file mode 100644 index 00000000..e20e6631 --- /dev/null +++ b/tests/various/attrib05_port_conn.v @@ -0,0 +1,21 @@ +module bar(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output reg out; + + always @(posedge clk) + if (rst) out <= 1'd0; + else out <= ~inp; + +endmodule + +module foo(clk, rst, inp, out); + input wire clk; + input wire rst; + input wire inp; + output wire out; + + bar bar_instance ( (* clock_connected *) clk, rst, (* this_is_the_input *) inp, out); +endmodule + diff --git a/tests/various/attrib05_port_conn.ys b/tests/various/attrib05_port_conn.ys new file mode 100644 index 00000000..27a01673 --- /dev/null +++ b/tests/various/attrib05_port_conn.ys @@ -0,0 +1,2 @@ +# Read and parse Verilog file +read_verilog attrib05_port_conn.v diff --git a/tests/various/attrib07_func_call.v b/tests/various/attrib07_func_call.v new file mode 100644 index 00000000..f55ef231 --- /dev/null +++ b/tests/various/attrib07_func_call.v @@ -0,0 +1,21 @@ +function [7:0] do_add; + input [7:0] inp_a; + input [7:0] inp_b; + + do_add = inp_a + inp_b; + +endfunction + +module foo(clk, rst, inp_a, inp_b, out); + input wire clk; + input wire rst; + input wire [7:0] inp_a; + input wire [7:0] inp_b; + output wire [7:0] out; + + always @(posedge clk) + if (rst) out <= 0; + else out <= do_add (* combinational_adder *) (inp_a, inp_b); + +endmodule + diff --git a/tests/various/attrib07_func_call.ys b/tests/various/attrib07_func_call.ys new file mode 100644 index 00000000..77482765 --- /dev/null +++ b/tests/various/attrib07_func_call.ys @@ -0,0 +1,2 @@ +# Read and parse Verilog file +read_verilog attrib07_func_call.v diff --git a/tests/various/chparam.sh b/tests/various/chparam.sh new file mode 100644 index 00000000..9bb8d81d --- /dev/null +++ b/tests/various/chparam.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +trap 'echo "ERROR in chparam.sh" >&2; exit 1' ERR + +cat > chparam1.sv << "EOT" +module top #( + parameter [31:0] X = 0 +) ( + input [31:0] din, + output [31:0] dout +); + assign dout = X-din; +endmodule + +module top_props #( + parameter [31:0] X = 0 +) ( + input [31:0] dout +); + always @* assert (dout != X); +endmodule + +bind top top_props #(.X(123456789)) props (.*); +EOT + +cat > chparam2.sv << "EOT" +module top #( + parameter [31:0] X = 0 +) ( + input [31:0] din, + output [31:0] dout +); + assign dout = X-din; + always @* assert (dout != 123456789); +endmodule +EOT + +if ../../yosys -q -p 'verific -sv chparam1.sv'; then + ../../yosys -q -p 'verific -sv chparam1.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ + -p 'sat -verify -prove-asserts -show-ports -set din[0] 1' \ + -p 'sat -falsify -prove-asserts -show-ports -set din[0] 0' + + ../../yosys -q -p 'verific -sv chparam2.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ + -p 'sat -verify -prove-asserts -show-ports -set din[0] 1' \ + -p 'sat -falsify -prove-asserts -show-ports -set din[0] 0' +fi +../../yosys -q -p 'read_verilog -sv chparam2.sv; hierarchy -chparam X 123123123 -top top; prep -flatten' \ + -p 'sat -verify -prove-asserts -show-ports -set din[0] 1' \ + -p 'sat -falsify -prove-asserts -show-ports -set din[0] 0' + +rm chparam1.sv +rm chparam2.sv diff --git a/tests/various/elab_sys_tasks.sv b/tests/various/elab_sys_tasks.sv new file mode 100644 index 00000000..774d85b3 --- /dev/null +++ b/tests/various/elab_sys_tasks.sv @@ -0,0 +1,30 @@ +module test; +localparam X=1; +genvar i; +generate +if (X == 1) + $info("X is 1"); +if (X == 1) + $warning("X is 1"); +else + $error("X is not 1"); +case (X) + 1: $info("X is 1 in a case statement"); +endcase +//case (X-1) +// 1: $warn("X is 2"); +// default: $warn("X might be anything in a case statement"); +//endcase +for (i = 0; i < 3; i = i + 1) +begin + case(i) + 0: $info; + 1: $warning; + default: $info("default case statemnent"); + endcase +end + +$info("This is a standalone $info(). Next $info has no parameters"); +$info; +endgenerate +endmodule diff --git a/tests/various/elab_sys_tasks.ys b/tests/various/elab_sys_tasks.ys new file mode 100644 index 00000000..45bee3a6 --- /dev/null +++ b/tests/various/elab_sys_tasks.ys @@ -0,0 +1 @@ +read_verilog -sv elab_sys_tasks.sv diff --git a/tests/various/hierarchy.sh b/tests/various/hierarchy.sh new file mode 100644 index 00000000..9dbd1c89 --- /dev/null +++ b/tests/various/hierarchy.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# Simple test of hierarchy -auto-top. + +set -e + +echo -n " TOP first - " +../../yosys -s - <<- EOY | grep "Automatically selected TOP as design top module" + read_verilog << EOV + module TOP(a, y); + input a; + output [31:0] y; + + aoi12 p [31:0] (a, y); + endmodule + + module aoi12(a, y); + input a; + output y; + assign y = ~a; + endmodule + EOV + hierarchy -auto-top +EOY + +echo -n " TOP last - " +../../yosys -s - <<- EOY | grep "Automatically selected TOP as design top module" + read_verilog << EOV + module aoi12(a, y); + input a; + output y; + assign y = ~a; + endmodule + + module TOP(a, y); + input a; + output [31:0] y; + + aoi12 foo (a, y); + endmodule + EOV + hierarchy -auto-top +EOY + +echo -n " no explicit top - " +../../yosys -s - <<- EOY | grep "Automatically selected noTop as design top module." + read_verilog << EOV + module aoi12(a, y); + input a; + output y; + assign y = ~a; + endmodule + + module noTop(a, y); + input a; + output [31:0] y; + assign y = a; + endmodule + EOV + hierarchy -auto-top +EOY diff --git a/tests/various/muxcover.ys b/tests/various/muxcover.ys index 7ac460f1..67e9625e 100644 --- a/tests/various/muxcover.ys +++ b/tests/various/muxcover.ys @@ -13,7 +13,7 @@ read_verilog -formal <<EOT EOT -## Examle usage for "pmuxtree" and "muxcover" +## Example usage for "pmuxtree" and "muxcover" proc pmuxtree @@ -49,3 +49,462 @@ hierarchy -top equiv equiv_simple -undef equiv_status -assert +## Partial matching MUX4 + +design -reset +read_verilog -formal <<EOT +module mux_if_bal_3_1 #(parameter N=3, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {{W{{1'bx}}}}; + if (s[0] == 1'b0) + if (s[1] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[1] == 1'b0) + o <= i[2*W+:W]; +end +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux4=150 +select -assert-count 0 t:$_MUX_ +select -assert-count 1 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX4_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## Partial matching MUX8 + +design -reset +read_verilog -formal <<EOT +module mux_if_bal_5_1 #(parameter N=5, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {{W{{1'bx}}}}; + if (s[0] == 1'b0) + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[2] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[4*W+:W]; +end +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux4=150 -mux8=200 +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 1 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX8_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## Partial matching MUX16 + +design -reset +read_verilog -formal <<EOT +module mux_if_bal_9_1 #(parameter N=9, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {{W{{1'bx}}}}; + if (s[0] == 1'b0) + if (s[1] == 1'b0) + if (s[2] == 1'b0) + if (s[3] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[3] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + if (s[2] == 1'b0) + if (s[3] == 1'b0) + o <= i[4*W+:W]; + else + o <= i[5*W+:W]; + else + if (s[3] == 1'b0) + o <= i[6*W+:W]; + else + o <= i[7*W+:W]; + else + if (s[1] == 1'b0) + if (s[2] == 1'b0) + if (s[3] == 1'b0) + o <= i[8*W+:W]; +end +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux4=150 -mux8=200 -mux16=250 +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 1 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX16_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## MUX2 in MUX4 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux2in4(input [1:0] i, input s, output o); + assign o = s ? i[1] : i[0]; +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux4=99 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 1 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX4_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## MUX2 in MUX8 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux2in8(input [1:0] i, input s, output o); + assign o = s ? i[1] : i[0]; +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux8=99 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 1 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX8_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## MUX4 in MUX8 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux4in8(input [3:0] i, input [1:0] s, output o); + assign o = s[1] ? (s[0] ? i[3] : i[2]) : (s[0] ? i[1] : i[0]); +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux8=299 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 1 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX8_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## MUX2 in MUX16 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux2in16(input [1:0] i, input s, output o); + assign o = s ? i[1] : i[0]; +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux16=99 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 1 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX16_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## MUX4 in MUX16 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux4in16(input [3:0] i, input [1:0] s, output o); + assign o = s[1] ? (s[0] ? i[3] : i[2]) : (s[0] ? i[1] : i[0]); +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux16=299 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 1 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX16_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## MUX8 in MUX16 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux4in16(input [7:0] i, input [2:0] s, output o); + assign o = s[2] ? s[1] ? (s[0] ? i[3] : i[2]) : (s[0] ? i[1] : i[0]) + : s[1] ? (s[0] ? i[7] : i[6]) : (s[0] ? i[5] : i[4]); +endmodule +EOT +prep +design -save gold + +techmap +muxcover -mux16=699 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 1 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX16_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +## mux_if_bal_5_1 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux_if_bal_5_1 #(parameter N=5, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {{W{{1'bx}}}}; + if (s[0] == 1'b0) + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[2] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[4*W+:W]; +end +endmodule +EOT +prep +design -save gold + +wreduce +opt -full +techmap +muxcover -mux8=350 +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 1 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX8_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs -ignore_gold_x gold gate miter +sat -verify -prove-asserts -show-ports miter + +## mux_if_bal_5_1 (nodecode) :: https://github.com/YosysHQ/yosys/issues/1132 +design -load gold + +wreduce +opt -full +techmap +muxcover -mux8=350 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 1 t:$_MUX8_ +select -assert-count 0 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX8_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs -ignore_gold_x gold gate miter +sat -verify -prove-asserts -show-ports miter + +## mux_if_bal_9_1 :: https://github.com/YosysHQ/yosys/issues/1132 + +design -reset +read_verilog -formal <<EOT +module mux_if_bal_9_1 #(parameter N=9, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {{W{{1'bx}}}}; + if (s[3] == 1'b0) + if (s[2] == 1'b0) + if (s[1] == 1'b0) + if (s[0] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[0] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + if (s[1] == 1'b0) + if (s[0] == 1'b0) + o <= i[4*W+:W]; + else + o <= i[5*W+:W]; + else + if (s[0] == 1'b0) + o <= i[6*W+:W]; + else + o <= i[7*W+:W]; + else + if (s[2] == 1'b0) + if (s[1] == 1'b0) + if (s[0] == 1'b0) + o <= i[8*W+:W]; +end +endmodule +EOT +prep +design -save gold + +wreduce +opt -full +techmap +muxcover -mux16=750 +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 1 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX16_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs -ignore_gold_x gold gate miter +sat -verify -prove-asserts -show-ports miter + +## mux_if_bal_9_1 (nodecode) :: https://github.com/YosysHQ/yosys/issues/1132 + +design -load gold + +wreduce +opt -full +techmap +muxcover -mux16=750 -nodecode +clean +opt_expr -mux_bool +select -assert-count 0 t:$_MUX_ +select -assert-count 0 t:$_MUX4_ +select -assert-count 0 t:$_MUX8_ +select -assert-count 1 t:$_MUX16_ +techmap -map +/simcells.v t:$_MUX16_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs -ignore_gold_x gold gate miter +sat -verify -prove-asserts -show-ports miter diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v new file mode 100644 index 00000000..33ece1f1 --- /dev/null +++ b/tests/various/muxpack.v @@ -0,0 +1,259 @@ +module mux_if_unbal_4_1 #(parameter N=4, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* + if (s == 0) o <= i[0*W+:W]; + else if (s == 1) o <= i[1*W+:W]; + else if (s == 2) o <= i[2*W+:W]; + else if (s == 3) o <= i[3*W+:W]; + else o <= {W{1'bx}}; +endmodule + +module mux_if_unbal_5_3 #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {W{1'bx}}; + if (s == 0) o <= i[0*W+:W]; + if (s == 1) o <= i[1*W+:W]; + if (s == 2) o <= i[2*W+:W]; + if (s == 3) o <= i[3*W+:W]; + if (s == 4) o <= i[4*W+:W]; +end +endmodule + +module mux_if_unbal_5_3_invert #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* + if (s != 0) + if (s != 1) + if (s != 2) + if (s != 3) + if (s != 4) o <= i[4*W+:W]; + else o <= i[0*W+:W]; + else o <= i[3*W+:W]; + else o <= i[2*W+:W]; + else o <= i[1*W+:W]; + else o <= {W{1'bx}}; +endmodule + +module mux_if_unbal_5_3_width_mismatch #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {W{1'bx}}; + if (s == 0) o <= i[0*W+:W]; + if (s == 1) o <= i[1*W+:W]; + if (s == 2) o[W-2:0] <= i[2*W+:W-1]; + if (s == 3) o <= i[3*W+:W]; + if (s == 4) o <= i[4*W+:W]; +end +endmodule + +module mux_if_unbal_4_1_missing #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + if (s == 0) o <= i[0*W+:W]; +// else if (s == 1) o <= i[1*W+:W]; +// else if (s == 2) o <= i[2*W+:W]; + else if (s == 3) o <= i[3*W+:W]; + else o <= {W{1'bx}}; +end +endmodule + +module mux_if_unbal_5_3_order #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {W{1'bx}}; + if (s == 3) o <= i[3*W+:W]; + if (s == 2) o <= i[2*W+:W]; + if (s == 1) o <= i[1*W+:W]; + if (s == 4) o <= i[4*W+:W]; + if (s == 0) o <= i[0*W+:W]; +end +endmodule + +module mux_if_unbal_4_1_nonexcl #(parameter N=4, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* + if (s == 0) o <= i[0*W+:W]; + else if (s == 1) o <= i[1*W+:W]; + else if (s == 2) o <= i[2*W+:W]; + else if (s == 3) o <= i[3*W+:W]; + else if (s == 0) o <= {W{1'b0}}; + else o <= {W{1'bx}}; +endmodule + +module mux_if_unbal_5_3_nonexcl #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {W{1'bx}}; + if (s == 0) o <= i[0*W+:W]; + if (s == 1) o <= i[1*W+:W]; + if (s == 2) o <= i[2*W+:W]; + if (s == 3) o <= i[3*W+:W]; + if (s == 4) o <= i[4*W+:W]; + if (s == 0) o <= i[2*W+:W]; +end +endmodule + +module mux_case_unbal_8_7#(parameter N=8, parameter W=7) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* begin + o <= {W{1'bx}}; + case (s) + 0: o <= i[0*W+:W]; + default: + case (s) + 1: o <= i[1*W+:W]; + 2: o <= i[2*W+:W]; + default: + case (s) + 3: o <= i[3*W+:W]; + 4: o <= i[4*W+:W]; + 5: o <= i[5*W+:W]; + default: + case (s) + 6: o <= i[6*W+:W]; + default: o <= i[7*W+:W]; + endcase + endcase + endcase + endcase +end +endmodule + +module mux_if_bal_8_2 #(parameter N=8, parameter W=2) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* + if (s[0] == 1'b0) + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[2] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[4*W+:W]; + else + o <= i[5*W+:W]; + else + if (s[2] == 1'b0) + o <= i[6*W+:W]; + else + o <= i[7*W+:W]; +endmodule + +module mux_if_bal_5_1 #(parameter N=5, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* + if (s[0] == 1'b0) + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[2] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + o <= i[4*W+:W]; +endmodule + +module cliffordwolf_nonexclusive_select ( + input wire x, y, z, + input wire a, b, c, d, + output reg o +); + always @* begin + o = a; + if (x) o = b; + if (y) o = c; + if (z) o = d; + end +endmodule + +module cliffordwolf_freduce ( + input wire [1:0] s, + input wire a, b, c, d, + output reg [3:0] o +); + always @* begin + o = {4{a}}; + if (s == 0) o = {3{b}}; + if (s == 1) o = {2{c}}; + if (s == 2) o = d; + end +endmodule + +module case_nonexclusive_select ( + input wire [1:0] x, y, + input wire a, b, c, d, e, + output reg o +); + always @* begin + case (x) + 0: o = b; + 2: o = b; + 1: o = c; + default: begin + o = a; + if (y == 0) o = d; + if (y == 1) o = e; + end + endcase + end +endmodule + +module case_nonoverlap ( + input wire [2:0] x, + input wire a, b, c, d, e, + output reg o +); + always @* begin + case (x) + 0, 2: o = b; // Creates $reduce_or + 1: o = c; + default: + case (x) + 3: o = d; 4: o = d; // Creates $reduce_or + 5: o = e; + default: o = 1'b0; + endcase + endcase + end +endmodule + +module case_overlap ( + input wire [2:0] x, + input wire a, b, c, d, e, + output reg o +); + always @* begin + case (x) + 0, 2: o = b; // Creates $reduce_or + 1: o = c; + default: + case (x) + 0: o = 1'b1; // OVERLAP! + 3, 4: o = d; // Creates $reduce_or + 5: o = e; + default: o = 1'b0; + endcase + endcase + end +endmodule + +module case_overlap2 ( + input wire [2:0] x, + input wire a, b, c, d, e, + output reg o +); + always @* begin + case (x) + 0: o = b; 2: o = b; // Creates $reduce_or + 1: o = c; + default: + case (x) + 0: o = d; 2: o = d; // Creates $reduce_or + 3: o = d; 4: o = d; // Creates $reduce_or + 5: o = e; + default: o = 1'b0; + endcase + endcase + end +endmodule diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys new file mode 100644 index 00000000..af23fcec --- /dev/null +++ b/tests/various/muxpack.ys @@ -0,0 +1,268 @@ +read_verilog muxpack.v +design -save read + +hierarchy -top mux_if_unbal_4_1 +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_unbal_5_3 +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +# TODO: Currently ExclusiveDatabase only analyses $eq cells +#design -load read +#hierarchy -top mux_if_unbal_5_3_invert +#prep +#design -save gold +#muxpack +#opt +#stat +#select -assert-count 0 t:$mux +#select -assert-count 1 t:$pmux +#design -stash gate +#design -import gold -as gold +#design -import gate -as gate +#miter -equiv -flatten -make_assert -make_outputs gold gate miter +#sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_unbal_5_3_width_mismatch +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 2 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_unbal_4_1_missing +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_unbal_5_3_order +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_unbal_4_1_nonexcl +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_unbal_5_3_nonexcl +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_case_unbal_8_7 +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_bal_8_2 +prep +design -save gold +muxpack +opt +stat +select -assert-count 7 t:$mux +select -assert-count 0 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_bal_5_1 +prep +design -save gold +muxpack +opt +stat +select -assert-count 4 t:$mux +select -assert-count 0 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top cliffordwolf_nonexclusive_select +prep +design -save gold +muxpack +opt +stat +select -assert-count 3 t:$mux +select -assert-count 0 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +#design -load read +#hierarchy -top cliffordwolf_freduce +#prep +#design -save gold +#proc; opt; freduce; opt +#show +#muxpack +#opt +#stat +#select -assert-count 0 t:$mux +#select -assert-count 1 t:$pmux +#design -stash gate +#design -import gold -as gold +#design -import gate -as gate +#miter -equiv -flatten -make_assert -make_outputs gold gate miter +#sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top case_nonexclusive_select +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 2 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top case_nonoverlap +#prep # Do not prep otherwise $pmux's overlapping entry will get removed +proc +design -save gold +opt -fast -mux_undef +select -assert-count 2 t:$pmux +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top case_overlap +#prep # Do not prep otherwise $pmux's overlapping entry will get removed +proc +design -save gold +opt -fast -mux_undef +select -assert-count 2 t:$pmux +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 2 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top case_overlap2 +#prep # Do not prep otherwise $pmux's overlapping entry will get removed +proc +design -save gold +opt -fast -mux_undef +select -assert-count 2 t:$pmux +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 2 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter diff --git a/tests/various/opt_rmdff.v b/tests/various/opt_rmdff.v new file mode 100644 index 00000000..b1c06703 --- /dev/null +++ b/tests/various/opt_rmdff.v @@ -0,0 +1,50 @@ +module opt_rmdff_test (input C, input D, input E, output [29:0] Q); +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove0 (.CLK(C), .D(D), .EN(1'b0), .Q(Q[0])); // EN is never active +(* init = "1'b1" *) wire Q1; assign Q[1] = Q1; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove1 (.CLK(C), .D(D), .EN(1'b0), .Q(Q1)); // EN is never active +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove2 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[2])); // EN is don't care +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep3 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[3])); // EN is always active +(* init = "1'b0" *) wire Q4; assign Q[4] = Q4; +\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) keep4 (.CLK(C), .D(D), .EN(1'b1), .Q(Q4)); // EN is always active +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove5 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[5])); // EN is never active +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove6 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[6])); // EN is don't care +(* init = "1'b0" *) wire Q7; assign Q[7] = Q7; +\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(0)) keep7 (.CLK(C), .D(D), .EN(E), .Q(Q7)); // EN is non constant + +\$_DFFE_PP_ remove8 (.C(C), .D(D), .E(1'b0), .Q(Q[8])); // EN is never active +(* init = "1'b1" *) wire Q9; assign Q[9] = Q9; +\$_DFFE_PP_ remove9 (.C(C), .D(D), .E(1'b0), .Q(Q9)); // EN is never active +\$_DFFE_PP_ remove10 (.C(C), .D(D), .E(1'bx), .Q(Q[10])); // EN is don't care +\$_DFFE_PP_ keep11 (.C(C), .D(D), .E(1'b1), .Q(Q[11])); // EN is always active +(* init = "1'b0" *) wire Q12; assign Q[12] = Q12; +\$_DFFE_PP_ keep12 (.C(C), .D(D), .E(1'b1), .Q(Q12)); // EN is always active + +\$_DFFE_NN_ remove13 (.C(C), .D(D), .E(1'b1), .Q(Q[13])); // EN is never active +(* init = "1'b1" *) wire Q14; assign Q[14] = Q14; +\$_DFFE_NN_ remove14 (.C(C), .D(D), .E(1'b1), .Q(Q14)); // EN is never active +\$_DFFE_NN_ remove15 (.C(C), .D(D), .E(1'bx), .Q(Q[15])); // EN is don't care +\$_DFFE_NN_ keep16 (.C(C), .D(D), .E(1'b0), .Q(Q[16])); // EN is always active +(* init = "1'b0" *) wire Q17; assign Q[17] = Q17; +\$_DFFE_NN_ keep17 (.C(C), .D(D), .E(1'b0), .Q(Q17)); // EN is always active + +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove18 (.CLK(1'b0), .D(D), .EN(E), .Q(Q[18])); // CLK is constant +(* init = "1'b1" *) wire Q19; assign Q[19] = Q19; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove19 (.CLK(1'b1), .D(D), .EN(E), .Q(Q19)); // CLK is constant +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove20 (.CLK(C), .D(1'bx), .EN(E), .Q(Q[20])); // D is undriven, Q has no initial value +(* init = "1'b0" *) wire Q21; assign Q[21] = Q21; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep21 (.CLK(C), .D(1'bx), .EN(E), .Q(Q21)); // D is undriven, Q has initial value +//\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) remove22 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q[22])); // D is constant, no initial Q value, EN is always active +// // (TODO, Q starts with 1'bx and becomes 1'b0) +(* init = "1'b0" *) wire Q23; assign Q[23] = Q23; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) noenable23 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q23)); // D is constant, initial Q value same as D, EN is always active +(* init = "1'b1" *) wire Q24; assign Q[24] = Q24; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) keep24 (.CLK(C), .D(1'b0), .EN(1'b0), .Q(Q24)); // D is constant, initial Q value NOT same as D, EN is always active +(* init = "1'b1" *) wire Q25; assign Q[25] = Q25; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove25 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q25)); // D is constant, EN is never active +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove26 (.CLK(C), .D(Q[26]), .EN(1'b1), .Q(Q[26])); // D is Q, EN is always active +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove27 (.CLK(C), .D(Q[27]), .EN(1'b1), .Q(Q[27])); // D is Q, EN is never active, but no initial value +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove28 (.CLK(C), .D(Q[28]), .EN(E), .Q(Q[28])); // EN is nonconst, but no initial value +(* init = "1'b1" *) wire Q29; assign Q[29] = Q29; +\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep29 (.CLK(C), .D(Q[29]), .EN(1'b1), .Q(Q29)); // EN is always active, but with initial value + +endmodule diff --git a/tests/various/opt_rmdff.ys b/tests/various/opt_rmdff.ys new file mode 100644 index 00000000..081f8178 --- /dev/null +++ b/tests/various/opt_rmdff.ys @@ -0,0 +1,26 @@ +read_verilog -icells opt_rmdff.v +prep +design -stash gold +read_verilog -icells opt_rmdff.v +proc +opt_rmdff + +select -assert-count 0 c:remove* +select -assert-min 7 c:keep* +select -assert-count 0 t:$dffe 7:$_DFFE_* %u c:noenable* %i + +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +equiv_make gold gate equiv +hierarchy -top equiv +equiv_simple -undef +equiv_status -assert + +design -load gold +stat + +design -load gate +stat diff --git a/tests/various/pmux2shiftx.v b/tests/various/pmux2shiftx.v new file mode 100644 index 00000000..56339408 --- /dev/null +++ b/tests/various/pmux2shiftx.v @@ -0,0 +1,44 @@ +module pmux2shiftx_test ( + input [2:0] S1, + input [5:0] S2, + input [1:0] S3, + input [9:0] A, B, C, D, D, E, F, G, H, + input [9:0] I, J, K, L, M, N, O, P, Q, + output reg [9:0] X +); + always @* begin + case (S1) + 3'd 0: X = A; + 3'd 1: X = B; + 3'd 2: X = C; + 3'd 3: X = D; + 3'd 4: X = E; + 3'd 5: X = F; + 3'd 6: X = G; + 3'd 7: X = H; + endcase + case (S2) + 6'd 45: X = I; + 6'd 47: X = J; + 6'd 49: X = K; + 6'd 55: X = L; + 6'd 57: X = M; + 6'd 59: X = N; + endcase + case (S3) + 2'd 1: X = O; + 2'd 2: X = P; + 2'd 3: X = Q; + endcase + end +endmodule + +module issue01135(input [7:0] i, output o); +always @* +case (i[6:3]) + 4: o <= i[0]; + 3: o <= i[2]; + 7: o <= i[3]; + default: o <= 1'b0; +endcase +endmodule diff --git a/tests/various/pmux2shiftx.ys b/tests/various/pmux2shiftx.ys new file mode 100644 index 00000000..51ee2f7b --- /dev/null +++ b/tests/various/pmux2shiftx.ys @@ -0,0 +1,39 @@ +read_verilog pmux2shiftx.v +design -save read + +hierarchy -top pmux2shiftx_test +prep +design -save gold + +pmux2shiftx -min_density 70 + +opt + +stat +# show -width +select -assert-count 1 t:$sub +select -assert-count 1 t:$mux +select -assert-count 1 t:$shift +select -assert-count 3 t:$shiftx + +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +#design -load gold +#stat +# +#design -load gate +#stat + +design -load read +hierarchy -top issue01135 +proc +pmux2shiftx -norange +opt -full +select -assert-count 0 t:$shift* +select -assert-count 1 t:$pmux diff --git a/tests/various/run-test.sh b/tests/various/run-test.sh index 67e1beb2..d49553ed 100755 --- a/tests/various/run-test.sh +++ b/tests/various/run-test.sh @@ -1,6 +1,14 @@ -#!/bin/bash +#!/usr/bin/env bash set -e for x in *.ys; do echo "Running $x.." ../../yosys -ql ${x%.ys}.log $x done +# Run any .sh files in this directory (with the exception of the file - run-test.sh +shell_tests=$(echo *.sh | sed -e 's/run-test.sh//') +if [ "$shell_tests" ]; then + for s in $shell_tests; do + echo "Running $s.." + bash $s + done +fi diff --git a/tests/various/shregmap.v b/tests/various/shregmap.v new file mode 100644 index 00000000..604c2c97 --- /dev/null +++ b/tests/various/shregmap.v @@ -0,0 +1,48 @@ +module shregmap_static_test(input i, clk, output [1:0] q); +reg head = 1'b0; +reg [3:0] shift1 = 4'b0000; +reg [3:0] shift2 = 4'b0000; + +always @(posedge clk) begin + head <= i; + shift1 <= {shift1[2:0], head}; + shift2 <= {shift2[2:0], head}; +end + +assign q = {shift2[3], shift1[3]}; +endmodule + +module $__SHREG_DFF_P_(input C, D, output Q); +parameter DEPTH = 1; +parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}}; +reg [DEPTH-1:0] r = INIT; +always @(posedge C) + r <= { r[DEPTH-2:0], D }; +assign Q = r[DEPTH-1]; +endmodule + +module shregmap_variable_test(input i, clk, input [1:0] l1, l2, output [1:0] q); +reg head = 1'b0; +reg [3:0] shift1 = 4'b0000; +reg [3:0] shift2 = 4'b0000; + +always @(posedge clk) begin + head <= i; + shift1 <= {shift1[2:0], head}; + shift2 <= {shift2[2:0], head}; +end + +assign q = {shift2[l2], shift1[l1]}; +endmodule + +module $__XILINX_SHREG_(input C, D, input [1:0] L, output Q); +parameter CLKPOL = 1; +parameter ENPOL = 1; +parameter DEPTH = 1; +parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}}; +reg [DEPTH-1:0] r = INIT; +wire clk = C ^ CLKPOL; +always @(posedge C) + r <= { r[DEPTH-2:0], D }; +assign Q = r[L]; +endmodule diff --git a/tests/various/shregmap.ys b/tests/various/shregmap.ys new file mode 100644 index 00000000..d644a88a --- /dev/null +++ b/tests/various/shregmap.ys @@ -0,0 +1,66 @@ +read_verilog shregmap.v +design -save read + +design -copy-to model $__SHREG_DFF_P_ +hierarchy -top shregmap_static_test +prep +design -save gold + +techmap +shregmap -init + +opt + +stat +# show -width +select -assert-count 1 t:$_DFF_P_ +select -assert-count 2 t:$__SHREG_DFF_P_ + +design -stash gate + +design -import gold -as gold +design -import gate -as gate +design -copy-from model -as $__SHREG_DFF_P_ \$__SHREG_DFF_P_ +prep + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -seq 5 miter + +design -load gold +stat + +design -load gate +stat + +########## + +design -load read +design -copy-to model $__XILINX_SHREG_ +hierarchy -top shregmap_variable_test +prep +design -save gold + +simplemap t:$dff t:$dffe +shregmap -tech xilinx + +stat +# show -width +write_verilog -noexpr -norename +select -assert-count 1 t:$_DFF_P_ +select -assert-count 2 t:$__XILINX_SHREG_ + +design -stash gate + +design -import gold -as gold +design -import gate -as gate +design -copy-from model -as $__XILINX_SHREG_ \$__XILINX_SHREG_ +prep + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -seq 5 miter + +design -load gold +stat + +design -load gate +stat diff --git a/tests/various/signext.ys b/tests/various/signext.ys new file mode 100644 index 00000000..0c8d671e --- /dev/null +++ b/tests/various/signext.ys @@ -0,0 +1,33 @@ + +read_verilog -formal <<EOT +module gate(input clk, output [32:0] o, p, q, r, s, t, u); +assign o = 'bx; +assign p = 1'bx; +assign q = 'bz; +assign r = 1'bz; +assign s = 1'b0; +assign t = 'b1; +assign u = -'sb1; +endmodule +EOT + +proc + +## Equivalence checking + +read_verilog -formal <<EOT +module gold(input clk, output [32:0] o, p, q, r, s, t, u); +assign o = {33{1'bx}}; +assign p = {{32{1'b0}}, 1'bx}; +assign q = {33{1'bz}}; +assign r = {{32{1'b0}}, 1'bz}; +assign s = {33{1'b0}}; +assign t = {{32{1'b0}}, 1'b1}; +assign u = {33{1'b1}}; +endmodule +EOT + +proc + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -enable_undef miter diff --git a/tests/various/specify.v b/tests/various/specify.v new file mode 100644 index 00000000..5d44d78f --- /dev/null +++ b/tests/various/specify.v @@ -0,0 +1,39 @@ +module test ( + input EN, CLK, + input [3:0] D, + output reg [3:0] Q +); + always @(posedge CLK) + if (EN) Q <= D; + + specify +`ifndef SKIP_UNSUPPORTED_IGN_PARSER_CONSTRUCTS + if (EN) (posedge CLK *> (Q : D)) = (1, 2:3:4); + $setup(D, posedge CLK &&& EN, 5); + $hold(posedge CLK, D &&& EN, 6); +`endif + endspecify +endmodule + +module test2 ( + input A, B, + output Q +); + xor (Q, A, B); + specify + //specparam T_rise = 1; + //specparam T_fall = 2; + `define T_rise 1 + `define T_fall 2 + (A => Q) = (`T_rise,`T_fall); + //(B => Q) = (`T_rise+`T_fall)/2.0; + (B => Q) = 1.5; + endspecify +endmodule + +module issue01144(input clk, d, output q); +specify + (posedge clk => (q +: d)) = (3,1); + (posedge clk *> (q +: d)) = (3,1); +endspecify +endmodule diff --git a/tests/various/specify.ys b/tests/various/specify.ys new file mode 100644 index 00000000..00597e1e --- /dev/null +++ b/tests/various/specify.ys @@ -0,0 +1,58 @@ +read_verilog -specify specify.v +prep +cd test +select t:$specify2 -assert-count 0 +select t:$specify3 -assert-count 1 +select t:$specrule -assert-count 2 +cd test2 +select t:$specify2 -assert-count 2 +select t:$specify3 -assert-count 0 +select t:$specrule -assert-count 0 +cd +write_verilog specify.out +design -stash gold + +read_verilog -specify specify.out +prep +cd test +select t:$specify2 -assert-count 0 +select t:$specify3 -assert-count 1 +select t:$specrule -assert-count 2 +cd test2 +select t:$specify2 -assert-count 2 +select t:$specify3 -assert-count 0 +select t:$specrule -assert-count 0 +cd +design -stash gate + +design -copy-from gold -as gold test +design -copy-from gate -as gate test +rename -hide +rename -enumerate -pattern A_% t:$specify3 +rename -enumerate -pattern B_% t:$specrule r:TYPE=$setup %i +rename -enumerate -pattern C_% t:$specrule r:TYPE=$hold %i +select n:A_* -assert-count 2 +select n:B_* -assert-count 2 +select n:C_* -assert-count 2 +equiv_make gold gate equiv +hierarchy -top equiv +equiv_struct +equiv_induct -seq 5 +equiv_status -assert +design -reset + +design -copy-from gold -as gold test2 +design -copy-from gate -as gate test2 +rename -hide +rename -enumerate -pattern A_% t:$specify2 r:T_RISE_TYP=1 %i +rename -enumerate -pattern B_% t:$specify2 n:A_* %d +select n:A_* -assert-count 2 +select n:B_* -assert-count 2 +equiv_make gold gate equiv +hierarchy -top equiv +equiv_struct +equiv_induct -seq 5 +equiv_status -assert +design -reset + +read_verilog -DSKIP_UNSUPPORTED_IGN_PARSER_CONSTRUCTS specify.v |