1#!/usr/bin/env python3 2 3import sys, os, re, shutil 4import numpy as np 5 6max_span_hack = True 7 8pins = np.random.permutation(""" 9 1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34 10 37 38 41 42 43 44 45 47 48 52 56 58 60 61 62 63 64 11 73 74 75 76 78 79 80 81 87 88 90 91 95 96 97 98 101 102 104 105 106 107 12 112 113 114 115 116 117 118 119 120 121 122 134 135 136 137 138 139 141 142 143 144 13""".split()) 14 15io_names = None 16mode = sys.argv[1] 17 18with open("%s.v" % sys.argv[1], "w") as f: 19 if mode == "test0": 20 io_names = [ "clk", "i0", "o0", "o1", "o2" ] 21 print("module top(input clk, i0, output o0, o1, o2);", file=f) 22 print(" reg [31:0] state;", file=f) 23 print(" always @(posedge clk) state <= ((state << 5) + state) ^ i0;", file=f) 24 print(" assign o0 = ^state, o1 = |state, o2 = state[31:16] + state[15:0];", file=f) 25 print("endmodule", file=f) 26 if mode == "test1": 27 io_names = [ "clk", "i0", "i1", "i2", "i3", "o0", "o1", "o2", "o3" ] 28 print("module top(input clk, i0, i1, i2, i3, output o0, o1, o2, o3);", file=f) 29 print(" reg [15:0] din, dout;", file=f) 30 print(" always @(posedge clk) din <= {din, i3, i2, i1, i0};", file=f) 31 print(" always @(posedge clk) dout <= din + {din[7:0], din[15:8]};", file=f) 32 print(" assign {o3, o2, o1, o0} = dout >> din;", file=f) 33 print("endmodule", file=f) 34 if mode == "test2": 35 io_names = [ "clk", "i0", "i1", "i2", "i3", "o0", "o1", "o2", "o3" ] 36 print(""" 37 module top(input clk, i0, i1, i2, i3, output reg o0, o1, o2, o3); 38 reg [7:0] raddr, waddr, rdata, wdata; 39 reg [7:0] memory [0:255]; 40 always @(posedge clk) begin 41 case ({i0, i1, i2}) 42 0: raddr <= {raddr, i3}; 43 1: waddr <= {waddr, i3}; 44 2: wdata <= {wdata, i3}; 45 3: rdata <= memory[raddr]; 46 4: memory[waddr] <= wdata; 47 5: {o0, o1, o2, o3} <= rdata[3:0]; 48 6: {o0, o1, o2, o3} <= rdata[7:4]; 49 endcase 50 end 51 endmodule 52 """, file=f) 53 if mode == "test3": 54 io_names = [ "clk", "i0", "i1", "i2", "i3", "o0", "o1", "o2", "o3", "o4" ] 55 print(""" 56 module top(input clk, i0, i1, i2, i3, output reg o0, o1, o2, o3, o4); 57 reg [9:0] raddr, waddr, rdata, wdata; 58 reg [9:0] memory [0:1023]; 59 always @(posedge clk) begin 60 case ({i0, i1, i2}) 61 0: raddr <= {raddr, i3}; 62 1: waddr <= {waddr, i3}; 63 2: wdata <= {wdata, i3}; 64 3: rdata <= memory[raddr]; 65 4: memory[waddr] <= wdata; 66 5: rdata <= memory[waddr]; 67 6: {o0, o1, o2, o3, o4} <= rdata[4:0]; 68 7: {o0, o1, o2, o3, o4} <= rdata[9:5]; 69 endcase 70 end 71 endmodule 72 """, file=f) 73 if mode == "test4": 74 io_names = [ "clk", "i", "s", "o" ] 75 print(""" 76 module top(input clk, i, s, output reg o); 77 reg re1, rclke1, we1, wclke1; 78 reg [7:0] raddr1, waddr1; 79 reg [15:0] rdata1, wdata1, mask1; 80 wire [15:0] rdata1_unreg; 81 82 reg re2, rclke2, we2, wclke2; 83 reg [7:0] raddr2, waddr2; 84 reg [15:0] rdata2, wdata2, mask2; 85 wire [15:0] rdata2_unreg; 86 87 always @(posedge clk) begin 88 o <= rdata1[15]; 89 {rdata1, rdata2} <= {rdata1, rdata2} << 1; 90 {raddr1, waddr1, wdata1, mask1, re1, rclke1, we1, wclke1, 91 raddr2, waddr2, wdata2, mask2, re2, rclke2, we2, wclke2} <= 92 ({raddr1, waddr1, wdata1, mask1, re1, rclke1, we1, wclke1, 93 raddr2, waddr2, wdata2, mask2, re2, rclke2, we2, wclke2} << 1) | i; 94 if (s) begin 95 rdata1 <= rdata1_unreg; 96 rdata2 <= rdata2_unreg; 97 end 98 end 99 100 SB_RAM40_4K mem1 ( 101 .RDATA(rdata1_unreg), 102 .RCLK(clk), 103 .RCLKE(rclke1), 104 .RE(re1), 105 .RADDR(raddr1), 106 .WCLK(clk), 107 .WCLKE(wclke1), 108 .WE(we1), 109 .WADDR(waddr1), 110 .MASK(mask1), 111 .WDATA(wdata1) 112 ); 113 114 SB_RAM40_4K mem2 ( 115 .RDATA(rdata2_unreg), 116 .RCLK(clk), 117 .RCLKE(rclke2), 118 .RE(re2), 119 .RADDR(raddr1), // <- cascade 120 .WCLK(clk), 121 .WCLKE(wclke2), 122 .WE(we2), 123 .WADDR(waddr1), // <- cascade 124 .MASK(mask2), 125 .WDATA(wdata2) 126 ); 127 endmodule 128 """, file=f) 129 130with open("%s.pcf" % sys.argv[1], "w") as f: 131 for i, name in enumerate(io_names): 132 print("set_io %s %s" % (name, pins[i]), file=f) 133 134with open("%s.ys" % sys.argv[1], "w") as f: 135 print("echo on", file=f) 136 print("read_verilog -lib cells.v", file=f) 137 print("read_verilog %s_ref.v" % sys.argv[1], file=f) 138 print("read_verilog %s_out.v" % sys.argv[1], file=f) 139 print("prep", file=f) 140 print("equiv_make top chip equiv", file=f) 141 print("# check -assert", file=f) 142 print("cd equiv", file=f) 143 print("script %s.lc" % sys.argv[1], file=f) 144 print("rename -hide w:N_*", file=f) 145 print("equiv_struct -maxiter 100", file=f) 146 print("opt_clean -purge", file=f) 147 print("write_ilang %s.il" % sys.argv[1], file=f) 148 print("equiv_status -assert", file=f) 149 150assert os.system("bash ../icefuzz/icecube.sh %s.v" % sys.argv[1]) == 0 151os.rename("%s.v" % sys.argv[1], "%s_in.v" % sys.argv[1]) 152 153if False: 154 assert os.system("python3 ../icebox/icebox_explain.py %s.asc > %s.ex" % (sys.argv[1], sys.argv[1])) == 0 155 156with open("%s_ref.v" % sys.argv[1], "w") as f: 157 for line in open("%s.vsb" % sys.argv[1], "r"): 158 if re.match(r" *defparam .*\.(IO_STANDARD|PULLUP|INIT_.|WRITE_MODE|READ_MODE)=", line): 159 continue 160 161 line = line.replace(" Span4Mux_s0_h ", " Span4Mux_h4 " if max_span_hack else " Span4Mux_h0 ") 162 line = line.replace(" Span4Mux_s1_h ", " Span4Mux_h4 " if max_span_hack else " Span4Mux_h1 ") 163 line = line.replace(" Span4Mux_s2_h ", " Span4Mux_h4 " if max_span_hack else " Span4Mux_h2 ") 164 line = line.replace(" Span4Mux_s3_h ", " Span4Mux_h4 " if max_span_hack else " Span4Mux_h3 ") 165 line = line.replace(" Span4Mux_h ", " Span4Mux_h4 " if max_span_hack else " Span4Mux_h4 ") 166 167 line = line.replace(" Span4Mux_s0_v ", " Span4Mux_v4 " if max_span_hack else " Span4Mux_v0 ") 168 line = line.replace(" Span4Mux_s1_v ", " Span4Mux_v4 " if max_span_hack else " Span4Mux_v1 ") 169 line = line.replace(" Span4Mux_s2_v ", " Span4Mux_v4 " if max_span_hack else " Span4Mux_v2 ") 170 line = line.replace(" Span4Mux_s3_v ", " Span4Mux_v4 " if max_span_hack else " Span4Mux_v3 ") 171 line = line.replace(" Span4Mux_v ", " Span4Mux_v4 " if max_span_hack else " Span4Mux_v4 ") 172 line = line.replace(" Span4Mux ", " Span4Mux_v4 " if max_span_hack else " Span4Mux_v4 ") 173 174 line = line.replace(" Span12Mux_s0_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h0 ") 175 line = line.replace(" Span12Mux_s1_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h1 ") 176 line = line.replace(" Span12Mux_s2_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h2 ") 177 line = line.replace(" Span12Mux_s3_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h3 ") 178 line = line.replace(" Span12Mux_s4_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h4 ") 179 line = line.replace(" Span12Mux_s5_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h5 ") 180 line = line.replace(" Span12Mux_s6_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h6 ") 181 line = line.replace(" Span12Mux_s7_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h7 ") 182 line = line.replace(" Span12Mux_s8_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h8 ") 183 line = line.replace(" Span12Mux_s9_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h9 ") 184 line = line.replace(" Span12Mux_s10_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h10 ") 185 line = line.replace(" Span12Mux_s11_h ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h11 ") 186 line = line.replace(" Span12Mux ", " Span12Mux_h12 " if max_span_hack else " Span12Mux_h12 ") 187 188 line = line.replace(" Span12Mux_s0_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v0 ") 189 line = line.replace(" Span12Mux_s1_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v1 ") 190 line = line.replace(" Span12Mux_s2_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v2 ") 191 line = line.replace(" Span12Mux_s3_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v3 ") 192 line = line.replace(" Span12Mux_s4_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v4 ") 193 line = line.replace(" Span12Mux_s5_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v5 ") 194 line = line.replace(" Span12Mux_s6_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v6 ") 195 line = line.replace(" Span12Mux_s7_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v7 ") 196 line = line.replace(" Span12Mux_s8_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v8 ") 197 line = line.replace(" Span12Mux_s9_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v9 ") 198 line = line.replace(" Span12Mux_s10_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v10 ") 199 line = line.replace(" Span12Mux_s11_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v11 ") 200 line = line.replace(" Span12Mux_v ", " Span12Mux_v12 " if max_span_hack else " Span12Mux_v12 ") 201 202 f.write(line) 203 204assert os.system("yosys -qp 'select -write %s.lc t:LogicCell40' %s_ref.v" % (sys.argv[1], sys.argv[1])) == 0 205assert os.system(r"sed -i -r 's,.*/(.*)LC_(.*),equiv_add -try -cell \1LC_\2_gold lc40_\2_gate,' %s.lc" % sys.argv[1]) == 0 206 207os.remove("%s.bin" % sys.argv[1]) 208os.remove("%s.vsb" % sys.argv[1]) 209os.remove("%s.glb" % sys.argv[1]) 210os.remove("%s.psb" % sys.argv[1]) 211os.remove("%s.sdf" % sys.argv[1]) 212shutil.rmtree("%s.tmp" % sys.argv[1]) 213 214