aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/arch/anlogic/blockram.ys13
-rw-r--r--tests/arch/anlogic/lutram.ys2
-rw-r--r--tests/arch/ecp5/memories.ys153
-rw-r--r--tests/arch/efinix/lutram.ys13
-rw-r--r--tests/arch/gatemate/.gitignore4
-rw-r--r--tests/arch/gatemate/gen_luttrees.py48
-rw-r--r--tests/arch/gatemate/luttrees.v752
-rw-r--r--tests/arch/gatemate/luttrees.ys13
-rw-r--r--tests/arch/gowin/lutram.ys5
-rw-r--r--tests/arch/ice40/memories.ys56
-rw-r--r--tests/arch/intel_alm/blockram.ys3
-rw-r--r--tests/arch/nexus/blockram.ys4
-rw-r--r--tests/arch/xilinx/attributes_test.ys12
-rw-r--r--tests/arch/xilinx/blockram.ys32
-rw-r--r--tests/arch/xilinx/lutram.ys17
-rw-r--r--tests/arch/xilinx/tribuf.sh4
-rw-r--r--tests/blif/bug3374.ys4
-rw-r--r--tests/bram/run-single.sh2
-rw-r--r--tests/memlib/.gitignore5
-rw-r--r--tests/memlib/generate.py900
-rw-r--r--tests/memlib/memlib_block_sdp.txt12
-rw-r--r--tests/memlib/memlib_block_sdp.v26
-rw-r--r--tests/memlib/memlib_block_sdp_1clk.txt22
-rw-r--r--tests/memlib/memlib_block_sdp_1clk.v36
-rw-r--r--tests/memlib/memlib_block_sp.txt95
-rw-r--r--tests/memlib/memlib_block_sp.v81
-rw-r--r--tests/memlib/memlib_block_tdp.txt10
-rw-r--r--tests/memlib/memlib_block_tdp.v38
-rw-r--r--tests/memlib/memlib_lut.txt12
-rw-r--r--tests/memlib/memlib_lut.v30
-rw-r--r--tests/memlib/memlib_wide_read.txt12
-rw-r--r--tests/memlib/memlib_wide_read.v25
-rw-r--r--tests/memlib/memlib_wide_sdp.txt17
-rw-r--r--tests/memlib/memlib_wide_sdp.v45
-rw-r--r--tests/memlib/memlib_wide_sp.txt22
-rw-r--r--tests/memlib/memlib_wide_sp.v54
-rw-r--r--tests/memlib/memlib_wide_write.txt13
-rw-r--r--tests/memlib/memlib_wide_write.v29
-rwxr-xr-xtests/memlib/run-test.sh15
-rwxr-xr-xtests/memories/run-test.sh2
-rw-r--r--tests/opt/bug3117.ys34
-rw-r--r--tests/opt/memory_bmux2rom.ys27
-rw-r--r--tests/opt/opt_merge_init.ys50
-rw-r--r--tests/opt/opt_reduce_bmux.ys117
-rw-r--r--tests/opt/opt_reduce_demux.ys91
-rw-r--r--tests/proc/proc_rom.ys189
-rw-r--r--tests/sat/.gitignore2
-rw-r--r--tests/sat/alu.v79
-rw-r--r--tests/sat/grom.ys9
-rw-r--r--tests/sat/grom_computer.v31
-rw-r--r--tests/sat/grom_cpu.v747
-rw-r--r--tests/sat/ram_memory.v39
-rw-r--r--tests/sat/sim_counter.ys48
-rw-r--r--tests/sim/.gitignore6
-rw-r--r--tests/sim/adff.v7
-rw-r--r--tests/sim/adffe.v8
-rw-r--r--tests/sim/adlatch.v8
-rw-r--r--tests/sim/aldff.v7
-rw-r--r--tests/sim/aldffe.v8
-rw-r--r--tests/sim/dff.v4
-rw-r--r--tests/sim/dffe.v5
-rw-r--r--tests/sim/dffsr.v9
-rw-r--r--tests/sim/dlatch.v6
-rw-r--r--tests/sim/dlatchsr.v11
-rwxr-xr-xtests/sim/run-test.sh12
-rw-r--r--tests/sim/sdff.v7
-rw-r--r--tests/sim/sdffce.v8
-rw-r--r--tests/sim/sdffe.v8
-rw-r--r--tests/sim/sim_adff.ys6
-rw-r--r--tests/sim/sim_adffe.ys6
-rw-r--r--tests/sim/sim_adlatch.ys10
-rw-r--r--tests/sim/sim_aldff.ys6
-rw-r--r--tests/sim/sim_aldffe.ys6
-rw-r--r--tests/sim/sim_dff.ys6
-rw-r--r--tests/sim/sim_dffe.ys6
-rw-r--r--tests/sim/sim_dffsr.ys6
-rw-r--r--tests/sim/sim_dlatch.ys6
-rw-r--r--tests/sim/sim_dlatchsr.ys10
-rw-r--r--tests/sim/sim_sdff.ys6
-rw-r--r--tests/sim/sim_sdffce.ys6
-rw-r--r--tests/sim/sim_sdffe.ys6
-rwxr-xr-xtests/sim/tb/tb_adff.v40
-rwxr-xr-xtests/sim/tb/tb_adffe.v58
-rwxr-xr-xtests/sim/tb/tb_adlatch.v70
-rwxr-xr-xtests/sim/tb/tb_aldff.v73
-rwxr-xr-xtests/sim/tb/tb_aldffe.v75
-rwxr-xr-xtests/sim/tb/tb_dff.v47
-rwxr-xr-xtests/sim/tb/tb_dffe.v42
-rwxr-xr-xtests/sim/tb/tb_dffsr.v69
-rwxr-xr-xtests/sim/tb/tb_dlatch.v50
-rwxr-xr-xtests/sim/tb/tb_dlatchsr.v65
-rwxr-xr-xtests/sim/tb/tb_sdff.v48
-rwxr-xr-xtests/sim/tb/tb_sdffce.v79
-rwxr-xr-xtests/sim/tb/tb_sdffe.v70
-rw-r--r--tests/simple/case_expr_extend.sv11
-rw-r--r--tests/simple/case_expr_query.sv32
-rw-r--r--tests/simple/hierdefparam.v6
-rw-r--r--tests/simple/implicit_ports.sv (renamed from tests/simple/implicit_ports.v)0
-rw-r--r--tests/simple/lesser_size_cast.sv7
-rw-r--r--tests/simple/module_scope.v8
-rw-r--r--tests/simple/specify.v2
-rw-r--r--tests/sva/.gitignore1
-rw-r--r--tests/sva/Makefile1
-rw-r--r--tests/sva/nested_clk_else.sv11
-rw-r--r--tests/sva/runtest.sh11
-rw-r--r--tests/sva/sva_value_change_changed.sv17
-rw-r--r--tests/sva/sva_value_change_changed_wide.sv22
-rw-r--r--tests/sva/sva_value_change_rose.sv20
-rw-r--r--tests/sva/sva_value_change_sim.sv70
-rw-r--r--tests/sva/sva_value_change_sim.ys3
-rw-r--r--tests/techmap/.gitignore1
-rw-r--r--tests/techmap/mem_simple_4x1_runtest.sh16
-rw-r--r--tests/techmap/recursive_runtest.sh2
-rw-r--r--tests/various/.gitignore3
-rw-r--r--tests/various/async.sh8
-rw-r--r--tests/various/json_escape_chars.ys14
-rwxr-xr-xtests/various/logger_fail.sh42
-rw-r--r--tests/various/param_struct.ys3
-rw-r--r--tests/various/smtlib2_module-expected.smt288
-rwxr-xr-xtests/various/smtlib2_module.sh5
-rw-r--r--tests/various/smtlib2_module.v33
-rw-r--r--tests/various/struct_access.sv43
-rw-r--r--tests/various/struct_access.ys5
-rw-r--r--tests/verilog/.gitignore1
-rw-r--r--tests/verilog/always_comb_latch_1.ys13
-rw-r--r--tests/verilog/always_comb_latch_2.ys15
-rw-r--r--tests/verilog/always_comb_latch_3.ys20
-rw-r--r--tests/verilog/always_comb_latch_4.ys17
-rw-r--r--tests/verilog/always_comb_nolatch_1.ys16
-rw-r--r--tests/verilog/always_comb_nolatch_2.ys17
-rw-r--r--tests/verilog/always_comb_nolatch_3.ys21
-rw-r--r--tests/verilog/always_comb_nolatch_4.ys16
-rw-r--r--tests/verilog/always_comb_nolatch_5.ys15
-rw-r--r--tests/verilog/always_comb_nolatch_6.ys15
-rw-r--r--tests/verilog/delay_time_scale.ys25
-rw-r--r--tests/verilog/doubleslash.ys21
-rwxr-xr-xtests/verilog/dynamic_range_lhs.sh32
-rw-r--r--tests/verilog/dynamic_range_lhs.v76
-rw-r--r--tests/verilog/func_tern_hint.sv42
-rw-r--r--tests/verilog/func_tern_hint.ys4
-rw-r--r--tests/verilog/func_upto.sv77
-rw-r--r--tests/verilog/func_upto.ys7
-rw-r--r--tests/verilog/past_signedness.ys35
-rw-r--r--tests/verilog/sign_array_query.ys52
-rw-r--r--tests/verilog/size_cast.sv140
-rw-r--r--tests/verilog/size_cast.ys5
-rw-r--r--tests/verilog/struct_access.sv5
-rw-r--r--tests/verilog/unreachable_case_sign.ys33
148 files changed, 5994 insertions, 298 deletions
diff --git a/tests/arch/anlogic/blockram.ys b/tests/arch/anlogic/blockram.ys
new file mode 100644
index 000000000..da23409ba
--- /dev/null
+++ b/tests/arch/anlogic/blockram.ys
@@ -0,0 +1,13 @@
+read_verilog ../common/blockram.v
+hierarchy -top sync_ram_sp
+proc
+memory -nomap
+equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
+memory
+opt -full
+
+design -load postopt
+cd sync_ram_sp
+
+select -assert-count 1 t:EG_PHY_BRAM
+select -assert-none t:EG_PHY_BRAM %% t:* %D
diff --git a/tests/arch/anlogic/lutram.ys b/tests/arch/anlogic/lutram.ys
index 6dbdbdac3..fe6135c73 100644
--- a/tests/arch/anlogic/lutram.ys
+++ b/tests/arch/anlogic/lutram.ys
@@ -2,7 +2,7 @@ read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r
proc
memory -nomap
-equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
+equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic -nobram
memory
opt -full
diff --git a/tests/arch/ecp5/memories.ys b/tests/arch/ecp5/memories.ys
index 44651ba25..5cddcb952 100644
--- a/tests/arch/ecp5/memories.ys
+++ b/tests/arch/ecp5/memories.ys
@@ -1,11 +1,11 @@
# ================================ RAM ================================
-# RAM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD
+# RAM bits <= 18K; Data width <= 36; Address width <= 9: -> DP16KD
design -reset; read_verilog -defer ../common/blockram.v
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:PDPW16KD
+select -assert-count 1 t:DP16KD
## With parameters
@@ -13,7 +13,7 @@ design -reset; read_verilog -defer ../common/blockram.v
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 0 t:PDPW16KD # too inefficient
+select -assert-count 0 t:DP16KD # too inefficient
select -assert-count 9 t:TRELLIS_DPR16X4
design -reset; read_verilog -defer ../common/blockram.v
@@ -21,28 +21,29 @@ chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
setattr -set syn_ramstyle "block_ram" m:memory
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:PDPW16KD
+select -assert-count 1 t:DP16KD
design -reset; read_verilog -defer ../common/blockram.v
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
setattr -set syn_ramstyle "Block_RAM" m:memory
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:PDPW16KD # any case works
+select -assert-count 1 t:DP16KD # any case works
design -reset; read_verilog -defer ../common/blockram.v
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
setattr -set ram_block 1 m:memory
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:PDPW16KD
+select -assert-count 0 t:DP16KD
+select -assert-count 9 t:TRELLIS_DPR16X4
design -reset; read_verilog -defer ../common/blockram.v
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
setattr -set syn_ramstyle "registers" m:memory
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly
+select -assert-count 0 t:DP16KD # requested FFRAM explicitly
select -assert-count 180 t:TRELLIS_FF
design -reset; read_verilog -defer ../common/blockram.v
@@ -50,37 +51,9 @@ chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
hierarchy -top sync_ram_sdp
setattr -set logic_block 1 m:memory
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly
+select -assert-count 0 t:DP16KD # requested FFRAM explicitly
select -assert-count 180 t:TRELLIS_FF
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_romstyle "ebr" m:memory
-synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set rom_block 1 m:memory
-synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set ram_block 1 m:memory
-synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
# RAM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD
design -reset; read_verilog -defer ../common/blockram.v
@@ -141,7 +114,8 @@ chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
hierarchy -top sync_ram_sdp
setattr -set ram_block 1 m:memory
synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:DP16KD
+select -assert-count 0 t:DP16KD # too inefficient
+select -assert-count 5 t:TRELLIS_DPR16X4
design -reset; read_verilog -defer ../common/blockram.v
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
@@ -159,34 +133,6 @@ synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
select -assert-count 0 t:DP16KD # requested FFRAM explicitly
select -assert-count 90 t:TRELLIS_FF
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_romstyle "ebr" m:memory
-synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set rom_block 1 m:memory
-synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set ram_block 1 m:memory
-synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
# RAM bits <= 64; Data width <= 4; Address width <= 4: -> DPR16X4
design -reset; read_verilog -defer ../common/blockram.v
@@ -220,21 +166,14 @@ synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly
select -assert-count 68 t:TRELLIS_FF
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_ramstyle "distributed" m:memory
-synth_ecp5 -top sync_ram_sdp -nolutram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested LUTRAM but LUTRAM is disabled
-
# ================================ ROM ================================
-# ROM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD
+# ROM bits <= 18K; Data width <= 36; Address width <= 9: -> DP16KD
design -reset; read_verilog -defer ../common/blockrom.v
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_rom
hierarchy -top sync_rom
synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:PDPW16KD
+select -assert-count 1 t:DP16KD
## With parameters
@@ -242,7 +181,7 @@ design -reset; read_verilog -defer ../common/blockrom.v
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
hierarchy -top sync_rom
synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 0 t:PDPW16KD # too inefficient
+select -assert-count 0 t:DP16KD # too inefficient
select -assert-min 18 t:LUT4
design -reset; read_verilog -defer ../common/blockrom.v
@@ -250,21 +189,21 @@ chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
hierarchy -top sync_rom
setattr -set syn_romstyle "ebr" m:memory
synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:PDPW16KD
+select -assert-count 1 t:DP16KD
design -reset; read_verilog -defer ../common/blockrom.v
chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
hierarchy -top sync_rom
setattr -set rom_block 1 m:memory
synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:PDPW16KD
+select -assert-count 1 t:DP16KD
design -reset; read_verilog -defer ../common/blockrom.v
chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
hierarchy -top sync_rom
setattr -set syn_romstyle "logic" m:memory
synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly
+select -assert-count 0 t:DP16KD # requested LUTROM explicitly
select -assert-min 18 t:LUT4
design -reset; read_verilog -defer ../common/blockrom.v
@@ -272,37 +211,9 @@ chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
hierarchy -top sync_rom
setattr -set logic_block 1 m:memory
synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly
+select -assert-count 0 t:DP16KD # requested LUTROM explicitly
select -assert-min 18 t:LUT4
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
-hierarchy -top sync_rom
-setattr -set ram_block 1 m:memory
-synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_ramstyle "block_rom" m:memory
-synth_ecp5 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
-hierarchy -top sync_rom
-setattr -set rom_block 1 m:memory
-synth_ecp5 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
-
# ROM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD
design -reset; read_verilog -defer ../common/blockrom.v
@@ -349,31 +260,3 @@ setattr -set logic_block 1 m:memory
synth_ecp5 -top sync_rom; cd sync_rom
select -assert-count 0 t:DP16KD # requested LUTROM explicitly
select -assert-min 9 t:LUT4
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
-hierarchy -top sync_rom
-setattr -set ram_block 1 m:memory
-synth_ecp5 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_ramstyle "block_rom" m:memory
-synth_ecp5 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
-hierarchy -top sync_rom
-setattr -set rom_block 1 m:memory
-synth_ecp5 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
diff --git a/tests/arch/efinix/lutram.ys b/tests/arch/efinix/lutram.ys
index dcf647ce0..8412d1389 100644
--- a/tests/arch/efinix/lutram.ys
+++ b/tests/arch/efinix/lutram.ys
@@ -1,17 +1,6 @@
read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r
-proc
-memory -nomap
-equiv_opt -run :prove -map +/efinix/cells_sim.v synth_efinix
-memory
-opt -full
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-#ERROR: Called with -verify and proof did fail!
-#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
-sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
-
-design -load postopt
+synth_efinix
cd lutram_1w1r
select -assert-count 1 t:EFX_GBUFCE
select -assert-count 1 t:EFX_RAM_5K
diff --git a/tests/arch/gatemate/.gitignore b/tests/arch/gatemate/.gitignore
new file mode 100644
index 000000000..9a71dca69
--- /dev/null
+++ b/tests/arch/gatemate/.gitignore
@@ -0,0 +1,4 @@
+*.log
+/run-test.mk
++*_synth.v
++*_testbench
diff --git a/tests/arch/gatemate/gen_luttrees.py b/tests/arch/gatemate/gen_luttrees.py
new file mode 100644
index 000000000..27d2225a2
--- /dev/null
+++ b/tests/arch/gatemate/gen_luttrees.py
@@ -0,0 +1,48 @@
+from random import Random
+
+def main():
+ r = Random(1)
+
+ N = 750
+ with open("tests/arch/gatemate/luttrees.v", "w") as v:
+ print(f"module luttrees(input [{N-1}:0] a, b, c, d, e, output [{N-1}:0] q);", file=v)
+ for i in range(N):
+ def f():
+ return r.choice(["&", "|", "^"])
+
+ def a(x):
+ return f"({r.choice(['', '!'])}{x}[{i}])"
+
+ # Bias towards testing bigger functions
+ k = r.choice([2, 3, 4, 4, 4, 5, 5, 5])
+ if k == 2:
+ expr = f"{a('a')}{f()}{a('b')}"
+ elif k == 3:
+ expr = f"({a('a')}{f()}{a('b')}){f()}{a('c')}"
+ elif k == 4:
+ # Two types of 4-input function
+ if r.choice([False, True]):
+ expr = f"(({a('a')}{f()}{a('b')}){f()}{a('c')}){f()}{a('d')}"
+ else:
+ expr = f"({a('a')}{f()}{a('b')}){f()}({a('c')}{f()}{a('d')})"
+ elif k == 5:
+ expr = f"(({a('a')}{f()}{a('b')}){f()}({a('c')}{f()}{a('d')})){f()}{a('e')}"
+ print(f" assign q[{i}] = {expr};", file=v)
+ print("endmodule", file=v)
+ with open("tests/arch/gatemate/luttrees.ys", "w") as s:
+ print(f"""
+read_verilog luttrees.v
+design -save read
+
+hierarchy -top luttrees
+proc
+equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -nomx4 -nomx8 # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd luttrees # Constrain all select calls below inside the top module
+
+select -assert-count {N} t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %%
+select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D
+""", file=s)
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/arch/gatemate/luttrees.v b/tests/arch/gatemate/luttrees.v
new file mode 100644
index 000000000..7fc02916d
--- /dev/null
+++ b/tests/arch/gatemate/luttrees.v
@@ -0,0 +1,752 @@
+module luttrees(input [749:0] a, b, c, d, e, output [749:0] q);
+ assign q[0] = ((!a[0])&(!b[0]))|((!c[0])^(!d[0]));
+ assign q[1] = ((!a[1])&(!b[1]))|((c[1])^(!d[1]));
+ assign q[2] = ((a[2])|(b[2]))&((c[2])^(d[2]));
+ assign q[3] = (((a[3])|(b[3]))^((c[3])|(!d[3])))^(e[3]);
+ assign q[4] = (((a[4])^(b[4]))|((!c[4])&(!d[4])))^(e[4]);
+ assign q[5] = (((a[5])^(!b[5]))^(!c[5]))^(d[5]);
+ assign q[6] = (((!a[6])^(!b[6]))^(c[6]))|(d[6]);
+ assign q[7] = (((!a[7])^(b[7]))|((!c[7])&(!d[7])))^(e[7]);
+ assign q[8] = (((!a[8])|(b[8]))|(c[8]))|(!d[8]);
+ assign q[9] = ((a[9])&(b[9]))^((c[9])|(!d[9]));
+ assign q[10] = (((!a[10])|(b[10]))|((c[10])^(d[10])))|(e[10]);
+ assign q[11] = (((!a[11])^(b[11]))^((!c[11])|(!d[11])))|(!e[11]);
+ assign q[12] = (!a[12])|(b[12]);
+ assign q[13] = ((a[13])&(!b[13]))&((c[13])&(d[13]));
+ assign q[14] = (((a[14])|(b[14]))|((c[14])^(d[14])))|(!e[14]);
+ assign q[15] = ((a[15])&(!b[15]))^(c[15]);
+ assign q[16] = (((!a[16])^(!b[16]))|(!c[16]))&(d[16]);
+ assign q[17] = (((!a[17])|(b[17]))|(c[17]))|(d[17]);
+ assign q[18] = (((a[18])&(b[18]))|((c[18])&(d[18])))|(!e[18]);
+ assign q[19] = (((a[19])^(b[19]))|(!c[19]))^(!d[19]);
+ assign q[20] = (!a[20])&(b[20]);
+ assign q[21] = (!a[21])&(b[21]);
+ assign q[22] = (((a[22])|(!b[22]))&(c[22]))^(d[22]);
+ assign q[23] = (((a[23])^(b[23]))|(c[23]))|(d[23]);
+ assign q[24] = (((a[24])|(b[24]))^(!c[24]))|(!d[24]);
+ assign q[25] = (!a[25])^(!b[25]);
+ assign q[26] = ((a[26])&(!b[26]))^((c[26])|(!d[26]));
+ assign q[27] = (((a[27])|(!b[27]))^(!c[27]))^(d[27]);
+ assign q[28] = ((a[28])&(b[28]))&(c[28]);
+ assign q[29] = (((!a[29])^(!b[29]))|(!c[29]))|(d[29]);
+ assign q[30] = ((!a[30])&(b[30]))|((c[30])|(d[30]));
+ assign q[31] = (((a[31])&(!b[31]))&((!c[31])&(d[31])))^(e[31]);
+ assign q[32] = (((!a[32])^(b[32]))|(!c[32]))&(d[32]);
+ assign q[33] = ((a[33])&(!b[33]))&((c[33])&(d[33]));
+ assign q[34] = (((a[34])&(!b[34]))&((c[34])&(d[34])))|(!e[34]);
+ assign q[35] = (((!a[35])|(b[35]))&(!c[35]))&(d[35]);
+ assign q[36] = (!a[36])^(!b[36]);
+ assign q[37] = (((!a[37])|(!b[37]))&((c[37])|(!d[37])))&(!e[37]);
+ assign q[38] = (((!a[38])|(b[38]))^(c[38]))|(d[38]);
+ assign q[39] = (((a[39])|(b[39]))|(c[39]))^(!d[39]);
+ assign q[40] = (((!a[40])&(!b[40]))&(!c[40]))^(!d[40]);
+ assign q[41] = (((a[41])^(b[41]))&(c[41]))&(d[41]);
+ assign q[42] = (((a[42])|(b[42]))^((c[42])&(d[42])))|(!e[42]);
+ assign q[43] = (((!a[43])&(b[43]))^((!c[43])&(d[43])))&(e[43]);
+ assign q[44] = (((!a[44])&(!b[44]))&(c[44]))&(d[44]);
+ assign q[45] = (((a[45])&(!b[45]))|((c[45])&(d[45])))|(e[45]);
+ assign q[46] = (((!a[46])^(!b[46]))^((!c[46])^(!d[46])))&(!e[46]);
+ assign q[47] = (((a[47])|(!b[47]))&((!c[47])^(d[47])))&(!e[47]);
+ assign q[48] = ((a[48])|(!b[48]))|((!c[48])&(d[48]));
+ assign q[49] = (((a[49])&(!b[49]))^(!c[49]))^(d[49]);
+ assign q[50] = (((!a[50])^(!b[50]))&(!c[50]))|(!d[50]);
+ assign q[51] = ((a[51])^(!b[51]))&((c[51])|(!d[51]));
+ assign q[52] = (((a[52])^(!b[52]))^(c[52]))&(!d[52]);
+ assign q[53] = ((!a[53])|(b[53]))^((c[53])|(!d[53]));
+ assign q[54] = (((!a[54])^(b[54]))^((c[54])^(d[54])))|(e[54]);
+ assign q[55] = ((a[55])^(b[55]))|((c[55])|(!d[55]));
+ assign q[56] = (((a[56])|(!b[56]))&((!c[56])&(d[56])))|(!e[56]);
+ assign q[57] = ((!a[57])|(b[57]))|(c[57]);
+ assign q[58] = (((a[58])&(b[58]))|(c[58]))&(!d[58]);
+ assign q[59] = ((!a[59])|(!b[59]))^((!c[59])&(!d[59]));
+ assign q[60] = (((!a[60])&(b[60]))^((!c[60])&(!d[60])))&(e[60]);
+ assign q[61] = ((a[61])^(!b[61]))^(c[61]);
+ assign q[62] = ((!a[62])^(!b[62]))|(!c[62]);
+ assign q[63] = (((a[63])&(!b[63]))^((!c[63])|(!d[63])))^(!e[63]);
+ assign q[64] = (((!a[64])&(!b[64]))|((c[64])^(d[64])))|(e[64]);
+ assign q[65] = (((!a[65])^(!b[65]))^((c[65])|(d[65])))|(e[65]);
+ assign q[66] = (((!a[66])|(!b[66]))^((c[66])|(d[66])))^(!e[66]);
+ assign q[67] = (!a[67])^(b[67]);
+ assign q[68] = (((!a[68])&(b[68]))^((c[68])|(!d[68])))^(!e[68]);
+ assign q[69] = ((!a[69])|(!b[69]))&((!c[69])^(d[69]));
+ assign q[70] = ((!a[70])&(!b[70]))&((!c[70])&(d[70]));
+ assign q[71] = ((!a[71])^(!b[71]))^((!c[71])&(d[71]));
+ assign q[72] = (((!a[72])&(b[72]))^(!c[72]))|(d[72]);
+ assign q[73] = (((!a[73])|(b[73]))|(!c[73]))&(!d[73]);
+ assign q[74] = (((a[74])|(b[74]))^(c[74]))^(!d[74]);
+ assign q[75] = (((!a[75])&(!b[75]))&((c[75])^(d[75])))^(!e[75]);
+ assign q[76] = (((!a[76])^(b[76]))&(c[76]))^(!d[76]);
+ assign q[77] = (((!a[77])|(b[77]))&((c[77])^(!d[77])))&(e[77]);
+ assign q[78] = (((!a[78])|(b[78]))&(c[78]))&(d[78]);
+ assign q[79] = ((!a[79])^(!b[79]))|((!c[79])&(d[79]));
+ assign q[80] = ((a[80])|(b[80]))|(!c[80]);
+ assign q[81] = (((a[81])&(b[81]))|((!c[81])^(!d[81])))&(!e[81]);
+ assign q[82] = (((!a[82])^(b[82]))&(c[82]))&(d[82]);
+ assign q[83] = (!a[83])|(!b[83]);
+ assign q[84] = ((!a[84])&(b[84]))&((c[84])|(d[84]));
+ assign q[85] = (!a[85])|(b[85]);
+ assign q[86] = ((!a[86])^(!b[86]))&(c[86]);
+ assign q[87] = (a[87])&(!b[87]);
+ assign q[88] = ((!a[88])&(b[88]))&(!c[88]);
+ assign q[89] = (((a[89])^(!b[89]))|(!c[89]))^(!d[89]);
+ assign q[90] = ((a[90])&(b[90]))|((!c[90])^(d[90]));
+ assign q[91] = (((!a[91])^(b[91]))^((!c[91])^(d[91])))^(!e[91]);
+ assign q[92] = ((!a[92])&(b[92]))&(c[92]);
+ assign q[93] = (((a[93])&(b[93]))^(!c[93]))^(!d[93]);
+ assign q[94] = ((!a[94])&(b[94]))^(c[94]);
+ assign q[95] = (((a[95])|(!b[95]))&((!c[95])&(!d[95])))|(e[95]);
+ assign q[96] = ((!a[96])&(!b[96]))|((c[96])|(!d[96]));
+ assign q[97] = ((!a[97])&(!b[97]))&(c[97]);
+ assign q[98] = (((!a[98])^(!b[98]))^((!c[98])&(d[98])))^(!e[98]);
+ assign q[99] = (!a[99])^(b[99]);
+ assign q[100] = (((!a[100])^(!b[100]))&(!c[100]))|(d[100]);
+ assign q[101] = ((a[101])|(!b[101]))|(!c[101]);
+ assign q[102] = (((!a[102])|(!b[102]))^((c[102])^(d[102])))&(!e[102]);
+ assign q[103] = (((!a[103])^(b[103]))|((!c[103])|(!d[103])))|(!e[103]);
+ assign q[104] = ((a[104])&(b[104]))^(!c[104]);
+ assign q[105] = ((!a[105])|(!b[105]))|((!c[105])|(!d[105]));
+ assign q[106] = ((a[106])|(b[106]))^((c[106])&(d[106]));
+ assign q[107] = (((a[107])&(!b[107]))^((c[107])&(!d[107])))&(e[107]);
+ assign q[108] = ((a[108])^(b[108]))^(!c[108]);
+ assign q[109] = (!a[109])|(!b[109]);
+ assign q[110] = ((!a[110])&(!b[110]))|((!c[110])^(d[110]));
+ assign q[111] = (((a[111])|(!b[111]))&((c[111])^(!d[111])))^(!e[111]);
+ assign q[112] = ((!a[112])^(!b[112]))&(!c[112]);
+ assign q[113] = (((a[113])&(!b[113]))^((c[113])^(d[113])))|(!e[113]);
+ assign q[114] = (((!a[114])^(!b[114]))|(!c[114]))&(!d[114]);
+ assign q[115] = ((!a[115])^(b[115]))|((c[115])|(!d[115]));
+ assign q[116] = (((!a[116])^(b[116]))&((c[116])&(!d[116])))|(!e[116]);
+ assign q[117] = (((!a[117])|(!b[117]))|(c[117]))|(!d[117]);
+ assign q[118] = (((a[118])&(b[118]))|(!c[118]))&(!d[118]);
+ assign q[119] = (((!a[119])^(!b[119]))^((!c[119])^(!d[119])))|(!e[119]);
+ assign q[120] = (((a[120])^(!b[120]))|((!c[120])&(d[120])))&(e[120]);
+ assign q[121] = ((a[121])&(!b[121]))&((!c[121])&(!d[121]));
+ assign q[122] = ((a[122])|(b[122]))^((c[122])^(!d[122]));
+ assign q[123] = (((a[123])^(b[123]))^((!c[123])^(d[123])))|(!e[123]);
+ assign q[124] = (((a[124])&(b[124]))|(c[124]))^(!d[124]);
+ assign q[125] = (((!a[125])&(!b[125]))&(c[125]))|(d[125]);
+ assign q[126] = (((!a[126])^(!b[126]))|(c[126]))^(!d[126]);
+ assign q[127] = (((a[127])&(!b[127]))^((!c[127])&(!d[127])))|(e[127]);
+ assign q[128] = (((!a[128])^(b[128]))|(c[128]))&(!d[128]);
+ assign q[129] = (((a[129])^(b[129]))|(!c[129]))|(!d[129]);
+ assign q[130] = (((!a[130])&(!b[130]))|(!c[130]))&(!d[130]);
+ assign q[131] = ((!a[131])^(b[131]))&((!c[131])^(d[131]));
+ assign q[132] = (((!a[132])|(!b[132]))&(c[132]))&(!d[132]);
+ assign q[133] = ((a[133])^(b[133]))^((c[133])&(d[133]));
+ assign q[134] = (((!a[134])&(b[134]))|(c[134]))&(d[134]);
+ assign q[135] = (((!a[135])^(!b[135]))&(c[135]))|(!d[135]);
+ assign q[136] = ((!a[136])&(b[136]))|((c[136])&(d[136]));
+ assign q[137] = (((a[137])|(b[137]))|(c[137]))&(d[137]);
+ assign q[138] = (((!a[138])^(b[138]))&((!c[138])|(d[138])))^(!e[138]);
+ assign q[139] = ((!a[139])^(b[139]))^(!c[139]);
+ assign q[140] = (((a[140])^(!b[140]))^((!c[140])^(!d[140])))|(e[140]);
+ assign q[141] = ((a[141])^(b[141]))&((c[141])&(!d[141]));
+ assign q[142] = ((!a[142])^(!b[142]))^((!c[142])|(d[142]));
+ assign q[143] = (((a[143])^(!b[143]))&((!c[143])^(d[143])))^(!e[143]);
+ assign q[144] = (((a[144])&(b[144]))^((c[144])^(d[144])))|(!e[144]);
+ assign q[145] = (((!a[145])&(b[145]))|((!c[145])|(d[145])))^(e[145]);
+ assign q[146] = (((a[146])^(b[146]))^(c[146]))|(d[146]);
+ assign q[147] = (((a[147])|(!b[147]))|((!c[147])|(!d[147])))^(!e[147]);
+ assign q[148] = (a[148])|(b[148]);
+ assign q[149] = (a[149])&(b[149]);
+ assign q[150] = (((!a[150])^(!b[150]))|((c[150])^(d[150])))&(!e[150]);
+ assign q[151] = ((a[151])^(!b[151]))|((!c[151])|(d[151]));
+ assign q[152] = (((!a[152])|(!b[152]))|((!c[152])|(d[152])))^(e[152]);
+ assign q[153] = (!a[153])^(b[153]);
+ assign q[154] = (((!a[154])^(b[154]))^(c[154]))|(d[154]);
+ assign q[155] = (((a[155])|(b[155]))&((c[155])|(!d[155])))^(e[155]);
+ assign q[156] = (((!a[156])|(!b[156]))^((c[156])|(!d[156])))|(e[156]);
+ assign q[157] = (((!a[157])&(b[157]))&((!c[157])|(d[157])))&(e[157]);
+ assign q[158] = (((!a[158])^(!b[158]))&(c[158]))^(d[158]);
+ assign q[159] = ((!a[159])|(b[159]))^((!c[159])&(d[159]));
+ assign q[160] = (((a[160])^(b[160]))|((c[160])&(d[160])))&(!e[160]);
+ assign q[161] = (a[161])|(b[161]);
+ assign q[162] = (a[162])^(b[162]);
+ assign q[163] = (((!a[163])&(b[163]))|(c[163]))^(d[163]);
+ assign q[164] = (((a[164])^(b[164]))&((c[164])|(!d[164])))|(!e[164]);
+ assign q[165] = ((!a[165])^(!b[165]))^((!c[165])^(d[165]));
+ assign q[166] = (((!a[166])&(!b[166]))|((!c[166])&(!d[166])))^(!e[166]);
+ assign q[167] = ((!a[167])|(b[167]))|((!c[167])|(!d[167]));
+ assign q[168] = (((!a[168])^(!b[168]))&((c[168])&(!d[168])))&(e[168]);
+ assign q[169] = ((a[169])^(!b[169]))^(c[169]);
+ assign q[170] = (((!a[170])^(b[170]))&(c[170]))&(d[170]);
+ assign q[171] = (!a[171])|(!b[171]);
+ assign q[172] = ((a[172])&(!b[172]))&((!c[172])&(!d[172]));
+ assign q[173] = (((a[173])&(!b[173]))^((c[173])|(!d[173])))^(!e[173]);
+ assign q[174] = ((!a[174])&(!b[174]))&(!c[174]);
+ assign q[175] = ((!a[175])|(!b[175]))^(c[175]);
+ assign q[176] = (!a[176])&(b[176]);
+ assign q[177] = ((a[177])|(b[177]))^(c[177]);
+ assign q[178] = (((a[178])^(b[178]))|((c[178])^(!d[178])))^(e[178]);
+ assign q[179] = ((a[179])^(!b[179]))^(!c[179]);
+ assign q[180] = (((a[180])^(b[180]))^(c[180]))|(!d[180]);
+ assign q[181] = (((!a[181])|(!b[181]))&((c[181])&(d[181])))|(e[181]);
+ assign q[182] = (((a[182])|(!b[182]))&((c[182])&(d[182])))|(!e[182]);
+ assign q[183] = ((a[183])^(!b[183]))^((!c[183])&(d[183]));
+ assign q[184] = (((a[184])|(b[184]))|((c[184])^(d[184])))&(!e[184]);
+ assign q[185] = (((a[185])^(b[185]))^((!c[185])&(!d[185])))^(!e[185]);
+ assign q[186] = (((!a[186])|(!b[186]))&((!c[186])&(!d[186])))|(!e[186]);
+ assign q[187] = (((a[187])^(!b[187]))|(!c[187]))^(d[187]);
+ assign q[188] = ((a[188])^(b[188]))&(!c[188]);
+ assign q[189] = (((!a[189])^(b[189]))^((!c[189])^(d[189])))|(e[189]);
+ assign q[190] = (((!a[190])^(b[190]))&((!c[190])|(d[190])))&(e[190]);
+ assign q[191] = ((!a[191])|(!b[191]))|(!c[191]);
+ assign q[192] = (((a[192])^(b[192]))^(c[192]))|(!d[192]);
+ assign q[193] = ((a[193])^(b[193]))|((!c[193])&(d[193]));
+ assign q[194] = (((a[194])&(b[194]))|(!c[194]))&(!d[194]);
+ assign q[195] = ((!a[195])|(!b[195]))^((c[195])&(!d[195]));
+ assign q[196] = (((a[196])&(!b[196]))|((c[196])^(d[196])))^(!e[196]);
+ assign q[197] = ((a[197])&(b[197]))^((c[197])^(!d[197]));
+ assign q[198] = (((a[198])&(!b[198]))|((!c[198])^(!d[198])))&(e[198]);
+ assign q[199] = (!a[199])&(b[199]);
+ assign q[200] = ((a[200])&(b[200]))^((c[200])&(d[200]));
+ assign q[201] = (((!a[201])&(!b[201]))^(!c[201]))|(!d[201]);
+ assign q[202] = ((a[202])^(b[202]))&(!c[202]);
+ assign q[203] = (((!a[203])|(b[203]))|((c[203])&(!d[203])))^(!e[203]);
+ assign q[204] = (((a[204])^(!b[204]))&((!c[204])^(!d[204])))^(!e[204]);
+ assign q[205] = (((a[205])|(!b[205]))^((!c[205])^(!d[205])))|(!e[205]);
+ assign q[206] = (a[206])|(!b[206]);
+ assign q[207] = (((a[207])^(!b[207]))&((!c[207])|(d[207])))|(!e[207]);
+ assign q[208] = (a[208])|(b[208]);
+ assign q[209] = ((!a[209])|(b[209]))|((!c[209])|(d[209]));
+ assign q[210] = ((!a[210])&(b[210]))&((!c[210])|(!d[210]));
+ assign q[211] = ((a[211])^(!b[211]))|((!c[211])|(!d[211]));
+ assign q[212] = (((a[212])&(!b[212]))&((c[212])^(d[212])))^(e[212]);
+ assign q[213] = (((!a[213])&(b[213]))^(!c[213]))^(!d[213]);
+ assign q[214] = (!a[214])|(!b[214]);
+ assign q[215] = ((a[215])|(!b[215]))^((!c[215])^(!d[215]));
+ assign q[216] = (((a[216])^(!b[216]))^((!c[216])|(d[216])))|(e[216]);
+ assign q[217] = (((a[217])^(b[217]))^((!c[217])|(!d[217])))&(e[217]);
+ assign q[218] = ((a[218])&(!b[218]))&(c[218]);
+ assign q[219] = ((a[219])|(b[219]))&((c[219])&(d[219]));
+ assign q[220] = (((!a[220])&(b[220]))^((c[220])|(d[220])))|(!e[220]);
+ assign q[221] = ((a[221])&(!b[221]))&((c[221])^(!d[221]));
+ assign q[222] = (!a[222])|(!b[222]);
+ assign q[223] = ((a[223])^(b[223]))^(c[223]);
+ assign q[224] = ((a[224])&(!b[224]))&((c[224])|(d[224]));
+ assign q[225] = ((!a[225])&(b[225]))&(!c[225]);
+ assign q[226] = (((a[226])^(b[226]))|((c[226])&(d[226])))&(e[226]);
+ assign q[227] = ((a[227])&(b[227]))|((!c[227])^(!d[227]));
+ assign q[228] = ((!a[228])&(!b[228]))|((!c[228])|(!d[228]));
+ assign q[229] = (((a[229])|(b[229]))|((!c[229])&(d[229])))&(e[229]);
+ assign q[230] = (((!a[230])^(!b[230]))|((!c[230])|(!d[230])))|(!e[230]);
+ assign q[231] = (((!a[231])|(b[231]))|((c[231])|(d[231])))|(e[231]);
+ assign q[232] = ((!a[232])^(b[232]))&((c[232])&(!d[232]));
+ assign q[233] = (((!a[233])&(!b[233]))|(!c[233]))&(!d[233]);
+ assign q[234] = (((!a[234])&(b[234]))^(!c[234]))&(d[234]);
+ assign q[235] = (((a[235])&(b[235]))^((!c[235])^(!d[235])))^(!e[235]);
+ assign q[236] = (((!a[236])^(b[236]))&((!c[236])&(!d[236])))^(e[236]);
+ assign q[237] = (a[237])|(!b[237]);
+ assign q[238] = (((a[238])|(b[238]))&((!c[238])^(d[238])))&(e[238]);
+ assign q[239] = ((!a[239])^(!b[239]))&((c[239])&(d[239]));
+ assign q[240] = (((!a[240])^(!b[240]))&(!c[240]))&(!d[240]);
+ assign q[241] = ((!a[241])&(b[241]))&(c[241]);
+ assign q[242] = ((a[242])|(!b[242]))&((c[242])|(d[242]));
+ assign q[243] = ((a[243])|(b[243]))^((!c[243])&(d[243]));
+ assign q[244] = (((!a[244])^(b[244]))&(!c[244]))|(!d[244]);
+ assign q[245] = (((a[245])^(!b[245]))^(!c[245]))^(!d[245]);
+ assign q[246] = ((!a[246])|(!b[246]))&(!c[246]);
+ assign q[247] = ((!a[247])&(b[247]))|(c[247]);
+ assign q[248] = (((!a[248])|(!b[248]))|((!c[248])&(!d[248])))&(!e[248]);
+ assign q[249] = (a[249])|(!b[249]);
+ assign q[250] = (((!a[250])^(!b[250]))^(!c[250]))^(!d[250]);
+ assign q[251] = (((a[251])|(b[251]))|(!c[251]))^(d[251]);
+ assign q[252] = (((!a[252])&(!b[252]))^((c[252])&(d[252])))&(e[252]);
+ assign q[253] = (!a[253])^(!b[253]);
+ assign q[254] = (((a[254])^(!b[254]))|((c[254])|(!d[254])))&(!e[254]);
+ assign q[255] = (!a[255])|(!b[255]);
+ assign q[256] = (((a[256])|(!b[256]))&(c[256]))&(!d[256]);
+ assign q[257] = (!a[257])^(!b[257]);
+ assign q[258] = (((!a[258])&(b[258]))^(c[258]))|(d[258]);
+ assign q[259] = (((!a[259])&(!b[259]))|(c[259]))&(!d[259]);
+ assign q[260] = ((!a[260])&(!b[260]))|((!c[260])^(!d[260]));
+ assign q[261] = (((a[261])|(b[261]))^(c[261]))|(d[261]);
+ assign q[262] = (((!a[262])^(b[262]))^((!c[262])|(!d[262])))|(e[262]);
+ assign q[263] = (a[263])^(b[263]);
+ assign q[264] = ((!a[264])&(!b[264]))|(c[264]);
+ assign q[265] = (((!a[265])^(b[265]))^((c[265])^(!d[265])))|(!e[265]);
+ assign q[266] = (((a[266])^(!b[266]))&(c[266]))^(d[266]);
+ assign q[267] = ((a[267])|(!b[267]))|(!c[267]);
+ assign q[268] = ((!a[268])&(!b[268]))|(!c[268]);
+ assign q[269] = (((!a[269])^(b[269]))&((!c[269])^(!d[269])))^(!e[269]);
+ assign q[270] = (((a[270])|(b[270]))^(c[270]))&(d[270]);
+ assign q[271] = (((a[271])&(b[271]))|((c[271])|(d[271])))|(!e[271]);
+ assign q[272] = (((a[272])|(!b[272]))^(!c[272]))|(!d[272]);
+ assign q[273] = (((!a[273])|(b[273]))&((!c[273])&(!d[273])))&(!e[273]);
+ assign q[274] = ((a[274])^(!b[274]))|(!c[274]);
+ assign q[275] = (((!a[275])^(!b[275]))|((!c[275])^(!d[275])))^(e[275]);
+ assign q[276] = ((a[276])^(b[276]))&((!c[276])^(d[276]));
+ assign q[277] = (((!a[277])&(!b[277]))|((!c[277])^(!d[277])))&(!e[277]);
+ assign q[278] = (((!a[278])^(!b[278]))^(c[278]))&(!d[278]);
+ assign q[279] = (((a[279])&(b[279]))^((!c[279])|(d[279])))^(!e[279]);
+ assign q[280] = ((!a[280])&(!b[280]))&(!c[280]);
+ assign q[281] = ((a[281])|(b[281]))|((!c[281])|(!d[281]));
+ assign q[282] = ((a[282])&(b[282]))&((c[282])|(d[282]));
+ assign q[283] = (((a[283])|(!b[283]))^((c[283])&(!d[283])))&(e[283]);
+ assign q[284] = (((!a[284])&(b[284]))&(!c[284]))^(d[284]);
+ assign q[285] = (((a[285])|(!b[285]))&(!c[285]))|(d[285]);
+ assign q[286] = (((a[286])^(b[286]))&((c[286])^(!d[286])))&(!e[286]);
+ assign q[287] = ((a[287])&(!b[287]))|((c[287])|(!d[287]));
+ assign q[288] = ((!a[288])|(!b[288]))|((!c[288])|(!d[288]));
+ assign q[289] = ((a[289])&(b[289]))&((c[289])&(!d[289]));
+ assign q[290] = (((!a[290])^(b[290]))&((c[290])^(d[290])))&(!e[290]);
+ assign q[291] = (((a[291])&(!b[291]))|(!c[291]))^(d[291]);
+ assign q[292] = (((a[292])^(!b[292]))^((c[292])|(d[292])))&(e[292]);
+ assign q[293] = (((a[293])&(!b[293]))&((c[293])|(d[293])))|(e[293]);
+ assign q[294] = (((a[294])^(!b[294]))&((!c[294])^(d[294])))&(!e[294]);
+ assign q[295] = (((a[295])^(!b[295]))|((!c[295])|(d[295])))&(e[295]);
+ assign q[296] = (((a[296])&(!b[296]))&((c[296])&(d[296])))&(!e[296]);
+ assign q[297] = ((!a[297])|(b[297]))^((!c[297])^(!d[297]));
+ assign q[298] = (((a[298])^(b[298]))|((!c[298])|(d[298])))|(!e[298]);
+ assign q[299] = (((!a[299])^(b[299]))|((c[299])^(!d[299])))|(!e[299]);
+ assign q[300] = (((!a[300])^(!b[300]))^(!c[300]))|(d[300]);
+ assign q[301] = ((a[301])&(!b[301]))&((!c[301])|(!d[301]));
+ assign q[302] = ((a[302])^(b[302]))|((c[302])|(!d[302]));
+ assign q[303] = (((!a[303])&(b[303]))^((c[303])|(d[303])))|(!e[303]);
+ assign q[304] = (!a[304])^(b[304]);
+ assign q[305] = (((a[305])&(!b[305]))^((!c[305])&(!d[305])))^(!e[305]);
+ assign q[306] = (a[306])&(b[306]);
+ assign q[307] = ((a[307])&(!b[307]))&(c[307]);
+ assign q[308] = ((a[308])&(!b[308]))^((!c[308])|(d[308]));
+ assign q[309] = ((a[309])^(!b[309]))&((c[309])|(!d[309]));
+ assign q[310] = (((!a[310])|(b[310]))&((c[310])^(d[310])))^(!e[310]);
+ assign q[311] = (((!a[311])|(b[311]))&((c[311])&(d[311])))|(e[311]);
+ assign q[312] = (((!a[312])&(b[312]))|((c[312])^(!d[312])))&(!e[312]);
+ assign q[313] = (!a[313])|(!b[313]);
+ assign q[314] = ((a[314])^(!b[314]))^((c[314])|(!d[314]));
+ assign q[315] = (a[315])&(!b[315]);
+ assign q[316] = ((!a[316])^(!b[316]))&(!c[316]);
+ assign q[317] = ((a[317])&(!b[317]))^(c[317]);
+ assign q[318] = (((!a[318])^(!b[318]))|(!c[318]))&(!d[318]);
+ assign q[319] = (((a[319])&(!b[319]))|(!c[319]))^(d[319]);
+ assign q[320] = (((!a[320])^(!b[320]))|(c[320]))|(d[320]);
+ assign q[321] = ((a[321])|(!b[321]))|((c[321])|(d[321]));
+ assign q[322] = ((!a[322])^(!b[322]))&(!c[322]);
+ assign q[323] = (((!a[323])&(b[323]))|(c[323]))|(d[323]);
+ assign q[324] = ((!a[324])&(!b[324]))^((c[324])|(d[324]));
+ assign q[325] = ((a[325])&(!b[325]))|(!c[325]);
+ assign q[326] = ((!a[326])^(!b[326]))|(c[326]);
+ assign q[327] = (((a[327])|(b[327]))&((c[327])|(!d[327])))^(!e[327]);
+ assign q[328] = ((!a[328])|(b[328]))&((c[328])&(d[328]));
+ assign q[329] = (((a[329])&(b[329]))^(c[329]))|(!d[329]);
+ assign q[330] = ((a[330])|(b[330]))|((c[330])^(!d[330]));
+ assign q[331] = (((!a[331])|(b[331]))&(c[331]))&(d[331]);
+ assign q[332] = (((!a[332])&(b[332]))|((!c[332])^(d[332])))&(e[332]);
+ assign q[333] = (((a[333])^(!b[333]))|(!c[333]))|(!d[333]);
+ assign q[334] = ((a[334])&(!b[334]))&((c[334])&(!d[334]));
+ assign q[335] = (((!a[335])&(b[335]))^((c[335])&(d[335])))&(e[335]);
+ assign q[336] = (!a[336])^(b[336]);
+ assign q[337] = (((a[337])^(b[337]))&(c[337]))&(d[337]);
+ assign q[338] = (((a[338])^(!b[338]))&(!c[338]))&(!d[338]);
+ assign q[339] = (((!a[339])^(!b[339]))|((!c[339])|(d[339])))&(!e[339]);
+ assign q[340] = (((a[340])^(b[340]))^((c[340])^(d[340])))|(e[340]);
+ assign q[341] = (((!a[341])&(!b[341]))^(!c[341]))^(d[341]);
+ assign q[342] = (a[342])^(!b[342]);
+ assign q[343] = (((!a[343])^(b[343]))&((c[343])|(!d[343])))|(e[343]);
+ assign q[344] = ((a[344])&(b[344]))&((!c[344])&(d[344]));
+ assign q[345] = (((!a[345])&(b[345]))&((c[345])^(!d[345])))|(e[345]);
+ assign q[346] = (((a[346])^(!b[346]))&(c[346]))&(!d[346]);
+ assign q[347] = (((!a[347])^(!b[347]))|((c[347])|(!d[347])))|(!e[347]);
+ assign q[348] = (((a[348])|(b[348]))&((!c[348])&(d[348])))|(!e[348]);
+ assign q[349] = (!a[349])&(b[349]);
+ assign q[350] = (((!a[350])^(b[350]))|((c[350])|(!d[350])))&(e[350]);
+ assign q[351] = (((!a[351])^(!b[351]))^((c[351])|(!d[351])))&(!e[351]);
+ assign q[352] = ((!a[352])|(b[352]))^(c[352]);
+ assign q[353] = (((a[353])&(!b[353]))^((c[353])&(!d[353])))|(!e[353]);
+ assign q[354] = (((!a[354])^(b[354]))^((!c[354])^(d[354])))^(e[354]);
+ assign q[355] = (a[355])|(b[355]);
+ assign q[356] = (((a[356])^(!b[356]))^(!c[356]))&(!d[356]);
+ assign q[357] = (((a[357])&(!b[357]))^((c[357])&(!d[357])))^(e[357]);
+ assign q[358] = (((a[358])&(b[358]))&((!c[358])&(d[358])))|(e[358]);
+ assign q[359] = (((a[359])&(!b[359]))&((!c[359])^(!d[359])))&(e[359]);
+ assign q[360] = (((!a[360])|(!b[360]))|((!c[360])|(d[360])))&(!e[360]);
+ assign q[361] = (((a[361])|(b[361]))^((c[361])|(!d[361])))^(!e[361]);
+ assign q[362] = (((!a[362])|(!b[362]))|(c[362]))|(d[362]);
+ assign q[363] = ((a[363])|(!b[363]))&((!c[363])^(!d[363]));
+ assign q[364] = (((a[364])&(!b[364]))&((c[364])&(d[364])))|(e[364]);
+ assign q[365] = ((a[365])|(!b[365]))&((c[365])|(d[365]));
+ assign q[366] = (((a[366])|(!b[366]))&((!c[366])|(!d[366])))^(!e[366]);
+ assign q[367] = ((a[367])^(!b[367]))^((!c[367])|(!d[367]));
+ assign q[368] = (((!a[368])&(b[368]))&((!c[368])|(!d[368])))&(!e[368]);
+ assign q[369] = ((a[369])^(b[369]))|((c[369])|(d[369]));
+ assign q[370] = (((a[370])^(b[370]))^(!c[370]))|(!d[370]);
+ assign q[371] = (((a[371])^(b[371]))&((!c[371])&(d[371])))&(!e[371]);
+ assign q[372] = (((!a[372])|(!b[372]))|((!c[372])&(d[372])))&(!e[372]);
+ assign q[373] = ((a[373])&(b[373]))&((!c[373])&(!d[373]));
+ assign q[374] = (((!a[374])^(!b[374]))^((!c[374])&(!d[374])))|(e[374]);
+ assign q[375] = ((!a[375])&(b[375]))^(!c[375]);
+ assign q[376] = (!a[376])|(b[376]);
+ assign q[377] = (((!a[377])^(b[377]))^((!c[377])^(!d[377])))^(e[377]);
+ assign q[378] = (((a[378])|(!b[378]))^((c[378])^(d[378])))&(!e[378]);
+ assign q[379] = (((a[379])|(b[379]))&((!c[379])^(!d[379])))^(e[379]);
+ assign q[380] = (((!a[380])^(!b[380]))^((c[380])|(!d[380])))&(!e[380]);
+ assign q[381] = (((!a[381])^(b[381]))^(c[381]))^(!d[381]);
+ assign q[382] = (((!a[382])^(b[382]))^(!c[382]))&(!d[382]);
+ assign q[383] = (((!a[383])&(!b[383]))&((c[383])^(d[383])))|(e[383]);
+ assign q[384] = (((a[384])&(b[384]))&((c[384])&(d[384])))^(e[384]);
+ assign q[385] = ((a[385])|(!b[385]))&(!c[385]);
+ assign q[386] = ((a[386])|(b[386]))&(!c[386]);
+ assign q[387] = (((!a[387])^(b[387]))|(c[387]))^(d[387]);
+ assign q[388] = (!a[388])&(!b[388]);
+ assign q[389] = ((a[389])^(b[389]))^(!c[389]);
+ assign q[390] = (((!a[390])|(b[390]))^(c[390]))|(d[390]);
+ assign q[391] = (!a[391])^(!b[391]);
+ assign q[392] = ((!a[392])^(b[392]))|(c[392]);
+ assign q[393] = (((!a[393])&(!b[393]))^((c[393])^(d[393])))^(e[393]);
+ assign q[394] = (((!a[394])^(b[394]))|(!c[394]))|(!d[394]);
+ assign q[395] = ((!a[395])&(!b[395]))^(!c[395]);
+ assign q[396] = ((a[396])^(b[396]))|((!c[396])|(d[396]));
+ assign q[397] = (((a[397])|(!b[397]))&((!c[397])&(d[397])))&(!e[397]);
+ assign q[398] = (((a[398])&(!b[398]))^((c[398])&(d[398])))|(!e[398]);
+ assign q[399] = (((!a[399])^(!b[399]))^((c[399])&(d[399])))|(!e[399]);
+ assign q[400] = (!a[400])&(b[400]);
+ assign q[401] = (((a[401])&(!b[401]))^(!c[401]))^(!d[401]);
+ assign q[402] = ((a[402])|(!b[402]))^((!c[402])^(!d[402]));
+ assign q[403] = (((!a[403])|(!b[403]))|((c[403])|(d[403])))^(!e[403]);
+ assign q[404] = (((!a[404])^(b[404]))&((c[404])&(d[404])))^(!e[404]);
+ assign q[405] = (((!a[405])^(b[405]))&(!c[405]))&(d[405]);
+ assign q[406] = (((!a[406])|(b[406]))|((c[406])^(!d[406])))&(!e[406]);
+ assign q[407] = (!a[407])|(b[407]);
+ assign q[408] = (((!a[408])&(!b[408]))|(!c[408]))&(!d[408]);
+ assign q[409] = (!a[409])^(!b[409]);
+ assign q[410] = (((!a[410])|(b[410]))|((!c[410])|(d[410])))|(!e[410]);
+ assign q[411] = (((!a[411])^(b[411]))|((c[411])&(d[411])))|(e[411]);
+ assign q[412] = ((!a[412])&(!b[412]))&((c[412])|(d[412]));
+ assign q[413] = (((!a[413])^(b[413]))^((c[413])&(!d[413])))&(!e[413]);
+ assign q[414] = (a[414])^(!b[414]);
+ assign q[415] = (((!a[415])^(b[415]))&(c[415]))|(!d[415]);
+ assign q[416] = ((!a[416])|(!b[416]))&(c[416]);
+ assign q[417] = (((!a[417])^(!b[417]))^((c[417])^(d[417])))|(!e[417]);
+ assign q[418] = ((!a[418])&(!b[418]))^((!c[418])&(!d[418]));
+ assign q[419] = (!a[419])&(!b[419]);
+ assign q[420] = ((a[420])^(!b[420]))|(!c[420]);
+ assign q[421] = ((!a[421])&(!b[421]))&((!c[421])^(d[421]));
+ assign q[422] = ((!a[422])^(b[422]))^((!c[422])&(!d[422]));
+ assign q[423] = (((a[423])|(b[423]))^((c[423])&(d[423])))^(!e[423]);
+ assign q[424] = (a[424])|(b[424]);
+ assign q[425] = (!a[425])^(b[425]);
+ assign q[426] = (!a[426])^(!b[426]);
+ assign q[427] = ((a[427])&(!b[427]))^((!c[427])^(!d[427]));
+ assign q[428] = (((!a[428])&(!b[428]))^(!c[428]))^(d[428]);
+ assign q[429] = (((!a[429])^(b[429]))&(c[429]))&(d[429]);
+ assign q[430] = ((!a[430])&(b[430]))^((c[430])^(d[430]));
+ assign q[431] = (((!a[431])|(b[431]))^((!c[431])|(d[431])))&(e[431]);
+ assign q[432] = (((!a[432])|(!b[432]))|((!c[432])^(d[432])))|(!e[432]);
+ assign q[433] = (((a[433])^(!b[433]))&(!c[433]))&(d[433]);
+ assign q[434] = ((!a[434])&(!b[434]))|((c[434])|(!d[434]));
+ assign q[435] = (!a[435])|(!b[435]);
+ assign q[436] = (((!a[436])^(!b[436]))&((!c[436])|(!d[436])))&(e[436]);
+ assign q[437] = (((!a[437])^(!b[437]))^(!c[437]))&(!d[437]);
+ assign q[438] = (!a[438])^(b[438]);
+ assign q[439] = ((a[439])^(!b[439]))|(c[439]);
+ assign q[440] = ((a[440])^(!b[440]))|((!c[440])&(!d[440]));
+ assign q[441] = (((a[441])&(b[441]))^((c[441])&(d[441])))|(e[441]);
+ assign q[442] = (!a[442])|(b[442]);
+ assign q[443] = (!a[443])^(b[443]);
+ assign q[444] = ((a[444])^(!b[444]))|((c[444])&(d[444]));
+ assign q[445] = (((a[445])|(!b[445]))&(c[445]))|(d[445]);
+ assign q[446] = ((a[446])&(b[446]))^((c[446])^(!d[446]));
+ assign q[447] = ((!a[447])&(!b[447]))^(!c[447]);
+ assign q[448] = (((!a[448])^(b[448]))&(c[448]))|(!d[448]);
+ assign q[449] = (((a[449])|(!b[449]))|((c[449])&(d[449])))|(!e[449]);
+ assign q[450] = (((!a[450])|(b[450]))|(c[450]))^(!d[450]);
+ assign q[451] = ((a[451])^(b[451]))|((c[451])^(d[451]));
+ assign q[452] = (((a[452])^(!b[452]))|(c[452]))|(d[452]);
+ assign q[453] = (!a[453])^(!b[453]);
+ assign q[454] = (((a[454])|(!b[454]))|(c[454]))^(d[454]);
+ assign q[455] = ((!a[455])&(b[455]))^((!c[455])|(!d[455]));
+ assign q[456] = (((a[456])^(!b[456]))|((c[456])^(d[456])))^(e[456]);
+ assign q[457] = (((a[457])&(!b[457]))^(c[457]))|(d[457]);
+ assign q[458] = (((!a[458])^(b[458]))^(c[458]))&(!d[458]);
+ assign q[459] = (((!a[459])&(b[459]))^((!c[459])&(!d[459])))&(e[459]);
+ assign q[460] = ((!a[460])^(!b[460]))|((c[460])&(!d[460]));
+ assign q[461] = ((a[461])&(!b[461]))&(c[461]);
+ assign q[462] = (((a[462])|(b[462]))^((c[462])^(d[462])))|(!e[462]);
+ assign q[463] = (((a[463])|(!b[463]))&((!c[463])|(d[463])))|(e[463]);
+ assign q[464] = (((!a[464])^(b[464]))&((!c[464])|(!d[464])))^(e[464]);
+ assign q[465] = ((!a[465])|(b[465]))&((c[465])&(d[465]));
+ assign q[466] = (((!a[466])^(b[466]))|((!c[466])&(d[466])))&(e[466]);
+ assign q[467] = (((!a[467])|(!b[467]))&((!c[467])&(!d[467])))^(!e[467]);
+ assign q[468] = ((!a[468])^(!b[468]))&((c[468])&(!d[468]));
+ assign q[469] = (((a[469])^(b[469]))^(c[469]))&(!d[469]);
+ assign q[470] = (((a[470])&(b[470]))^(c[470]))&(d[470]);
+ assign q[471] = (((!a[471])&(b[471]))^(c[471]))&(!d[471]);
+ assign q[472] = (((!a[472])|(b[472]))|((!c[472])|(!d[472])))|(!e[472]);
+ assign q[473] = (((a[473])|(b[473]))|((c[473])^(d[473])))|(e[473]);
+ assign q[474] = (a[474])^(!b[474]);
+ assign q[475] = (a[475])&(!b[475]);
+ assign q[476] = (((a[476])^(!b[476]))&((c[476])&(d[476])))|(!e[476]);
+ assign q[477] = ((a[477])^(b[477]))&(!c[477]);
+ assign q[478] = (((a[478])|(!b[478]))&((c[478])^(d[478])))|(e[478]);
+ assign q[479] = (((a[479])|(!b[479]))&((c[479])&(!d[479])))|(!e[479]);
+ assign q[480] = (((!a[480])|(b[480]))&((!c[480])|(!d[480])))|(e[480]);
+ assign q[481] = (((!a[481])&(b[481]))|((!c[481])^(d[481])))&(!e[481]);
+ assign q[482] = (a[482])^(!b[482]);
+ assign q[483] = (a[483])|(b[483]);
+ assign q[484] = (((a[484])|(!b[484]))&(c[484]))|(!d[484]);
+ assign q[485] = (((a[485])^(!b[485]))&(c[485]))|(!d[485]);
+ assign q[486] = ((!a[486])^(b[486]))&(c[486]);
+ assign q[487] = ((!a[487])&(b[487]))^((!c[487])^(!d[487]));
+ assign q[488] = ((a[488])&(b[488]))^((c[488])^(d[488]));
+ assign q[489] = (a[489])^(!b[489]);
+ assign q[490] = (((!a[490])^(b[490]))&(!c[490]))|(!d[490]);
+ assign q[491] = (a[491])^(!b[491]);
+ assign q[492] = (!a[492])|(!b[492]);
+ assign q[493] = (((!a[493])|(!b[493]))|((c[493])^(d[493])))^(e[493]);
+ assign q[494] = (((a[494])&(b[494]))^((c[494])&(!d[494])))&(e[494]);
+ assign q[495] = (((a[495])|(!b[495]))|((!c[495])^(d[495])))^(!e[495]);
+ assign q[496] = (((a[496])^(b[496]))&((!c[496])^(!d[496])))&(!e[496]);
+ assign q[497] = (((a[497])^(!b[497]))|((!c[497])&(d[497])))|(e[497]);
+ assign q[498] = (((!a[498])|(!b[498]))&(c[498]))&(!d[498]);
+ assign q[499] = (((a[499])|(b[499]))^((c[499])^(!d[499])))|(!e[499]);
+ assign q[500] = ((a[500])&(b[500]))^((!c[500])^(!d[500]));
+ assign q[501] = (((a[501])&(!b[501]))|(!c[501]))|(!d[501]);
+ assign q[502] = (((a[502])^(!b[502]))^(!c[502]))|(!d[502]);
+ assign q[503] = (((!a[503])&(b[503]))|(!c[503]))^(!d[503]);
+ assign q[504] = (((a[504])&(b[504]))|(c[504]))|(d[504]);
+ assign q[505] = (((!a[505])&(b[505]))&((c[505])&(!d[505])))^(!e[505]);
+ assign q[506] = (((!a[506])|(b[506]))|(c[506]))&(!d[506]);
+ assign q[507] = (((!a[507])^(b[507]))^(c[507]))&(d[507]);
+ assign q[508] = (((!a[508])&(b[508]))|((!c[508])|(d[508])))|(!e[508]);
+ assign q[509] = (!a[509])|(b[509]);
+ assign q[510] = (((a[510])|(!b[510]))^(c[510]))^(d[510]);
+ assign q[511] = ((!a[511])|(!b[511]))|((c[511])|(d[511]));
+ assign q[512] = ((a[512])|(!b[512]))&((!c[512])&(d[512]));
+ assign q[513] = (!a[513])&(!b[513]);
+ assign q[514] = (((a[514])|(!b[514]))^(!c[514]))&(d[514]);
+ assign q[515] = (((!a[515])|(!b[515]))^(c[515]))|(!d[515]);
+ assign q[516] = ((a[516])|(b[516]))|((c[516])&(!d[516]));
+ assign q[517] = (((a[517])^(!b[517]))^((c[517])&(!d[517])))&(e[517]);
+ assign q[518] = (((a[518])&(!b[518]))^((c[518])|(!d[518])))^(!e[518]);
+ assign q[519] = (((!a[519])^(!b[519]))&((c[519])&(d[519])))|(e[519]);
+ assign q[520] = ((a[520])^(b[520]))|((c[520])&(!d[520]));
+ assign q[521] = (((!a[521])^(!b[521]))^((!c[521])|(!d[521])))|(e[521]);
+ assign q[522] = (((a[522])|(b[522]))|(c[522]))&(!d[522]);
+ assign q[523] = (((a[523])|(b[523]))^((c[523])|(!d[523])))|(e[523]);
+ assign q[524] = ((!a[524])^(b[524]))&(c[524]);
+ assign q[525] = (a[525])&(b[525]);
+ assign q[526] = ((a[526])|(!b[526]))^((!c[526])^(!d[526]));
+ assign q[527] = ((!a[527])&(!b[527]))&((!c[527])|(!d[527]));
+ assign q[528] = ((a[528])^(b[528]))&(!c[528]);
+ assign q[529] = ((a[529])^(b[529]))|((c[529])|(!d[529]));
+ assign q[530] = ((!a[530])&(b[530]))|((c[530])&(!d[530]));
+ assign q[531] = (a[531])|(b[531]);
+ assign q[532] = (((!a[532])|(b[532]))&(c[532]))|(d[532]);
+ assign q[533] = ((a[533])&(!b[533]))&((c[533])&(!d[533]));
+ assign q[534] = (((a[534])&(!b[534]))&(!c[534]))|(d[534]);
+ assign q[535] = ((!a[535])^(b[535]))|((c[535])&(!d[535]));
+ assign q[536] = (((a[536])&(!b[536]))|((c[536])|(!d[536])))|(!e[536]);
+ assign q[537] = ((!a[537])^(b[537]))^((c[537])&(!d[537]));
+ assign q[538] = (((!a[538])&(b[538]))&(c[538]))|(d[538]);
+ assign q[539] = (a[539])|(!b[539]);
+ assign q[540] = (((!a[540])|(!b[540]))^((!c[540])|(d[540])))&(!e[540]);
+ assign q[541] = ((!a[541])&(!b[541]))&((c[541])^(d[541]));
+ assign q[542] = (((a[542])|(!b[542]))^(!c[542]))&(d[542]);
+ assign q[543] = (((!a[543])&(b[543]))&(!c[543]))^(d[543]);
+ assign q[544] = (((!a[544])|(b[544]))&((!c[544])&(d[544])))&(e[544]);
+ assign q[545] = (((a[545])^(!b[545]))|(!c[545]))&(d[545]);
+ assign q[546] = (((!a[546])|(!b[546]))^((!c[546])|(d[546])))&(!e[546]);
+ assign q[547] = (((a[547])^(!b[547]))|(c[547]))|(!d[547]);
+ assign q[548] = (((!a[548])^(b[548]))&((c[548])|(!d[548])))&(!e[548]);
+ assign q[549] = ((a[549])|(!b[549]))^((!c[549])^(d[549]));
+ assign q[550] = ((!a[550])&(!b[550]))^(c[550]);
+ assign q[551] = (((!a[551])&(b[551]))|((c[551])&(!d[551])))&(!e[551]);
+ assign q[552] = (((a[552])|(b[552]))^((!c[552])|(!d[552])))&(!e[552]);
+ assign q[553] = (((a[553])|(b[553]))|((!c[553])|(d[553])))&(e[553]);
+ assign q[554] = (((a[554])&(!b[554]))^(!c[554]))^(d[554]);
+ assign q[555] = ((!a[555])^(b[555]))|(!c[555]);
+ assign q[556] = (((!a[556])^(!b[556]))^(!c[556]))|(d[556]);
+ assign q[557] = ((a[557])&(!b[557]))|((c[557])&(d[557]));
+ assign q[558] = (((a[558])&(!b[558]))^((!c[558])^(!d[558])))^(!e[558]);
+ assign q[559] = (((!a[559])|(!b[559]))|((!c[559])|(!d[559])))^(!e[559]);
+ assign q[560] = ((!a[560])|(!b[560]))|((!c[560])^(d[560]));
+ assign q[561] = (((!a[561])|(b[561]))|(c[561]))^(!d[561]);
+ assign q[562] = ((!a[562])&(!b[562]))&((!c[562])^(!d[562]));
+ assign q[563] = (((a[563])^(b[563]))^(!c[563]))|(d[563]);
+ assign q[564] = (((!a[564])|(b[564]))|(!c[564]))|(d[564]);
+ assign q[565] = (((a[565])&(!b[565]))&((c[565])|(d[565])))|(!e[565]);
+ assign q[566] = (((a[566])&(b[566]))^(!c[566]))|(!d[566]);
+ assign q[567] = (((!a[567])&(!b[567]))&((c[567])&(!d[567])))|(!e[567]);
+ assign q[568] = (((!a[568])|(!b[568]))|(!c[568]))&(!d[568]);
+ assign q[569] = (!a[569])&(b[569]);
+ assign q[570] = ((!a[570])|(b[570]))|((!c[570])|(!d[570]));
+ assign q[571] = (((a[571])|(b[571]))&((!c[571])|(!d[571])))&(!e[571]);
+ assign q[572] = ((!a[572])&(b[572]))|((c[572])|(!d[572]));
+ assign q[573] = ((a[573])^(!b[573]))|((!c[573])|(!d[573]));
+ assign q[574] = (((!a[574])|(b[574]))&((!c[574])&(!d[574])))&(!e[574]);
+ assign q[575] = (((!a[575])&(b[575]))&((!c[575])|(!d[575])))|(!e[575]);
+ assign q[576] = (((a[576])|(!b[576]))^((c[576])^(d[576])))|(e[576]);
+ assign q[577] = (((a[577])|(b[577]))&(c[577]))^(d[577]);
+ assign q[578] = ((a[578])^(!b[578]))&(!c[578]);
+ assign q[579] = (((!a[579])&(!b[579]))^((!c[579])|(!d[579])))|(!e[579]);
+ assign q[580] = (((!a[580])|(b[580]))|(!c[580]))^(d[580]);
+ assign q[581] = ((a[581])&(b[581]))&((!c[581])|(d[581]));
+ assign q[582] = (((!a[582])^(b[582]))|(!c[582]))&(!d[582]);
+ assign q[583] = (a[583])&(b[583]);
+ assign q[584] = (((!a[584])|(b[584]))|((c[584])^(d[584])))^(e[584]);
+ assign q[585] = ((a[585])&(b[585]))|((!c[585])|(!d[585]));
+ assign q[586] = (((a[586])|(b[586]))^((!c[586])|(d[586])))^(!e[586]);
+ assign q[587] = ((a[587])|(!b[587]))&(!c[587]);
+ assign q[588] = (((!a[588])&(b[588]))^((!c[588])|(!d[588])))|(!e[588]);
+ assign q[589] = (((!a[589])|(b[589]))&((!c[589])|(d[589])))&(e[589]);
+ assign q[590] = (((a[590])^(b[590]))^((!c[590])&(d[590])))&(!e[590]);
+ assign q[591] = ((a[591])^(!b[591]))|(!c[591]);
+ assign q[592] = ((a[592])|(!b[592]))^((!c[592])^(!d[592]));
+ assign q[593] = ((!a[593])|(b[593]))&((c[593])&(!d[593]));
+ assign q[594] = ((!a[594])&(!b[594]))^(!c[594]);
+ assign q[595] = (((!a[595])^(b[595]))|(!c[595]))&(d[595]);
+ assign q[596] = (((a[596])|(!b[596]))&(!c[596]))|(!d[596]);
+ assign q[597] = (a[597])&(!b[597]);
+ assign q[598] = ((a[598])^(b[598]))|((!c[598])&(d[598]));
+ assign q[599] = ((a[599])&(b[599]))&(!c[599]);
+ assign q[600] = ((!a[600])|(b[600]))|((!c[600])^(!d[600]));
+ assign q[601] = ((a[601])&(!b[601]))|((c[601])^(!d[601]));
+ assign q[602] = ((!a[602])&(!b[602]))^(!c[602]);
+ assign q[603] = ((a[603])&(!b[603]))^((c[603])&(!d[603]));
+ assign q[604] = ((a[604])&(!b[604]))&((c[604])^(!d[604]));
+ assign q[605] = (((!a[605])|(b[605]))&((c[605])|(d[605])))|(e[605]);
+ assign q[606] = (((a[606])|(!b[606]))|((!c[606])^(d[606])))&(e[606]);
+ assign q[607] = ((a[607])&(!b[607]))^(!c[607]);
+ assign q[608] = ((a[608])^(!b[608]))&(!c[608]);
+ assign q[609] = ((a[609])^(!b[609]))&((!c[609])&(d[609]));
+ assign q[610] = ((!a[610])&(!b[610]))&(c[610]);
+ assign q[611] = (((!a[611])|(b[611]))&(!c[611]))|(!d[611]);
+ assign q[612] = (((a[612])^(!b[612]))&((!c[612])|(d[612])))^(e[612]);
+ assign q[613] = (((!a[613])|(b[613]))^((c[613])&(!d[613])))|(!e[613]);
+ assign q[614] = (a[614])^(!b[614]);
+ assign q[615] = (((!a[615])^(b[615]))|(!c[615]))^(d[615]);
+ assign q[616] = ((!a[616])&(!b[616]))|((c[616])&(!d[616]));
+ assign q[617] = (((a[617])^(b[617]))|(c[617]))|(d[617]);
+ assign q[618] = (((!a[618])^(!b[618]))^((c[618])^(d[618])))^(e[618]);
+ assign q[619] = (((!a[619])|(!b[619]))|(c[619]))^(!d[619]);
+ assign q[620] = (!a[620])^(!b[620]);
+ assign q[621] = ((!a[621])&(!b[621]))&((!c[621])|(d[621]));
+ assign q[622] = (((a[622])^(b[622]))&((!c[622])|(!d[622])))|(!e[622]);
+ assign q[623] = (((a[623])&(!b[623]))^(c[623]))&(d[623]);
+ assign q[624] = (((a[624])&(b[624]))|(c[624]))^(!d[624]);
+ assign q[625] = (((!a[625])^(!b[625]))&((!c[625])|(d[625])))&(!e[625]);
+ assign q[626] = (((!a[626])&(!b[626]))^(!c[626]))|(!d[626]);
+ assign q[627] = ((!a[627])|(b[627]))|(c[627]);
+ assign q[628] = (((!a[628])&(!b[628]))^((!c[628])|(!d[628])))^(e[628]);
+ assign q[629] = ((a[629])&(!b[629]))|((c[629])^(d[629]));
+ assign q[630] = (((!a[630])|(b[630]))^((c[630])|(!d[630])))|(!e[630]);
+ assign q[631] = (((!a[631])&(b[631]))&(!c[631]))^(!d[631]);
+ assign q[632] = (((a[632])&(!b[632]))&(!c[632]))|(!d[632]);
+ assign q[633] = (((a[633])|(b[633]))^(c[633]))|(d[633]);
+ assign q[634] = (((a[634])&(b[634]))|((c[634])|(d[634])))&(e[634]);
+ assign q[635] = (((a[635])&(!b[635]))&((c[635])&(!d[635])))&(!e[635]);
+ assign q[636] = (((!a[636])|(b[636]))^((!c[636])^(d[636])))^(e[636]);
+ assign q[637] = (((a[637])&(b[637]))&((!c[637])&(d[637])))|(!e[637]);
+ assign q[638] = ((!a[638])|(!b[638]))&(!c[638]);
+ assign q[639] = (((a[639])|(!b[639]))&((c[639])|(d[639])))^(!e[639]);
+ assign q[640] = (!a[640])&(b[640]);
+ assign q[641] = ((!a[641])^(!b[641]))^((!c[641])^(d[641]));
+ assign q[642] = (((!a[642])^(!b[642]))&(c[642]))&(!d[642]);
+ assign q[643] = (!a[643])^(!b[643]);
+ assign q[644] = ((!a[644])|(!b[644]))|((!c[644])^(!d[644]));
+ assign q[645] = (((a[645])&(b[645]))^((c[645])&(!d[645])))|(e[645]);
+ assign q[646] = ((a[646])&(!b[646]))&(c[646]);
+ assign q[647] = ((a[647])&(!b[647]))^((!c[647])^(!d[647]));
+ assign q[648] = (((!a[648])|(b[648]))&((!c[648])&(d[648])))|(e[648]);
+ assign q[649] = ((!a[649])|(b[649]))|((c[649])&(!d[649]));
+ assign q[650] = (((!a[650])&(b[650]))^(c[650]))^(d[650]);
+ assign q[651] = ((a[651])|(b[651]))^(!c[651]);
+ assign q[652] = (((a[652])^(b[652]))&((c[652])|(d[652])))|(e[652]);
+ assign q[653] = (((!a[653])|(b[653]))^(c[653]))^(d[653]);
+ assign q[654] = (((a[654])^(!b[654]))^(!c[654]))^(d[654]);
+ assign q[655] = (((!a[655])|(b[655]))|((!c[655])&(d[655])))&(e[655]);
+ assign q[656] = (((a[656])^(b[656]))|((!c[656])^(!d[656])))^(!e[656]);
+ assign q[657] = ((a[657])&(!b[657]))&(c[657]);
+ assign q[658] = (((!a[658])|(b[658]))|((!c[658])^(!d[658])))|(e[658]);
+ assign q[659] = (((a[659])&(b[659]))&((c[659])|(!d[659])))^(e[659]);
+ assign q[660] = (((!a[660])&(!b[660]))|((!c[660])|(!d[660])))&(e[660]);
+ assign q[661] = ((a[661])&(!b[661]))^((!c[661])^(!d[661]));
+ assign q[662] = (((!a[662])|(!b[662]))|((c[662])|(!d[662])))^(!e[662]);
+ assign q[663] = (a[663])^(b[663]);
+ assign q[664] = ((!a[664])&(!b[664]))|((!c[664])&(!d[664]));
+ assign q[665] = (((a[665])|(b[665]))&((!c[665])&(!d[665])))^(e[665]);
+ assign q[666] = (((a[666])&(b[666]))|((c[666])|(d[666])))|(!e[666]);
+ assign q[667] = ((a[667])&(!b[667]))&(!c[667]);
+ assign q[668] = (((!a[668])&(b[668]))^(c[668]))|(d[668]);
+ assign q[669] = (((!a[669])^(b[669]))^((!c[669])^(!d[669])))&(e[669]);
+ assign q[670] = ((!a[670])|(b[670]))&((c[670])|(!d[670]));
+ assign q[671] = (((a[671])&(!b[671]))^(c[671]))^(!d[671]);
+ assign q[672] = (((a[672])^(b[672]))^((c[672])&(!d[672])))|(!e[672]);
+ assign q[673] = (((a[673])^(!b[673]))&((c[673])|(d[673])))|(!e[673]);
+ assign q[674] = ((!a[674])|(!b[674]))|((!c[674])^(d[674]));
+ assign q[675] = ((!a[675])^(b[675]))&((!c[675])|(!d[675]));
+ assign q[676] = (((!a[676])&(!b[676]))^((!c[676])&(d[676])))|(!e[676]);
+ assign q[677] = (((!a[677])&(!b[677]))^(c[677]))&(!d[677]);
+ assign q[678] = (((!a[678])|(!b[678]))&((c[678])^(!d[678])))&(e[678]);
+ assign q[679] = (!a[679])|(b[679]);
+ assign q[680] = (a[680])&(!b[680]);
+ assign q[681] = (((!a[681])|(b[681]))|((c[681])&(d[681])))|(!e[681]);
+ assign q[682] = ((a[682])&(!b[682]))^((!c[682])|(!d[682]));
+ assign q[683] = ((!a[683])&(!b[683]))|((!c[683])^(!d[683]));
+ assign q[684] = (!a[684])&(!b[684]);
+ assign q[685] = (((a[685])&(!b[685]))|((c[685])&(!d[685])))|(!e[685]);
+ assign q[686] = (a[686])^(!b[686]);
+ assign q[687] = (((!a[687])|(b[687]))&((!c[687])|(d[687])))^(e[687]);
+ assign q[688] = (((a[688])^(!b[688]))^((!c[688])&(!d[688])))&(!e[688]);
+ assign q[689] = (((!a[689])^(b[689]))^(c[689]))&(!d[689]);
+ assign q[690] = ((a[690])^(!b[690]))|((!c[690])|(!d[690]));
+ assign q[691] = (((!a[691])^(b[691]))&((!c[691])&(!d[691])))^(!e[691]);
+ assign q[692] = ((a[692])^(!b[692]))|((c[692])|(!d[692]));
+ assign q[693] = (((a[693])&(b[693]))&((!c[693])|(d[693])))^(e[693]);
+ assign q[694] = ((!a[694])^(!b[694]))^((c[694])^(!d[694]));
+ assign q[695] = ((a[695])&(b[695]))&((!c[695])|(!d[695]));
+ assign q[696] = ((a[696])|(b[696]))&((c[696])|(d[696]));
+ assign q[697] = (((!a[697])^(b[697]))|((c[697])^(!d[697])))|(e[697]);
+ assign q[698] = (((a[698])|(b[698]))|((!c[698])&(!d[698])))^(!e[698]);
+ assign q[699] = (((!a[699])|(!b[699]))&(c[699]))|(!d[699]);
+ assign q[700] = ((!a[700])&(b[700]))|((!c[700])|(d[700]));
+ assign q[701] = (((!a[701])|(b[701]))|((c[701])^(d[701])))&(e[701]);
+ assign q[702] = (((!a[702])&(b[702]))&(c[702]))&(!d[702]);
+ assign q[703] = ((!a[703])&(!b[703]))|((c[703])|(d[703]));
+ assign q[704] = (((a[704])^(b[704]))^((c[704])&(d[704])))|(!e[704]);
+ assign q[705] = ((a[705])^(!b[705]))^((!c[705])^(!d[705]));
+ assign q[706] = (((!a[706])^(b[706]))^((!c[706])&(!d[706])))&(e[706]);
+ assign q[707] = ((a[707])&(!b[707]))|((c[707])^(d[707]));
+ assign q[708] = (((a[708])^(b[708]))|(!c[708]))|(d[708]);
+ assign q[709] = (((!a[709])&(b[709]))^((!c[709])&(!d[709])))&(!e[709]);
+ assign q[710] = ((!a[710])^(!b[710]))^(c[710]);
+ assign q[711] = (!a[711])&(b[711]);
+ assign q[712] = ((a[712])^(b[712]))&((c[712])^(!d[712]));
+ assign q[713] = (((a[713])^(b[713]))|((!c[713])^(d[713])))|(!e[713]);
+ assign q[714] = (((a[714])|(b[714]))&((c[714])^(d[714])))^(!e[714]);
+ assign q[715] = ((a[715])|(b[715]))|((!c[715])^(d[715]));
+ assign q[716] = (((a[716])|(b[716]))^(c[716]))^(!d[716]);
+ assign q[717] = (((!a[717])|(!b[717]))^((!c[717])^(!d[717])))^(e[717]);
+ assign q[718] = (((a[718])^(!b[718]))&(!c[718]))^(d[718]);
+ assign q[719] = (((!a[719])^(!b[719]))&((!c[719])|(d[719])))&(!e[719]);
+ assign q[720] = ((!a[720])^(b[720]))|(c[720]);
+ assign q[721] = ((!a[721])&(!b[721]))|((c[721])&(d[721]));
+ assign q[722] = (((!a[722])|(!b[722]))&((!c[722])&(!d[722])))&(!e[722]);
+ assign q[723] = ((a[723])|(b[723]))&((c[723])|(d[723]));
+ assign q[724] = (((!a[724])|(b[724]))^((c[724])^(!d[724])))^(e[724]);
+ assign q[725] = (((!a[725])^(!b[725]))|(!c[725]))&(!d[725]);
+ assign q[726] = ((a[726])^(!b[726]))^(c[726]);
+ assign q[727] = ((!a[727])&(!b[727]))^(c[727]);
+ assign q[728] = ((!a[728])^(!b[728]))^(c[728]);
+ assign q[729] = ((!a[729])&(b[729]))&(!c[729]);
+ assign q[730] = (((a[730])|(!b[730]))&(!c[730]))&(!d[730]);
+ assign q[731] = ((!a[731])|(!b[731]))^(c[731]);
+ assign q[732] = ((!a[732])&(!b[732]))|(c[732]);
+ assign q[733] = ((!a[733])&(!b[733]))^(!c[733]);
+ assign q[734] = (((a[734])|(b[734]))|((!c[734])^(!d[734])))|(!e[734]);
+ assign q[735] = (a[735])^(b[735]);
+ assign q[736] = ((!a[736])|(b[736]))&(!c[736]);
+ assign q[737] = (((!a[737])|(b[737]))|(c[737]))&(!d[737]);
+ assign q[738] = (((a[738])^(b[738]))^((c[738])^(!d[738])))|(e[738]);
+ assign q[739] = (!a[739])^(b[739]);
+ assign q[740] = (((a[740])|(b[740]))^((!c[740])^(!d[740])))&(!e[740]);
+ assign q[741] = ((!a[741])&(b[741]))^((!c[741])^(!d[741]));
+ assign q[742] = (((a[742])|(b[742]))|(c[742]))|(d[742]);
+ assign q[743] = (((a[743])&(b[743]))&((c[743])&(d[743])))|(!e[743]);
+ assign q[744] = (((!a[744])&(!b[744]))^((!c[744])&(d[744])))^(e[744]);
+ assign q[745] = (((!a[745])&(b[745]))^((!c[745])|(!d[745])))^(e[745]);
+ assign q[746] = (((a[746])&(b[746]))^(!c[746]))&(!d[746]);
+ assign q[747] = (((!a[747])^(b[747]))^((!c[747])^(d[747])))|(e[747]);
+ assign q[748] = (((a[748])^(b[748]))|((c[748])^(d[748])))&(!e[748]);
+ assign q[749] = (((a[749])^(b[749]))|((c[749])|(!d[749])))|(e[749]);
+endmodule
diff --git a/tests/arch/gatemate/luttrees.ys b/tests/arch/gatemate/luttrees.ys
new file mode 100644
index 000000000..545643226
--- /dev/null
+++ b/tests/arch/gatemate/luttrees.ys
@@ -0,0 +1,13 @@
+
+read_verilog luttrees.v
+design -save read
+
+hierarchy -top luttrees
+proc
+equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -nomx4 -nomx8 # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd luttrees # Constrain all select calls below inside the top module
+
+select -assert-count 750 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %%
+select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D
+
diff --git a/tests/arch/gowin/lutram.ys b/tests/arch/gowin/lutram.ys
index 56f69e7c5..d668783a2 100644
--- a/tests/arch/gowin/lutram.ys
+++ b/tests/arch/gowin/lutram.ys
@@ -7,12 +7,11 @@ memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
-#ERROR: Called with -verify and proof did fail!
-#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
+sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_1w1r
-select -assert-count 8 t:RAM16S4
+select -assert-count 8 t:RAM16SDP4
# other logic present that is not simple
#select -assert-none t:RAM16S4 %% t:* %D
diff --git a/tests/arch/ice40/memories.ys b/tests/arch/ice40/memories.ys
index 4920a45e3..d480a3abe 100644
--- a/tests/arch/ice40/memories.ys
+++ b/tests/arch/ice40/memories.ys
@@ -71,34 +71,6 @@ synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly
select -assert-min 1 t:SB_DFFE
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_romstyle "ebr" m:memory
-synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set rom_block 1 m:memory
-synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set ram_block 1 m:memory
-synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
# ================================ ROM ================================
# ROM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K
@@ -164,31 +136,3 @@ setattr -set logic_block 1 m:memory
synth_ice40 -top sync_rom; cd sync_rom
select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly
select -assert-min 1 t:SB_LUT4
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ice40 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set ram_block 1 m:memory
-synth_ice40 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_romstyle "ebr" m:memory
-synth_ice40 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set rom_block 1 m:memory
-synth_ice40 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
diff --git a/tests/arch/intel_alm/blockram.ys b/tests/arch/intel_alm/blockram.ys
index c157c3165..3b61b9339 100644
--- a/tests/arch/intel_alm/blockram.ys
+++ b/tests/arch/intel_alm/blockram.ys
@@ -2,5 +2,6 @@ read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 10 sync_ram_sdp
synth_intel_alm -family cyclonev -noiopad -noclkbuf
cd sync_ram_sdp
+select -assert-count 1 t:MISTRAL_NOT
select -assert-count 1 t:MISTRAL_M10K
-select -assert-none t:MISTRAL_M10K %% t:* %D
+select -assert-none t:MISTRAL_NOT t:MISTRAL_M10K %% t:* %D
diff --git a/tests/arch/nexus/blockram.ys b/tests/arch/nexus/blockram.ys
index 9540136d5..a85b5141e 100644
--- a/tests/arch/nexus/blockram.ys
+++ b/tests/arch/nexus/blockram.ys
@@ -3,7 +3,7 @@ design -save read
# Check that we use the right dual and single clock variants
-chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp
+chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp
synth_nexus -top sync_ram_sdp
cd sync_ram_sdp
select -assert-count 1 t:PDPSC16K
@@ -11,7 +11,7 @@ select -assert-none t:PDPSC16K t:INV t:IB t:OB t:VLO t:VHI %% t:* %D
design -reset
read_verilog blockram_dc.v
-chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp_dc
+chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp_dc
synth_nexus -top sync_ram_sdp_dc
cd sync_ram_sdp_dc
select -assert-count 1 t:PDP16K
diff --git a/tests/arch/xilinx/attributes_test.ys b/tests/arch/xilinx/attributes_test.ys
index 58552d8fb..74861850f 100644
--- a/tests/arch/xilinx/attributes_test.ys
+++ b/tests/arch/xilinx/attributes_test.ys
@@ -11,7 +11,7 @@ read_verilog ../common/memory_attributes/attributes_test.v
hierarchy -top distributed_ram
synth_xilinx -top distributed_ram -noiopad
cd distributed_ram # Constrain all select calls below inside the top module
-select -assert-count 8 t:RAM32X1D
+select -assert-count 1 t:RAM32M
# Set ram_style distributed to blockram memory; will be implemented as distributed
design -reset
@@ -19,7 +19,7 @@ read_verilog ../common/memory_attributes/attributes_test.v
setattr -set ram_style "distributed" block_ram/m:*
synth_xilinx -top block_ram -noiopad
cd block_ram # Constrain all select calls below inside the top module
-select -assert-count 32 t:RAM128X1D
+select -assert-count 16 t:RAM256X1S
# Set synthesis, logic_block to blockram memory; will be implemented as distributed
design -reset
@@ -28,7 +28,6 @@ setattr -set logic_block 1 block_ram/m:*
synth_xilinx -top block_ram -noiopad
cd block_ram # Constrain all select calls below inside the top module
select -assert-count 0 t:RAMB18E1
-select -assert-count 32 t:RAM128X1D
# Set ram_style block to a distributed memory; will be implemented as blockram
design -reset
@@ -36,10 +35,3 @@ read_verilog ../common/memory_attributes/attributes_test.v
synth_xilinx -top distributed_ram_manual -noiopad
cd distributed_ram_manual # Constrain all select calls below inside the top module
select -assert-count 1 t:RAMB18E1
-
-# Set synthesis, ram_block block to a distributed memory; will be implemented as blockram
-design -reset
-read_verilog ../common/memory_attributes/attributes_test.v
-synth_xilinx -top distributed_ram_manual_syn -noiopad
-cd distributed_ram_manual_syn # Constrain all select calls below inside the top module
-select -assert-count 1 t:RAMB18E1
diff --git a/tests/arch/xilinx/blockram.ys b/tests/arch/xilinx/blockram.ys
index ed743cf44..c2b7aede7 100644
--- a/tests/arch/xilinx/blockram.ys
+++ b/tests/arch/xilinx/blockram.ys
@@ -2,7 +2,7 @@
### currently. Checking instance counts instead.
# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1
read_verilog ../common/blockram.v
-chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 1 sync_ram_sdp
+chparam -set ADDRESS_WIDTH 12 -set DATA_WIDTH 1 sync_ram_sdp
synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
@@ -35,7 +35,7 @@ chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp
synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 0 t:RAMB18E1
-select -assert-count 4 t:RAM128X1D
+select -assert-count 4 t:RAM64M
# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1
design -reset
@@ -50,7 +50,7 @@ select -assert-count 1 t:RAMB36E1
design -reset
read_verilog ../common/blockram.v
-hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
+hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1
setattr -set ram_style "block" m:memory
synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
@@ -58,23 +58,7 @@ select -assert-count 1 t:RAMB18E1
design -reset
read_verilog ../common/blockram.v
-hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
-setattr -set ram_block 1 m:memory
-synth_xilinx -top sync_ram_sdp -noiopad
-cd sync_ram_sdp
-select -assert-count 1 t:RAMB18E1
-
-design -reset
-read_verilog ../common/blockram.v
-hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
-setattr -set ram_style "dont_infer_a_ram_pretty_please" m:memory
-synth_xilinx -top sync_ram_sdp -noiopad
-cd sync_ram_sdp
-select -assert-count 0 t:RAMB18E1
-
-design -reset
-read_verilog ../common/blockram.v
-hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 10 -chparam DATA_WIDTH 1
+hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1
setattr -set logic_block 1 m:memory
synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
@@ -87,11 +71,3 @@ setattr -set ram_style "block" m:memory
synth_xilinx -top sync_ram_sdp -noiopad
cd sync_ram_sdp
select -assert-count 1 t:RAMB18E1
-
-design -reset
-read_verilog ../common/blockram.v
-hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 8 -chparam DATA_WIDTH 1
-setattr -set ram_block 1 m:memory
-synth_xilinx -top sync_ram_sdp -noiopad
-cd sync_ram_sdp
-select -assert-count 1 t:RAMB18E1
diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys
index cc7354501..34caa8c6c 100644
--- a/tests/arch/xilinx/lutram.ys
+++ b/tests/arch/xilinx/lutram.ys
@@ -33,8 +33,8 @@ design -load postopt
cd lutram_1w1r
select -assert-count 1 t:BUFG
select -assert-count 8 t:FDRE
-select -assert-count 8 t:RAM32X1D
-select -assert-none t:BUFG t:FDRE t:RAM32X1D %% t:* %D
+select -assert-count 1 t:RAM32M
+select -assert-none t:BUFG t:FDRE t:RAM32M %% t:* %D
design -reset
@@ -51,10 +51,11 @@ sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs mite
design -load postopt
cd lutram_1w1r
+dump
select -assert-count 1 t:BUFG
select -assert-count 8 t:FDRE
-select -assert-count 8 t:RAM64X1D
-select -assert-none t:BUFG t:FDRE t:RAM64X1D %% t:* %D
+select -assert-count 8 t:RAM64X1S
+select -assert-none t:BUFG t:FDRE t:RAM64X1S %% t:* %D
design -reset
@@ -133,8 +134,8 @@ design -load postopt
cd lutram_1w1r
select -assert-count 1 t:BUFG
select -assert-count 6 t:FDRE
-select -assert-count 2 t:RAM64M
-select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D
+select -assert-count 6 t:RAM64X1S
+select -assert-none t:BUFG t:FDRE t:RAM64X1S %% t:* %D
design -reset
@@ -153,5 +154,5 @@ design -load postopt
cd lutram_1w1r
select -assert-count 1 t:BUFG
select -assert-count 8 t:FDRE
-select -assert-count 8 t:RAM16X1D
-select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D
+select -assert-count 8 t:RAM16X1S
+select -assert-none t:BUFG t:FDRE t:RAM16X1S %% t:* %D
diff --git a/tests/arch/xilinx/tribuf.sh b/tests/arch/xilinx/tribuf.sh
index bd44395cb..eca33e490 100644
--- a/tests/arch/xilinx/tribuf.sh
+++ b/tests/arch/xilinx/tribuf.sh
@@ -1,5 +1,5 @@
-! ../../../yosys -qp "synth_xilinx" ../common/tribuf.v
-../../../yosys -qp "synth_xilinx -iopad; \
+../../../yosys -f verilog -qp "synth_xilinx" ../common/tribuf.v
+../../../yosys -f verilog -qp "synth_xilinx -iopad; \
select -assert-count 2 t:IBUF; \
select -assert-count 1 t:INV; \
select -assert-count 1 t:OBUFT" ../common/tribuf.v
diff --git a/tests/blif/bug3374.ys b/tests/blif/bug3374.ys
new file mode 100644
index 000000000..792d4de20
--- /dev/null
+++ b/tests/blif/bug3374.ys
@@ -0,0 +1,4 @@
+logger -expect error "Syntax error in line 1!" 1
+read_blif <<EOF
+.model
+EOF
diff --git a/tests/bram/run-single.sh b/tests/bram/run-single.sh
index 98a45b613..429a79e3c 100644
--- a/tests/bram/run-single.sh
+++ b/tests/bram/run-single.sh
@@ -1,6 +1,6 @@
#!/bin/bash
set -e
-../../yosys -qq -p "proc; opt; memory -nomap -bram temp/brams_${2}.txt; opt -fast -full" \
+../../yosys -qq -f verilog -p "proc; opt; memory -nomap -bram temp/brams_${2}.txt; opt -fast -full" \
-l temp/synth_${1}_${2}.log -o temp/synth_${1}_${2}.v temp/brams_${1}.v
iverilog -Dvcd_file=\"temp/tb_${1}_${2}.vcd\" -DSIMLIB_MEMDELAY=1 -o temp/tb_${1}_${2}.tb temp/brams_${1}_tb.v \
temp/brams_${1}_ref.v temp/synth_${1}_${2}.v temp/brams_${2}.v ../../techlibs/common/simlib.v
diff --git a/tests/memlib/.gitignore b/tests/memlib/.gitignore
new file mode 100644
index 000000000..03dbe82ae
--- /dev/null
+++ b/tests/memlib/.gitignore
@@ -0,0 +1,5 @@
+t_*.log
+t_*.out
+t_*.v
+t_*.ys
+run-test.mk
diff --git a/tests/memlib/generate.py b/tests/memlib/generate.py
new file mode 100644
index 000000000..341486584
--- /dev/null
+++ b/tests/memlib/generate.py
@@ -0,0 +1,900 @@
+# TODO:
+
+# - memory initialization
+# - clock polarity combinations
+# - CE/srst/rdwr/be interactions
+# - priority logic
+# - byte enables, wrbe_separate
+# - duplication for read ports
+# - abits/dbits determination
+# - mixed width
+# - swizzles for weird width progressions
+
+
+class Test:
+ def __init__(self, name, src, libs, defs, cells):
+ self.name = name
+ self.src = src
+ self.libs = libs
+ self.defs = defs
+ self.cells = cells
+
+TESTS = []
+
+### basic sanity tests
+
+ASYNC = """
+module top(clk, ra, wa, rd, wd, we);
+
+localparam ABITS = {abits};
+localparam DBITS = {dbits};
+
+input wire clk;
+input wire we;
+input wire [ABITS-1:0] ra, wa;
+input wire [DBITS-1:0] wd;
+output wire [DBITS-1:0] rd;
+
+reg [DBITS-1:0] mem [0:2**ABITS-1];
+
+always @(posedge clk)
+ if (we)
+ mem[wa] <= wd;
+
+assign rd = mem[ra];
+
+endmodule
+"""
+
+ASYNC_SMALL = ASYNC.format(abits=6, dbits=6)
+ASYNC_BIG = ASYNC.format(abits=11, dbits=10)
+
+TESTS += [
+ Test("async_big", ASYNC_BIG, ["lut", "block_tdp"], [], {"RAM_LUT": 384}),
+ Test("async_big_block", ASYNC_BIG, ["block_tdp"], [], {"RAM_BLOCK_TDP": 0}),
+ Test("async_small", ASYNC_SMALL, ["lut", "block_tdp"], [], {"RAM_LUT": 8}),
+ Test("async_small_block", ASYNC_SMALL, ["block_tdp"], [], {"RAM_BLOCK_TDP": 0}),
+]
+
+SYNC = """
+module top(clk, ra, wa, rd, wd, we);
+
+localparam ABITS = {abits};
+localparam DBITS = {dbits};
+
+input wire clk;
+input wire we;
+input wire [ABITS-1:0] ra, wa;
+input wire [DBITS-1:0] wd;
+output reg [DBITS-1:0] rd;
+
+{attr}
+reg [DBITS-1:0] mem [0:2**ABITS-1];
+
+always @(posedge clk)
+ if (we)
+ mem[wa] <= wd;
+
+always @(posedge clk)
+ rd <= mem[ra];
+
+endmodule
+"""
+
+SYNC_SMALL = SYNC.format(abits=6, dbits=6, attr="")
+SYNC_SMALL_BLOCK = SYNC.format(abits=6, dbits=6, attr='(* ram_style="block" *)')
+SYNC_BIG = SYNC.format(abits=11, dbits=10, attr="")
+SYNC_MID = SYNC.format(abits=6, dbits=16, attr="")
+
+TESTS += [
+ Test("sync_big", SYNC_BIG, ["lut", "block_tdp"], [], {"RAM_BLOCK_TDP": 20}),
+ Test("sync_big_sdp", SYNC_BIG, ["lut", "block_sdp"], [], {"RAM_BLOCK_SDP": 20}),
+ Test("sync_big_lut", SYNC_BIG, ["lut"], [], {"RAM_LUT": 384}),
+ Test("sync_small", SYNC_SMALL, ["lut", "block_tdp"], [], {"RAM_LUT": 8}),
+ Test("sync_small_block", SYNC_SMALL, ["block_tdp"], [], {"RAM_BLOCK_TDP": 1}),
+ Test("sync_small_block_attr", SYNC_SMALL_BLOCK, ["lut", "block_tdp"], [], {"RAM_BLOCK_TDP": 1}),
+]
+
+### basic TDP test
+
+TDP = """
+module top(clka, clkb, addra, addrb, rda, rdb, wda, wdb, wea, web);
+
+localparam ABITS = 6;
+localparam DBITS = 6;
+
+input wire clka, clkb;
+input wire wea, web;
+input wire [ABITS-1:0] addra, addrb;
+input wire [DBITS-1:0] wda, wdb;
+output reg [DBITS-1:0] rda, rdb;
+
+reg [DBITS-1:0] mem [0:2**ABITS-1];
+
+always @(posedge clka)
+ if (wea)
+ mem[addra] <= wda;
+ else
+ rda <= mem[addra];
+
+always @(posedge clkb)
+ if (web)
+ mem[addrb] <= wdb;
+ else
+ rdb <= mem[addrb];
+
+endmodule
+"""
+
+TESTS += [
+ Test("tdp", TDP, ["block_tdp", "block_sdp"], [], {"RAM_BLOCK_TDP": 1}),
+]
+
+# shared clock
+
+SYNC_2CLK = """
+module top(rclk, wclk, ra, wa, rd, wd, we);
+
+localparam ABITS = 6;
+localparam DBITS = 16;
+
+input wire rclk, wclk;
+input wire we;
+input wire [ABITS-1:0] ra, wa;
+input wire [DBITS-1:0] wd;
+output reg [DBITS-1:0] rd;
+
+reg [DBITS-1:0] mem [0:2**ABITS-1];
+
+always @(posedge wclk)
+ if (we)
+ mem[wa] <= wd;
+
+always @(posedge rclk)
+ rd <= mem[ra];
+
+endmodule
+"""
+
+TESTS += [
+ Test("sync_2clk", SYNC_2CLK, ["block_sdp"], [], {"RAM_BLOCK_SDP": 1}),
+ Test("sync_shared", SYNC_MID, ["block_sdp_1clk"], [], {"RAM_BLOCK_SDP_1CLK": 1}),
+ Test("sync_2clk_shared", SYNC_2CLK, ["block_sdp_1clk"], [], {"RAM_BLOCK_SDP_1CLK": 0}),
+]
+
+# inter-port transparency
+
+SYNC_TRANS = """
+module top(clk, ra, wa, rd, wd, we);
+
+localparam ABITS = 6;
+localparam DBITS = 16;
+
+input wire clk;
+input wire we;
+input wire [ABITS-1:0] ra, wa;
+input wire [DBITS-1:0] wd;
+output reg [DBITS-1:0] rd;
+
+reg [DBITS-1:0] mem [0:2**ABITS-1];
+
+always @(negedge clk)
+ if (we)
+ mem[wa] <= wd;
+
+always @(negedge clk) begin
+ rd <= mem[ra];
+ if (we && ra == wa)
+ rd <= wd;
+end
+
+endmodule
+"""
+
+TESTS += [
+ Test("sync_trans_old_old", SYNC_MID, ["block_sdp_1clk"], ["TRANS_OLD"], {"RAM_BLOCK_SDP_1CLK": (1, {"OPTION_TRANS": 0})}),
+ Test("sync_trans_old_new", SYNC_MID, ["block_sdp_1clk"], ["TRANS_NEW"], {"RAM_BLOCK_SDP_1CLK": 1}),
+ Test("sync_trans_old_none", SYNC_MID, ["block_sdp_1clk"], [], {"RAM_BLOCK_SDP_1CLK": 1}),
+ Test("sync_trans_new_old", SYNC_TRANS, ["block_sdp_1clk"], ["TRANS_OLD"], {"RAM_BLOCK_SDP_1CLK": 1}),
+ Test("sync_trans_new_new", SYNC_TRANS, ["block_sdp_1clk"], ["TRANS_NEW"], {"RAM_BLOCK_SDP_1CLK": (1, {"OPTION_TRANS": 1})}),
+ Test("sync_trans_new_none", SYNC_TRANS, ["block_sdp_1clk"], [], {"RAM_BLOCK_SDP_1CLK": 1}),
+]
+
+# rdwr checks
+
+SP_NO_CHANGE = """
+module top(clk, addr, rd, wd, we);
+
+input wire clk;
+input wire we;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+always @(negedge clk) begin
+ if (we)
+ mem[addr] <= wd;
+ else
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_NO_CHANGE_BE = """
+module top(clk, addr, rd, wd, we);
+
+input wire clk;
+input wire [1:0] we;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+always @(negedge clk) begin
+ if (we) begin
+ if (we[0])
+ mem[addr][7:0] <= wd[7:0];
+ if (we[1])
+ mem[addr][15:8] <= wd[15:8];
+ end else
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_NEW = """
+module top(clk, addr, rd, wd, we);
+
+input wire clk;
+input wire we;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+always @(negedge clk) begin
+ if (we) begin
+ mem[addr] <= wd;
+ rd <= wd;
+ end else
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_NEW_BE = """
+module top(clk, addr, rd, wd, we);
+
+input wire clk;
+input wire [1:0] we;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+always @(negedge clk) begin
+ rd <= mem[addr];
+ if (we[0]) begin
+ mem[addr][7:0] <= wd[7:0];
+ rd[7:0] <= wd[7:0];
+ end
+ if (we[1]) begin
+ mem[addr][15:8] <= wd[15:8];
+ rd[15:8] <= wd[15:8];
+ end
+end
+
+endmodule
+"""
+
+SP_OLD = """
+module top(clk, addr, rd, wd, we);
+
+input wire clk;
+input wire we;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+always @(negedge clk) begin
+ if (we)
+ mem[addr] <= wd;
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_OLD_BE = """
+module top(clk, addr, rd, wd, we);
+
+input wire clk;
+input wire [1:0] we;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+always @(negedge clk) begin
+ if (we[0])
+ mem[addr][7:0] <= wd[7:0];
+ if (we[1])
+ mem[addr][15:8] <= wd[15:8];
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+TESTS += [
+ Test("sp_nc_none", SP_NO_CHANGE, ["block_sp"], [], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_none", SP_NEW, ["block_sp"], [], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_none", SP_OLD, ["block_sp"], [], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_nc", SP_NO_CHANGE, ["block_sp"], ["RDWR_NO_CHANGE"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_nc", SP_NEW, ["block_sp"], ["RDWR_NO_CHANGE"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_nc", SP_OLD, ["block_sp"], ["RDWR_NO_CHANGE"], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_new", SP_NO_CHANGE, ["block_sp"], ["RDWR_NEW"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_new", SP_NEW, ["block_sp"], ["RDWR_NEW"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_new", SP_OLD, ["block_sp"], ["RDWR_NEW"], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_old", SP_NO_CHANGE, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_old", SP_NEW, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_old", SP_OLD, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_nc_new_only", SP_NO_CHANGE, ["block_sp"], ["RDWR_NEW_ONLY"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_new_only", SP_NEW, ["block_sp"], ["RDWR_NEW_ONLY"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_new_only", SP_OLD, ["block_sp"], ["RDWR_NEW_ONLY"], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_new_only_be", SP_NO_CHANGE_BE, ["block_sp"], ["RDWR_NEW_ONLY"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_new_only_be", SP_NEW_BE, ["block_sp"], ["RDWR_NEW_ONLY"], {"RAM_BLOCK_SP": 2}),
+ Test("sp_old_new_only_be", SP_OLD_BE, ["block_sp"], ["RDWR_NEW_ONLY"], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_new_be", SP_NO_CHANGE_BE, ["block_sp"], ["RDWR_NEW"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_new_be", SP_NEW_BE, ["block_sp"], ["RDWR_NEW"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_new_be", SP_OLD_BE, ["block_sp"], ["RDWR_NEW"], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_old_be", SP_NO_CHANGE_BE, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_old_be", SP_NEW_BE, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_old_old_be", SP_OLD_BE, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_nc_nc_be", SP_NO_CHANGE_BE, ["block_sp"], ["RDWR_NO_CHANGE"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_nc_be", SP_NEW_BE, ["block_sp"], ["RDWR_NO_CHANGE"], {"RAM_BLOCK_SP": 2}),
+ Test("sp_old_nc_be", SP_OLD_BE, ["block_sp"], ["RDWR_NO_CHANGE"], {"RAM_BLOCK_SP": 0}),
+ Test("sp_nc_auto", SP_NO_CHANGE, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_auto", SP_NEW, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": (1, {"OPTION_RDWR": "NEW"})}),
+ Test("sp_old_auto", SP_OLD, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": (1, {"OPTION_RDWR": "OLD"})}),
+ Test("sp_nc_auto_be", SP_NO_CHANGE_BE, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_new_auto_be", SP_NEW_BE, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": (1, {"OPTION_RDWR": "NEW"})}),
+ Test("sp_old_auto_be", SP_OLD_BE, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": (1, {"OPTION_RDWR": "OLD"})}),
+]
+
+SP_INIT = """
+module top(clk, addr, rd, wd, we, re);
+
+input wire clk;
+input wire we, re;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+initial rd = {ival};
+
+always @(posedge clk) begin
+ if (we)
+ mem[addr] <= wd;
+ if (re)
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_INIT_X = SP_INIT.format(ival="16'hxxxx")
+SP_INIT_0 = SP_INIT.format(ival="16'h0000")
+SP_INIT_V = SP_INIT.format(ival="16'h55aa")
+
+TESTS += [
+ Test("sp_init_x_x", SP_INIT_X, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_x_x_re", SP_INIT_X, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_x_x_ce", SP_INIT_X, ["block_sp"], ["CLKEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_0_x", SP_INIT_0, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_0_x_re", SP_INIT_0, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_0_0", SP_INIT_0, ["block_sp"], ["RDINIT_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_0_0_re", SP_INIT_0, ["block_sp"], ["RDINIT_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_0_any", SP_INIT_0, ["block_sp"], ["RDINIT_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_0_any_re", SP_INIT_0, ["block_sp"], ["RDINIT_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_v_x", SP_INIT_V, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_v_x_re", SP_INIT_V, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_v_0", SP_INIT_V, ["block_sp"], ["RDINIT_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_v_0_re", SP_INIT_V, ["block_sp"], ["RDINIT_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_v_any", SP_INIT_V, ["block_sp"], ["RDINIT_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_init_v_any_re", SP_INIT_V, ["block_sp"], ["RDINIT_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+]
+
+SP_ARST = """
+module top(clk, addr, rd, wd, we, re, ar);
+
+input wire clk;
+input wire we, re, ar;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+initial rd = {ival};
+
+always @(posedge clk) begin
+ if (we)
+ mem[addr] <= wd;
+end
+always @(posedge clk, posedge ar) begin
+ if (ar)
+ rd <= {aval};
+ else if (re)
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_ARST_X = SP_ARST.format(ival="16'hxxxx", aval="16'hxxxx")
+SP_ARST_0 = SP_ARST.format(ival="16'hxxxx", aval="16'h0000")
+SP_ARST_V = SP_ARST.format(ival="16'hxxxx", aval="16'h55aa")
+SP_ARST_E = SP_ARST.format(ival="16'h55aa", aval="16'h55aa")
+SP_ARST_N = SP_ARST.format(ival="16'h1234", aval="16'h55aa")
+
+TESTS += [
+ Test("sp_arst_x_x", SP_ARST_X, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_x_x_re", SP_ARST_X, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_x", SP_ARST_0, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_x_re", SP_ARST_0, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_0", SP_ARST_0, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_0_re", SP_ARST_0, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_any", SP_ARST_0, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_any_re", SP_ARST_0, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_init", SP_ARST_0, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_0_init_re", SP_ARST_0, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_x", SP_ARST_V, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_x_re", SP_ARST_V, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_0", SP_ARST_V, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_0_re", SP_ARST_V, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_any", SP_ARST_V, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_any_re", SP_ARST_V, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_init", SP_ARST_V, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_v_init_re", SP_ARST_V, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_x", SP_ARST_E, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_x_re", SP_ARST_E, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_0", SP_ARST_E, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_0_re", SP_ARST_E, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_any", SP_ARST_E, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_any_re", SP_ARST_E, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_init", SP_ARST_E, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_e_init_re", SP_ARST_E, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_x", SP_ARST_N, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_x_re", SP_ARST_N, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_0", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_0_re", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_any", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_any_re", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_init", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_arst_n_init_re", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+]
+
+SP_SRST = """
+module top(clk, addr, rd, wd, we, re, sr);
+
+input wire clk;
+input wire we, re, sr;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+initial rd = {ival};
+
+always @(posedge clk) begin
+ if (we)
+ mem[addr] <= wd;
+end
+always @(posedge clk) begin
+ if (sr)
+ rd <= {sval};
+ else if (re)
+ rd <= mem[addr];
+end
+
+endmodule
+"""
+
+SP_SRST_G = """
+module top(clk, addr, rd, wd, we, re, sr);
+
+input wire clk;
+input wire we, re, sr;
+input wire [3:0] addr;
+input wire [15:0] wd;
+output reg [15:0] rd;
+
+reg [15:0] mem [0:15];
+
+initial rd = {ival};
+
+always @(posedge clk) begin
+ if (we)
+ mem[addr] <= wd;
+end
+always @(posedge clk) begin
+ if (re) begin
+ if (sr)
+ rd <= {sval};
+ else
+ rd <= mem[addr];
+ end
+end
+
+endmodule
+"""
+
+SP_SRST_X = SP_SRST.format(ival="16'hxxxx", sval="16'hxxxx")
+SP_SRST_0 = SP_SRST.format(ival="16'hxxxx", sval="16'h0000")
+SP_SRST_V = SP_SRST.format(ival="16'hxxxx", sval="16'h55aa")
+SP_SRST_E = SP_SRST.format(ival="16'h55aa", sval="16'h55aa")
+SP_SRST_N = SP_SRST.format(ival="16'h1234", sval="16'h55aa")
+SP_SRST_GV = SP_SRST_G.format(ival="16'hxxxx", sval="16'h55aa")
+
+TESTS += [
+ Test("sp_srst_x_x", SP_SRST_X, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_x_x_re", SP_SRST_X, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_x", SP_SRST_0, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_x_re", SP_SRST_0, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_0", SP_SRST_0, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_0_re", SP_SRST_0, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_any", SP_SRST_0, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_any_re", SP_SRST_0, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_init", SP_SRST_0, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_0_init_re", SP_SRST_0, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_x", SP_SRST_V, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_x_re", SP_SRST_V, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_0", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_0_re", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_any", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_any_re", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_any_re_gated", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY_RE", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_any_ce", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "CLKEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_any_ce_gated", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY_CE", "CLKEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_init", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_v_init_re", SP_SRST_V, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_x", SP_SRST_E, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_x_re", SP_SRST_E, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_0", SP_SRST_E, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_0_re", SP_SRST_E, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_any", SP_SRST_E, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_any_re", SP_SRST_E, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_init", SP_SRST_E, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_e_init_re", SP_SRST_E, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_x", SP_SRST_N, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_x_re", SP_SRST_N, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_0", SP_SRST_N, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_0_re", SP_SRST_N, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_any", SP_SRST_N, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_any_re", SP_SRST_N, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_init", SP_SRST_N, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_n_init_re", SP_SRST_N, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_x", SP_SRST_GV, ["block_sp"], ["RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_x_re", SP_SRST_GV, ["block_sp"], ["RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_0", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_0_re", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_0", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_any", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_any_re", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_any_re_gated", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY_RE", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_any_ce", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY", "CLKEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_any_ce_gated", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_ANY_CE", "CLKEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_init", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+ Test("sp_srst_gv_init_re", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}),
+]
+
+WIDE_SDP = """
+module top(rclk, ra, rd, re, rr, wclk, wa, wd, we);
+
+input wire rclk, wclk, re, rr;
+input wire [2**({ww}-{bw})-1:0] we;
+input wire [{aw}-{rw}+{xw}-1:0] ra;
+input wire [{aw}-{ww}+{xw}-1:0] wa;
+input wire [2**{ww}-1:0] wd;
+output reg [2**{rw}-1:0] rd;
+
+reg mem [0:2**{aw}-1];
+
+initial mem[3] = 0;
+initial mem[17] = 1;
+initial mem[23] = 0;
+initial mem[24] = 1;
+
+integer i, j;
+always @(posedge wclk)
+ for (i = 0; i < 2**{ww}; i = i + 2**{bw})
+ if (we[i >> {bw}])
+ for (j = 0; j < 2**{bw}; j = j + 1)
+ mem[wa << {ww} | i | j] <= wd[i | j];
+
+always @(posedge rclk)
+ if (rr)
+ rd <= {sval};
+ else if (re)
+ for (i = 0; i < 2**{rw}; i = i + 1)
+ rd[i] <= mem[ra << {rw} | i];
+
+endmodule
+"""
+
+for (aw, rw, ww, bw, xw, sval, cnt) in [
+ (6, 1, 1, 1, 1, "2'h1", 1),
+ (7, 1, 1, 1, 1, "2'h2", 2),
+ (8, 1, 1, 1, 1, "2'h3", 4),
+ (6, 0, 0, 0, 0, "2'h0", 1),
+ (6, 1, 0, 0, 0, "2'h0", 1),
+ (6, 2, 0, 0, 0, "2'h0", 1),
+ (6, 3, 0, 0, 0, "2'h0", 1),
+ (6, 4, 0, 0, 0, "2'h0", 1),
+ (6, 5, 0, 0, 0, "2'h0", 2),
+ (6, 0, 1, 0, 0, "2'h0", 2),
+ (6, 0, 1, 1, 0, "2'h0", 1),
+ (6, 0, 2, 0, 0, "2'h0", 4),
+ (6, 0, 2, 2, 0, "2'h0", 1),
+ (6, 0, 3, 2, 0, "2'h0", 1),
+ (6, 0, 4, 2, 0, "2'h0", 1),
+ (6, 0, 5, 2, 0, "2'h0", 2),
+ (7, 0, 0, 0, 0, "2'h0", 2),
+ (7, 1, 0, 0, 0, "2'h0", 2),
+ (7, 2, 0, 0, 0, "2'h0", 2),
+ (7, 3, 0, 0, 0, "2'h0", 2),
+ (7, 4, 0, 0, 0, "2'h0", 2),
+ (7, 5, 0, 0, 0, "2'h0", 2),
+ (7, 0, 1, 0, 0, "2'h0", 2),
+ (7, 0, 1, 1, 0, "2'h0", 2),
+ (7, 0, 2, 0, 0, "2'h0", 4),
+ (7, 0, 2, 2, 0, "2'h0", 2),
+ (7, 0, 3, 2, 0, "2'h0", 2),
+ (7, 0, 4, 2, 0, "2'h0", 2),
+ (7, 0, 5, 2, 0, "2'h0", 2),
+]:
+ TESTS.append(Test(
+ f"wide_sdp_a{aw}r{rw}w{ww}b{bw}x{xw}",
+ WIDE_SDP.format(aw=aw, rw=rw, ww=ww, bw=bw, xw=xw, sval=sval),
+ ["wide_sdp"], [],
+ {"RAM_WIDE_SDP": cnt}
+ ))
+
+WIDE_SP = """
+module top(clk, a, rd, re, rr, wd, we);
+
+input wire clk, re, rr;
+input wire [2**({ww}-{bw})-1:0] we;
+input wire [{aw}-1:0] a;
+input wire [2**{ww}-1:0] wd;
+output reg [2**{rw}-1:0] rd;
+
+reg mem [0:2**{aw}-1];
+
+initial mem[3] = 0;
+initial mem[17] = 1;
+initial mem[23] = 0;
+initial mem[24] = 1;
+
+integer i, j;
+always @(posedge clk) begin
+ for (i = 0; i < 2**{ww}; i = i + 2**{bw})
+ if (we[i >> {bw}])
+ for (j = 0; j < 2**{bw}; j = j + 1)
+ mem[a & ~((1 << {ww}) - 1) | i | j] <= wd[i | j];
+ if (rr)
+ rd <= {sval};
+ else if (re)
+ for (i = 0; i < 2**{rw}; i = i + 1)
+ rd[i] <= mem[a & ~((1 << {rw}) - 1) | i];
+end
+
+endmodule
+"""
+
+for (aw, rw, ww, bw, sval, cnt) in [
+ (6, 1, 1, 1, "2'h1", 1),
+ (7, 1, 1, 1, "2'h2", 2),
+ (8, 1, 1, 1, "2'h3", 4),
+ (6, 0, 0, 0, "2'h0", 1),
+ (6, 1, 0, 0, "2'h0", 1),
+ (6, 2, 0, 0, "2'h0", 1),
+ (6, 3, 0, 0, "2'h0", 1),
+ (6, 4, 0, 0, "2'h0", 1),
+ (6, 5, 0, 0, "2'h0", 2),
+ (6, 0, 1, 0, "2'h0", 2),
+ (6, 0, 1, 1, "2'h0", 1),
+ (6, 0, 2, 0, "2'h0", 4),
+ (6, 0, 2, 2, "2'h0", 1),
+ (6, 0, 3, 2, "2'h0", 1),
+ (6, 0, 4, 2, "2'h0", 1),
+ (6, 0, 5, 2, "2'h0", 2),
+ (7, 0, 0, 0, "2'h0", 2),
+ (7, 1, 0, 0, "2'h0", 2),
+ (7, 2, 0, 0, "2'h0", 2),
+ (7, 3, 0, 0, "2'h0", 2),
+ (7, 4, 0, 0, "2'h0", 2),
+ (7, 5, 0, 0, "2'h0", 2),
+ (7, 0, 1, 0, "2'h0", 2),
+ (7, 0, 1, 1, "2'h0", 2),
+ (7, 0, 2, 0, "2'h0", 4),
+ (7, 0, 2, 2, "2'h0", 2),
+ (7, 0, 3, 2, "2'h0", 2),
+ (7, 0, 4, 2, "2'h0", 2),
+ (7, 0, 5, 2, "2'h0", 2),
+]:
+ TESTS.append(Test(
+ f"wide_sp_mix_a{aw}r{rw}w{ww}b{bw}",
+ WIDE_SP.format(aw=aw, rw=rw, ww=ww, bw=bw, sval=sval),
+ ["wide_sp"], ["WIDTH_MIX"],
+ {"RAM_WIDE_SP": cnt}
+ ))
+
+for (aw, rw, ww, bw, sval, cnt) in [
+ (6, 1, 1, 1, "2'h1", 1),
+ (7, 1, 1, 1, "2'h2", 2),
+ (8, 1, 1, 1, "2'h3", 4),
+ (6, 0, 0, 0, "2'h0", 1),
+ (6, 1, 0, 0, "2'h0", 2),
+ (6, 2, 0, 0, "2'h0", 4),
+ (6, 3, 0, 0, "2'h0", 4),
+ (6, 4, 0, 0, "2'h0", 4),
+ (6, 5, 0, 0, "2'h0", 8),
+ (6, 0, 1, 0, "2'h0", 2),
+ (6, 0, 1, 1, "2'h0", 1),
+ (6, 0, 2, 0, "2'h0", 4),
+ (6, 0, 2, 2, "2'h0", 1),
+ (6, 0, 3, 2, "2'h0", 1),
+ (6, 0, 4, 2, "2'h0", 1),
+ (6, 0, 5, 2, "2'h0", 2),
+ (7, 0, 0, 0, "2'h0", 2),
+ (7, 1, 0, 0, "2'h0", 2),
+ (7, 2, 0, 0, "2'h0", 4),
+ (7, 3, 0, 0, "2'h0", 8),
+ (7, 4, 0, 0, "2'h0", 8),
+ (7, 5, 0, 0, "2'h0", 8),
+ (7, 0, 1, 0, "2'h0", 2),
+ (7, 0, 1, 1, "2'h0", 2),
+ (7, 0, 2, 0, "2'h0", 4),
+ (7, 0, 2, 2, "2'h0", 2),
+ (7, 0, 3, 2, "2'h0", 2),
+ (7, 0, 4, 2, "2'h0", 2),
+ (7, 0, 5, 2, "2'h0", 2),
+]:
+ TESTS.append(Test(
+ f"wide_sp_tied_a{aw}r{rw}w{ww}b{bw}",
+ WIDE_SP.format(aw=aw, rw=rw, ww=ww, bw=bw, sval=sval),
+ ["wide_sp"], [],
+ {"RAM_WIDE_SP": cnt}
+ ))
+
+WIDE_RW = """
+module top(clk, a, rd, re, wd, we);
+
+input wire clk, re;
+input wire [2**({ww}-{bw})-1:0] we;
+input wire [{aw}-1:0] a;
+input wire [2**{ww}-1:0] wd;
+output reg [2**{rw}-1:0] rd;
+
+(* ram_block *)
+reg mem [0:2**{aw}-1];
+
+initial mem[3] = 0;
+initial mem[17] = 1;
+initial mem[23] = 0;
+initial mem[24] = 1;
+
+integer i, j;
+always @(posedge clk) begin
+ for (i = 0; i < 2**{ww}; i = i + 2**{bw})
+ if (we[i >> {bw}])
+ for (j = 0; j < 2**{bw}; j = j + 1)
+ mem[a & ~((1 << {ww}) - 1) | i | j] <= wd[i | j];
+ if (re)
+ for (i = 0; i < 2**{rw}; i = i + 1)
+ rd[i] <= mem[a & ~((1 << {rw}) - 1) | i];
+end
+
+endmodule
+"""
+
+for (aw, rw, ww, bw, cntww, cntwr) in [
+ (6, 1, 1, 1, 2, 1),
+ (7, 1, 1, 1, 4, 2),
+ (8, 1, 1, 1, 8, 4),
+ (6, 0, 0, 0, 4, 2),
+ (6, 1, 0, 0, 4, 2),
+ (6, 2, 0, 0, 4, 2),
+ (6, 3, 0, 0, 8, 2),
+ (6, 4, 0, 0, 16, 4),
+ (6, 5, 0, 0, 32, 8),
+ (6, 0, 1, 0, 4, 2),
+ (6, 0, 1, 1, 2, 1),
+ (6, 0, 2, 0, 4, 4),
+ (6, 0, 2, 2, 1, 2),
+ (6, 0, 3, 2, 1, 4),
+ (6, 0, 4, 2, 2, 8),
+ (6, 0, 5, 2, 4, 16),
+ (7, 0, 0, 0, 8, 4),
+ (7, 1, 0, 0, 8, 4),
+ (7, 2, 0, 0, 8, 4),
+ (7, 3, 0, 0, 8, 4),
+ (7, 4, 0, 0, 16, 4),
+ (7, 5, 0, 0, 32, 8),
+ (7, 0, 1, 0, 8, 4),
+ (7, 0, 1, 1, 4, 2),
+ (7, 0, 2, 0, 8, 4),
+ (7, 0, 2, 2, 2, 2),
+ (7, 0, 3, 2, 2, 4),
+ (7, 0, 4, 2, 2, 8),
+ (7, 0, 5, 2, 4, 16),
+]:
+ TESTS.append(Test(
+ f"wide_read_a{aw}r{rw}w{ww}b{bw}",
+ WIDE_RW.format(aw=aw, rw=rw, ww=ww, bw=bw),
+ ["wide_read"], [],
+ {"RAM_WIDE_READ": cntwr}
+ ))
+ TESTS.append(Test(
+ f"wide_write_a{aw}r{rw}w{ww}b{bw}",
+ WIDE_RW.format(aw=aw, rw=rw, ww=ww, bw=bw),
+ ["wide_write"], [],
+ {"RAM_WIDE_WRITE": cntww}
+ ))
+
+with open("run-test.mk", "w") as mf:
+ mf.write("ifneq ($(strip $(SEED)),)\n")
+ mf.write("SEEDOPT=-S$(SEED)\n")
+ mf.write("endif\n")
+ mf.write("all:")
+ for t in TESTS:
+ mf.write(" " + t.name)
+ mf.write("\n")
+ mf.write(".PHONY: all\n")
+
+
+ for t in TESTS:
+ with open("t_{}.v".format(t.name), "w") as tf:
+ tf.write(t.src)
+ with open("t_{}.ys".format(t.name), "w") as sf:
+ sf.write("proc\n")
+ sf.write("opt\n")
+ sf.write("opt -full\n")
+ sf.write("memory -nomap\n")
+ sf.write("dump\n")
+ sf.write("memory_libmap")
+ for lib in t.libs:
+ sf.write(" -lib ../memlib_{}.txt".format(lib))
+ for d in t.defs:
+ sf.write(" -D {}".format(d))
+ sf.write("\n")
+ sf.write("memory_map\n")
+ for k, v in t.cells.items():
+ if isinstance(v, tuple):
+ (cc, ca) = v
+ sf.write("select -assert-count {} t:{}\n".format(cc, k))
+ for kk, vv in ca.items():
+ sf.write("select -assert-count {} t:{} r:{}={} %i\n".format(cc, k, kk, vv))
+ else:
+ sf.write("select -assert-count {} t:{}\n".format(v, k))
+ mf.write("{}:\n".format(t.name))
+ mf.write("\t@../tools/autotest.sh -G -j $(SEEDOPT) $(EXTRA_FLAGS) -p 'script ../t_{}.ys'".format(t.name))
+ for lib in t.libs:
+ mf.write(" -l memlib_{}.v".format(lib))
+ mf.write(" t_{}.v || (cat t_{}.err; exit 1)\n".format(t.name, t.name))
+ mf.write(".PHONY: {}\n".format(t.name))
diff --git a/tests/memlib/memlib_block_sdp.txt b/tests/memlib/memlib_block_sdp.txt
new file mode 100644
index 000000000..6c34c5a96
--- /dev/null
+++ b/tests/memlib/memlib_block_sdp.txt
@@ -0,0 +1,12 @@
+ram block \RAM_BLOCK_SDP {
+ cost 64;
+ abits 10;
+ widths 1 2 4 8 16 per_port;
+ init any;
+ port sw "W" {
+ clock anyedge;
+ }
+ port sr "R" {
+ clock anyedge;
+ }
+}
diff --git a/tests/memlib/memlib_block_sdp.v b/tests/memlib/memlib_block_sdp.v
new file mode 100644
index 000000000..d8dac68e3
--- /dev/null
+++ b/tests/memlib/memlib_block_sdp.v
@@ -0,0 +1,26 @@
+module RAM_BLOCK_SDP(
+ input PORT_R_CLK,
+ input [9:0] PORT_R_ADDR,
+ output reg [15:0] PORT_R_RD_DATA,
+ input PORT_W_CLK,
+ input PORT_W_WR_EN,
+ input [9:0] PORT_W_ADDR,
+ input [15:0] PORT_W_WR_DATA
+);
+
+parameter INIT = 0;
+parameter PORT_R_WIDTH = 1;
+parameter PORT_W_WIDTH = 1;
+parameter PORT_R_CLK_POL = 0;
+parameter PORT_W_CLK_POL = 0;
+
+reg [2**10-1:0] mem = INIT;
+
+always @(negedge (PORT_R_CLK ^ PORT_R_CLK_POL))
+ PORT_R_RD_DATA <= mem[PORT_R_ADDR+:PORT_R_WIDTH];
+
+always @(negedge (PORT_W_CLK ^ PORT_W_CLK_POL))
+ if (PORT_W_WR_EN)
+ mem[PORT_W_ADDR+:PORT_W_WIDTH] <= PORT_W_WR_DATA;
+
+endmodule
diff --git a/tests/memlib/memlib_block_sdp_1clk.txt b/tests/memlib/memlib_block_sdp_1clk.txt
new file mode 100644
index 000000000..07c76c2a2
--- /dev/null
+++ b/tests/memlib/memlib_block_sdp_1clk.txt
@@ -0,0 +1,22 @@
+ram block \RAM_BLOCK_SDP_1CLK {
+ cost 64;
+ abits 10;
+ widths 1 2 4 8 16 per_port;
+ init any;
+ port sw "W" {
+ clock anyedge "C";
+ ifdef TRANS_OLD {
+ option "TRANS" 0 {
+ wrtrans "R" old;
+ }
+ }
+ ifdef TRANS_NEW {
+ option "TRANS" 1 {
+ wrtrans "R" new;
+ }
+ }
+ }
+ port sr "R" {
+ clock anyedge "C";
+ }
+}
diff --git a/tests/memlib/memlib_block_sdp_1clk.v b/tests/memlib/memlib_block_sdp_1clk.v
new file mode 100644
index 000000000..5e8159f9d
--- /dev/null
+++ b/tests/memlib/memlib_block_sdp_1clk.v
@@ -0,0 +1,36 @@
+module RAM_BLOCK_SDP_1CLK(
+ input CLK_C,
+ input PORT_R_CLK,
+ input [9:0] PORT_R_ADDR,
+ output reg [15:0] PORT_R_RD_DATA,
+ input PORT_W_CLK,
+ input PORT_W_WR_EN,
+ input [9:0] PORT_W_ADDR,
+ input [15:0] PORT_W_WR_DATA
+);
+
+parameter PORT_R_CLK_POL = 0;
+parameter PORT_W_CLK_POL = 0;
+parameter CLK_C_POL = 0;
+parameter INIT = 0;
+parameter OPTION_TRANS = 2;
+parameter PORT_R_WIDTH = 1;
+parameter PORT_W_WIDTH = 1;
+
+reg [2**10-1:0] mem = INIT;
+
+always @(negedge (CLK_C ^ CLK_C_POL)) begin
+ if (OPTION_TRANS == 0)
+ PORT_R_RD_DATA <= mem[PORT_R_ADDR+:PORT_R_WIDTH];
+ if (PORT_W_WR_EN)
+ mem[PORT_W_ADDR+:PORT_W_WIDTH] = 16'hx;
+ if (OPTION_TRANS == 2)
+ PORT_R_RD_DATA <= mem[PORT_R_ADDR+:PORT_R_WIDTH];
+ if (PORT_W_WR_EN)
+ mem[PORT_W_ADDR+:PORT_W_WIDTH] = PORT_W_WR_DATA;
+ if (OPTION_TRANS == 1)
+ PORT_R_RD_DATA <= mem[PORT_R_ADDR+:PORT_R_WIDTH];
+end
+
+
+endmodule
diff --git a/tests/memlib/memlib_block_sp.txt b/tests/memlib/memlib_block_sp.txt
new file mode 100644
index 000000000..f99320d73
--- /dev/null
+++ b/tests/memlib/memlib_block_sp.txt
@@ -0,0 +1,95 @@
+ram block \RAM_BLOCK_SP {
+ cost 2;
+ abits 4;
+ width 16;
+ byte 8;
+ port srsw "A" {
+ clock posedge;
+ ifdef CLKEN {
+ clken;
+ }
+ ifdef RDEN {
+ rden;
+ }
+ ifdef RDWR_NO_CHANGE {
+ option "RDWR" "NO_CHANGE" {
+ rdwr no_change;
+ }
+ }
+ ifdef RDWR_OLD {
+ option "RDWR" "OLD" {
+ rdwr old;
+ }
+ }
+ ifdef RDWR_NEW {
+ option "RDWR" "NEW" {
+ rdwr new;
+ }
+ }
+ ifdef RDWR_NEW_ONLY {
+ option "RDWR" "NEW_ONLY" {
+ rdwr new_only;
+ }
+ }
+ ifdef RDINIT_0 {
+ option "RDINIT" "ZERO" {
+ rdinit zero;
+ }
+ }
+ ifdef RDINIT_ANY {
+ option "RDINIT" "ANY" {
+ rdinit any;
+ }
+ }
+ ifdef RDARST_0 {
+ option "RDARST" "ZERO" {
+ rdarst zero;
+ }
+ }
+ ifdef RDARST_ANY {
+ option "RDARST" "ANY" {
+ rdarst any;
+ }
+ }
+ ifdef RDARST_INIT {
+ option "RDARST" "INIT" {
+ rdarst init;
+ }
+ }
+ ifdef RDSRST_0 {
+ option "SRST_GATE" 0 {
+ option "RDSRST" "ZERO" {
+ rdsrst zero ungated;
+ }
+ }
+ }
+ ifdef RDSRST_ANY {
+ option "SRST_GATE" 0 {
+ option "RDSRST" "ANY" {
+ rdsrst any ungated;
+ }
+ }
+ }
+ ifdef RDSRST_INIT {
+ option "SRST_GATE" 0 {
+ option "RDSRST" "INIT" {
+ rdsrst init ungated;
+ }
+ }
+ }
+ ifdef RDSRST_ANY_CE {
+ option "SRST_GATE" 1 {
+ option "RDSRST" "ANY" {
+ rdsrst any gated_clken;
+ }
+ }
+ }
+ ifdef RDSRST_ANY_RE {
+ option "SRST_GATE" 2 {
+ option "RDSRST" "ANY" {
+ rdsrst any gated_rden;
+ }
+ }
+ }
+ }
+}
diff --git a/tests/memlib/memlib_block_sp.v b/tests/memlib/memlib_block_sp.v
new file mode 100644
index 000000000..1f7830137
--- /dev/null
+++ b/tests/memlib/memlib_block_sp.v
@@ -0,0 +1,81 @@
+module RAM_BLOCK_SP(
+ input PORT_A_CLK,
+ input PORT_A_CLK_EN,
+ input PORT_A_RD_EN,
+ input PORT_A_RD_ARST,
+ input PORT_A_RD_SRST,
+ input [1:0] PORT_A_WR_EN,
+ input [3:0] PORT_A_ADDR,
+ output reg [15:0] PORT_A_RD_DATA,
+ input [15:0] PORT_A_WR_DATA
+);
+
+parameter OPTION_RDWR = "UNDEFINED";
+parameter OPTION_RDINIT = "UNDEFINED";
+parameter OPTION_RDARST = "UNDEFINED";
+parameter OPTION_RDSRST = "UNDEFINED";
+parameter OPTION_SRST_GATE = 0;
+parameter PORT_A_RD_INIT_VALUE = 16'hxxxx;
+parameter PORT_A_RD_ARST_VALUE = 16'hxxxx;
+parameter PORT_A_RD_SRST_VALUE = 16'hxxxx;
+
+reg [15:0] mem [0:15];
+
+initial
+ if (OPTION_RDINIT == "ZERO")
+ PORT_A_RD_DATA = 0;
+ else if (OPTION_RDINIT == "ANY")
+ PORT_A_RD_DATA = PORT_A_RD_INIT_VALUE;
+
+localparam ARST_VALUE =
+ (OPTION_RDARST == "ZERO") ? 16'h0000 :
+ (OPTION_RDARST == "INIT") ? PORT_A_RD_INIT_VALUE :
+ (OPTION_RDARST == "ANY") ? PORT_A_RD_ARST_VALUE :
+ 16'hxxxx;
+
+localparam SRST_VALUE =
+ (OPTION_RDSRST == "ZERO") ? 16'h0000 :
+ (OPTION_RDSRST == "INIT") ? PORT_A_RD_INIT_VALUE :
+ (OPTION_RDSRST == "ANY") ? PORT_A_RD_SRST_VALUE :
+ 16'hxxxx;
+
+pullup (PORT_A_CLK_EN);
+pullup (PORT_A_RD_EN);
+pulldown (PORT_A_RD_ARST);
+pulldown (PORT_A_RD_SRST);
+
+always @(posedge PORT_A_CLK) begin
+ if (PORT_A_CLK_EN) begin
+ if (PORT_A_WR_EN[0])
+ mem[PORT_A_ADDR][7:0] <= PORT_A_WR_DATA[7:0];
+ if (PORT_A_WR_EN[1])
+ mem[PORT_A_ADDR][15:8] <= PORT_A_WR_DATA[15:8];
+ if (PORT_A_RD_EN && (!PORT_A_WR_EN || OPTION_RDWR != "NO_CHANGE")) begin
+ PORT_A_RD_DATA <= mem[PORT_A_ADDR];
+ if (PORT_A_WR_EN && OPTION_RDWR == "NEW_ONLY")
+ PORT_A_RD_DATA <= 16'hx;
+ if (PORT_A_WR_EN[0])
+ case (OPTION_RDWR)
+ "NEW": PORT_A_RD_DATA[7:0] <= PORT_A_WR_DATA[7:0];
+ "NEW_ONLY": PORT_A_RD_DATA[7:0] <= PORT_A_WR_DATA[7:0];
+ "UNDEFINED": PORT_A_RD_DATA[7:0] <= 8'hx;
+ endcase
+ if (PORT_A_WR_EN[1])
+ case (OPTION_RDWR)
+ "NEW": PORT_A_RD_DATA[15:8] <= PORT_A_WR_DATA[15:8];
+ "NEW_ONLY": PORT_A_RD_DATA[15:8] <= PORT_A_WR_DATA[15:8];
+ "UNDEFINED": PORT_A_RD_DATA[15:8] <= 8'hx;
+ endcase
+ end
+ end
+ if (PORT_A_RD_SRST && (!OPTION_SRST_GATE || (OPTION_SRST_GATE == 2 && PORT_A_RD_EN) || (OPTION_SRST_GATE == 1 && PORT_A_CLK_EN)))
+ PORT_A_RD_DATA <= SRST_VALUE;
+end
+
+always @(PORT_A_RD_ARST)
+ if (PORT_A_RD_ARST)
+ force PORT_A_RD_DATA = ARST_VALUE;
+ else
+ release PORT_A_RD_DATA;
+
+endmodule
diff --git a/tests/memlib/memlib_block_tdp.txt b/tests/memlib/memlib_block_tdp.txt
new file mode 100644
index 000000000..80cc7e504
--- /dev/null
+++ b/tests/memlib/memlib_block_tdp.txt
@@ -0,0 +1,10 @@
+ram block \RAM_BLOCK_TDP {
+ cost 64;
+ abits 10;
+ widths 1 2 4 8 16 per_port;
+ init any;
+ port srsw "A" "B" {
+ clock anyedge;
+ rdwr no_change;
+ }
+}
diff --git a/tests/memlib/memlib_block_tdp.v b/tests/memlib/memlib_block_tdp.v
new file mode 100644
index 000000000..c6b876360
--- /dev/null
+++ b/tests/memlib/memlib_block_tdp.v
@@ -0,0 +1,38 @@
+module RAM_BLOCK_TDP(
+ input PORT_A_CLK,
+ input PORT_A_WR_EN,
+ input [9:0] PORT_A_ADDR,
+ input [15:0] PORT_A_WR_DATA,
+ output reg [15:0] PORT_A_RD_DATA,
+ input PORT_B_CLK,
+ input PORT_B_WR_EN,
+ input [9:0] PORT_B_ADDR,
+ input [15:0] PORT_B_WR_DATA,
+ output reg [15:0] PORT_B_RD_DATA
+);
+
+parameter INIT = 0;
+parameter PORT_A_WIDTH = 1;
+parameter PORT_B_WIDTH = 1;
+parameter PORT_A_CLK_POL = 0;
+parameter PORT_B_CLK_POL = 0;
+
+reg [2**10-1:0] mem = INIT;
+
+always @(negedge (PORT_A_CLK ^ PORT_A_CLK_POL)) begin
+ if (PORT_A_WR_EN) begin
+ mem[PORT_A_ADDR+:PORT_A_WIDTH] <= PORT_A_WR_DATA;
+ end else begin
+ PORT_A_RD_DATA <= mem[PORT_A_ADDR+:PORT_A_WIDTH];
+ end
+end
+
+always @(negedge (PORT_B_CLK ^ PORT_B_CLK_POL)) begin
+ if (PORT_B_WR_EN) begin
+ mem[PORT_B_ADDR+:PORT_B_WIDTH] <= PORT_B_WR_DATA;
+ end else begin
+ PORT_B_RD_DATA <= mem[PORT_B_ADDR+:PORT_B_WIDTH];
+ end
+end
+
+endmodule
diff --git a/tests/memlib/memlib_lut.txt b/tests/memlib/memlib_lut.txt
new file mode 100644
index 000000000..0cc8fda15
--- /dev/null
+++ b/tests/memlib/memlib_lut.txt
@@ -0,0 +1,12 @@
+ram distributed \RAM_LUT {
+ abits 4;
+ width 4;
+ init any;
+ cost 4;
+ port ar "R" {
+ }
+ port arsw "RW" {
+ clock anyedge;
+ }
+}
+
diff --git a/tests/memlib/memlib_lut.v b/tests/memlib/memlib_lut.v
new file mode 100644
index 000000000..1f20a110a
--- /dev/null
+++ b/tests/memlib/memlib_lut.v
@@ -0,0 +1,30 @@
+module RAM_LUT(
+ input [3:0] PORT_R_ADDR,
+ input [3:0] PORT_RW_ADDR,
+ input PORT_RW_CLK,
+ input PORT_RW_WR_EN,
+ input [3:0] PORT_RW_WR_DATA,
+ output [3:0] PORT_R_RD_DATA,
+ output [3:0] PORT_RW_RD_DATA
+);
+
+parameter INIT = 0;
+parameter PORT_RW_CLK_POL = 1;
+
+reg [3:0] mem [0:15];
+
+integer i;
+initial
+ for (i = 0; i < 16; i += 1)
+ mem[i] = INIT[i*4+:4];
+
+assign PORT_R_RD_DATA = mem[PORT_R_ADDR];
+assign PORT_RW_RD_DATA = mem[PORT_RW_ADDR];
+
+wire CLK = PORT_RW_CLK ~^ PORT_RW_CLK_POL;
+
+always @(posedge CLK)
+ if (PORT_RW_WR_EN)
+ mem[PORT_RW_ADDR] <= PORT_RW_WR_DATA;
+
+endmodule
diff --git a/tests/memlib/memlib_wide_read.txt b/tests/memlib/memlib_wide_read.txt
new file mode 100644
index 000000000..c11021045
--- /dev/null
+++ b/tests/memlib/memlib_wide_read.txt
@@ -0,0 +1,12 @@
+ram block \RAM_WIDE_READ {
+ cost 2;
+ abits 6;
+ widths 1 2 4 8 per_port;
+ init any;
+ port srsw "A" {
+ width rd 8 wr 2;
+ clock posedge;
+ rden;
+ rdwr old;
+ }
+}
diff --git a/tests/memlib/memlib_wide_read.v b/tests/memlib/memlib_wide_read.v
new file mode 100644
index 000000000..e45f64376
--- /dev/null
+++ b/tests/memlib/memlib_wide_read.v
@@ -0,0 +1,25 @@
+module RAM_WIDE_READ #(
+ parameter [63:0] INIT = 64'hx,
+ parameter PORT_A_RD_WIDTH = 8,
+ parameter PORT_A_WR_WIDTH = 2
+) (
+ input PORT_A_CLK,
+ input PORT_A_RD_EN,
+ input [5:0] PORT_A_ADDR,
+ output reg [7:0] PORT_A_RD_DATA,
+ input PORT_A_WR_EN,
+ input [1:0] PORT_A_WR_DATA
+);
+
+reg [63:0] mem;
+
+initial mem = INIT;
+
+always @(posedge PORT_A_CLK) begin
+ if (PORT_A_RD_EN)
+ PORT_A_RD_DATA <= mem[{PORT_A_ADDR[5:3], 3'b000}+:8];
+ if (PORT_A_WR_EN)
+ mem[{PORT_A_ADDR[5:1],1'b0}+:2] <= PORT_A_WR_DATA;
+end
+
+endmodule
diff --git a/tests/memlib/memlib_wide_sdp.txt b/tests/memlib/memlib_wide_sdp.txt
new file mode 100644
index 000000000..ec90c45bd
--- /dev/null
+++ b/tests/memlib/memlib_wide_sdp.txt
@@ -0,0 +1,17 @@
+ram block \RAM_WIDE_SDP {
+ cost 2;
+ abits 6;
+ widths 1 2 5 10 20 per_port;
+ byte 5;
+ init any;
+ port sr "R" {
+ clock posedge;
+ rden;
+ rdsrst any ungated;
+ }
+ port sw "W" {
+ clock posedge;
+ wrtrans "R" old;
+ wrbe_separate;
+ }
+}
diff --git a/tests/memlib/memlib_wide_sdp.v b/tests/memlib/memlib_wide_sdp.v
new file mode 100644
index 000000000..456853177
--- /dev/null
+++ b/tests/memlib/memlib_wide_sdp.v
@@ -0,0 +1,45 @@
+module RAM_WIDE_SDP #(
+ parameter [79:0] INIT = 80'hx,
+ parameter PORT_R_WIDTH = 1,
+ parameter PORT_W_WIDTH = 1,
+ parameter PORT_W_WR_BE_WIDTH = 1,
+ parameter PORT_R_RD_SRST_VALUE = 16'hx
+) (
+ input PORT_R_CLK,
+ input PORT_R_RD_EN,
+ input PORT_R_RD_SRST,
+ input [5:0] PORT_R_ADDR,
+ output reg [PORT_R_WIDTH-1:0] PORT_R_RD_DATA,
+ input PORT_W_CLK,
+ input PORT_W_WR_EN,
+ input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE,
+ input [5:0] PORT_W_ADDR,
+ input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA
+);
+
+reg [79:0] mem;
+
+initial mem = INIT;
+
+always @(posedge PORT_R_CLK)
+ if (PORT_R_RD_SRST)
+ PORT_R_RD_DATA <= PORT_R_RD_SRST_VALUE;
+ else if (PORT_R_RD_EN)
+ PORT_R_RD_DATA <= mem[PORT_R_ADDR[5:2] * 5 + PORT_R_ADDR[1:0]+:PORT_R_WIDTH];
+
+generate
+ if (PORT_W_WIDTH < 5) begin
+ always @(posedge PORT_W_CLK)
+ if (PORT_W_WR_EN && PORT_W_WR_BE[0])
+ mem[PORT_W_ADDR[5:2] * 5 + PORT_W_ADDR[1:0]+:PORT_W_WIDTH] <= PORT_W_WR_DATA;
+ end else begin
+ integer i;
+ always @(posedge PORT_W_CLK)
+ if (PORT_W_WR_EN)
+ for (i = 0; i < PORT_W_WR_BE_WIDTH; i = i + 1)
+ if (PORT_W_WR_BE[i])
+ mem[(PORT_W_ADDR[5:2] + i) * 5+:5] <= PORT_W_WR_DATA[i * 5+:5];
+ end
+endgenerate
+
+endmodule
diff --git a/tests/memlib/memlib_wide_sp.txt b/tests/memlib/memlib_wide_sp.txt
new file mode 100644
index 000000000..7780e4f9d
--- /dev/null
+++ b/tests/memlib/memlib_wide_sp.txt
@@ -0,0 +1,22 @@
+ram block \RAM_WIDE_SP {
+ cost 2;
+ abits 6;
+ widths 1 2 5 10 20 per_port;
+ byte 5;
+ init any;
+ port srsw "A" {
+ ifdef WIDTH_MIX {
+ option "WIDTH_MIX" 1 {
+ width mix;
+ }
+ } else {
+ option "WIDTH_MIX" 0 {
+ width tied;
+ }
+ }
+ clock posedge;
+ rden;
+ rdwr old;
+ rdsrst any ungated;
+ }
+}
diff --git a/tests/memlib/memlib_wide_sp.v b/tests/memlib/memlib_wide_sp.v
new file mode 100644
index 000000000..920a3339a
--- /dev/null
+++ b/tests/memlib/memlib_wide_sp.v
@@ -0,0 +1,54 @@
+module RAM_WIDE_SP #(
+ parameter [79:0] INIT = 80'hx,
+ parameter PORT_A_RD_WIDTH = 1,
+ parameter PORT_A_WR_WIDTH = 1,
+ parameter PORT_A_WIDTH = 1,
+ parameter OPTION_WIDTH_MIX = 0,
+ parameter PORT_A_WR_EN_WIDTH = 1,
+ parameter PORT_A_RD_SRST_VALUE = 16'hx,
+ parameter RD_WIDTH = OPTION_WIDTH_MIX ? PORT_A_RD_WIDTH : PORT_A_WIDTH,
+ parameter WR_WIDTH = OPTION_WIDTH_MIX ? PORT_A_WR_WIDTH : PORT_A_WIDTH
+) (
+ input PORT_A_CLK,
+ input PORT_A_RD_EN,
+ input PORT_A_RD_SRST,
+ input [5:0] PORT_A_ADDR,
+ output reg [RD_WIDTH-1:0] PORT_A_RD_DATA,
+ input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN,
+ input [WR_WIDTH-1:0] PORT_A_WR_DATA
+);
+
+reg [79:0] mem;
+
+initial mem = INIT;
+
+always @(posedge PORT_A_CLK)
+ if (PORT_A_RD_SRST)
+ PORT_A_RD_DATA <= PORT_A_RD_SRST_VALUE;
+ else if (PORT_A_RD_EN)
+ case (RD_WIDTH)
+ 1: PORT_A_RD_DATA <= mem[PORT_A_ADDR[5:2] * 5 + PORT_A_ADDR[1:0]+:1];
+ 2: PORT_A_RD_DATA <= mem[PORT_A_ADDR[5:2] * 5 + PORT_A_ADDR[1] * 2+:2];
+ 5: PORT_A_RD_DATA <= mem[PORT_A_ADDR[5:2] * 5+:5];
+ 10: PORT_A_RD_DATA <= mem[PORT_A_ADDR[5:3] * 10+:10];
+ 20: PORT_A_RD_DATA <= mem[PORT_A_ADDR[5:4] * 20+:20];
+ endcase
+
+always @(posedge PORT_A_CLK)
+ case (WR_WIDTH)
+ 1: if (PORT_A_WR_EN) mem[PORT_A_ADDR[5:2] * 5 + PORT_A_ADDR[1:0]+:1] <= PORT_A_WR_DATA;
+ 2: if (PORT_A_WR_EN) mem[PORT_A_ADDR[5:2] * 5 + PORT_A_ADDR[1] * 2+:2] <= PORT_A_WR_DATA;
+ 5: if (PORT_A_WR_EN) mem[PORT_A_ADDR[5:2] * 5+:5] <= PORT_A_WR_DATA;
+ 10: begin
+ if (PORT_A_WR_EN[0]) mem[PORT_A_ADDR[5:3] * 10+:5] <= PORT_A_WR_DATA[4:0];
+ if (PORT_A_WR_EN[1]) mem[PORT_A_ADDR[5:3] * 10 + 5+:5] <= PORT_A_WR_DATA[9:5];
+ end
+ 20: begin
+ if (PORT_A_WR_EN[0]) mem[PORT_A_ADDR[5:4] * 20+:5] <= PORT_A_WR_DATA[4:0];
+ if (PORT_A_WR_EN[1]) mem[PORT_A_ADDR[5:4] * 20 + 5+:5] <= PORT_A_WR_DATA[9:5];
+ if (PORT_A_WR_EN[2]) mem[PORT_A_ADDR[5:4] * 20 + 10+:5] <= PORT_A_WR_DATA[14:10];
+ if (PORT_A_WR_EN[3]) mem[PORT_A_ADDR[5:4] * 20 + 15+:5] <= PORT_A_WR_DATA[19:15];
+ end
+ endcase
+
+endmodule
diff --git a/tests/memlib/memlib_wide_write.txt b/tests/memlib/memlib_wide_write.txt
new file mode 100644
index 000000000..59222b7fb
--- /dev/null
+++ b/tests/memlib/memlib_wide_write.txt
@@ -0,0 +1,13 @@
+ram block \RAM_WIDE_WRITE {
+ cost 2;
+ abits 6;
+ widths 1 2 4 8 per_port;
+ byte 4;
+ init any;
+ port srsw "A" {
+ width rd 2 wr 8;
+ clock posedge;
+ rden;
+ rdwr old;
+ }
+}
diff --git a/tests/memlib/memlib_wide_write.v b/tests/memlib/memlib_wide_write.v
new file mode 100644
index 000000000..afed6d00c
--- /dev/null
+++ b/tests/memlib/memlib_wide_write.v
@@ -0,0 +1,29 @@
+module RAM_WIDE_WRITE #(
+ parameter [63:0] INIT = 64'hx,
+ parameter PORT_A_RD_WIDTH = 2,
+ parameter PORT_A_WR_WIDTH = 8,
+ parameter PORT_A_WR_EN_WIDTH = 2
+) (
+ input PORT_A_CLK,
+ input PORT_A_RD_EN,
+ input [5:0] PORT_A_ADDR,
+ output reg [1:0] PORT_A_RD_DATA,
+ input [1:0] PORT_A_WR_EN,
+ input [7:0] PORT_A_WR_DATA
+);
+
+reg [63:0] mem;
+
+initial mem = INIT;
+
+always @(posedge PORT_A_CLK) begin
+ if (PORT_A_RD_EN)
+ PORT_A_RD_DATA <= mem[{PORT_A_ADDR[5:1],1'b0}+:2];
+ if (PORT_A_WR_EN[0])
+ mem[{PORT_A_ADDR[5:3],3'b000}+:4] <= PORT_A_WR_DATA[3:0];
+ if (PORT_A_WR_EN[1])
+ mem[{PORT_A_ADDR[5:3],3'b100}+:4] <= PORT_A_WR_DATA[7:4];
+end
+
+endmodule
+
diff --git a/tests/memlib/run-test.sh b/tests/memlib/run-test.sh
new file mode 100755
index 000000000..abe88a6cb
--- /dev/null
+++ b/tests/memlib/run-test.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+set -eu
+
+OPTIND=1
+seed="" # default to no seed specified
+while getopts "S:" opt
+do
+ case "$opt" in
+ S) seed="$OPTARG" ;;
+ esac
+done
+shift "$((OPTIND-1))"
+
+python3 generate.py
+exec ${MAKE:-make} -f run-test.mk SEED="$seed"
diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh
index b8657056a..c65066a9c 100755
--- a/tests/memories/run-test.sh
+++ b/tests/memories/run-test.sh
@@ -18,7 +18,7 @@ ${MAKE:-make} -f ../tools/autotest.mk SEED="$seed" EXTRA_FLAGS="$abcopt" *.v
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_v2" $f
+ ../../yosys -f verilog -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem_v2" $f
if grep -q expect-wr-ports $f; then
grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp ||
{ echo " ERROR: Unexpected number of write ports."; false; }
diff --git a/tests/opt/bug3117.ys b/tests/opt/bug3117.ys
new file mode 100644
index 000000000..177b3ab9a
--- /dev/null
+++ b/tests/opt/bug3117.ys
@@ -0,0 +1,34 @@
+read_verilog << EOT
+
+module test (...);
+
+input [7:1] wa1;
+input [7:1] wa2;
+input [7:0] ra;
+output [7:0] rd;
+input clk;
+input we1, we2;
+input [15:0] wd1, wd2;
+
+reg [7:0] mem [0:255];
+
+assign rd = mem[ra];
+
+always @(posedge clk) begin
+ if (we1) begin
+ mem[{wa1, 1'b0}] <= wd1[7:0];
+ mem[{wa1, 1'b1}] <= wd1[15:8];
+ end else begin
+ mem[{wa2, 1'b0}] <= wd2[7:0];
+ mem[{wa2, 1'b1}] <= wd2[15:8];
+ end
+end
+
+endmodule
+
+EOT
+
+proc
+opt
+memory_share
+select -assert-count 1 t:$memwr_v2
diff --git a/tests/opt/memory_bmux2rom.ys b/tests/opt/memory_bmux2rom.ys
new file mode 100644
index 000000000..039885965
--- /dev/null
+++ b/tests/opt/memory_bmux2rom.ys
@@ -0,0 +1,27 @@
+read_ilang << EOT
+
+module \top
+ wire width 4 input 0 \S
+ wire width 5 output 1 \Y
+
+ cell $bmux $0
+ parameter \WIDTH 5
+ parameter \S_WIDTH 4
+ connect \A 80'10110100011101110001110010001110101010111000110011111111111110100000110100111000
+ connect \S \S
+ connect \Y \Y
+ end
+end
+
+EOT
+
+hierarchy -auto-top
+
+design -save preopt
+memory_bmux2rom
+select -assert-count 1 t:$memrd_v2
+memory_map
+opt_dff
+design -stash postopt
+
+equiv_opt -assert -run prepare: dummy
diff --git a/tests/opt/opt_merge_init.ys b/tests/opt/opt_merge_init.ys
index 20b6cabee..7ee7d3dd7 100644
--- a/tests/opt/opt_merge_init.ys
+++ b/tests/opt/opt_merge_init.ys
@@ -75,3 +75,53 @@ EOT
opt_merge
select -assert-count 2 t:$dff
+
+design -reset
+read_verilog -icells <<EOT
+module top(input clk, i, (* init = 1'b0 *) output o, p);
+ \$dff #(
+ .CLK_POLARITY(1'h1),
+ .WIDTH(32'd1)
+ ) ffo (
+ .CLK(clk),
+ .D(i),
+ .Q(o)
+ );
+ \$dff #(
+ .CLK_POLARITY(1'h1),
+ .WIDTH(32'd1)
+ ) ffp (
+ .CLK(clk),
+ .D(i),
+ .Q(p)
+ );
+endmodule
+EOT
+
+opt_merge -keepdc
+select -assert-count 1 t:$dff
+
+design -reset
+read_verilog -icells <<EOT
+module top(input clk, i, output o, p);
+ \$dff #(
+ .CLK_POLARITY(1'h1),
+ .WIDTH(32'd1)
+ ) ffo (
+ .CLK(clk),
+ .D(i),
+ .Q(o)
+ );
+ \$dff #(
+ .CLK_POLARITY(1'h1),
+ .WIDTH(32'd1)
+ ) ffp (
+ .CLK(clk),
+ .D(i),
+ .Q(p)
+ );
+endmodule
+EOT
+
+opt_merge -keepdc
+select -assert-count 2 t:$dff
diff --git a/tests/opt/opt_reduce_bmux.ys b/tests/opt/opt_reduce_bmux.ys
new file mode 100644
index 000000000..55e0b6d4b
--- /dev/null
+++ b/tests/opt/opt_reduce_bmux.ys
@@ -0,0 +1,117 @@
+read_ilang << EOT
+
+module \top
+ wire width 12 input 0 \A
+ wire width 2 input 1 \S
+ wire width 6 output 2 \Y
+
+ cell $bmux $0
+ parameter \WIDTH 6
+ parameter \S_WIDTH 2
+ connect \A { \A [11:10] \A [3:2] \A [10:9] \A [7] \A [7] \A [8] \A [2] \A [7:6] \A [5] \A [5] \A [3:2] \A [5:4] \A [1] \A [1] \A [3:0] }
+ connect \S \S
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 1 t:$bmux r:WIDTH=4 %i
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 6 input 0 \A
+ wire width 2 input 1 \S
+ wire width 6 output 2 \Y
+
+ cell $bmux $0
+ parameter \WIDTH 6
+ parameter \S_WIDTH 2
+ connect \A { \A [5:0] \A [5:0] \A [5:0] \A [5:0] }
+ connect \S \S
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 0 t:$bmux
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 160 input 0 \A
+ wire width 2 input 1 \S
+ wire width 5 output 2 \Y
+
+ cell $bmux $0
+ parameter \WIDTH 5
+ parameter \S_WIDTH 5
+ connect \A \A
+ connect \S { \S [1] 1'1 \S [0] \S [1] 1'0 }
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 1 t:$bmux r:S_WIDTH=2 %i
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 10 input 0 \A
+ wire input 1 \S
+ wire width 5 output 2 \Y
+
+ cell $bmux $0
+ parameter \WIDTH 5
+ parameter \S_WIDTH 1
+ connect \A \A
+ connect \S \S
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 0 t:$bmux
+select -assert-count 1 t:$mux
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 5 input 0 \A
+ wire width 5 output 1 \Y
+
+ cell $bmux $0
+ parameter \WIDTH 5
+ parameter \S_WIDTH 0
+ connect \A \A
+ connect \S { }
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 0 t:$bmux
diff --git a/tests/opt/opt_reduce_demux.ys b/tests/opt/opt_reduce_demux.ys
new file mode 100644
index 000000000..3c5bd7d43
--- /dev/null
+++ b/tests/opt/opt_reduce_demux.ys
@@ -0,0 +1,91 @@
+read_ilang << EOT
+
+module \top
+ wire width 4 input 0 \A
+ wire width 2 input 1 \S
+ wire width 24 output 2 \Y
+
+ cell $demux $0
+ parameter \WIDTH 6
+ parameter \S_WIDTH 2
+ connect \A { \A [3] \A [1] 1'0 \A [2:0] }
+ connect \S \S
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 1 t:$demux r:WIDTH=4 %i
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 2 input 1 \S
+ wire width 24 output 2 \Y
+
+ cell $demux $0
+ parameter \WIDTH 6
+ parameter \S_WIDTH 2
+ connect \A 6'000000
+ connect \S \S
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 0 t:$demux
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 5 input 0 \A
+ wire width 2 input 1 \S
+ wire width 160 output 2 \Y
+
+ cell $demux $0
+ parameter \WIDTH 5
+ parameter \S_WIDTH 5
+ connect \A \A
+ connect \S { \S [0] \S [1] 1'1 \S [0] 1'0 }
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 1 t:$demux r:S_WIDTH=2 %i
+
+design -reset
+
+read_ilang << EOT
+
+module \top
+ wire width 5 input 0 \A
+ wire width 20 output 2 \Y
+
+ cell $demux $0
+ parameter \WIDTH 5
+ parameter \S_WIDTH 2
+ connect \A \A
+ connect \S { 2'10 }
+ connect \Y \Y
+ end
+end
+
+EOT
+
+equiv_opt -assert opt_reduce -fine
+opt_reduce -fine
+select -assert-count 0 t:$demux
diff --git a/tests/proc/proc_rom.ys b/tests/proc/proc_rom.ys
new file mode 100644
index 000000000..0ef2e2c61
--- /dev/null
+++ b/tests/proc/proc_rom.ys
@@ -0,0 +1,189 @@
+read_verilog << EOT
+
+module top(input [3:0] a, input en, output [7:0] d);
+
+always @*
+ if (en)
+ case(a)
+ 4'h0: d <= 8'h12;
+ 4'h1: d <= 8'h34;
+ 4'h2: d <= 8'h56;
+ 4'h3: d <= 8'h78;
+ 4'h4: d <= 8'h9a;
+ 4'h5: d <= 8'hbc;
+ 4'h6: d <= 8'hde;
+ 4'h7: d <= 8'hff;
+ 4'h8: d <= 8'h61;
+ 4'h9: d <= 8'h49;
+ 4'ha: d <= 8'h36;
+ 4'hb: d <= 8'h81;
+ 4'hc: d <= 8'h8c;
+ 4'hd: d <= 8'ha9;
+ 4'he: d <= 8'h99;
+ 4'hf: d <= 8'h51;
+ endcase
+ else
+ d <= 0;
+
+endmodule
+
+EOT
+
+hierarchy -auto-top
+
+design -save orig
+proc
+select -assert-count 1 t:$memrd_v2
+memory
+opt_dff
+design -stash postopt
+design -load orig
+proc -norom
+design -stash preopt
+
+equiv_opt -assert -run prepare: dummy
+
+
+
+design -reset
+
+read_verilog << EOT
+
+module top(input [3:0] a, input en, output [7:0] d);
+
+always @*
+ if (en)
+ case(a)
+ 4'h0: d <= 8'h12;
+ 4'h1: d <= 8'h34;
+ 4'h2: d <= 8'h56;
+ 4'h3: d <= 8'h78;
+ 4'h4: d <= 8'h9a;
+ 4'h5: d <= 8'hbc;
+ 4'h6: d <= 8'hde;
+ 4'h7: d <= 8'hff;
+ 4'h8: d <= 8'h61;
+ 4'h9: d <= 8'h49;
+ 4'ha: d <= 8'h36;
+ 4'hb: d <= 8'h81;
+ 4'hc: d <= 8'h8c;
+ default: d <= 8'h11;
+ endcase
+ else
+ d <= 0;
+
+endmodule
+
+EOT
+
+hierarchy -auto-top
+
+design -save orig
+proc
+select -assert-count 1 t:$memrd_v2
+memory
+opt_dff
+design -stash postopt
+design -load orig
+proc -norom
+design -stash preopt
+
+equiv_opt -assert -run prepare: dummy
+
+
+
+design -reset
+
+read_verilog << EOT
+
+module top(input [31:0] a, input en, output [7:0] d);
+
+always @*
+ if (en)
+ case(a)
+ 0: d <= 8'h12;
+ 1: d <= 8'h34;
+ 2: d <= 8'h56;
+ 3: d <= 8'h78;
+ 4: d <= 8'h9a;
+ 5: d <= 8'hbc;
+ 6: d <= 8'hde;
+ 7: d <= 8'hff;
+ 8: d <= 8'h61;
+ 9: d <= 8'h49;
+ 10: d <= 8'h36;
+ 11: d <= 8'h81;
+ 12: d <= 8'h8c;
+ default: d <= 8'h11;
+ endcase
+ else
+ d <= 0;
+
+endmodule
+
+EOT
+
+hierarchy -auto-top
+
+design -save orig
+proc
+select -assert-count 1 t:$memrd_v2
+memory
+opt_dff
+design -stash postopt
+design -load orig
+proc -norom
+design -stash preopt
+
+equiv_opt -assert -run prepare: dummy
+
+
+design -reset
+
+read_verilog << EOT
+
+module top(input [3:0] a, input en, output [7:0] d);
+
+always @*
+ if (en)
+ case(a)
+ 'h0: d <= 8'h12;
+ 'h1: d <= 8'h34;
+ 'h2: d <= 8'h56;
+ 'h3: d <= 8'h78;
+ 'h4: d <= 8'h9a;
+ 'h5: d <= 8'hbc;
+ 'h6: d <= 8'hde;
+ 'h7: d <= 8'hff;
+ 'h8: d <= 8'h61;
+ 'h9: d <= 8'h49;
+ 'ha: d <= 8'h36;
+ 'hb: d <= 8'h81;
+ 'hc: d <= 8'h8c;
+ 'hd: d <= 8'ha9;
+ 'he: d <= 8'h99;
+ 'hf: d <= 8'h51;
+ endcase
+ else
+ d <= 0;
+
+endmodule
+
+EOT
+
+hierarchy -auto-top
+
+design -save orig
+proc
+select -assert-count 1 t:$memrd_v2
+memory
+opt_dff
+design -stash postopt
+design -load orig
+proc -norom
+design -stash preopt
+
+equiv_opt -assert -run prepare: dummy
+
+
+
diff --git a/tests/sat/.gitignore b/tests/sat/.gitignore
index 8355de9dc..664425d73 100644
--- a/tests/sat/.gitignore
+++ b/tests/sat/.gitignore
@@ -1,2 +1,4 @@
*.log
run-test.mk
+*.vcd
+*.fst
diff --git a/tests/sat/alu.v b/tests/sat/alu.v
new file mode 100644
index 000000000..9826fe05d
--- /dev/null
+++ b/tests/sat/alu.v
@@ -0,0 +1,79 @@
+module alu(
+ input clk,
+ input [7:0] A,
+ input [7:0] B,
+ input [3:0] operation,
+ output reg [7:0] result,
+ output reg CF,
+ output reg ZF,
+ output reg SF
+);
+
+ localparam ALU_OP_ADD /* verilator public_flat */ = 4'b0000;
+ localparam ALU_OP_SUB /* verilator public_flat */ = 4'b0001;
+ localparam ALU_OP_ADC /* verilator public_flat */ = 4'b0010;
+ localparam ALU_OP_SBC /* verilator public_flat */ = 4'b0011;
+
+ localparam ALU_OP_AND /* verilator public_flat */ = 4'b0100;
+ localparam ALU_OP_OR /* verilator public_flat */ = 4'b0101;
+ localparam ALU_OP_NOT /* verilator public_flat */ = 4'b0110;
+ localparam ALU_OP_XOR /* verilator public_flat */ = 4'b0111;
+
+ localparam ALU_OP_SHL /* verilator public_flat */ = 4'b1000;
+ localparam ALU_OP_SHR /* verilator public_flat */ = 4'b1001;
+ localparam ALU_OP_SAL /* verilator public_flat */ = 4'b1010;
+ localparam ALU_OP_SAR /* verilator public_flat */ = 4'b1011;
+
+ localparam ALU_OP_ROL /* verilator public_flat */ = 4'b1100;
+ localparam ALU_OP_ROR /* verilator public_flat */ = 4'b1101;
+ localparam ALU_OP_RCL /* verilator public_flat */ = 4'b1110;
+ localparam ALU_OP_RCR /* verilator public_flat */ = 4'b1111;
+
+ reg [8:0] tmp;
+
+ always @(posedge clk)
+ begin
+ case (operation)
+ ALU_OP_ADD :
+ tmp = A + B;
+ ALU_OP_SUB :
+ tmp = A - B;
+ ALU_OP_ADC :
+ tmp = A + B + { 7'b0000000, CF };
+ ALU_OP_SBC :
+ tmp = A - B - { 7'b0000000, CF };
+ ALU_OP_AND :
+ tmp = {1'b0, A & B };
+ ALU_OP_OR :
+ tmp = {1'b0, A | B };
+ ALU_OP_NOT :
+ tmp = {1'b0, ~B };
+ ALU_OP_XOR :
+ tmp = {1'b0, A ^ B};
+ ALU_OP_SHL :
+ tmp = { A[7], A[6:0], 1'b0};
+ ALU_OP_SHR :
+ tmp = { A[0], 1'b0, A[7:1]};
+ ALU_OP_SAL :
+ // Same as SHL
+ tmp = { A[7], A[6:0], 1'b0};
+ ALU_OP_SAR :
+ tmp = { A[0], A[7], A[7:1]};
+ ALU_OP_ROL :
+ tmp = { A[7], A[6:0], A[7]};
+ ALU_OP_ROR :
+ tmp = { A[0], A[0], A[7:1]};
+ ALU_OP_RCL :
+ tmp = { A[7], A[6:0], CF};
+ ALU_OP_RCR :
+ tmp = { A[0], CF, A[7:1]};
+ endcase
+
+ CF <= tmp[8];
+ ZF <= tmp[7:0] == 0;
+ SF <= tmp[7];
+
+ result <= tmp[7:0];
+ end
+endmodule
+
diff --git a/tests/sat/grom.ys b/tests/sat/grom.ys
new file mode 100644
index 000000000..da0f3b620
--- /dev/null
+++ b/tests/sat/grom.ys
@@ -0,0 +1,9 @@
+read_verilog grom_computer.v grom_cpu.v alu.v ram_memory.v;
+prep -top grom_computer;
+sim -clock clk -reset reset -fst grom.fst -vcd grom.vcd -n 80
+
+sim -clock clk -r grom.fst -scope grom_computer -start 25ns -stop 100ns -sim-cmp
+
+sim -clock clk -r grom.fst -scope grom_computer -stop 100ns -sim-gold
+
+sim -clock clk -r grom.fst -scope grom_computer -n 10 -sim-gate
diff --git a/tests/sat/grom_computer.v b/tests/sat/grom_computer.v
new file mode 100644
index 000000000..63a5c8ff8
--- /dev/null
+++ b/tests/sat/grom_computer.v
@@ -0,0 +1,31 @@
+module grom_computer
+ (input clk, // Main Clock
+ input reset, // reset
+ output hlt,
+ output reg[7:0] display_out
+ );
+
+ wire [11:0] addr;
+ wire [7:0] memory_out;
+ wire [7:0] memory_in;
+ wire mem_enable;
+ wire we;
+ wire ioreq;
+
+ grom_cpu cpu(.clk(clk),.reset(reset),.addr(addr),.data_in(memory_out),.data_out(memory_in),.we(we),.ioreq(ioreq),.hlt(hlt));
+
+ assign mem_enable = we & ~ioreq;
+
+ ram_memory memory(.clk(clk),.addr(addr),.data_in(memory_in),.we(mem_enable),.data_out(memory_out));
+
+ always @(posedge clk)
+ begin
+ if(ioreq==1 && we==1)
+ begin
+ display_out <= memory_in;
+ `ifdef DISASSEMBLY
+ $display("Display output : %h", memory_in);
+ `endif
+ end
+ end
+endmodule
diff --git a/tests/sat/grom_cpu.v b/tests/sat/grom_cpu.v
new file mode 100644
index 000000000..914c0f56c
--- /dev/null
+++ b/tests/sat/grom_cpu.v
@@ -0,0 +1,747 @@
+module grom_cpu(
+ input clk,
+ input reset,
+ output reg [11:0] addr,
+ input [7:0] data_in,
+ output reg [7:0] data_out,
+ output reg we,
+ output reg ioreq,
+ output reg hlt
+);
+
+ reg[11:0] PC /* verilator public_flat */; // Program counter
+ reg[7:0] IR /* verilator public_flat */; // Instruction register
+ reg[7:0] VALUE /* verilator public_flat */; // Temp reg for storing 2nd operand
+ reg[3:0] CS /* verilator public_flat */; // Code segment regiser
+ reg[3:0] DS /* verilator public_flat */; // Data segment regiser
+ reg[11:0] SP /* verilator public_flat */; // Stack pointer regiser
+ reg[7:0] R[0:3] /* verilator public_flat */; // General purpose registers
+ reg[11:0] FUTURE_PC /* verilator public_flat */; // PC to jump to
+
+ localparam STATE_RESET /*verilator public_flat*/ = 5'b00000;
+ localparam STATE_FETCH_PREP /*verilator public_flat*/ = 5'b00001;
+ localparam STATE_FETCH_WAIT /*verilator public_flat*/ = 5'b00010;
+ localparam STATE_FETCH /*verilator public_flat*/ = 5'b00011;
+ localparam STATE_EXECUTE /*verilator public_flat*/ = 5'b00100;
+ localparam STATE_FETCH_VALUE_PREP /*verilator public_flat*/ = 5'b00101;
+ localparam STATE_FETCH_VALUE /*verilator public_flat*/ = 5'b00110;
+ localparam STATE_EXECUTE_DBL /*verilator public_flat*/ = 5'b00111;
+ localparam STATE_LOAD_VALUE /*verilator public_flat*/ = 5'b01000;
+ localparam STATE_LOAD_VALUE_WAIT /*verilator public_flat*/ = 5'b01001;
+ localparam STATE_ALU_RESULT_WAIT /*verilator public_flat*/ = 5'b01010;
+ localparam STATE_ALU_RESULT /*verilator public_flat*/ = 5'b01011;
+ localparam STATE_PUSH_PC_LOW /*verilator public_flat*/ = 5'b01100;
+ localparam STATE_JUMP /*verilator public_flat*/ = 5'b01101;
+ localparam STATE_RET_VALUE_WAIT /*verilator public_flat*/ = 5'b01110;
+ localparam STATE_RET_VALUE /*verilator public_flat*/ = 5'b01111;
+ localparam STATE_RET_VALUE_WAIT2 /*verilator public_flat*/ = 5'b10000;
+ localparam STATE_RET_VALUE2 /*verilator public_flat*/ = 5'b10001;
+
+ reg [4:0] state /* verilator public_flat */ = STATE_RESET;
+
+ reg [7:0] alu_a /* verilator public_flat */;
+ reg [7:0] alu_b /* verilator public_flat */;
+ reg [3:0] alu_op /* verilator public_flat */;
+
+ reg [1:0] RESULT_REG /* verilator public_flat */;
+
+ wire [7:0] alu_res /* verilator public_flat */;
+ wire alu_CF /* verilator public_flat */;
+ wire alu_ZF /* verilator public_flat */;
+ wire alu_SF /* verilator public_flat */;
+ reg jump;
+
+ alu alu(.clk(clk),.A(alu_a),.B(alu_b),.operation(alu_op),.result(alu_res),.CF(alu_CF),.ZF(alu_ZF),.SF(alu_SF));
+
+ always @(posedge clk)
+ begin
+ if (reset)
+ begin
+ state <= STATE_RESET;
+ hlt <= 0;
+ end
+ else
+ begin
+ case (state)
+ STATE_RESET :
+ begin
+ PC <= 12'h000;
+ state <= STATE_FETCH_PREP;
+ CS <= 4'h0;
+ DS <= 4'h0;
+ R[0] <= 8'h00;
+ R[1] <= 8'h00;
+ R[2] <= 8'h00;
+ R[3] <= 8'h00;
+ SP <= 12'hfff;
+ end
+
+ STATE_FETCH_PREP :
+ begin
+ addr <= PC;
+ we <= 0;
+ ioreq <= 0;
+
+ state <= STATE_FETCH_WAIT;
+ end
+
+ STATE_FETCH_WAIT :
+ begin
+ // Sync with memory due to CLK
+ state <= (hlt) ? STATE_FETCH_PREP : STATE_FETCH;
+ end
+
+ STATE_FETCH :
+ begin
+ IR <= data_in;
+ PC <= PC + 1;
+
+ state <= STATE_EXECUTE;
+ end
+ STATE_EXECUTE :
+ begin
+ `ifdef DISASSEMBLY
+ $display(" PC %h R0 %h R1 %h R2 %h R3 %h CS %h DS %h SP %h ALU [%d %d %d]", PC, R[0], R[1], R[2], R[3], CS, DS, SP, alu_CF,alu_SF,alu_ZF);
+ `endif
+ if (IR[7])
+ begin
+ addr <= PC;
+ state <= STATE_FETCH_VALUE_PREP;
+ PC <= PC + 1;
+ end
+ else
+ begin
+ case(IR[6:4])
+ 3'b000 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("MOV R%d,R%d",IR[3:2],IR[1:0]);
+ `endif
+ R[IR[3:2]] <= R[IR[1:0]];
+ state <= STATE_FETCH_PREP;
+ end
+ 3'b001 :
+ begin
+ alu_a <= R[0]; // first input R0
+ alu_b <= R[IR[1:0]];
+ RESULT_REG <= 0; // result in R0
+ alu_op <= { 2'b00, IR[3:2] };
+
+ state <= STATE_ALU_RESULT_WAIT;
+
+ `ifdef DISASSEMBLY
+ case(IR[3:2])
+ 2'b00 : begin
+ $display("ADD R%d",IR[1:0]);
+ end
+ 2'b01 : begin
+ $display("SUB R%d",IR[1:0]);
+ end
+ 2'b10 : begin
+ $display("ADC R%d",IR[1:0]);
+ end
+ 2'b11 : begin
+ $display("SBC R%d",IR[1:0]);
+ end
+ endcase
+ `endif
+ end
+ 3'b010 :
+ begin
+ alu_a <= R[0]; // first input R0
+ alu_b <= R[IR[1:0]];
+ RESULT_REG <= 0; // result in R0
+ alu_op <= { 2'b01, IR[3:2] };
+ state <= STATE_ALU_RESULT_WAIT;
+ `ifdef DISASSEMBLY
+ case(IR[3:2])
+ 2'b00 : begin
+ $display("AND R%d",IR[1:0]);
+ end
+ 2'b01 : begin
+ $display("OR R%d",IR[1:0]);
+ end
+ 2'b10 : begin
+ $display("NOT R%d",IR[1:0]);
+ end
+ 2'b11 : begin
+ $display("XOR R%d",IR[1:0]);
+ end
+ endcase
+ `endif
+ end
+ 3'b011 :
+ begin
+ RESULT_REG <= IR[1:0]; // result in REG
+ // CMP and TEST are not storing result
+ state <= IR[3] ? STATE_FETCH_PREP : STATE_ALU_RESULT_WAIT;
+ // CMP and TEST are having first input R0, for INC and DEC is REG
+ alu_a <= IR[3] ? R[0] : R[IR[1:0]];
+ // CMP and TEST are having second input REG, for INC and DEC is 1
+ alu_b <= IR[3] ? R[IR[1:0]] : 8'b00000001;
+
+ case(IR[3:2])
+ 2'b00 : begin
+ `ifdef DISASSEMBLY
+ $display("INC R%d",IR[1:0]);
+ `endif
+ alu_op <= 4'b0000; // ALU_OP_ADD
+ end
+ 2'b01 : begin
+ `ifdef DISASSEMBLY
+ $display("DEC R%d",IR[1:0]);
+ `endif
+ alu_op <= 4'b0001; // ALU_OP_SUB
+ end
+ 2'b10 : begin
+ `ifdef DISASSEMBLY
+ $display("CMP R%d",IR[1:0]);
+ `endif
+ alu_op <= 4'b0001; // ALU_OP_SUB
+ end
+ 2'b11 : begin
+ `ifdef DISASSEMBLY
+ $display("TST R%d",IR[1:0]);
+ `endif
+ alu_op <= 4'b0100; // ALU_OP_AND
+ end
+ endcase
+ end
+ 3'b100 :
+ begin
+ if (IR[3]==0)
+ begin
+ alu_a <= R[0]; // first input R0
+ // no 2nd input
+ RESULT_REG <= 0; // result in R0
+ alu_op <= { 1'b1, IR[2:0] };
+ `ifdef DISASSEMBLY
+ case(IR[2:0])
+ 3'b000 : begin
+ $display("SHL");
+ end
+ 3'b001 : begin
+ $display("SHR");
+ end
+ 3'b010 : begin
+ $display("SAL");
+ end
+ 3'b011 : begin
+ $display("SAR");
+ end
+ 3'b100 : begin
+ $display("ROL");
+ end
+ 3'b101 : begin
+ $display("ROR");
+ end
+ 3'b110 : begin
+ $display("RCL");
+ end
+ 3'b111 : begin
+ $display("RCR");
+ end
+ endcase
+ `endif
+ state <= STATE_ALU_RESULT_WAIT;
+ end
+ else
+ begin
+ if (IR[2]==0)
+ begin
+ `ifdef DISASSEMBLY
+ $display("PUSH R%d",IR[1:0]);
+ `endif
+ addr <= SP;
+ we <= 1;
+ ioreq <= 0;
+ data_out <= R[IR[1:0]];
+ SP <= SP - 1;
+ state <= STATE_FETCH_PREP;
+ end
+ else
+ begin
+ `ifdef DISASSEMBLY
+ $display("POP R%d",IR[1:0]);
+ `endif
+ addr <= SP + 1;
+ we <= 0;
+ ioreq <= 0;
+ RESULT_REG <= IR[1:0];
+ SP <= SP + 1;
+ state <= STATE_LOAD_VALUE_WAIT;
+ end
+ end
+ end
+ 3'b101 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("LOAD R%d,[R%d]", IR[3:2], IR[1:0]);
+ `endif
+ addr <= { DS, R[IR[1:0]] };
+ we <= 0;
+ ioreq <= 0;
+ RESULT_REG <= IR[3:2];
+
+ state <= STATE_LOAD_VALUE_WAIT;
+ end
+ 3'b110 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("STORE [R%d],R%d", IR[3:2], IR[1:0]);
+ `endif
+ addr <= { DS, R[IR[3:2]] };
+ we <= 1;
+ ioreq <= 0;
+ data_out <= R[IR[1:0]];
+
+ state <= STATE_FETCH_PREP;
+ end
+ 3'b111 :
+ begin
+ // Special instuctions
+ case(IR[3:2])
+ 2'b00 : begin
+ CS <= R[IR[1:0]][3:0];
+ state <= STATE_FETCH_PREP;
+ `ifdef DISASSEMBLY
+ $display("MOV CS,R%d",IR[1:0]);
+ `endif
+ end
+ 2'b01 : begin
+ DS <= R[IR[1:0]][3:0];
+ state <= STATE_FETCH_PREP;
+ `ifdef DISASSEMBLY
+ $display("MOV DS,R%d",IR[1:0]);
+ `endif
+ end
+ 2'b10 : begin
+ case(IR[1:0])
+ 2'b00 : begin
+ `ifdef DISASSEMBLY
+ $display("PUSH CS");
+ `endif
+ addr <= SP;
+ we <= 1;
+ ioreq <= 0;
+ data_out <= { 4'b0000, CS};
+ SP <= SP - 1;
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b01 : begin
+ `ifdef DISASSEMBLY
+ $display("PUSH DS");
+ `endif
+ addr <= SP;
+ we <= 1;
+ ioreq <= 0;
+ data_out <= { 4'b0000, DS};
+ SP <= SP - 1;
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b10 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode");
+ `endif
+ end
+ 2'b11 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode");
+ `endif
+ end
+ endcase
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b11 : begin
+ case(IR[1:0])
+ 2'b00 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode");
+ `endif
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b01 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode");
+ `endif
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b10 : begin
+ `ifdef DISASSEMBLY
+ $display("RET");
+ `endif
+ addr <= SP + 1;
+ we <= 0;
+ ioreq <= 0;
+ SP <= SP + 1;
+ state <= STATE_RET_VALUE_WAIT;
+ end
+ 2'b11 : begin
+ hlt <= 1;
+ `ifdef DISASSEMBLY
+ $display("HALT");
+ `endif
+ state <= STATE_FETCH_PREP;
+ end
+ endcase
+ end
+ endcase
+ end
+ endcase
+ end
+ end
+ STATE_FETCH_VALUE_PREP :
+ begin
+ // Sync with memory due to CLK
+ state <= STATE_FETCH_VALUE;
+ end
+ STATE_FETCH_VALUE :
+ begin
+ VALUE <= data_in;
+ state <= STATE_EXECUTE_DBL;
+ end
+ STATE_EXECUTE_DBL :
+ begin
+ case(IR[6:4])
+ 3'b000 :
+ begin
+ if (IR[3]==0)
+ begin
+ case(IR[2:0])
+ 3'b000 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JMP %h ",{ CS, VALUE[7:0] });
+ `endif
+ jump = 1;
+ end
+ 3'b001 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JC %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_CF==1);
+ end
+ 3'b010 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JNC %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_CF==0);
+ end
+ 3'b011 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JM %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_SF==1);
+ end
+ 3'b100 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JP %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_SF==0);
+ end
+ 3'b101 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JZ %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_ZF==1);
+ end
+ 3'b110 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JNZ %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_ZF==0);
+ end
+ 3'b111 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode %h",IR);
+ `endif
+ jump = 0;
+ end
+ endcase
+
+ if (jump)
+ begin
+ PC <= { CS, VALUE[7:0] };
+ addr <= { CS, VALUE[7:0] };
+ we <= 0;
+ ioreq <= 0;
+ end
+ state <= STATE_FETCH_PREP;
+ end
+ else
+ begin
+ case(IR[2:0])
+ 3'b000 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JR %h ", PC + {VALUE[7],VALUE[7],VALUE[7],VALUE[7],VALUE[7:0]} );
+ `endif
+ jump = 1;
+ end
+ 3'b001 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JRC %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_CF==1);
+ end
+ 3'b010 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JRNC %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_CF==0);
+ end
+ 3'b011 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JRM %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_SF==1);
+ end
+ 3'b100 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JRP %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_SF==0);
+ end
+ 3'b101 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JRZ %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_ZF==1);
+ end
+ 3'b110 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JRNZ %h ",{CS, VALUE[7:0] });
+ `endif
+ jump = (alu_ZF==0);
+ end
+ 3'b111 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode %h",IR);
+ `endif
+ jump = 0;
+ end
+ endcase
+ if (jump)
+ begin
+ PC <= PC + {VALUE[7],VALUE[7],VALUE[7],VALUE[7],VALUE[7:0]};
+ addr <= PC + {VALUE[7],VALUE[7],VALUE[7],VALUE[7],VALUE[7:0]};
+ we <= 0;
+ ioreq <= 0;
+ end
+ state <= STATE_FETCH_PREP;
+ end
+ end
+ 3'b001 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("JUMP %h ",{ IR[3:0], VALUE[7:0] });
+ `endif
+ PC <= { IR[3:0], VALUE[7:0] };
+ addr <= { IR[3:0], VALUE[7:0] };
+ we <= 0;
+ ioreq <= 0;
+ state <= STATE_FETCH_PREP;
+ end
+ 3'b010 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("CALL %h ",{ IR[3:0], VALUE[7:0] });
+ `endif
+ FUTURE_PC <= { IR[3:0], VALUE[7:0] };
+ addr <= SP;
+ we <= 1;
+ ioreq <= 0;
+ data_out <= { 4'b0000, PC[11:8]};
+ SP <= SP - 1;
+ state <= STATE_PUSH_PC_LOW;
+ end
+ 3'b011 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("MOV SP,%h ",{ IR[3:0], VALUE[7:0] });
+ `endif
+ SP <= { IR[3:0], VALUE[7:0] };
+ state <= STATE_FETCH_PREP;
+ end
+ 3'b100 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("IN R%d,[0x%h]",IR[1:0], VALUE);
+ `endif
+ ioreq <= 1;
+ we <= 0;
+ addr <= { 4'b0000, VALUE };
+ RESULT_REG <= IR[1:0];
+ state <= STATE_LOAD_VALUE_WAIT;
+ end
+ 3'b101 :
+ begin
+ `ifdef DISASSEMBLY
+ $display("OUT [0x%h],R%d",VALUE,IR[1:0]);
+ `endif
+ ioreq <= 1;
+ we <= 1;
+ addr <= { 4'b0000, VALUE };
+ data_out <= R[IR[1:0]];
+ state <= STATE_FETCH_PREP;
+ end
+ 3'b110 :
+ begin
+ // Special instuctions
+ case(IR[1:0])
+ 2'b00 : begin
+ `ifdef DISASSEMBLY
+ $display("MOV CS,0x%h",VALUE);
+ `endif
+ CS <= VALUE[3:0];
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b01 : begin
+ `ifdef DISASSEMBLY
+ $display("MOV DS,0x%h",VALUE);
+ `endif
+ DS <= VALUE[3:0];
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b10 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode %h",IR);
+ `endif
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b11 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode %h",IR);
+ `endif
+ state <= STATE_FETCH_PREP;
+ end
+ endcase
+ end
+ 3'b111 :
+ begin
+ case(IR[3:2])
+ 2'b00 : begin
+ `ifdef DISASSEMBLY
+ $display("MOV R%d,0x%h",IR[1:0],VALUE);
+ `endif
+ R[IR[1:0]] <= VALUE;
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b01 : begin
+ `ifdef DISASSEMBLY
+ $display("LOAD R%d,[0x%h]",IR[1:0], {DS, VALUE});
+ `endif
+ addr <= { DS, VALUE };
+ we <= 0;
+ ioreq <= 0;
+ RESULT_REG <= IR[1:0];
+
+ state <= STATE_LOAD_VALUE_WAIT;
+ end
+ 2'b10 : begin
+ `ifdef DISASSEMBLY
+ $display("STORE [0x%h],R%d", {DS, VALUE}, IR[1:0]);
+ `endif
+ addr <= { DS, VALUE };
+ we <= 1;
+ ioreq <= 0;
+ data_out <= R[IR[1:0]];
+
+ state <= STATE_FETCH_PREP;
+ end
+ 2'b11 : begin
+ `ifdef DISASSEMBLY
+ $display("Unused opcode %h",IR);
+ `endif
+ state <= STATE_FETCH_PREP;
+ end
+ endcase
+ end
+ endcase
+ end
+ STATE_LOAD_VALUE_WAIT :
+ begin
+ // Sync with memory due to CLK
+ state <= STATE_LOAD_VALUE;
+ end
+ STATE_LOAD_VALUE :
+ begin
+ R[RESULT_REG] <= data_in;
+ we <= 0;
+ state <= STATE_FETCH_PREP;
+ end
+ STATE_ALU_RESULT_WAIT :
+ begin
+ state <= STATE_ALU_RESULT;
+ end
+ STATE_ALU_RESULT :
+ begin
+ R[RESULT_REG] <= alu_res;
+ state <= STATE_FETCH_PREP;
+ end
+ STATE_PUSH_PC_LOW :
+ begin
+ addr <= SP;
+ we <= 1;
+ ioreq <= 0;
+ data_out <= PC[7:0];
+ SP <= SP - 1;
+ state <= STATE_JUMP;
+ end
+ STATE_JUMP :
+ begin
+ `ifdef DISASSEMBLY
+ $display("Jumping to %h",FUTURE_PC);
+ `endif
+ PC <= FUTURE_PC;
+ state <= STATE_FETCH_PREP;
+ end
+ STATE_RET_VALUE_WAIT :
+ begin
+ // Sync with memory due to CLK
+ state <= STATE_RET_VALUE;
+ end
+ STATE_RET_VALUE :
+ begin
+ FUTURE_PC <= { 4'b0000, data_in };
+ we <= 0;
+ state <= STATE_RET_VALUE_WAIT2;
+
+ addr <= SP + 1;
+ we <= 0;
+ ioreq <= 0;
+ SP <= SP + 1;
+ end
+ STATE_RET_VALUE_WAIT2 :
+ begin
+ // Sync with memory due to CLK
+ state <= STATE_RET_VALUE2;
+ end
+ STATE_RET_VALUE2 :
+ begin
+ FUTURE_PC <= FUTURE_PC | ({ 4'b0000, data_in } << 8);
+ we <= 0;
+ state <= STATE_JUMP;
+ end
+ default :
+ begin
+ state <= STATE_FETCH_PREP;
+ end
+ endcase
+ end
+ end
+endmodule
diff --git a/tests/sat/ram_memory.v b/tests/sat/ram_memory.v
new file mode 100644
index 000000000..0d91514b2
--- /dev/null
+++ b/tests/sat/ram_memory.v
@@ -0,0 +1,39 @@
+module ram_memory(
+ input clk,
+ input [11:0] addr,
+ input [7:0] data_in,
+ input we,
+ output reg [7:0] data_out
+);
+
+ reg [7:0] store[0:4095] /* verilator public_flat */;
+
+ initial
+ begin
+ store[0] <= 8'b11100001; // MOV DS,2
+ store[1] <= 8'b00000010; //
+ store[2] <= 8'b01010100; // LOAD R1,[R0]
+ store[3] <= 8'b00110001; // INC R1
+ store[4] <= 8'b00110001; // INC R1
+ store[5] <= 8'b01100001; // STORE [R0],R1
+ store[6] <= 8'b11010001; // OUT [0],R1
+ store[7] <= 8'b00000000; //
+ store[8] <= 8'b00110001; // INC R1
+ store[9] <= 8'b10100001; // CALL 0x100
+ store[10] <= 8'b00000000; //
+ store[11] <= 8'b01111111; // HLT
+
+
+ store[256] <= 8'b11010001; // OUT [0],R1
+ store[257] <= 8'b00000000; //
+ store[258] <= 8'b01111110; // RET
+
+ store[512] <= 8'b00000000;
+ end
+
+ always @(posedge clk)
+ if (we)
+ store[addr] <= data_in;
+ else
+ data_out <= store[addr];
+endmodule
diff --git a/tests/sat/sim_counter.ys b/tests/sat/sim_counter.ys
new file mode 100644
index 000000000..a0ff41b6e
--- /dev/null
+++ b/tests/sat/sim_counter.ys
@@ -0,0 +1,48 @@
+# Create stimulus file
+read_verilog <<EOT
+module top (clk, reset, cnt);
+
+input clk;
+input reset;
+output [7:0] cnt;
+
+reg [7:0] cnt;
+
+endmodule
+EOT
+prep -top top;
+sim -clock clk -reset reset -fst stimulus.fst -n 10
+design -reset
+
+# Counter implementation
+read_verilog <<EOT
+module top (clk, reset, cnt);
+
+input clk;
+input reset;
+output [7:0] cnt;
+
+reg [7:0] cnt;
+
+always @(posedge clk)
+ if (!reset)
+ cnt = cnt + 1;
+ else
+ cnt = 0;
+
+endmodule
+EOT
+prep -top top;
+
+# Simulate with stimulus
+sim -clock clk -scope top -r stimulus.fst
+
+# Stimulus does not have counter values
+# x in FST can match any value in simulation
+sim -clock clk -scope top -r stimulus.fst -sim-gate
+
+# Stimulus does not have counter values
+# x in simulation can match any value in FST
+# so we expect error
+logger -expect error "Signal difference" 1
+sim -clock clk -scope top -r stimulus.fst -sim-gold
diff --git a/tests/sim/.gitignore b/tests/sim/.gitignore
new file mode 100644
index 000000000..2c96b65f8
--- /dev/null
+++ b/tests/sim/.gitignore
@@ -0,0 +1,6 @@
+*.log
+/run-test.mk
++*_synth.v
++*_testbench
+*.out
+*.fst
diff --git a/tests/sim/adff.v b/tests/sim/adff.v
new file mode 100644
index 000000000..8c8fb0acf
--- /dev/null
+++ b/tests/sim/adff.v
@@ -0,0 +1,7 @@
+module adff( input d, clk, rst, output reg q );
+ always @( posedge clk, posedge rst )
+ if (rst)
+ q <= 0;
+ else
+ q <= d;
+endmodule
diff --git a/tests/sim/adffe.v b/tests/sim/adffe.v
new file mode 100644
index 000000000..55c7d8d4e
--- /dev/null
+++ b/tests/sim/adffe.v
@@ -0,0 +1,8 @@
+module adffe( input d, clk, rst, en, output reg q );
+ always @( posedge clk, posedge rst )
+ if (rst)
+ q <= 0;
+ else
+ if (en)
+ q <= d;
+endmodule
diff --git a/tests/sim/adlatch.v b/tests/sim/adlatch.v
new file mode 100644
index 000000000..5e8f48e49
--- /dev/null
+++ b/tests/sim/adlatch.v
@@ -0,0 +1,8 @@
+module adlatch( input d, rst, en, output reg q );
+ always @* begin
+ if (rst)
+ q = 0;
+ else if (en)
+ q = d;
+ end
+endmodule
diff --git a/tests/sim/aldff.v b/tests/sim/aldff.v
new file mode 100644
index 000000000..eeb0f0673
--- /dev/null
+++ b/tests/sim/aldff.v
@@ -0,0 +1,7 @@
+module aldff( input [0:3] d, input [0:3] ad, input clk, aload, output reg [0:3] q );
+ always @( posedge clk, posedge aload)
+ if (aload)
+ q <= ad;
+ else
+ q <= d;
+endmodule
diff --git a/tests/sim/aldffe.v b/tests/sim/aldffe.v
new file mode 100644
index 000000000..79c65afc4
--- /dev/null
+++ b/tests/sim/aldffe.v
@@ -0,0 +1,8 @@
+module aldffe( input [0:3] d, input [0:3] ad, input clk, aload, en, output reg [0:3] q );
+ always @( posedge clk, posedge aload)
+ if (aload)
+ q <= ad;
+ else
+ if (en)
+ q <= d;
+endmodule
diff --git a/tests/sim/dff.v b/tests/sim/dff.v
new file mode 100644
index 000000000..ce792b59a
--- /dev/null
+++ b/tests/sim/dff.v
@@ -0,0 +1,4 @@
+module dff( input d, clk, output reg q );
+ always @( posedge clk )
+ q <= d;
+endmodule
diff --git a/tests/sim/dffe.v b/tests/sim/dffe.v
new file mode 100644
index 000000000..853fcf66a
--- /dev/null
+++ b/tests/sim/dffe.v
@@ -0,0 +1,5 @@
+module dffe( input clk, en, d, output reg q );
+ always @( posedge clk )
+ if ( en )
+ q <= d;
+endmodule
diff --git a/tests/sim/dffsr.v b/tests/sim/dffsr.v
new file mode 100644
index 000000000..2158708f1
--- /dev/null
+++ b/tests/sim/dffsr.v
@@ -0,0 +1,9 @@
+module dffsr( input clk, d, clr, set, output reg q );
+ always @( posedge clk, posedge set, posedge clr)
+ if ( clr )
+ q <= 0;
+ else if (set)
+ q <= 1;
+ else
+ q <= d;
+endmodule
diff --git a/tests/sim/dlatch.v b/tests/sim/dlatch.v
new file mode 100644
index 000000000..315b43216
--- /dev/null
+++ b/tests/sim/dlatch.v
@@ -0,0 +1,6 @@
+module dlatch( input d, en, output reg q );
+ always @* begin
+ if ( en )
+ q = d;
+ end
+endmodule
diff --git a/tests/sim/dlatchsr.v b/tests/sim/dlatchsr.v
new file mode 100644
index 000000000..1d13ac2ad
--- /dev/null
+++ b/tests/sim/dlatchsr.v
@@ -0,0 +1,11 @@
+module dlatchsr( input d, set, clr, en, output reg q );
+ always @* begin
+ if ( clr )
+ q = 0;
+ else if (set)
+ q = 1;
+ else
+ if (en)
+ q = d;
+ end
+endmodule
diff --git a/tests/sim/run-test.sh b/tests/sim/run-test.sh
new file mode 100755
index 000000000..d34d1f3c9
--- /dev/null
+++ b/tests/sim/run-test.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+set -eu
+source ../gen-tests-makefile.sh
+echo "Generate FST for sim models"
+find tb/* -name tb*.v | while read name; do
+ test_name=$(basename -s .v $name)
+ echo "Test $test_name"
+ verilog_name=${test_name:3}.v
+ iverilog -o tb/$test_name.out $name $verilog_name
+ ./tb/$test_name.out -fst
+done
+run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'"
diff --git a/tests/sim/sdff.v b/tests/sim/sdff.v
new file mode 100644
index 000000000..6b25516e1
--- /dev/null
+++ b/tests/sim/sdff.v
@@ -0,0 +1,7 @@
+module sdff( input d, clk, rst, output reg q );
+ always @( posedge clk)
+ if (rst)
+ q <= 0;
+ else
+ q <= d;
+endmodule
diff --git a/tests/sim/sdffce.v b/tests/sim/sdffce.v
new file mode 100644
index 000000000..7d27d5741
--- /dev/null
+++ b/tests/sim/sdffce.v
@@ -0,0 +1,8 @@
+module sdffce( input d, clk, rst, en, output reg q );
+ always @( posedge clk)
+ if(en)
+ if (rst)
+ q <= 0;
+ else
+ q <= d;
+endmodule
diff --git a/tests/sim/sdffe.v b/tests/sim/sdffe.v
new file mode 100644
index 000000000..0a96693e1
--- /dev/null
+++ b/tests/sim/sdffe.v
@@ -0,0 +1,8 @@
+module sdffe( input d, clk, rst, en, output reg q );
+ always @( posedge clk)
+ if (rst)
+ q <= 0;
+ else
+ if (en)
+ q <= d;
+endmodule
diff --git a/tests/sim/sim_adff.ys b/tests/sim/sim_adff.ys
new file mode 100644
index 000000000..6efd804a9
--- /dev/null
+++ b/tests/sim/sim_adff.ys
@@ -0,0 +1,6 @@
+read_verilog adff.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$adff
+sim -clock clk -r tb_adff.fst -scope tb_adff.uut -sim-cmp adff
diff --git a/tests/sim/sim_adffe.ys b/tests/sim/sim_adffe.ys
new file mode 100644
index 000000000..47a51ebce
--- /dev/null
+++ b/tests/sim/sim_adffe.ys
@@ -0,0 +1,6 @@
+read_verilog adffe.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$adffe
+sim -clock clk -r tb_adffe.fst -scope tb_adffe.uut -sim-cmp adffe
diff --git a/tests/sim/sim_adlatch.ys b/tests/sim/sim_adlatch.ys
new file mode 100644
index 000000000..eece7dc0d
--- /dev/null
+++ b/tests/sim/sim_adlatch.ys
@@ -0,0 +1,10 @@
+read_verilog -icells <<EOT
+module adlatch(input d, rst, en, output reg q);
+$adlatch #(.EN_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(1'b0), .WIDTH(1)) uut (.EN(en), .ARST(rst), .D(d), .Q(q));
+endmodule
+EOT
+proc
+opt_dff
+stat
+select -assert-count 1 t:$adlatch
+sim -r tb_adlatch.fst -scope tb_adlatch.uut -sim-cmp adlatch
diff --git a/tests/sim/sim_aldff.ys b/tests/sim/sim_aldff.ys
new file mode 100644
index 000000000..9c8b3bdfc
--- /dev/null
+++ b/tests/sim/sim_aldff.ys
@@ -0,0 +1,6 @@
+read_verilog aldff.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$aldff
+sim -clock clk -r tb_aldff.fst -scope tb_aldff.uut -sim-cmp aldff
diff --git a/tests/sim/sim_aldffe.ys b/tests/sim/sim_aldffe.ys
new file mode 100644
index 000000000..b191cf877
--- /dev/null
+++ b/tests/sim/sim_aldffe.ys
@@ -0,0 +1,6 @@
+read_verilog aldffe.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$aldffe
+sim -clock clk -r tb_aldffe.fst -scope tb_aldffe.uut -sim-cmp aldffe
diff --git a/tests/sim/sim_dff.ys b/tests/sim/sim_dff.ys
new file mode 100644
index 000000000..12f402443
--- /dev/null
+++ b/tests/sim/sim_dff.ys
@@ -0,0 +1,6 @@
+read_verilog dff.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$dff
+sim -clock clk -r tb_dff.fst -scope tb_dff.uut -sim-cmp dff
diff --git a/tests/sim/sim_dffe.ys b/tests/sim/sim_dffe.ys
new file mode 100644
index 000000000..f9b9e4767
--- /dev/null
+++ b/tests/sim/sim_dffe.ys
@@ -0,0 +1,6 @@
+read_verilog dffe.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$dffe
+sim -clock clk -r tb_dffe.fst -scope tb_dffe.uut -sim-cmp dffe
diff --git a/tests/sim/sim_dffsr.ys b/tests/sim/sim_dffsr.ys
new file mode 100644
index 000000000..e99ee860d
--- /dev/null
+++ b/tests/sim/sim_dffsr.ys
@@ -0,0 +1,6 @@
+read_verilog dffsr.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$dffsr
+sim -clock clk -r tb_dffsr.fst -scope tb_dffsr.uut -sim-cmp dffsr
diff --git a/tests/sim/sim_dlatch.ys b/tests/sim/sim_dlatch.ys
new file mode 100644
index 000000000..79e4601e3
--- /dev/null
+++ b/tests/sim/sim_dlatch.ys
@@ -0,0 +1,6 @@
+read_verilog dlatch.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$dlatch
+sim -r tb_dlatch.fst -scope tb_dlatch.uut -sim-cmp dlatch
diff --git a/tests/sim/sim_dlatchsr.ys b/tests/sim/sim_dlatchsr.ys
new file mode 100644
index 000000000..c83051c8b
--- /dev/null
+++ b/tests/sim/sim_dlatchsr.ys
@@ -0,0 +1,10 @@
+read_verilog -icells <<EOT
+module dlatchsr(input d, set, clr, en, output reg q);
+$dlatchsr #(.EN_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b1), .WIDTH(1)) uut (.EN(en), .SET(set), .CLR(clr), .D(d), .Q(q));
+endmodule
+EOT
+proc
+opt_dff
+stat
+select -assert-count 1 t:$dlatchsr
+sim -r tb_dlatchsr.fst -scope tb_dlatchsr.uut -sim-cmp dlatchsr
diff --git a/tests/sim/sim_sdff.ys b/tests/sim/sim_sdff.ys
new file mode 100644
index 000000000..a812c5d80
--- /dev/null
+++ b/tests/sim/sim_sdff.ys
@@ -0,0 +1,6 @@
+read_verilog sdff.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$sdff
+sim -clock clk -r tb_sdff.fst -scope tb_sdff.uut -sim-cmp sdff
diff --git a/tests/sim/sim_sdffce.ys b/tests/sim/sim_sdffce.ys
new file mode 100644
index 000000000..b28acb83d
--- /dev/null
+++ b/tests/sim/sim_sdffce.ys
@@ -0,0 +1,6 @@
+read_verilog sdffce.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$sdffce
+sim -clock clk -r tb_sdffce.fst -scope tb_sdffce.uut -sim-cmp sdffce
diff --git a/tests/sim/sim_sdffe.ys b/tests/sim/sim_sdffe.ys
new file mode 100644
index 000000000..044f78eb3
--- /dev/null
+++ b/tests/sim/sim_sdffe.ys
@@ -0,0 +1,6 @@
+read_verilog sdffe.v
+proc
+opt_dff
+stat
+select -assert-count 1 t:$sdffe
+sim -clock clk -r tb_sdffe.fst -scope tb_sdffe.uut -sim-cmp sdffe
diff --git a/tests/sim/tb/tb_adff.v b/tests/sim/tb/tb_adff.v
new file mode 100755
index 000000000..f1bc3547e
--- /dev/null
+++ b/tests/sim/tb/tb_adff.v
@@ -0,0 +1,40 @@
+`timescale 1ns/1ns
+module tb_adff();
+ reg clk = 0;
+ reg rst = 0;
+ reg d = 0;
+ wire q;
+
+ adff uut(.clk(clk),.d(d),.rst(rst),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_adff");
+ $dumpvars(0,tb_adff);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_adffe.v b/tests/sim/tb/tb_adffe.v
new file mode 100755
index 000000000..bb23f963d
--- /dev/null
+++ b/tests/sim/tb/tb_adffe.v
@@ -0,0 +1,58 @@
+`timescale 1ns/1ns
+module tb_adffe();
+ reg clk = 0;
+ reg rst = 0;
+ reg d = 0;
+ reg en = 0;
+ wire q;
+
+ adffe uut(.clk(clk),.d(d),.rst(rst),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_adffe");
+ $dumpvars(0,tb_adffe);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ en = 1;
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_adlatch.v b/tests/sim/tb/tb_adlatch.v
new file mode 100755
index 000000000..59dd498d2
--- /dev/null
+++ b/tests/sim/tb/tb_adlatch.v
@@ -0,0 +1,70 @@
+`timescale 1ns/1ns
+module tb_adlatch();
+ reg clk = 0;
+ reg rst = 0;
+ reg en = 0;
+ reg d = 0;
+ wire q;
+
+ adlatch uut(.d(d),.rst(rst),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_adlatch");
+ $dumpvars(0,tb_adlatch);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ en = 1;
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_aldff.v b/tests/sim/tb/tb_aldff.v
new file mode 100755
index 000000000..0591c8b3c
--- /dev/null
+++ b/tests/sim/tb/tb_aldff.v
@@ -0,0 +1,73 @@
+`timescale 1ns/1ns
+module tb_aldff();
+ reg clk = 0;
+ reg aload = 0;
+ reg [0:3] d = 4'b0000;
+ reg [0:3] ad = 4'b1010;
+ wire [0:3] q;
+
+ aldff uut(.clk(clk),.d(d),.ad(ad),.aload(aload),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_aldff");
+ $dumpvars(0,tb_aldff);
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 1;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 0;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 1;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 0;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_aldffe.v b/tests/sim/tb/tb_aldffe.v
new file mode 100755
index 000000000..c3cb57f4e
--- /dev/null
+++ b/tests/sim/tb/tb_aldffe.v
@@ -0,0 +1,75 @@
+`timescale 1ns/1ns
+module tb_aldffe();
+ reg clk = 0;
+ reg aload = 0;
+ reg [0:3] d = 4'b0000;
+ reg [0:3] ad = 4'b1010;
+ reg en = 0;
+ wire [0:3] q;
+
+ aldffe uut(.clk(clk),.d(d),.ad(ad),.aload(aload),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_aldffe");
+ $dumpvars(0,tb_aldffe);
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 1;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 0;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ en = 1;
+ aload = 1;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ aload = 0;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ d = 4'b1100;
+ #10
+ d = 4'b0011;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_dff.v b/tests/sim/tb/tb_dff.v
new file mode 100755
index 000000000..aa41d1c6c
--- /dev/null
+++ b/tests/sim/tb/tb_dff.v
@@ -0,0 +1,47 @@
+`timescale 1ns/1ns
+module tb_dff();
+ reg clk = 0;
+ reg d = 0;
+ wire q;
+
+ dff uut(.clk(clk),.d(d),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_dff");
+ $dumpvars(0,tb_dff);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_dffe.v b/tests/sim/tb/tb_dffe.v
new file mode 100755
index 000000000..4e262b928
--- /dev/null
+++ b/tests/sim/tb/tb_dffe.v
@@ -0,0 +1,42 @@
+`timescale 1ns/1ns
+module tb_dffe();
+ reg clk = 0;
+ reg en = 0;
+ reg d = 0;
+ wire q;
+
+ dffe uut(.clk(clk),.d(d),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_dffe");
+ $dumpvars(0,tb_dffe);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ en = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_dffsr.v b/tests/sim/tb/tb_dffsr.v
new file mode 100755
index 000000000..6ecb85d67
--- /dev/null
+++ b/tests/sim/tb/tb_dffsr.v
@@ -0,0 +1,69 @@
+`timescale 1ns/1ns
+module tb_dffsr();
+ reg clk = 0;
+ reg d = 0;
+ reg set = 0;
+ reg clr = 0;
+ wire q;
+
+ dffsr uut(.d(d),.clk(clk),.set(set),.clr(clr),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_dffsr");
+ $dumpvars(0,tb_dffsr);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ clr = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ clr = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ set = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ set = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_dlatch.v b/tests/sim/tb/tb_dlatch.v
new file mode 100755
index 000000000..aea6cb0a3
--- /dev/null
+++ b/tests/sim/tb/tb_dlatch.v
@@ -0,0 +1,50 @@
+`timescale 1ns/1ns
+module tb_dlatch();
+ reg clk = 0;
+ reg en = 0;
+ reg d = 0;
+ wire q;
+
+ dlatch uut(.d(d),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_dlatch");
+ $dumpvars(0,tb_dlatch);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ en = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_dlatchsr.v b/tests/sim/tb/tb_dlatchsr.v
new file mode 100755
index 000000000..0105d3288
--- /dev/null
+++ b/tests/sim/tb/tb_dlatchsr.v
@@ -0,0 +1,65 @@
+`timescale 1ns/1ns
+module tb_dlatchsr();
+ reg d = 0;
+ reg set = 0;
+ reg clr = 0;
+ wire q;
+
+ dlatchsr uut(.d(d),.set(set),.clr(clr),.q(q));
+
+ initial
+ begin
+ $dumpfile("tb_dlatchsr");
+ $dumpvars(0,tb_dlatchsr);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ clr = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ clr = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ set = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ set = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_sdff.v b/tests/sim/tb/tb_sdff.v
new file mode 100755
index 000000000..f8e2a1c9d
--- /dev/null
+++ b/tests/sim/tb/tb_sdff.v
@@ -0,0 +1,48 @@
+`timescale 1ns/1ns
+module tb_sdff();
+ reg clk = 0;
+ reg rst = 0;
+ reg d = 0;
+ wire q;
+
+ sdff uut(.clk(clk),.d(d),.rst(rst),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_sdff");
+ $dumpvars(0,tb_sdff);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_sdffce.v b/tests/sim/tb/tb_sdffce.v
new file mode 100755
index 000000000..1c9952806
--- /dev/null
+++ b/tests/sim/tb/tb_sdffce.v
@@ -0,0 +1,79 @@
+`timescale 1ns/1ns
+module tb_sdffce();
+ reg clk = 0;
+ reg rst = 0;
+ reg d = 0;
+ reg en = 0;
+ wire q;
+
+ sdffce uut(.clk(clk),.d(d),.rst(rst),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_sdffce");
+ $dumpvars(0,tb_sdffce);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ en = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/sim/tb/tb_sdffe.v b/tests/sim/tb/tb_sdffe.v
new file mode 100755
index 000000000..36072f93d
--- /dev/null
+++ b/tests/sim/tb/tb_sdffe.v
@@ -0,0 +1,70 @@
+`timescale 1ns/1ns
+module tb_sdffe();
+ reg clk = 0;
+ reg rst = 0;
+ reg d = 0;
+ reg en = 0;
+ wire q;
+
+ sdffe uut(.clk(clk),.d(d),.rst(rst),.en(en),.q(q));
+
+ always
+ #(5) clk <= !clk;
+
+ initial
+ begin
+ $dumpfile("tb_sdffe");
+ $dumpvars(0,tb_sdffe);
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ en = 1;
+ rst = 1;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ rst = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ d = 1;
+ #10
+ d = 0;
+ #10
+ $finish;
+ end
+endmodule
diff --git a/tests/simple/case_expr_extend.sv b/tests/simple/case_expr_extend.sv
new file mode 100644
index 000000000..d4ca2aa9b
--- /dev/null
+++ b/tests/simple/case_expr_extend.sv
@@ -0,0 +1,11 @@
+module top(
+ output logic [5:0] out
+);
+initial begin
+ out = '0;
+ case (1'b1 << 1)
+ 2'b10: out = '1;
+ default: out = '0;
+ endcase
+end
+endmodule
diff --git a/tests/simple/case_expr_query.sv b/tests/simple/case_expr_query.sv
new file mode 100644
index 000000000..844dfb713
--- /dev/null
+++ b/tests/simple/case_expr_query.sv
@@ -0,0 +1,32 @@
+module top(
+ output logic [5:0] out
+);
+initial begin
+ out = '0;
+ case ($bits (out)) 6:
+ case ($size (out)) 6:
+ case ($high (out)) 5:
+ case ($low (out)) 0:
+ case ($left (out)) 5:
+ case ($right(out)) 0:
+ case (6) $bits (out):
+ case (6) $size (out):
+ case (5) $high (out):
+ case (0) $low (out):
+ case (5) $left (out):
+ case (0) $right(out):
+ out = '1;
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+ endcase
+end
+endmodule
diff --git a/tests/simple/hierdefparam.v b/tests/simple/hierdefparam.v
index c9368ca7a..a6e0ac1b7 100644
--- a/tests/simple/hierdefparam.v
+++ b/tests/simple/hierdefparam.v
@@ -1,6 +1,6 @@
`default_nettype none
-module hierdefparam_top(input [7:0] A, output [7:0] Y);
+module hierdefparam_top(input wire [7:0] A, output wire [7:0] Y);
generate begin:foo
hierdefparam_a mod_a(.A(A), .Y(Y));
end endgenerate
@@ -8,7 +8,7 @@ module hierdefparam_top(input [7:0] A, output [7:0] Y);
defparam foo.mod_a.bar[1].mod_b.addvalue = 43;
endmodule
-module hierdefparam_a(input [7:0] A, output [7:0] Y);
+module hierdefparam_a(input wire [7:0] A, output wire [7:0] Y);
genvar i;
generate
for (i = 0; i < 2; i=i+1) begin:bar
@@ -19,7 +19,7 @@ module hierdefparam_a(input [7:0] A, output [7:0] Y);
assign bar[0].a = A, bar[1].a = bar[0].y, Y = bar[1].y;
endmodule
-module hierdefparam_b(input [7:0] A, output [7:0] Y);
+module hierdefparam_b(input wire [7:0] A, output wire [7:0] Y);
parameter [7:0] addvalue = 44;
assign Y = A + addvalue;
endmodule
diff --git a/tests/simple/implicit_ports.v b/tests/simple/implicit_ports.sv
index 8b0a6f386..8b0a6f386 100644
--- a/tests/simple/implicit_ports.v
+++ b/tests/simple/implicit_ports.sv
diff --git a/tests/simple/lesser_size_cast.sv b/tests/simple/lesser_size_cast.sv
new file mode 100644
index 000000000..8c0bc9814
--- /dev/null
+++ b/tests/simple/lesser_size_cast.sv
@@ -0,0 +1,7 @@
+module top (
+ input signed [1:0] a,
+ input signed [2:0] b,
+ output signed [4:0] c
+);
+ assign c = 2'(a) * b;
+endmodule
diff --git a/tests/simple/module_scope.v b/tests/simple/module_scope.v
index d07783912..ceeab7311 100644
--- a/tests/simple/module_scope.v
+++ b/tests/simple/module_scope.v
@@ -3,7 +3,7 @@
module module_scope_Example(o1, o2);
parameter [31:0] v1 = 10;
parameter [31:0] v2 = 20;
- output [31:0] o1, o2;
+ output wire [31:0] o1, o2;
assign module_scope_Example.o1 = module_scope_Example.v1;
assign module_scope_Example.o2 = module_scope_Example.v2;
endmodule
@@ -11,14 +11,14 @@ endmodule
module module_scope_ExampleLong(o1, o2);
parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1 = 10;
parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2 = 20;
- output [31:0] o1, o2;
+ output wire [31:0] o1, o2;
assign module_scope_ExampleLong.o1 = module_scope_ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1;
assign module_scope_ExampleLong.o2 = module_scope_ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2;
endmodule
module module_scope_top(
- output [31:0] a1, a2, b1, b2, c1, c2,
- output [31:0] d1, d2, e1, e2, f1, f2
+ output wire [31:0] a1, a2, b1, b2, c1, c2,
+ output wire [31:0] d1, d2, e1, e2, f1, f2
);
module_scope_Example a(a1, a2);
module_scope_Example #(1) b(b1, b2);
diff --git a/tests/simple/specify.v b/tests/simple/specify.v
index f19418d90..2c784ef6d 100644
--- a/tests/simple/specify.v
+++ b/tests/simple/specify.v
@@ -1,4 +1,4 @@
-module test_specify;
+module test_specify(input A, output B);
specparam a=1;
diff --git a/tests/sva/.gitignore b/tests/sva/.gitignore
index cc254049a..b1965c97d 100644
--- a/tests/sva/.gitignore
+++ b/tests/sva/.gitignore
@@ -3,5 +3,6 @@
/*_pass
/*_fail
/*.ok
+/*.fst
/vhdlpsl[0-9][0-9]
/vhdlpsl[0-9][0-9].sby
diff --git a/tests/sva/Makefile b/tests/sva/Makefile
index 1b217f746..dcabcf42b 100644
--- a/tests/sva/Makefile
+++ b/tests/sva/Makefile
@@ -10,4 +10,5 @@ clean:
rm -rf $(addsuffix .ok,$(TESTS)) $(addsuffix .sby,$(TESTS)) $(TESTS)
rm -rf $(addsuffix _pass.sby,$(TESTS)) $(addsuffix _pass,$(TESTS))
rm -rf $(addsuffix _fail.sby,$(TESTS)) $(addsuffix _fail,$(TESTS))
+ rm -rf $(addsuffix .fst,$(TESTS))
diff --git a/tests/sva/nested_clk_else.sv b/tests/sva/nested_clk_else.sv
new file mode 100644
index 000000000..4421cb36a
--- /dev/null
+++ b/tests/sva/nested_clk_else.sv
@@ -0,0 +1,11 @@
+module top (input clk, a, b);
+ always @(posedge clk) begin
+ if (a);
+ else assume property (@(posedge clk) b);
+ end
+
+`ifndef FAIL
+ assume property (@(posedge clk) !a);
+`endif
+ assert property (@(posedge clk) b);
+endmodule
diff --git a/tests/sva/runtest.sh b/tests/sva/runtest.sh
index 1b65ca9c9..2ecc9780c 100644
--- a/tests/sva/runtest.sh
+++ b/tests/sva/runtest.sh
@@ -22,18 +22,17 @@ generate_sby() {
if [ -f $prefix.sv ]; then
if [ "$1" = "fail" ]; then
- echo "verific -sv ${prefix}_fail.sv"
+ echo "read -sv ${prefix}_fail.sv"
else
- echo "verific -sv $prefix.sv"
+ echo "read -sv $prefix.sv"
fi
fi
if [ -f $prefix.vhd ]; then
- echo "verific -vhdl $prefix.vhd"
+ echo "read -vhdl $prefix.vhd"
fi
cat <<- EOT
- verific -import -extnets -all top
prep -top top
chformal -early -assume
@@ -58,7 +57,9 @@ generate_sby() {
fi
}
-if [ -f $prefix.sv ]; then
+if [ -f $prefix.ys ]; then
+ $PWD/../../yosys -q -e "Assert .* failed." -s $prefix.ys
+elif [ -f $prefix.sv ]; then
generate_sby pass > ${prefix}_pass.sby
generate_sby fail > ${prefix}_fail.sby
sby --yosys $PWD/../../yosys -f ${prefix}_pass.sby
diff --git a/tests/sva/sva_value_change_changed.sv b/tests/sva/sva_value_change_changed.sv
new file mode 100644
index 000000000..8f3a05a2f
--- /dev/null
+++ b/tests/sva/sva_value_change_changed.sv
@@ -0,0 +1,17 @@
+module top (
+ input clk,
+ input a, b
+);
+ default clocking @(posedge clk); endclocking
+
+ assert property (
+ $changed(b)
+ );
+
+`ifndef FAIL
+ assume property (
+ b !== 'x ##1 $changed(b)
+ );
+`endif
+
+endmodule
diff --git a/tests/sva/sva_value_change_changed_wide.sv b/tests/sva/sva_value_change_changed_wide.sv
new file mode 100644
index 000000000..c9147c4f3
--- /dev/null
+++ b/tests/sva/sva_value_change_changed_wide.sv
@@ -0,0 +1,22 @@
+module top (
+ input clk,
+ input [2:0] a,
+ input [2:0] b
+);
+ default clocking @(posedge clk); endclocking
+
+ assert property (
+ $changed(a)
+ );
+
+ assert property (
+ $changed(b) == ($changed(b[0]) || $changed(b[1]) || $changed(b[2]))
+ );
+
+`ifndef FAIL
+ assume property (
+ a !== 'x ##1 $changed(a)
+ );
+`endif
+
+endmodule
diff --git a/tests/sva/sva_value_change_rose.sv b/tests/sva/sva_value_change_rose.sv
new file mode 100644
index 000000000..d1c5290f1
--- /dev/null
+++ b/tests/sva/sva_value_change_rose.sv
@@ -0,0 +1,20 @@
+module top (
+ input clk,
+ input a, b
+);
+ default clocking @(posedge clk); endclocking
+
+ wire a_copy;
+ assign a_copy = a;
+
+ assert property (
+ $rose(a) |-> b
+ );
+
+`ifndef FAIL
+ assume property (
+ $rose(a_copy) |-> b
+ );
+`endif
+
+endmodule
diff --git a/tests/sva/sva_value_change_sim.sv b/tests/sva/sva_value_change_sim.sv
new file mode 100644
index 000000000..92fe30b23
--- /dev/null
+++ b/tests/sva/sva_value_change_sim.sv
@@ -0,0 +1,70 @@
+module top (
+ input clk
+);
+
+reg [7:0] counter = 0;
+
+reg a = 0;
+reg b = 1;
+reg c;
+reg [2:0] wide_a = 3'b10x;
+reg [2:0] wide_b = 'x;
+
+wire a_fell; assign a_fell = $fell(a, @(posedge clk));
+wire a_rose; assign a_rose = $rose(a, @(posedge clk));
+wire a_stable; assign a_stable = $stable(a, @(posedge clk));
+
+wire b_fell; assign b_fell = $fell(b, @(posedge clk));
+wire b_rose; assign b_rose = $rose(b, @(posedge clk));
+wire b_stable; assign b_stable = $stable(b, @(posedge clk));
+
+wire c_fell; assign c_fell = $fell(c, @(posedge clk));
+wire c_rose; assign c_rose = $rose(c, @(posedge clk));
+wire c_stable; assign c_stable = $stable(c, @(posedge clk));
+
+wire wide_a_stable; assign wide_a_stable = $stable(wide_a, @(posedge clk));
+wire wide_b_stable; assign wide_b_stable = $stable(wide_b, @(posedge clk));
+
+always @(posedge clk) begin
+ counter <= counter + 1;
+
+ case (counter)
+ 0: begin
+ assert property ( $fell(a) && !$rose(a) && !$stable(a));
+ assert property (!$fell(b) && $rose(b) && !$stable(b));
+ assert property (!$fell(c) && !$rose(c) && $stable(c));
+ assert property (!$stable(wide_a));
+ assert property ($stable(wide_b));
+ a <= 1; b <= 1; c <= 1;
+ end
+ 1: begin
+ a <= 0; b <= 1; c <= 'x;
+ wide_a <= 3'b101; wide_b <= 3'bxx0;
+ end
+ 2: begin
+ assert property ( $fell(a) && !$rose(a) && !$stable(a));
+ assert property (!$fell(b) && !$rose(b) && $stable(b));
+ assert property (!$fell(c) && !$rose(c) && !$stable(c));
+ assert property (!$stable(wide_a));
+ assert property (!$stable(wide_b));
+ a <= 0; b <= 0; c <= 0;
+ end
+ 3: begin a <= 0; b <= 1; c <= 'x; end
+ 4: begin
+ assert property (!$fell(a) && !$rose(a) && $stable(a));
+ assert property (!$fell(b) && $rose(b) && !$stable(b));
+ assert property (!$fell(c) && !$rose(c) && !$stable(c));
+ assert property ($stable(wide_a));
+ assert property ($stable(wide_b));
+ a <= 'x; b <= 'x; c <= 'x;
+ wide_a <= 'x; wide_b <= 'x;
+ end
+ 5: begin
+ a <= 0; b <= 1; c <= 'x;
+ wide_a <= 3'b10x; wide_b <= 'x;
+ counter <= 0;
+ end
+ endcase;
+end
+
+endmodule
diff --git a/tests/sva/sva_value_change_sim.ys b/tests/sva/sva_value_change_sim.ys
new file mode 100644
index 000000000..e004520ce
--- /dev/null
+++ b/tests/sva/sva_value_change_sim.ys
@@ -0,0 +1,3 @@
+read -sv sva_value_change_sim.sv
+hierarchy -top top
+sim -clock clk -fst sva_value_change_sim.fst
diff --git a/tests/techmap/.gitignore b/tests/techmap/.gitignore
index cfed22fc5..56c9ba8f9 100644
--- a/tests/techmap/.gitignore
+++ b/tests/techmap/.gitignore
@@ -1,2 +1,3 @@
*.log
+*.out
/*.mk
diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh
index 9c41fa56a..5b5838b9d 100644
--- a/tests/techmap/mem_simple_4x1_runtest.sh
+++ b/tests/techmap/mem_simple_4x1_runtest.sh
@@ -1,17 +1,3 @@
#!/bin/bash
-set -e
-
-../../yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v
-
-iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v
-iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v
-
-./mem_simple_4x1_gold_tb > mem_simple_4x1_gold_tb.out
-./mem_simple_4x1_gate_tb > mem_simple_4x1_gate_tb.out
-
-diff -u mem_simple_4x1_gold_tb.out mem_simple_4x1_gate_tb.out
-rm -f mem_simple_4x1_synth.v mem_simple_4x1_tb.vcd
-rm -f mem_simple_4x1_{gold,gate}_tb{,.out}
-: OK
-
+exec ../tools/autotest.sh -G -j $@ -p 'proc; opt; memory -nomap; techmap -map ../mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v
diff --git a/tests/techmap/recursive_runtest.sh b/tests/techmap/recursive_runtest.sh
index 0725ccf40..564d678fa 100644
--- a/tests/techmap/recursive_runtest.sh
+++ b/tests/techmap/recursive_runtest.sh
@@ -1,3 +1,3 @@
set -e
-../../yosys -p 'hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar' recursive.v
+../../yosys -p 'read_verilog recursive.v; hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar'
diff --git a/tests/various/.gitignore b/tests/various/.gitignore
index 2bb6c7179..83e634820 100644
--- a/tests/various/.gitignore
+++ b/tests/various/.gitignore
@@ -5,3 +5,6 @@
/run-test.mk
/plugin.so
/plugin.so.dSYM
+/temp
+/smtlib2_module.smt2
+/smtlib2_module-filtered.smt2
diff --git a/tests/various/async.sh b/tests/various/async.sh
index 7c41d6d94..e83935d02 100644
--- a/tests/various/async.sh
+++ b/tests/various/async.sh
@@ -1,9 +1,9 @@
#!/bin/bash
set -ex
-../../yosys -q -o async_syn.v -p 'synth; rename uut syn' async.v
-../../yosys -q -o async_prp.v -p 'prep; rename uut prp' async.v
-../../yosys -q -o async_a2s.v -p 'prep; async2sync; rename uut a2s' async.v
-../../yosys -q -o async_ffl.v -p 'prep; clk2fflogic; rename uut ffl' async.v
+../../yosys -q -o async_syn.v -r uut -p 'synth; rename uut syn' async.v
+../../yosys -q -o async_prp.v -r uut -p 'prep; rename uut prp' async.v
+../../yosys -q -o async_a2s.v -r uut -p 'prep; async2sync; rename uut a2s' async.v
+../../yosys -q -o async_ffl.v -r uut -p 'prep; clk2fflogic; rename uut ffl' async.v
iverilog -o async_sim -DTESTBENCH async.v async_???.v
vvp -N async_sim > async.out
tail async.out
diff --git a/tests/various/json_escape_chars.ys b/tests/various/json_escape_chars.ys
new file mode 100644
index 000000000..f118357c0
--- /dev/null
+++ b/tests/various/json_escape_chars.ys
@@ -0,0 +1,14 @@
+! mkdir -p temp
+read_verilog <<EOT
+(* src = "\042 \057 \134 \010 \014 \012 \015 \011 \025 \033" *)
+module foo;
+endmodule
+EOT
+write_json temp/test_escapes.json
+design -reset
+read_json temp/test_escapes.json
+write_json temp/test_escapes.json
+design -reset
+read_json temp/test_escapes.json
+write_rtlil temp/test_escapes.json.il
+! grep -F 'attribute \src "\" / \\ \010 \014 \n \015 \t \025 \033"' temp/test_escapes.json.il
diff --git a/tests/various/logger_fail.sh b/tests/various/logger_fail.sh
new file mode 100755
index 000000000..19b650007
--- /dev/null
+++ b/tests/various/logger_fail.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+fail() {
+ echo "$1" >&2
+ exit 1
+}
+
+runTest() {
+ desc="$1"
+ want="$2"
+ shift 2
+ echo "running '$desc' with args $@"
+ output=`../../yosys -q "$@" 2>&1`
+ if [ $? -ne 1 ]; then
+ fail "exit code for '$desc' was not 1"
+ fi
+ if [ "$output" != "$want" ]; then
+ fail "output for '$desc' did not match"
+ fi
+}
+
+unmet() {
+ kind=$1
+ runTest "unmet $kind" \
+ "ERROR: Expected $kind pattern 'foobar' not found !" \
+ -p "logger -expect $kind \"foobar\" 1"
+}
+
+unmet log
+unmet warning
+unmet error
+
+runTest "too many logs" \
+ "ERROR: Expected log pattern 'statistics' found 2 time(s), instead of 1 time(s) !" \
+ -p "logger -expect log \"statistics\" 1" -p stat -p stat
+
+runTest "too many warnings" \
+ "Warning: Found log message matching -W regex:
+Printing statistics.
+ERROR: Expected warning pattern 'statistics' found 2 time(s), instead of 1 time(s) !" \
+ -p "logger -warn \"Printing statistics\"" \
+ -p "logger -expect warning \"statistics\" 1" -p stat -p stat
diff --git a/tests/various/param_struct.ys b/tests/various/param_struct.ys
index 6d7a7c6ad..b8de67968 100644
--- a/tests/various/param_struct.ys
+++ b/tests/various/param_struct.ys
@@ -41,8 +41,7 @@ always_comb begin
assert(j == 1'b1);
assert(k == 1'b0);
assert(l == 3'b111);
-// TODO: support access to whole sub-structs and unions
-// assert(m == 2'b10);
+ assert(m == 2'b10);
assert(u == 5'b11001);
end
endmodule
diff --git a/tests/various/smtlib2_module-expected.smt2 b/tests/various/smtlib2_module-expected.smt2
new file mode 100644
index 000000000..ace858ca8
--- /dev/null
+++ b/tests/various/smtlib2_module-expected.smt2
@@ -0,0 +1,88 @@
+; SMT-LIBv2 description generated by Yosys $VERSION
+; yosys-smt2-module smtlib2
+(declare-sort |smtlib2_s| 0)
+(declare-fun |smtlib2_is| (|smtlib2_s|) Bool)
+(declare-fun |smtlib2#0| (|smtlib2_s|) (_ BitVec 8)) ; \a
+; yosys-smt2-input a 8
+(define-fun |smtlib2_n a| ((state |smtlib2_s|)) (_ BitVec 8) (|smtlib2#0| state))
+(declare-fun |smtlib2#1| (|smtlib2_s|) (_ BitVec 8)) ; \b
+; yosys-smt2-input b 8
+(define-fun |smtlib2_n b| ((state |smtlib2_s|)) (_ BitVec 8) (|smtlib2#1| state))
+; yosys-smt2-output add 8
+(define-fun |smtlib2_n add| ((state |smtlib2_s|)) (_ BitVec 8) (let (
+(|a| (|smtlib2_n a| state))
+(|b| (|smtlib2_n b| state))
+)
+(bvadd a b)
+))
+; yosys-smt2-output eq 1
+(define-fun |smtlib2_n eq| ((state |smtlib2_s|)) Bool (let (
+(|a| (|smtlib2_n a| state))
+(|b| (|smtlib2_n b| state))
+)
+(= a b)
+))
+; yosys-smt2-output sub 8
+(define-fun |smtlib2_n sub| ((state |smtlib2_s|)) (_ BitVec 8) (let (
+(|a| (|smtlib2_n a| state))
+(|b| (|smtlib2_n b| state))
+)
+(bvadd a (bvneg b))
+))
+(define-fun |smtlib2_a| ((state |smtlib2_s|)) Bool true)
+(define-fun |smtlib2_u| ((state |smtlib2_s|)) Bool true)
+(define-fun |smtlib2_i| ((state |smtlib2_s|)) Bool true)
+(define-fun |smtlib2_h| ((state |smtlib2_s|)) Bool true)
+(define-fun |smtlib2_t| ((state |smtlib2_s|) (next_state |smtlib2_s|)) Bool true) ; end of module smtlib2
+; yosys-smt2-module uut
+(declare-sort |uut_s| 0)
+(declare-fun |uut_is| (|uut_s|) Bool)
+; yosys-smt2-cell smtlib2 s
+(declare-fun |uut#0| (|uut_s|) (_ BitVec 8)) ; \add
+(declare-fun |uut#1| (|uut_s|) Bool) ; \eq
+(declare-fun |uut#2| (|uut_s|) (_ BitVec 8)) ; \sub
+(declare-fun |uut_h s| (|uut_s|) |smtlib2_s|)
+; yosys-smt2-anyconst uut#3 8 smtlib2_module.v:14.17-14.26
+(declare-fun |uut#3| (|uut_s|) (_ BitVec 8)) ; \a
+; yosys-smt2-anyconst uut#4 8 smtlib2_module.v:14.32-14.41
+(declare-fun |uut#4| (|uut_s|) (_ BitVec 8)) ; \b
+(define-fun |uut#5| ((state |uut_s|)) (_ BitVec 8) (bvadd (|uut#3| state) (|uut#4| state))) ; \add2
+(define-fun |uut#6| ((state |uut_s|)) Bool (= (|uut#0| state) (|uut#5| state))) ; $0$formal$smtlib2_module.v:28$1_CHECK[0:0]$9
+; yosys-smt2-assert 0 $assert$smtlib2_module.v:28$19 smtlib2_module.v:28.17-29.22
+(define-fun |uut_a 0| ((state |uut_s|)) Bool (or (|uut#6| state) (not true))) ; $assert$smtlib2_module.v:28$19
+(define-fun |uut#7| ((state |uut_s|)) (_ BitVec 8) (bvsub (|uut#3| state) (|uut#4| state))) ; \sub2
+(define-fun |uut#8| ((state |uut_s|)) Bool (= (|uut#2| state) (|uut#7| state))) ; $0$formal$smtlib2_module.v:29$2_CHECK[0:0]$11
+; yosys-smt2-assert 1 $assert$smtlib2_module.v:29$20 smtlib2_module.v:29.23-30.22
+(define-fun |uut_a 1| ((state |uut_s|)) Bool (or (|uut#8| state) (not true))) ; $assert$smtlib2_module.v:29$20
+(define-fun |uut#9| ((state |uut_s|)) Bool (= (|uut#3| state) (|uut#4| state))) ; $eq$smtlib2_module.v:31$17_Y
+(define-fun |uut#10| ((state |uut_s|)) Bool (= (ite (|uut#1| state) #b1 #b0) (ite (|uut#9| state) #b1 #b0))) ; $0$formal$smtlib2_module.v:30$3_CHECK[0:0]$13
+; yosys-smt2-assert 2 $assert$smtlib2_module.v:30$21 smtlib2_module.v:30.23-31.25
+(define-fun |uut_a 2| ((state |uut_s|)) Bool (or (|uut#10| state) (not true))) ; $assert$smtlib2_module.v:30$21
+(define-fun |uut_a| ((state |uut_s|)) Bool (and
+ (|uut_a 0| state)
+ (|uut_a 1| state)
+ (|uut_a 2| state)
+ (|smtlib2_a| (|uut_h s| state))
+))
+(define-fun |uut_u| ((state |uut_s|)) Bool
+ (|smtlib2_u| (|uut_h s| state))
+)
+(define-fun |uut_i| ((state |uut_s|)) Bool
+ (|smtlib2_i| (|uut_h s| state))
+)
+(define-fun |uut_h| ((state |uut_s|)) Bool (and
+ (= (|uut_is| state) (|smtlib2_is| (|uut_h s| state)))
+ (= (|uut#3| state) (|smtlib2_n a| (|uut_h s| state))) ; smtlib2.a
+ (= (|uut#0| state) (|smtlib2_n add| (|uut_h s| state))) ; smtlib2.add
+ (= (|uut#4| state) (|smtlib2_n b| (|uut_h s| state))) ; smtlib2.b
+ (= (|uut#1| state) (|smtlib2_n eq| (|uut_h s| state))) ; smtlib2.eq
+ (= (|uut#2| state) (|smtlib2_n sub| (|uut_h s| state))) ; smtlib2.sub
+ (|smtlib2_h| (|uut_h s| state))
+))
+(define-fun |uut_t| ((state |uut_s|) (next_state |uut_s|)) Bool (and
+ (= (|uut#4| state) (|uut#4| next_state)) ; $anyconst$5 \b
+ (= (|uut#3| state) (|uut#3| next_state)) ; $anyconst$4 \a
+ (|smtlib2_t| (|uut_h s| state) (|uut_h s| next_state))
+)) ; end of module uut
+; yosys-smt2-topmod uut
+; end of yosys output
diff --git a/tests/various/smtlib2_module.sh b/tests/various/smtlib2_module.sh
new file mode 100755
index 000000000..491f65148
--- /dev/null
+++ b/tests/various/smtlib2_module.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -ex
+../../yosys -q -p 'read_verilog -formal smtlib2_module.v; prep; write_smt2 smtlib2_module.smt2'
+sed 's/; SMT-LIBv2 description generated by Yosys .*/; SMT-LIBv2 description generated by Yosys $VERSION/;s/ *$//' smtlib2_module.smt2 > smtlib2_module-filtered.smt2
+diff -au smtlib2_module-expected.smt2 smtlib2_module-filtered.smt2
diff --git a/tests/various/smtlib2_module.v b/tests/various/smtlib2_module.v
new file mode 100644
index 000000000..4aad86905
--- /dev/null
+++ b/tests/various/smtlib2_module.v
@@ -0,0 +1,33 @@
+(* smtlib2_module *)
+module smtlib2(a, b, add, sub, eq);
+ input [7:0] a, b;
+ (* smtlib2_comb_expr = "(bvadd a b)" *)
+ output [7:0] add;
+ (* smtlib2_comb_expr = "(bvadd a (bvneg b))" *)
+ output [7:0] sub;
+ (* smtlib2_comb_expr = "(= a b)" *)
+ output eq;
+endmodule
+
+(* top *)
+module uut;
+ wire [7:0] a = $anyconst, b = $anyconst, add, sub, add2, sub2;
+ wire eq;
+
+ assign add2 = a + b;
+ assign sub2 = a - b;
+
+ smtlib2 s (
+ .a(a),
+ .b(b),
+ .add(add),
+ .sub(sub),
+ .eq(eq)
+ );
+
+ always @* begin
+ assert(add == add2);
+ assert(sub == sub2);
+ assert(eq == (a == b));
+ end
+endmodule
diff --git a/tests/various/struct_access.sv b/tests/various/struct_access.sv
new file mode 100644
index 000000000..d41a7114f
--- /dev/null
+++ b/tests/various/struct_access.sv
@@ -0,0 +1,43 @@
+module dut();
+typedef struct packed {
+ logic a;
+ logic b;
+} sub_sub_struct_t;
+
+typedef struct packed {
+ sub_sub_struct_t c;
+} sub_struct_t;
+
+typedef struct packed {
+ sub_struct_t d;
+ sub_struct_t e;
+} struct_t;
+
+parameter struct_t P = 4'b1100;
+
+localparam sub_struct_t f = P.d;
+localparam sub_struct_t g = P.e;
+localparam sub_sub_struct_t h = f.c;
+localparam logic i = P.d.c.a;
+localparam logic j = P.d.c.b;
+localparam x = P.e;
+localparam y = x.c;
+localparam z = y.a;
+localparam q = P.d;
+localparam n = q.c.a;
+
+always_comb begin
+ assert(P == 4'b1100);
+ assert(f == 2'b11);
+ assert(g == 2'b00);
+ assert(h == 2'b11);
+ assert(i == 1'b1);
+ assert(j == 1'b1);
+ assert(x == 2'b00);
+ assert(y == 2'b00);
+ assert(x.c == 2'b00);
+ assert(y.b == 1'b0);
+ assert(n == 1'b1);
+ assert(z == 1'b0);
+end
+endmodule
diff --git a/tests/various/struct_access.ys b/tests/various/struct_access.ys
new file mode 100644
index 000000000..2282edd92
--- /dev/null
+++ b/tests/various/struct_access.ys
@@ -0,0 +1,5 @@
+read_verilog -sv struct_access.sv
+hierarchy
+proc
+opt
+sat -verify -seq 1 -prove-asserts -show-all
diff --git a/tests/verilog/.gitignore b/tests/verilog/.gitignore
index 34da23437..96ebe20ba 100644
--- a/tests/verilog/.gitignore
+++ b/tests/verilog/.gitignore
@@ -3,3 +3,4 @@
/run-test.mk
/const_arst.v
/const_sr.v
+/doubleslash.v
diff --git a/tests/verilog/always_comb_latch_1.ys b/tests/verilog/always_comb_latch_1.ys
new file mode 100644
index 000000000..c98c79fa2
--- /dev/null
+++ b/tests/verilog/always_comb_latch_1.ys
@@ -0,0 +1,13 @@
+read_verilog -sv <<EOF
+module top;
+logic x;
+always_comb begin
+ logic y;
+ if (x)
+ y = 1;
+ x = y;
+end
+endmodule
+EOF
+logger -expect error "^Latch inferred for signal `\\top\.\$unnamed_block\$1\.y' from always_comb process" 1
+proc
diff --git a/tests/verilog/always_comb_latch_2.ys b/tests/verilog/always_comb_latch_2.ys
new file mode 100644
index 000000000..567205a53
--- /dev/null
+++ b/tests/verilog/always_comb_latch_2.ys
@@ -0,0 +1,15 @@
+read_verilog -sv <<EOF
+module top;
+logic x;
+always_comb begin
+ logic y;
+ if (x)
+ x = 1;
+ else
+ y = 1;
+ x = y;
+end
+endmodule
+EOF
+logger -expect error "^Latch inferred for signal `\\top\.\$unnamed_block\$1\.y' from always_comb process" 1
+proc
diff --git a/tests/verilog/always_comb_latch_3.ys b/tests/verilog/always_comb_latch_3.ys
new file mode 100644
index 000000000..b9b028ac7
--- /dev/null
+++ b/tests/verilog/always_comb_latch_3.ys
@@ -0,0 +1,20 @@
+read_verilog -sv <<EOF
+module top;
+logic x;
+logic z;
+assign z = 1'b1;
+always_comb begin
+ logic y;
+ case (x)
+ 1'b0:
+ y = 1;
+ endcase
+ if (z)
+ x = y;
+ else
+ x = 1'b0;
+end
+endmodule
+EOF
+logger -expect error "^Latch inferred for signal `\\top\.\$unnamed_block\$1\.y' from always_comb process" 1
+proc
diff --git a/tests/verilog/always_comb_latch_4.ys b/tests/verilog/always_comb_latch_4.ys
new file mode 100644
index 000000000..46b78801b
--- /dev/null
+++ b/tests/verilog/always_comb_latch_4.ys
@@ -0,0 +1,17 @@
+read_verilog -sv <<EOF
+module top;
+parameter AVOID_LATCH = 0;
+logic x, z;
+assign z = 1'b1;
+always_comb begin
+ logic y;
+ if (z)
+ y = 0;
+ for (int i = 1; i == AVOID_LATCH; i++)
+ y = 1;
+ x = z ? y : 1'b0;
+end
+endmodule
+EOF
+logger -expect error "^Latch inferred for signal `\\top\.\$unnamed_block\$3\.y' from always_comb process" 1
+proc
diff --git a/tests/verilog/always_comb_nolatch_1.ys b/tests/verilog/always_comb_nolatch_1.ys
new file mode 100644
index 000000000..4d1952b52
--- /dev/null
+++ b/tests/verilog/always_comb_nolatch_1.ys
@@ -0,0 +1,16 @@
+read_verilog -sv <<EOF
+module top;
+logic [4:0] x;
+logic z;
+assign z = 1'b1;
+always_comb begin
+ x = '0;
+ if (z) begin
+ for (int i = 0; i < 5; i++) begin
+ x[i] = 1'b1;
+ end
+ end
+end
+endmodule
+EOF
+proc
diff --git a/tests/verilog/always_comb_nolatch_2.ys b/tests/verilog/always_comb_nolatch_2.ys
new file mode 100644
index 000000000..2ec6ca0f4
--- /dev/null
+++ b/tests/verilog/always_comb_nolatch_2.ys
@@ -0,0 +1,17 @@
+read_verilog -sv <<EOF
+module top;
+logic [4:0] x;
+logic z;
+assign z = 1'b1;
+always_comb begin
+ x = '0;
+ if (z) begin
+ int i;
+ for (i = 0; i < 5; i++) begin
+ x[i] = 1'b1;
+ end
+ end
+end
+endmodule
+EOF
+proc
diff --git a/tests/verilog/always_comb_nolatch_3.ys b/tests/verilog/always_comb_nolatch_3.ys
new file mode 100644
index 000000000..33f9833a2
--- /dev/null
+++ b/tests/verilog/always_comb_nolatch_3.ys
@@ -0,0 +1,21 @@
+read_verilog -sv <<EOF
+module top;
+logic x;
+logic z;
+assign z = 1'b1;
+always_comb begin
+ logic y;
+ case (x)
+ 1'b0:
+ y = 1;
+ default:
+ y = 0;
+ endcase
+ if (z)
+ x = y;
+ else
+ x = 1'b0;
+end
+endmodule
+EOF
+proc
diff --git a/tests/verilog/always_comb_nolatch_4.ys b/tests/verilog/always_comb_nolatch_4.ys
new file mode 100644
index 000000000..bc29b2771
--- /dev/null
+++ b/tests/verilog/always_comb_nolatch_4.ys
@@ -0,0 +1,16 @@
+read_verilog -sv <<EOF
+module top;
+parameter AVOID_LATCH = 1;
+logic x, z;
+assign z = 1'b1;
+always_comb begin
+ logic y;
+ if (z)
+ y = 0;
+ for (int i = 1; i == AVOID_LATCH; i++)
+ y = 1;
+ x = z ? y : 1'b0;
+end
+endmodule
+EOF
+proc
diff --git a/tests/verilog/always_comb_nolatch_5.ys b/tests/verilog/always_comb_nolatch_5.ys
new file mode 100644
index 000000000..132878626
--- /dev/null
+++ b/tests/verilog/always_comb_nolatch_5.ys
@@ -0,0 +1,15 @@
+read_verilog -sv <<EOF
+module top;
+logic [4:0] x;
+logic z;
+assign z = 1'b1;
+always_comb begin : foo
+ x = '0;
+ if (z) begin : bar
+ for (int i = 0; i < 5; i++)
+ x[i] = 1'b1;
+ end
+end
+endmodule
+EOF
+proc
diff --git a/tests/verilog/always_comb_nolatch_6.ys b/tests/verilog/always_comb_nolatch_6.ys
new file mode 100644
index 000000000..90ee78a68
--- /dev/null
+++ b/tests/verilog/always_comb_nolatch_6.ys
@@ -0,0 +1,15 @@
+read_verilog -sv <<EOF
+module top(input wire x, y, output reg z);
+function automatic f;
+ input inp;
+ for (int i = 0; i < 1; i++)
+ f = inp + 0;
+endfunction
+always_comb
+ if (y)
+ z = f(x);
+ else
+ z = 0;
+endmodule
+EOF
+proc
diff --git a/tests/verilog/delay_time_scale.ys b/tests/verilog/delay_time_scale.ys
new file mode 100644
index 000000000..f45ba7b26
--- /dev/null
+++ b/tests/verilog/delay_time_scale.ys
@@ -0,0 +1,25 @@
+logger -expect-no-warnings
+read_verilog -sv <<EOT
+module top;
+wand x;
+`define TEST(time_scale) if (1) assign #time_scale x = 1;
+
+`TEST(1s)
+`TEST(1ms)
+`TEST(1us)
+`TEST(1ns)
+`TEST(1ps)
+`TEST(1fs)
+
+`TEST((1s))
+`TEST(( 1s))
+`TEST((1s ))
+`TEST(( 1s ))
+
+`TEST(1.0s)
+`TEST(1.1s)
+`TEST(1.0e-1s)
+`TEST(1e-1s)
+
+endmodule
+EOT
diff --git a/tests/verilog/doubleslash.ys b/tests/verilog/doubleslash.ys
new file mode 100644
index 000000000..c41673ee5
--- /dev/null
+++ b/tests/verilog/doubleslash.ys
@@ -0,0 +1,21 @@
+read_verilog -sv <<EOT
+module doubleslash
+ (input logic a,
+ input logic b,
+ output logic z);
+
+ logic \a//b ;
+
+ assign \a//b = a & b;
+ assign z = ~\a//b ;
+
+endmodule : doubleslash
+EOT
+
+hierarchy
+proc
+opt -full
+
+write_verilog doubleslash.v
+design -reset
+read_verilog doubleslash.v
diff --git a/tests/verilog/dynamic_range_lhs.sh b/tests/verilog/dynamic_range_lhs.sh
new file mode 100755
index 000000000..618204aed
--- /dev/null
+++ b/tests/verilog/dynamic_range_lhs.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+run() {
+ alt=$1
+ span=$2
+ left=$3
+ right=$4
+ echo "a=$alt s=$span l=$left r=$right"
+
+ ../../yosys -q \
+ -DALT=$alt \
+ -DSPAN=$span \
+ -DLEFT=$left \
+ -DRIGHT=$right \
+ -p "read_verilog dynamic_range_lhs.v" \
+ -p "proc" \
+ -p "equiv_make gold gate equiv" \
+ -p "equiv_simple" \
+ -p "equiv_status -assert"
+}
+
+trap 'echo "ERROR in dynamic_range_lhs.sh span=$span left=$left right=$right" >&2; exit 1' ERR
+
+for alt in `seq 0 1`; do
+for span in `seq 1 4`; do
+for left in `seq -4 4`; do
+for right in `seq $(expr $left + -3) $(expr $left + 3)`; do
+ run $alt $span $left $right
+done
+done
+done
+done
diff --git a/tests/verilog/dynamic_range_lhs.v b/tests/verilog/dynamic_range_lhs.v
new file mode 100644
index 000000000..ae291374d
--- /dev/null
+++ b/tests/verilog/dynamic_range_lhs.v
@@ -0,0 +1,76 @@
+module gate(
+ output reg [`LEFT:`RIGHT] out_u, out_s,
+ (* nowrshmsk = `ALT *)
+ input wire data,
+ input wire [1:0] sel1, sel2
+);
+always @* begin
+ out_u = 0;
+ out_s = 0;
+ case (`SPAN)
+ 1: begin
+ out_u[sel1*sel2] = data;
+ out_s[$signed(sel1*sel2)] = data;
+ end
+ 2: begin
+ out_u[sel1*sel2+:2] = {data, data};
+ out_s[$signed(sel1*sel2)+:2] = {data, data};
+ end
+ 3: begin
+ out_u[sel1*sel2+:3] = {data, data, data};
+ out_s[$signed(sel1*sel2)+:3] = {data, data, data};
+ end
+ 4: begin
+ out_u[sel1*sel2+:4] = {data, data, data, data};
+ out_s[$signed(sel1*sel2)+:4] = {data, data, data, data};
+ end
+ endcase
+end
+endmodule
+
+module gold(
+ output reg [`LEFT:`RIGHT] out_u, out_s,
+ input wire data,
+ input wire [1:0] sel1, sel2
+);
+task set;
+ input integer a, b;
+ localparam LOW = `LEFT > `RIGHT ? `RIGHT : `LEFT;
+ localparam HIGH = `LEFT > `RIGHT ? `LEFT : `RIGHT;
+ if (LOW <= a && a <= HIGH)
+ out_u[a] = data;
+ if (LOW <= b && b <= HIGH)
+ out_s[b] = data;
+endtask
+always @* begin
+ out_u = 0;
+ out_s = 0;
+ case (sel1*sel2)
+ 2'b00: set(0, 0);
+ 2'b01: set(1, 1);
+ 2'b10: set(2, -2);
+ 2'b11: set(3, -1);
+ endcase
+ if (`SPAN >= 2)
+ case (sel1*sel2)
+ 2'b00: set(1, 1);
+ 2'b01: set(2, 2);
+ 2'b10: set(3, -1);
+ 2'b11: set(4, 0);
+ endcase
+ if (`SPAN >= 3)
+ case (sel1*sel2)
+ 2'b00: set(2, 2);
+ 2'b01: set(3, 3);
+ 2'b10: set(4, 0);
+ 2'b11: set(5, 1);
+ endcase
+ if (`SPAN >= 4)
+ case (sel1*sel2)
+ 2'b00: set(3, 3);
+ 2'b01: set(4, 4);
+ 2'b10: set(5, 1);
+ 2'b11: set(6, 2);
+ endcase
+end
+endmodule
diff --git a/tests/verilog/func_tern_hint.sv b/tests/verilog/func_tern_hint.sv
new file mode 100644
index 000000000..3c58c9913
--- /dev/null
+++ b/tests/verilog/func_tern_hint.sv
@@ -0,0 +1,42 @@
+module top;
+ function automatic [30:0] func;
+ input integer inp;
+ func = { // self-determined context
+ (
+ inp == 0
+ ? -1 // causes whole ternary to be 32 bits
+ : func(inp - 1) // 31 bits, unsigned
+ ) >> 2};
+ endfunction
+ function automatic signed [3:0] dunk;
+ input integer inp;
+ dunk = (
+ inp == 0
+ ? 4'hF
+ // shouldn't make the ternary signed
+ : dunk(inp - 1)
+ ) == -1;
+ endfunction
+ localparam A = func(0);
+ localparam B = func(1);
+ localparam C = func(2);
+ localparam D = func(3);
+ localparam X = dunk(0);
+ localparam Y = dunk(1);
+ initial begin
+ assert(A == 31'h3F_FFFFFF);
+ assert(B == 31'h0F_FFFFFF);
+ assert(C == 31'h03_FFFFFF);
+ assert(D == 31'h00_FFFFFF);
+ assert(X == 0);
+ assert(Y == 0);
+ end
+ initial begin
+ logic x;
+ case (1'b1)
+ dunk(0): x = 0;
+ default: x = 1;
+ endcase
+ assert(x);
+ end
+endmodule
diff --git a/tests/verilog/func_tern_hint.ys b/tests/verilog/func_tern_hint.ys
new file mode 100644
index 000000000..ab8a1e032
--- /dev/null
+++ b/tests/verilog/func_tern_hint.ys
@@ -0,0 +1,4 @@
+read_verilog -sv func_tern_hint.sv
+proc
+opt
+sat -verify -seq 1 -prove-asserts -show-all
diff --git a/tests/verilog/func_upto.sv b/tests/verilog/func_upto.sv
new file mode 100644
index 000000000..547e5d325
--- /dev/null
+++ b/tests/verilog/func_upto.sv
@@ -0,0 +1,77 @@
+`default_nettype none
+
+module evil;
+ parameter HI = 3;
+ parameter LO = 0;
+ parameter SPAN = 1;
+ parameter [HI:LO] A_VAL = 4'b0110;
+ parameter [HI:LO] B_VAL = 4'b1100;
+ parameter [2:0] SWAPS = 0;
+
+ localparam D_LEFT = !(SWAPS[0]) ? HI : LO;
+ localparam D_RIGHT = (SWAPS[0]) ? HI : LO;
+ localparam E_LEFT = !(SWAPS[1]) ? HI : LO;
+ localparam E_RIGHT = (SWAPS[1]) ? HI : LO;
+ localparam F_LEFT = !(SWAPS[2]) ? HI : LO;
+ localparam F_RIGHT = (SWAPS[2]) ? HI : LO;
+
+ localparam [HI:LO] A_CONST = A_VAL;
+ localparam [HI:LO] B_CONST = B_VAL;
+ localparam [HI:LO] C_CONST = F(A_CONST, B_CONST);
+
+ reg [HI:LO] C_WIRE, C_FUNC;
+ always @* begin
+ assert (C_CONST == C_WIRE);
+ assert (C_CONST == C_FUNC);
+ end
+
+ initial begin : blk
+ reg [HI:LO] A_WIRE;
+ reg [HI:LO] B_WIRE;
+ reg [D_LEFT:D_RIGHT] D;
+ reg [E_LEFT:E_RIGHT] E;
+ reg [F_LEFT:F_RIGHT] F_WIRE;
+ reg [31:0] i;
+ A_WIRE = A_VAL;
+ B_WIRE = B_VAL;
+ D = A_WIRE;
+ E = B_WIRE;
+ F_WIRE = 0;
+ for (i = LO; i + SPAN < HI; i = i + SPAN)
+ if (SPAN == 1)
+ F_WIRE[i] = D[i] && E[i];
+ else
+ F_WIRE[i+:SPAN] = D[i+:SPAN] && E[i+:SPAN];
+ C_WIRE = F_WIRE;
+ C_FUNC = F(A_WIRE, B_WIRE);
+ end
+
+ function automatic [F_LEFT:F_RIGHT] F(
+ input [D_LEFT:D_RIGHT] D,
+ input [E_LEFT:E_RIGHT] E);
+ reg [31:0] i;
+ F = 0;
+ for (i = LO; i + SPAN < HI; i = i + SPAN)
+ if (SPAN == 1)
+ F[i] = D[i] && E[i];
+ else
+ F[i+:SPAN] = D[i+:SPAN] && E[i+:SPAN];
+ endfunction
+endmodule
+
+module top;
+ for (genvar hi = 0; hi < 3; hi++)
+ for (genvar lo = 0; lo <= hi; lo++)
+ for (genvar span = 1; span <= hi - lo + 1; span++)
+ for (genvar a_val = 0; a_val < 2 ** (hi - lo + 1); a_val++)
+ for (genvar b_val = 0; b_val < 2 ** (hi - lo + 1); b_val++)
+ for (genvar swaps = 0; swaps < 2 ** 3; swaps++)
+ evil #(
+ .HI(hi),
+ .LO(lo),
+ .SPAN(span),
+ .A_VAL(a_val),
+ .B_VAL(b_val),
+ .SWAPS(swaps)
+ ) e();
+endmodule
diff --git a/tests/verilog/func_upto.ys b/tests/verilog/func_upto.ys
new file mode 100644
index 000000000..7a8c53506
--- /dev/null
+++ b/tests/verilog/func_upto.ys
@@ -0,0 +1,7 @@
+read_verilog -sv func_upto.sv
+hierarchy -top top
+proc
+flatten
+opt -full
+select -module top
+sat -verify -seq 1 -prove-asserts -enable_undef
diff --git a/tests/verilog/past_signedness.ys b/tests/verilog/past_signedness.ys
new file mode 100644
index 000000000..91f32328b
--- /dev/null
+++ b/tests/verilog/past_signedness.ys
@@ -0,0 +1,35 @@
+logger -expect-no-warnings
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg signed [3:0] value = -1;
+ reg ready = 0;
+
+ always @(posedge clk) begin
+ if (ready)
+ assert ($past(value) == -1);
+ ready <= 1;
+ end
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
+
+design -reset
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg signed [3:0] value = -1;
+ reg ready = 0;
+
+ always @(posedge clk) begin
+ if (ready)
+ assert ($past(value + 4'b0000) == 15);
+ ready <= 1;
+ end
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
diff --git a/tests/verilog/sign_array_query.ys b/tests/verilog/sign_array_query.ys
new file mode 100644
index 000000000..f955450b7
--- /dev/null
+++ b/tests/verilog/sign_array_query.ys
@@ -0,0 +1,52 @@
+logger -expect-no-warnings
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg [-1:-1] x;
+ reg good = 0;
+ reg signed [31:0] zero = 0;
+
+ always @(posedge clk) begin
+ case ($left(x) + zero) 36'shfffffffff: good = 1; endcase
+ assert (good);
+ end
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
+
+design -reset
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg [-1:-1] x;
+ reg good = 0;
+
+ always @(posedge clk) begin
+ case ($left(x)) 36'sh0ffffffff: good = 1; (32'h0 + $left(good)): ; endcase
+ assert (good);
+ end
+
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
+
+design -reset
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg [-1:-1] x;
+ reg good = 1;
+
+ always @(posedge clk) begin
+ case (36'sh100000000 + $left(x)) -1: good = 0; endcase
+ assert (good);
+ end
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
diff --git a/tests/verilog/size_cast.sv b/tests/verilog/size_cast.sv
new file mode 100644
index 000000000..1636f8d70
--- /dev/null
+++ b/tests/verilog/size_cast.sv
@@ -0,0 +1,140 @@
+module top;
+ logic L1b0 = 0;
+ logic L1b1 = 1;
+
+ logic signed L1sb0 = 0;
+ logic signed L1sb1 = 1;
+
+ logic [1:0] L2b00 = 0;
+ logic [1:0] L2b01 = 1;
+ logic [1:0] L2b10 = 2;
+ logic [1:0] L2b11 = 3;
+
+ logic signed [1:0] L2sb00 = 0;
+ logic signed [1:0] L2sb01 = 1;
+ logic signed [1:0] L2sb10 = 2;
+ logic signed [1:0] L2sb11 = 3;
+
+ logic y = 1;
+
+ always @* begin
+
+ assert (1'(L1b0 ) == 1'b0);
+ assert (1'(L1b1 ) == 1'b1);
+ assert (1'(L1sb0 ) == 1'b0);
+ assert (1'(L1sb1 ) == 1'b1);
+ assert (1'(L2b00 ) == 1'b0);
+ assert (1'(L2b01 ) == 1'b1);
+ assert (1'(L2b10 ) == 1'b0);
+ assert (1'(L2b11 ) == 1'b1);
+ assert (1'(L2sb00) == 1'b0);
+ assert (1'(L2sb01) == 1'b1);
+ assert (1'(L2sb10) == 1'b0);
+ assert (1'(L2sb11) == 1'b1);
+
+ assert (2'(L1b0 ) == 2'b00);
+ assert (2'(L1b1 ) == 2'b01);
+ assert (2'(L1sb0 ) == 2'b00);
+ assert (2'(L1sb1 ) == 2'b11);
+ assert (2'(L2b00 ) == 2'b00);
+ assert (2'(L2b01 ) == 2'b01);
+ assert (2'(L2b10 ) == 2'b10);
+ assert (2'(L2b11 ) == 2'b11);
+ assert (2'(L2sb00) == 2'b00);
+ assert (2'(L2sb01) == 2'b01);
+ assert (2'(L2sb10) == 2'b10);
+ assert (2'(L2sb11) == 2'b11);
+
+ assert (3'(L1b0 ) == 3'b000);
+ assert (3'(L1b1 ) == 3'b001);
+ assert (3'(L1sb0 ) == 3'b000);
+ assert (3'(L1sb1 ) == 3'b111);
+ assert (3'(L2b00 ) == 3'b000);
+ assert (3'(L2b01 ) == 3'b001);
+ assert (3'(L2b10 ) == 3'b010);
+ assert (3'(L2b11 ) == 3'b011);
+ assert (3'(L2sb00) == 3'b000);
+ assert (3'(L2sb01) == 3'b001);
+ assert (3'(L2sb10) == 3'b110);
+ assert (3'(L2sb11) == 3'b111);
+
+ assert (3'(L1b0 | '1) == 3'b111);
+ assert (3'(L1b1 | '1) == 3'b111);
+ assert (3'(L1sb0 | '1) == 3'b111);
+ assert (3'(L1sb1 | '1) == 3'b111);
+ assert (3'(L2b00 | '1) == 3'b111);
+ assert (3'(L2b01 | '1) == 3'b111);
+ assert (3'(L2b10 | '1) == 3'b111);
+ assert (3'(L2b11 | '1) == 3'b111);
+ assert (3'(L2sb00 | '1) == 3'b111);
+ assert (3'(L2sb01 | '1) == 3'b111);
+ assert (3'(L2sb10 | '1) == 3'b111);
+ assert (3'(L2sb11 | '1) == 3'b111);
+
+ assert (3'(L1b0 | '0) == 3'b000);
+ assert (3'(L1b1 | '0) == 3'b001);
+ assert (3'(L1sb0 | '0) == 3'b000);
+ assert (3'(L1sb1 | '0) == 3'b001);
+ assert (3'(L2b00 | '0) == 3'b000);
+ assert (3'(L2b01 | '0) == 3'b001);
+ assert (3'(L2b10 | '0) == 3'b010);
+ assert (3'(L2b11 | '0) == 3'b011);
+ assert (3'(L2sb00 | '0) == 3'b000);
+ assert (3'(L2sb01 | '0) == 3'b001);
+ assert (3'(L2sb10 | '0) == 3'b010);
+ assert (3'(L2sb11 | '0) == 3'b011);
+
+ assert (3'(y ? L1b0 : '1) == 3'b000);
+ assert (3'(y ? L1b1 : '1) == 3'b001);
+ assert (3'(y ? L1sb0 : '1) == 3'b000);
+ assert (3'(y ? L1sb1 : '1) == 3'b001);
+ assert (3'(y ? L2b00 : '1) == 3'b000);
+ assert (3'(y ? L2b01 : '1) == 3'b001);
+ assert (3'(y ? L2b10 : '1) == 3'b010);
+ assert (3'(y ? L2b11 : '1) == 3'b011);
+ assert (3'(y ? L2sb00 : '1) == 3'b000);
+ assert (3'(y ? L2sb01 : '1) == 3'b001);
+ assert (3'(y ? L2sb10 : '1) == 3'b010);
+ assert (3'(y ? L2sb11 : '1) == 3'b011);
+
+ assert (3'(y ? L1b0 : '0) == 3'b000);
+ assert (3'(y ? L1b1 : '0) == 3'b001);
+ assert (3'(y ? L1sb0 : '0) == 3'b000);
+ assert (3'(y ? L1sb1 : '0) == 3'b001);
+ assert (3'(y ? L2b00 : '0) == 3'b000);
+ assert (3'(y ? L2b01 : '0) == 3'b001);
+ assert (3'(y ? L2b10 : '0) == 3'b010);
+ assert (3'(y ? L2b11 : '0) == 3'b011);
+ assert (3'(y ? L2sb00 : '0) == 3'b000);
+ assert (3'(y ? L2sb01 : '0) == 3'b001);
+ assert (3'(y ? L2sb10 : '0) == 3'b010);
+ assert (3'(y ? L2sb11 : '0) == 3'b011);
+
+ assert (3'(y ? L1b0 : 1'sb0) == 3'b000);
+ assert (3'(y ? L1b1 : 1'sb0) == 3'b001);
+ assert (3'(y ? L1sb0 : 1'sb0) == 3'b000);
+ assert (3'(y ? L1sb1 : 1'sb0) == 3'b111);
+ assert (3'(y ? L2b00 : 1'sb0) == 3'b000);
+ assert (3'(y ? L2b01 : 1'sb0) == 3'b001);
+ assert (3'(y ? L2b10 : 1'sb0) == 3'b010);
+ assert (3'(y ? L2b11 : 1'sb0) == 3'b011);
+ assert (3'(y ? L2sb00 : 1'sb0) == 3'b000);
+ assert (3'(y ? L2sb01 : 1'sb0) == 3'b001);
+ assert (3'(y ? L2sb10 : 1'sb0) == 3'b110);
+ assert (3'(y ? L2sb11 : 1'sb0) == 3'b111);
+
+ assert (3'(y ? L1b0 : 1'sb1) == 3'b000);
+ assert (3'(y ? L1b1 : 1'sb1) == 3'b001);
+ assert (3'(y ? L1sb0 : 1'sb1) == 3'b000);
+ assert (3'(y ? L1sb1 : 1'sb1) == 3'b111);
+ assert (3'(y ? L2b00 : 1'sb1) == 3'b000);
+ assert (3'(y ? L2b01 : 1'sb1) == 3'b001);
+ assert (3'(y ? L2b10 : 1'sb1) == 3'b010);
+ assert (3'(y ? L2b11 : 1'sb1) == 3'b011);
+ assert (3'(y ? L2sb00 : 1'sb1) == 3'b000);
+ assert (3'(y ? L2sb01 : 1'sb1) == 3'b001);
+ assert (3'(y ? L2sb10 : 1'sb1) == 3'b110);
+ assert (3'(y ? L2sb11 : 1'sb1) == 3'b111);
+
+ end
+endmodule
diff --git a/tests/verilog/size_cast.ys b/tests/verilog/size_cast.ys
new file mode 100644
index 000000000..6890cd2d5
--- /dev/null
+++ b/tests/verilog/size_cast.ys
@@ -0,0 +1,5 @@
+read_verilog -sv size_cast.sv
+proc
+opt -full
+select -module top
+sat -verify -prove-asserts -show-all
diff --git a/tests/verilog/struct_access.sv b/tests/verilog/struct_access.sv
index f13b8dd51..bc91e3f01 100644
--- a/tests/verilog/struct_access.sv
+++ b/tests/verilog/struct_access.sv
@@ -77,9 +77,8 @@ module top;
`CHECK(s.y.a, 1, 0)
`CHECK(s.y.b, 1, 1)
- // TODO(zachjs): support access to whole sub-structs and unions
- // `CHECK(s.x, 2, 0)
- // `CHECK(s.y, 2, 1)
+ `CHECK(s.x, 2, 0)
+ `CHECK(s.y, 2, 1)
assert (fail === 0);
end
diff --git a/tests/verilog/unreachable_case_sign.ys b/tests/verilog/unreachable_case_sign.ys
new file mode 100644
index 000000000..25bc0c6f0
--- /dev/null
+++ b/tests/verilog/unreachable_case_sign.ys
@@ -0,0 +1,33 @@
+logger -expect-no-warnings
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg good = 0;
+
+ always @(posedge clk) begin
+ case (4'sb1111) 15: good = 1; 4'b0000: ; endcase
+ assert (good);
+ end
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
+
+design -reset
+
+read_verilog -formal <<EOT
+module top(input clk);
+ reg good = 1;
+ reg signed [1:0] case_value = -1;
+
+ always @(posedge clk) begin
+ case (4'sb1111) 4'b0000: ; case_value: good = 0; endcase
+ assert (good);
+ end
+endmodule
+EOT
+
+prep -top top
+sim -n 3 -clock clk
+