diff options
Diffstat (limited to 'tests')
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 + |