├── .gitignore ├── README.md ├── autocc.py ├── fixes ├── VSCALE_CEX_FIX ├── fix_combo_loop_vscale_rtl.sh └── fix_underconstrain_vscale.sh ├── ft_aes ├── FPV.tcl ├── files.vc └── sva │ ├── aes_wrap_bind.svh │ └── aes_wrap_prop.sv ├── ft_cva6 ├── FPV.tcl ├── files.vc ├── manual_sub.vc └── sva │ ├── cva6_bind.svh │ └── cva6_prop.sv ├── ft_maple ├── FPV.tcl ├── files.vc ├── ft_dcp_pipe │ ├── files.vc │ └── sva │ │ ├── dcp_pipe_bind.svh │ │ └── dcp_pipe_prop.sv └── sva │ ├── is_core_bind.svh │ └── is_core_prop.sv ├── maple_setup_build.sh ├── projs └── README.md └── sigs ├── aes.sig ├── cva6_c1.sig ├── cva6_c2.sig ├── maple.sig └── vscale.sig /.gitignore: -------------------------------------------------------------------------------- 1 | aes 2 | cva6 3 | openpiton 4 | 5 | vscale 6 | ft_vscale_core 7 | 8 | projs 9 | sigs 10 | *.sig~ 11 | 12 | jgproject 13 | */FPV_cvr/* 14 | */FPV_prv/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![LOGO](https://github.com/morenes/AutoCC/assets/55038083/6f578a9e-36ae-4641-8585-ca38cf50346f) 3 | 4 | # Requirements 5 | 6 | - **JasperGold (JG) 2019.12 or newer** (tested with 2019.12 and 2021.03). To run the Formal Testbenches. 7 | - **VCS Simulator** (tested with vcs-mx/O-2018.09-SP2). Only for the MAPLE use case to reproduce the covert-channel in RTL simulation. 8 | - **Python 2+.** To run AutoCC and also for the RTL simulation. 9 | 10 | # Installation 11 | 12 | git clone https://github.com/morenes/AutoCC.git; 13 | git checkout v1.0; 14 | cd AutoCC; 15 | export AUTOCC_ROOT=$PWD; 16 | 17 | which jg; 18 | alias jg='/jasper_2021.03/bin/jg'; # Or the version that you are using 19 | 20 | # Use cases 21 | 22 | ## **Vscale 32-bit core:** *Generating testbench and fixing underconstrains* 23 | 24 | Clone the VSCALE repo 25 | 26 | cd $AUTOCC_ROOT 27 | git clone https://github.com/LGTMCU/vscale.git 28 | 29 | 30 | Fixes a combinational loop in the original RTL that prevents JasperGold (JG) from running. 31 | 32 | export DUT_ROOT=$PWD/vscale/src/main/verilog; 33 | ./fixes/fix_combo_loop_vscale_rtl.sh 34 | 35 | Generate the Vscale Formal Testbench (FT) using AutoCC. 36 | 37 | python3 autocc.py -f vscale_core.v -i vscale_ctrl_constants.vh; 38 | 39 | 40 | Run JG on the generated testbench. 41 | 42 | jg ft_vscale_core/FPV.tcl -proj projs/vscale_init & 43 | 44 | **CEX.** The tool should find a CEX (of at least 6 cycles) to the assertion *as__dmem_hwrite* 45 | 46 | **GUI.** Clicking on the assertion the GUI opens a waveform window. To visualize the CEX, we add a list of signals to the waveform window. We can use the signal list in the file vscale.sig. To load the signal list, go to **File > Load Signal List**, and select vscale.sig from the sigs folder. 47 | 48 | **Waveform.** In the waveform we would see spy_mode starting in cycle 5. Then, hwrite signal is different in the last cycle because the opcode was different a cycle before (ctrl.opcode). 49 | This is because the PC is different (PC_IF), since the branch was taken in one universe and not in the other, because the register file data was different (regfile.data). 50 | 51 | **FIX.** 52 | As described in the paper, this is an underconstraint in the testbench, since the testbench does not constrain the register file data to be the same in both universes when the spy_mode starts. We fix this by adding conditions to the testbench and re-running JG. 53 | 54 | ./fixes/fix_underconstrain_vscale.sh; 55 | jg ft_vscale_core/FPV.tcl -proj projs/vscale_fixed & 56 | 57 | 58 | 59 | ## **CVA6 application-class RISCV-64 core:** *Uncovering and fixing hardware bugs* 60 | 61 | Clone the CVA6 repo and checkout the commit without fixes 62 | 63 | cd $AUTOCC_ROOT; 64 | git clone -b autocc https://github.com/morenes/cva6.git 65 | 66 | Run JG on the CVA6 testbench: 67 | 68 | jg ft_cva6/FPV.tcl -proj projs/cva6_orig & 69 | 70 | 71 | ### CEX1 - Leaks invalid I-Cache data to the next PC 72 | 73 | The tool should have found a CEX to the assertion *as__AXI_ar_valid_equal* 74 | in under 30 minutes with a depth of 76 cycles. 75 | 76 | **GUI.** Clicking on the assertion the GUI opens a waveform window. To visualize the CEX, we add the list of signals cva6_c1.sig from the sigs folder. 77 | 78 | **Waveform.** In the waveform we would see the PC being different because instr_compressed had a different value. This propagated based on garbagged data being read from the icache during an exception. 79 | 80 | **FIX.** 81 | Zero out data coming from the i-cache if the line is not a hit. 82 | We apply the fix by checking out a branch with the patch already included. 83 | 84 | cd cva6; git checkout autocc_fix_cex1; cd ..; 85 | jg ft_cva6/FPV.tcl -proj projs/cva6_fix_cex1 & 86 | 87 | ### CEX2 - Wrong transition in the FSM of the PTW 88 | 89 | The tool should have found a CEX to the assertion *as__AXI_ar_valid_equal* 90 | in under 6 hours with a depth of 80 cycles. 91 | 92 | **GUI.** We add the list of signals cva6_c2.sig from the sigs folder. 93 | 94 | **Waveform.** In the waveform we would see ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.state_q transitioning from *WAIT_VALID* to *IDLE*, which is an illegal FSM transition caused by ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.flush_i being set while the PTW is waiting for a response. 95 | 96 | **FIX.** 97 | Update the FSM to remain in *WAIT_VALID* even when flush_i is set. 98 | Fix applied to upstream CVA6 (github.com/openhwgroup/cva6/pull/1184) 99 | We apply the fix by checking out a branch with the patch already included. 100 | 101 | cd cva6; git checkout autocc_fix_cex2; cd ..; 102 | jg ft_cva6/FPV.tcl -proj projs/cva6_fix_cex2 & 103 | 104 | The previous CEX trace should not be found anymore due to the fix. We have not continued debugging possible CEXs that may appear to this or other assertions. 105 | 106 | 107 | 108 | ## **MAPLE memory-engine:** *Uncovering, reproducing in RTL Simulation and fixing a covert channel* 109 | 110 | ### Installing OpenPiton with MAPLE inside it 111 | 112 | Clone and building the OpenPiton repo 113 | 114 | cd $AUTOCC_ROOT 115 | git clone -b openpiton-maple https://github.com/PrincetonUniversity/openpiton.git 116 | cd openpiton; 117 | source piton/ariane_setup.sh; 118 | source piton/ariane_build_tools.sh; # Takes ~5-10 minutes 119 | 120 | Clone and build the MAPLE repo 121 | 122 | source ../maple_setup_build.sh # Takes ~1 minute 123 | 124 | ### Run MAPLE's Formal Testbench (FT) 125 | 126 | To run JG on MAPLE's FT, we do: 127 | 128 | cd $AUTOCC_ROOT 129 | jg ft_maple/FPV.tcl -proj projs/maple_not_fixed & 130 | 131 | While JG is running, we can reproduce the covert channel (that we will find with the CEX) in RTL Simulation at the system-level using OpenPiton. 132 | 133 | 134 | ### Reproducing the covert channel in RTL Simulation 135 | 136 | To run the attack that reveal the secret key, we do the following: 137 | 138 | cd openpiton/maple; 139 | ./run_test.sh 4; 140 | 141 | The recovered secret should be 0xdeadbeef. 142 | The reported cycle count should be less than 6000 cycles. 143 | 144 | 145 | We now apply the fixes to close the covert channel. 146 | 147 | git checkout fa614fc; 148 | source ../../maple_setup_build.sh 149 | ./run_test.sh 4; 150 | 151 | The recovered secret should be 0x00000000. This indicates that the secret cannot be extracted using this channel anymore 152 | 153 | ### CEX on the FT 154 | 155 | In the meantime, we have been running JG on MAPLE's Formal Testbench with the Design-under-test (DUT) being MAPLE's RTL before applying the fixes. 156 | In less than 30 minutes we should find a CEX at depth 21, where the assertion *as__dev1_merger_vr_noc1_val* fails. 157 | 158 | 159 | 160 | 161 | 162 | ## **AES encryption accelerator.** *Achieving full-proof* 163 | 164 | Clone the AES repo: 165 | 166 | cd $AUTOCC_ROOT 167 | git clone https://github.com/morenes/aes.git 168 | git checkout AutoCC-AE 169 | 170 | We run JG on the AES testbench, with the DUT being the RTL of the AES accelerator. 171 | This testbench already includes the architectural modeling described in Section 4.4 of the paper, to avoid spurious CEXs. 172 | The result of this run should be full-proof, i.e., no CEXs found, in less than 6 hours. 173 | 174 | jg ft_aes/FPV.tcl -proj projs/aes & 175 | -------------------------------------------------------------------------------- /autocc.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import re 4 | import sys 5 | from shutil import copyfile 6 | from datetime import date 7 | 8 | keywords = ["config", "clk", "rst", "htif", "boot","hart","irq","ipi","time","debug",] 9 | 10 | override_tool_script = 1 11 | recursive = 0 12 | 13 | IN = "--?IN>" 14 | OUT = "--?OUT>" 15 | implies = [IN, OUT] 16 | macro = "///AUTOSVA" 17 | # Arrays 18 | params = [] 19 | interfaces = [] 20 | def_wires = [] 21 | assign_wires = {} 22 | fields = {} 23 | handshakes = {} 24 | implications = {} 25 | signals = {} 26 | suffixes = {} 27 | tool_mode = "autocc" 28 | verbose = 0 29 | clk_sig = "clk" 30 | rst_sig = "rst_n" 31 | prop_filename_backup = "" 32 | 33 | def get_reset(): 34 | if "n" in rst_sig or "l" in rst_sig: 35 | return "!"+rst_sig 36 | else: 37 | return rst_sig 38 | def check_size(name, sub_size, size, params): 39 | if sub_size and sub_size not in params: 40 | print("Warning: Signal '" + name + "' has a size of '" + size + "' that is not defined in this module!") 41 | 42 | def check_interface(name, interfaces): 43 | if name not in interfaces: 44 | print("Error: '" + name + "' is not a valid interface!") 45 | return 1 46 | return 0 47 | 48 | def check_signal(name, signals): 49 | if name not in signals: 50 | print("Error: '" + name + "' is not a valid signal!") 51 | return 1 52 | return 0 53 | 54 | def check_annotation(annotation, line): 55 | if not annotation: 56 | print("Error: Invalid signal '" + line.replace("\n", "") + "' for annotation!") 57 | return 1 58 | #sys.exit(1) 59 | return 0 60 | 61 | def check_size_match(name, size1, size2): 62 | if (size1 != size2): 63 | print("Error: Annotation '" + name + "' has mismatched sizes! "+str(size1)+" and "+str(size2)) 64 | return 1 65 | return 0 66 | 67 | def check_id(name, entry): 68 | if not "p_id" in entry or not "q_id" in entry: 69 | print("Error: Annotation '" + name + "' is missing a main transaction ID!") 70 | return 1 71 | return 0 72 | 73 | def check_trans_id(name, entry): 74 | if not "p_trans_id" in entry or not "q_trans_id" in entry: 75 | print("Error: Annotation '" + name + "' is missing a transaction ID!") 76 | return 1 77 | return 0 78 | 79 | def create_dir(name): 80 | if (not os.path.exists(name)): 81 | try: 82 | os.makedirs(name) 83 | except OSError: 84 | print ("Creation of the directory %s failed" % name) 85 | sys.exit(1) 86 | else: 87 | print ("Successfully created the directory %s" % name) 88 | 89 | def parse_args(): 90 | parser = argparse.ArgumentParser(description='AutoCC tool for FT generation.') 91 | parser.add_argument("-f", "--filename", required=True, type=str, help="Path to DUT RTL module file.") 92 | parser.add_argument("-src", "--source", nargs="+", type=str, default=[], help="Path to source code folder where submodules are.") 93 | parser.add_argument("-i", "--include", type=str, help="Path to include folder that DUT and submodules use.") 94 | parser.add_argument("-as", "--submodule_assert", nargs="+", type=str, default=[], help="List of submodules for which ASSERT the behavior of outgoing transactions.") 95 | parser.add_argument("-am", "--submodule_assume", nargs="+", type=str, default=[], help="List of submodules for which ASSUME the behavior of outgoing transactions (ASSUME can constrain the DUT).") 96 | parser.add_argument("-x", "--xprop_macro", nargs="?", type=str, const = "NONE", help="Generate X Propagation assertions, specify argument to create property under (default none)") 97 | parser.add_argument("-tool", nargs="?", type=str, const = "jasper", default="jasper", help="Backend tool to use [jasper|sby] (default jasper)") 98 | parser.add_argument("-v", "--verbose", action='store_true', help="Add verbose output.") 99 | parser.add_argument("-mode", nargs="?", type=str, const = "autocc", default="autocc", help="Mode to use [autocc|autocc_only_wrap|autosva] (default autocc)") 100 | args = parser.parse_args() 101 | return args 102 | 103 | def clean(line): 104 | line = line.replace("\t", "") 105 | while line.startswith(" "): 106 | line = line[1:] 107 | return line 108 | 109 | def abort_tool(prop): 110 | print("ABORTING!") 111 | if not prop.closed: 112 | prop.close() 113 | copyfile(prop_filename_backup, prop.name) 114 | sys.exit(1) 115 | 116 | def parse_annotation(line): 117 | global implications 118 | global def_wires,assign_wires 119 | 120 | name = None 121 | symbol = None 122 | 123 | match_in = re.search("(?:"+macro+"\s)?(\w+)\s*:\s*(\w+)\s*" + IN + "\s*(\w+)", line) 124 | match_out = re.search("(?:"+macro+"\s)?(\w+)\s*:\s*(\w+)\s*" + OUT + "\s*(\w+)", line) 125 | match_wire = re.search("(?:"+macro+"\s)?(\[.*:0\]\s+)?(\w+)\s*[=]\s*(.+)", line) 126 | 127 | match_trans_id = re.search(macro+" trans_id", line) 128 | match_trans_id_other = re.search(macro+" (trans_id_\d+)", line) 129 | match_trans_id_unique = re.search(macro+" trans_id_unique", line) 130 | match_trans_id_other_unique = re.search(macro+" (trans_id_\d+_unique)", line) 131 | match_data = re.search(macro+" data", line) 132 | 133 | if (verbose): print("Parsing annotation:" + line[:-1]) 134 | #check_annotation((match_in or match_out or match_trans_id or 135 | # match_trans_id_other or match_data or match_wire), line) 136 | if match_in: 137 | name = match_in.group(1) 138 | p = match_in.group(2) 139 | q = match_in.group(3) 140 | symbol = IN 141 | elif match_out: 142 | name = match_out.group(1) 143 | p = match_out.group(2) 144 | q = match_out.group(3) 145 | symbol = OUT 146 | elif match_trans_id_other_unique: 147 | name = match_trans_id_other_unique.group(1) 148 | return name 149 | elif match_trans_id_unique: 150 | return "trans_id_unique" 151 | elif match_trans_id_other: 152 | name = match_trans_id_other.group(1) 153 | return name 154 | elif match_trans_id: 155 | return "trans_id" 156 | elif match_data: 157 | if (verbose): print("Matched data") 158 | return "data" 159 | elif match_wire: 160 | size = match_wire.group(1) 161 | name = match_wire.group(2) 162 | assign = match_wire.group(3) 163 | 164 | if not assign.endswith(";"): 165 | assign += ";" 166 | if size: 167 | wire = "wire "+size+name+";" 168 | else: 169 | wire = "wire "+name+";" 170 | 171 | def_wires.append(wire) 172 | assign_wires[name]=assign 173 | if (verbose): print("Matched wire:" + wire +", assign: "+assign) 174 | parse_signal(1,wire+"\n",None) 175 | 176 | 177 | #add implications 178 | if symbol in implies: 179 | annotation = {"p": p, "q": q, "symbol": symbol, "size": "", "p_unique": None, "q_unique": None} 180 | implications[name] = annotation 181 | if (verbose): print("Matched iface:" + p +", and: "+q) 182 | return None 183 | 184 | def parse_signal(is_input, line, annotation): 185 | global interfaces, handshakes, signals, verbose, rst_sig, clk_sig 186 | name = None 187 | entry = None 188 | val = None 189 | rdy = None 190 | 191 | if (verbose): print("Parsing signal: " + line[:-1]) 192 | match = re.search("\s*[wire|logic|reg]?\s+(?:\[(.*):0\]\s+)?(\w+)\s*[,;=]?\s*(//.*)?\n", line) 193 | if match: 194 | size = match.group(1) 195 | name = match.group(2) 196 | comment = match.group(3) 197 | if size is None: 198 | size = "0" 199 | else: 200 | size = size.replace(" ","") 201 | #check_size(name, sub_size, size, params) 202 | if (verbose): print("Parsed signal, name: " + str(name) + 203 | ", size: " + str(size) + ", com: " + str(comment)) 204 | 205 | if name.startswith("clk"): 206 | clk_sig = name 207 | elif name.startswith("rst") or name.startswith("reset") or name.endswith("reset"): 208 | rst_sig = name 209 | #if it is a valid or ready signal 210 | elif name.endswith("_val"): 211 | val = name.replace("_val", "") 212 | if val not in interfaces: # val sees first 213 | interfaces.append(val) 214 | handshakes[val] = val 215 | else: # got added by rdy, need to find match 216 | handshakes[val] = handshakes[val].replace("//", "") 217 | elif name.endswith("_res") or name.endswith("_rdy") or name.endswith("_ack"): 218 | rdy = name[0:len(name)-4] 219 | if rdy not in interfaces: # rdy sees first 220 | interfaces.append(rdy) 221 | handshakes[rdy] = name + "//" # yet to find matching val 222 | else: # got added by val 223 | handshakes[rdy] = name 224 | elif name.endswith("_trans_id") or name.endswith("_transid"): 225 | annotation = "trans_id" 226 | elif name.endswith("_trans_id_unique") or name.endswith("_transid_unique"): 227 | annotation = "trans_id_unique" 228 | # add only if the interface is defined (in implications) 229 | elif name.endswith("_stable"): 230 | annotation = "stable" 231 | elif name.endswith("_data"): 232 | key = name[:-5] 233 | if key in handshakes: 234 | annotation = "data" 235 | elif name.endswith("_active"): 236 | key = name[:-7] 237 | if key in implications: 238 | struct = implications[key] 239 | if (struct): struct["active"] = name 240 | 241 | #if the signal was annotated 242 | if annotation: 243 | fields[name] = annotation 244 | if (verbose): print("Annotated as: " + annotation) 245 | 246 | entry = {"size": size, "comment": comment, "type": is_input} 247 | signals[name] = entry 248 | 249 | def parse_fields(prop): 250 | options = "(" 251 | list = [] 252 | for impl_name in implications: 253 | entry = implications[impl_name] 254 | list.append(entry["p"]) 255 | list.append(entry["q"]) 256 | list.sort(reverse=True) 257 | for name in list: 258 | options+=name+"|" 259 | options+="ERROR)" 260 | 261 | ##fields are annotated signals 262 | for signal_name in fields: 263 | #separate iface_name and field_name (annotation) 264 | annotation_match = re.search(options+"_(\w+)", signal_name) 265 | if (check_annotation(annotation_match, signal_name)): 266 | continue 267 | #abort_tool(prop) 268 | interface = annotation_match.group(1) 269 | suffix = annotation_match.group(2) 270 | if (verbose): print("PF iface: " + interface + ", suffix: " + suffix) 271 | # Append the to interface entry of the dict, the suffix 272 | if (not interface in suffixes): 273 | suffixes[interface] = [] 274 | suffixes[interface].append(suffix) 275 | 276 | #field is the type of annotation 277 | field = fields[signal_name] 278 | for impl_name in implications: 279 | #print("PF implication_name: " + str(impl_name)); 280 | entry = implications[impl_name] 281 | if entry["p"] == interface: 282 | update_entry(field, impl_name, "p_", suffix) 283 | if entry["q"] == interface: 284 | update_entry(field, impl_name, "q_", suffix) 285 | 286 | def update_entry(field, impl_name, type, suffix): 287 | global implications 288 | if (verbose): print("UA field: " + field + ", impl_name: " + impl_name + ", type: " + type + ", suffix: " + suffix) 289 | entry = implications[impl_name] 290 | if field == "trans_id" or field == "trans_id_unique": 291 | entry[type + "id"] = suffix 292 | entry[type + field] = [suffix, ""] 293 | elif "trans_id" in field: 294 | entry[type + field] = [suffix, ""] 295 | elif field == "data" or field == "stable": 296 | entry[type + field] = suffix 297 | 298 | if "unique" in field: 299 | entry[type + field] = [suffix, ""] 300 | 301 | if (verbose): print("UA: " + str(entry)); 302 | 303 | def get_sizes(prop): 304 | global implications,signals 305 | for impl_name in implications: 306 | entry = implications[impl_name] 307 | #if (check_id(impl_name, entry)): abort_tool(prop) 308 | if not "p_id" in entry: 309 | name = entry["p"]+"_transid" 310 | signals[name] = {"size": "'0", "comment": ""} 311 | entry["p_id"] = "transid" 312 | entry["p_trans_id"] = ["transid", ""] 313 | if not "q_id" in entry: 314 | name = entry["q"]+"_transid" 315 | signals[name] = {"size": "'0", "comment": ""} 316 | entry["q_id"] = "transid" 317 | entry["q_trans_id"] = ["transid", ""] 318 | if entry["symbol"] in implies: 319 | if check_interface(entry["p"], interfaces) or check_interface(entry["q"], interfaces): 320 | abort_tool(prop) 321 | for key in entry: 322 | keyq = key.replace("p", "q") 323 | if ("p_trans_id" in key) and (keyq in entry): 324 | #trans_id signal suffix 325 | p_trans_id = entry[key][0] 326 | q_trans_id = entry[keyq][0] 327 | #full signal name with iface prefix 328 | p_signal_name = entry["p"] + "_" + p_trans_id 329 | q_signal_name = entry["q"] + "_" + q_trans_id 330 | if (verbose): print("GS p: " + p_signal_name + ", q: " + q_signal_name); 331 | #check that signals exist in signal dict 332 | if check_signal(p_signal_name, signals): 333 | abort_tool(prop) 334 | #get the size of p and q trans_id from signals dict 335 | size_p = signals[p_signal_name]["size"] 336 | size_q = signals[q_signal_name]["size"] 337 | #check that sizes match 338 | if check_size_match(impl_name, size_p, size_q): 339 | abort_tool(prop) 340 | #update size in entries 341 | entry[key][1] = size_p 342 | entry[keyq][1] = size_q 343 | if entry["p_id"] == p_trans_id: 344 | entry["size"] = size_p 345 | if (verbose): print("GS: " + str(entry)); 346 | 347 | def close_bind (module_name, bind): 348 | bind.write("\t\t.ASSERT_INPUTS (0)\n") 349 | bind.write("\t) u_" + module_name + "_sva(.*);") 350 | bind.close() 351 | 352 | def gen_disclaimer(prop,rtl_file_relation): 353 | if rtl_file_relation: 354 | prop.write("// This property file was autogenerated by AutoCC on "+str(date.today())+"\n") 355 | prop.write("// to check the behavior of the original RTL module, whose interface is described below: \n") 356 | 357 | def create_wrapper(rtl, wrap): 358 | global params 359 | 360 | is_param = False 361 | is_signal = False 362 | autosva_scope = False 363 | parsed_module_sec = False 364 | parsed_disclaimer_sec = False 365 | module_name = "error" 366 | annotation = None 367 | 368 | for line in rtl: 369 | line = clean(line) 370 | #Show the parsed line if verbose mode 371 | if (verbose): print("Parsing global:" + line[:-1]) 372 | 373 | if line.startswith("module"): 374 | if not parsed_disclaimer_sec: 375 | parsed_disclaimer_sec = True 376 | gen_disclaimer(wrap,True) 377 | parsed_module_sec = True 378 | matches = re.search("module\s+(\w+)(.*)", line) 379 | module_name = matches.group(1) 380 | print("Creating wrapper of module:" + module_name) 381 | rest = matches.group(2) 382 | # wrap.seek(0) 383 | # wrap.truncate() 384 | wrap.write("module " + module_name + "_wrap\n") 385 | 386 | if "#(" in rest: 387 | is_param = True 388 | wrap.write(rest+"\n\t\tparameter ASSERT_INPUTS = 0,\n") 389 | elif "(" in rest: 390 | wrap.write("#(\n\t\tparameter ASSERT_INPUTS = 0)\n"+rest+"\n") 391 | is_signal = True 392 | 393 | elif (is_param and (not is_signal)) or (parsed_module_sec and line.startswith("#(")): 394 | if line.startswith("#("): 395 | is_param = True 396 | line = line[2:] 397 | wrap.write("#(\n\t\tparameter ASSERT_INPUTS = 0,\n") 398 | if "parameter" in line: 399 | wrap.write("\t\t" + line) 400 | matches = re.findall("\s*\t*parameter\s+(\w+)\s+=\s*\d+(?:,)?", line) 401 | for param in matches: 402 | params.append(param) 403 | #when param section contains the close symbol 404 | elif line.startswith(")"): 405 | wrap.write(line) 406 | is_signal = True 407 | 408 | elif is_signal or (parsed_module_sec and line.startswith("(")): 409 | if line.startswith("("): 410 | if not is_signal: 411 | is_signal = True 412 | if (not is_param): 413 | wrap.write("#(\n\t\tparameter ASSERT_INPUTS = 0)\n(\n") 414 | else: 415 | wrap.write("(") 416 | elif line.startswith("/*AUTOSVA"): 417 | autosva_scope = True 418 | elif line.startswith("*/"): 419 | autosva_scope = False 420 | elif line.startswith(macro) or autosva_scope: # annotation 421 | annotation = parse_annotation(line) 422 | else: 423 | if line.startswith(");"): 424 | parse_fields(wrap) 425 | get_sizes(wrap) 426 | wrap.write("\t" + line) 427 | wrap.write("\n") 428 | wrap.write("//==============================================================================\n") 429 | wrap.write("// Instance Modules\n") 430 | wrap.write("//==============================================================================\n\n") 431 | #iterate over all the signals and create the instance 432 | wrap.write("\t" + module_name + " u_" + module_name + " (\n") 433 | first_param = True 434 | for signal in signals: 435 | if not first_param: 436 | wrap.write(",\n") 437 | wrap.write("\t." + signal + "(" + signal + ")") 438 | first_param = False 439 | wrap.write("\n);\n\n") 440 | wrap.write("\t" + module_name + " u_" + module_name + "2 (\n") 441 | first_param = True 442 | for signal in signals: 443 | if not first_param: 444 | wrap.write(",\n") 445 | if not any(x in signal for x in keywords): 446 | wrap.write("\t." + signal + "(" + signal + "_2)") 447 | else: 448 | wrap.write("\t." + signal + "(" + signal + ")") 449 | first_param = False 450 | wrap.write("\n);\n\n") 451 | wrap.write("endmodule\n") 452 | break 453 | 454 | if line.startswith("output") or line.startswith("input"): 455 | 456 | if not any(x in line for x in keywords): 457 | if "," in line: 458 | wrap.write("\t\t" + line.split(",")[0] + "_2,\n") 459 | else: 460 | wrap.write("\t\t" + line.split("\n")[0] + "_2,\n") 461 | wrap.write("\t\t" + line) 462 | elif line.startswith("wire"): 463 | wrap.write("\t\tinput " + line) 464 | else: 465 | wrap.write("\t\t" + line) 466 | annotation = None 467 | 468 | elif not parsed_module_sec or line.startswith("import"): 469 | if (not parsed_disclaimer_sec) and (not line.startswith("//")): 470 | parsed_disclaimer_sec = True 471 | gen_disclaimer(wrap,True) 472 | if parsed_disclaimer_sec: 473 | wrap.write(line) 474 | else: 475 | print("Unexpected line after module header parsed") 476 | #sys.exit(1) 477 | wrap.close() 478 | 479 | def write_line(prop, line): 480 | if tool_mode.startswith("autocc"): 481 | #write duplicate 482 | if not any(x in line for x in keywords): 483 | if "," in line: 484 | prop.write("\t\t" + line.split(",")[0] + "_2,\n") 485 | elif "//" in line: 486 | prop.write("\t\t" + line.split("//")[0].strip() + "_2,\n") 487 | else: 488 | prop.write("\t\t" + line.split("\n")[0] + "_2,\n") 489 | prop.write("\t\t" + line) 490 | 491 | def parse_global(rtl, prop, bind): 492 | global params 493 | 494 | is_param = False 495 | is_signal = False 496 | autosva_scope = False 497 | parsed_module_sec = False 498 | parsed_disclaimer_sec = False 499 | module_name = "error" 500 | annotation = None 501 | 502 | for line in rtl: 503 | line = clean(line) 504 | #Show the parsed line if verbose mode 505 | if (verbose): print("Parsing global:" + line[:-1]) 506 | 507 | if line.startswith("module"): 508 | if not parsed_disclaimer_sec: 509 | parsed_disclaimer_sec = True 510 | gen_disclaimer(prop,True) 511 | parsed_module_sec = True 512 | matches = re.search("module\s+(\w+)(.*)", line) 513 | module_name = matches.group(1) 514 | print("Module name:" + module_name) 515 | rest = matches.group(2) 516 | prop.write("module " + module_name + "_prop\n") 517 | gen_disclaimer(bind,False) 518 | #different bind for autocc 519 | if tool_mode.startswith("autocc"): 520 | bind.write("bind " + module_name + "_wrap " + module_name + "_prop\n") 521 | else: 522 | bind.write("bind " + module_name + " " + module_name + "_prop\n") 523 | 524 | bind.write("\t#(\n") 525 | if "#(" in rest: 526 | is_param = True 527 | prop.write(rest+"\n\t\tparameter ASSERT_INPUTS = 0,\n") 528 | elif "(" in rest: 529 | prop.write("#(\n\t\tparameter ASSERT_INPUTS = 0)\n"+rest+"\n") 530 | is_signal = True 531 | close_bind(module_name,bind) 532 | 533 | elif (is_param and (not is_signal)) or (parsed_module_sec and line.startswith("#(")): 534 | if line.startswith("#("): 535 | is_param = True 536 | line = line[2:] 537 | prop.write("#(\n\t\tparameter ASSERT_INPUTS = 0,\n") 538 | if "parameter" in line: 539 | prop.write("\t\t" + line) 540 | matches = re.findall("\s*\t*parameter\s+(\w+)\s+=\s*\d+(?:,)?", line) 541 | for param in matches: 542 | bind.write("\t\t." + param + " (" + param + "),\n") 543 | params.append(param) 544 | #when param section contains the close symbol 545 | elif line.startswith(")"): 546 | prop.write(line) 547 | is_signal = True 548 | close_bind(module_name,bind) 549 | #else: 550 | # print("Wrong format in parameter section! Expecting parameter or )") 551 | 552 | elif is_signal or (parsed_module_sec and line.startswith("(")): 553 | if line.startswith("("): 554 | if not is_signal: 555 | is_signal = True 556 | close_bind(module_name,bind) 557 | if (not is_param): 558 | prop.write("#(\n\t\tparameter ASSERT_INPUTS = 0)\n(\n") 559 | else: 560 | prop.write("(") 561 | elif line.startswith("/*AUTOSVA"): 562 | autosva_scope = True 563 | elif line.startswith("*/"): 564 | autosva_scope = False 565 | elif line.startswith(macro) or autosva_scope: # annotation 566 | annotation = parse_annotation(line) 567 | else: 568 | if line.startswith(");"): 569 | parse_fields(prop) 570 | get_sizes(prop) 571 | prop.write("\t" + line) 572 | prop.write("\n") 573 | prop.write("//==============================================================================\n") 574 | prop.write("// Local Parameters\n") 575 | prop.write("//==============================================================================\n\n") 576 | break 577 | if line.startswith("output"): # output wire 578 | line = line.replace("output", "input ").split("\n")[0] 579 | line += " //output\n" 580 | write_line(prop,line) 581 | parse_signal(0,line[5:], annotation) 582 | elif line.startswith("input"): 583 | write_line(prop,line) 584 | parse_signal(1,line[5:], annotation) 585 | elif line.startswith("wire"): 586 | prop.write("\t\tinput " + line) 587 | parse_signal(1,line, annotation) 588 | else: 589 | prop.write("\t\t" + line) 590 | annotation = None 591 | 592 | elif not parsed_module_sec or line.startswith("import"): 593 | if (not parsed_disclaimer_sec) and (not line.startswith("//")): 594 | parsed_disclaimer_sec = True 595 | gen_disclaimer(prop,True) 596 | if parsed_disclaimer_sec: 597 | prop.write(line) 598 | else: 599 | print("Unexpected line after module header parsed") 600 | #sys.exit(1) 601 | 602 | def gen_vars(tool, prop): 603 | prop.write("genvar j;\ndefault clocking cb @(posedge " + clk_sig + ");\nendclocking\ndefault disable iff (" + get_reset() + ");\n") 604 | if tool == "sby": 605 | prop.write("reg reset_r = 0;\n") 606 | prop.write("am__rst: assume property (reset_r != "+get_reset()+");\n") 607 | prop.write("always_ff @(posedge "+clk_sig+")\n") 608 | prop.write(" reset_r <= 1'b1;\n") 609 | prop.write("\n// Re-defined wires \n") 610 | # Keep track of the wires already defined for symbolics and handshakes 611 | def_symb_hsk = [] 612 | for line in def_wires: 613 | prop.write(line+"\n") 614 | prop.write("\n// Symbolics and Handshake signals\n") 615 | for impl_name in implications: 616 | entry = implications[impl_name] 617 | for key in entry: 618 | if "p_trans_id" in key and key.replace("p", "q") in entry: 619 | if (verbose): print("GenVAR:" + impl_name +", key "+key) 620 | trans_id_entry = entry[key] 621 | size = trans_id_entry[1] 622 | symb_name = "symb_" + entry["p"] + "_" + trans_id_entry[0] 623 | if size != "'0" and (not symb_name in def_symb_hsk): 624 | prop.write("wire [" + size + ":0] " + symb_name +";\n") 625 | prop.write("am__" + symb_name + "_stable: assume property($stable(" + symb_name + "));\n") 626 | def_symb_hsk.append(symb_name) 627 | elif key == "p" or key == "q": 628 | interface = entry[key] 629 | handshake = handshakes[interface] 630 | if handshake.endswith("//"): # skip those that never found matching val 631 | continue 632 | # Define Handshake wire 633 | base = handshake 634 | wire_def = base + "_hsk" 635 | if interface != handshake: # valid and ready 636 | base = handshake[0:len(handshake)-4] 637 | wire_def = base + "_hsk" 638 | 639 | # Check if the wire was defined already 640 | if not wire_def in def_symb_hsk: 641 | def_symb_hsk.append(wire_def) 642 | if interface != handshake: 643 | prop.write("wire " + base + "_hsk = " + base + "_val && " + handshake + ";\n") 644 | else: # Valid without a matching ready 645 | prop.write("wire " + wire_def + " = " + base + "_val;\n") 646 | 647 | prop.write("\n") 648 | 649 | def gen_models(prop): 650 | if tool_mode.startswith("autocc"): 651 | prop.write("localparam THRESHOLD = 3;\n") 652 | prop.write("reg [$clog2(THRESHOLD):0] equal_cnt;\n") 653 | prop.write("wire transfer_cond;\n") 654 | prop.write("reg spy_mode; //Set when the equal_cnt reaches THRESHOLD\n") 655 | prop.write("wire spy_starts = transfer_cond && equal_cnt >= THRESHOLD;\n") 656 | prop.write("wire flush_done; //Set free by default (anytime) USER may set the conditions that indicate the flush has finished for both universes.\n") 657 | 658 | prop.write("always_ff @(posedge " + clk_sig + ") begin\n") 659 | prop.write("\tif (" + get_reset() + ") begin\n") 660 | prop.write("\t\tspy_mode <= '0;\n") 661 | prop.write("\t\tequal_cnt <= '0;\n") 662 | prop.write("\tend else begin\n") 663 | prop.write("\t\tspy_mode <= spy_starts || spy_mode;\n") 664 | prop.write("\t\tequal_cnt <= (flush_done || equal_cnt>0) && transfer_cond ? equal_cnt + 1 : '0;\n") 665 | prop.write("\tend\n") 666 | prop.write("end\n") 667 | prop.write("\n") 668 | 669 | prop.write("// There is an assertion per output signal from the DUT\n") 670 | for signal in signals: 671 | if signals[signal]["type"] == 0 and not any(x in signal for x in keywords): 672 | if signal.endswith("val") or signal.endswith("write") or signal.endswith("trans"): 673 | prop.write("as__" + signal + ": assert property (spy_mode |-> (" + signal + " == " + signal + "_2));\n") 674 | prop.write("\n") 675 | 676 | prop.write("// There is an assumption per input signal to the DUT\n") 677 | for signal in signals: 678 | #assume inputs (type 1) 679 | if signals[signal]["type"] == 1 and not any(x in signal for x in keywords): 680 | prop.write("am__" + signal + ": assume property (spy_mode |-> (" + signal + " == " + signal + "_2));\n") 681 | prop.write("\nassign io_equal =") 682 | 683 | for signal in signals: 684 | if not any(x in signal for x in keywords): 685 | prop.write(" " + signal + " == " + signal + "_2 &&\n") 686 | prop.write("1'b1;\n") 687 | 688 | prop.write("// The USER includes conditions here based on the architectural state of the DUT\n") 689 | prop.write("wire architectural_state_eq;\n") 690 | prop.write("// Conjunction of all conditions that need to be met before starting to check \n") 691 | prop.write("assign transfer_cond = architectural_state_eq && io_equal;\n") 692 | 693 | prop.write("//==============================================================================\n") 694 | prop.write("// Modeling\n") 695 | prop.write("//==============================================================================\n\n") 696 | for iface_name in implications: 697 | entry = implications[iface_name] 698 | if entry["symbol"] == IN: 699 | gen_in(prop, iface_name, entry) 700 | elif entry["symbol"] == OUT: 701 | gen_out(prop, iface_name, entry) 702 | 703 | for key in entry: 704 | if key.startswith("p") and "unique" in key and key.replace("p", "q") in entry: 705 | if entry[key] and entry[key.replace("p", "q")]: 706 | gen_unique(prop, iface_name, entry, entry[key], entry[key.replace("p", "q")]) 707 | 708 | def gen_in(prop, name, entry): 709 | p = entry["p"] 710 | q = entry["q"] 711 | size = entry["size"] 712 | if (verbose): 713 | print("GenIN:" + name) 714 | 715 | prop.write("// Modeling incoming request for " + name + "\n") 716 | if q != handshakes[q]: # has ready signal, not equal to interface name 717 | # the external module eventually accepts the response 718 | prop.write("if (ASSERT_INPUTS) begin\n") 719 | prop.write("\tas__" + name + "_fairness: assert property (" + q + "_val |-> s_eventually(" + handshakes[q] + "));\n") 720 | prop.write("end else begin\n") 721 | prop.write("\tam__" + name + "_fairness: assume property (" + q + "_val |-> s_eventually(" + q + "_rdy));\n") 722 | prop.write("end\n\n") 723 | 724 | key = "p_trans_id"; keyq = "q_trans_id" 725 | if key in entry and keyq in entry: 726 | name_tid = name + "_" +entry[key][0] 727 | p_trans_id = p + "_" + entry[key][0] 728 | q_trans_id = q + "_" + entry[keyq][0] 729 | symb_name = "symb_" + p_trans_id 730 | 731 | if (verbose): print("GenIN Trans:" + p_trans_id) 732 | prop.write("// Generate sampling signals and model\n") 733 | count = 1 734 | if not "unique" in key: 735 | count = 3 #count_log-1 736 | gen_iface_sampled(prop, name_tid, p, q, p_trans_id, q_trans_id, symb_name, entry, count,size) 737 | 738 | # Generate Stability Assumptions 739 | # If stable then assume payload is stable and valid is non-dropping 740 | if p != handshakes[p] and "p_stable" in entry: 741 | prop.write("// Assume payload is stable and valid is non-dropping\n") 742 | prop.write("if (ASSERT_INPUTS) begin\n") 743 | prop.write("\tas__" + name_tid + "_stability: assert property (" + p + "_val && !" + handshakes[p] + " |=> "+ p +"_val && $stable(" + p + "_" + entry["p_stable"] + ") );\n") 744 | prop.write("end else begin\n") 745 | prop.write("\tam__" + name_tid + "_stability: assume property (" + p + "_val && !" + handshakes[p] + " |=> "+ p +"_val && $stable(" + p + "_" + entry["p_stable"] + ") );\n") 746 | prop.write("end\n\n") 747 | 748 | # Otherwise assert that if valid eventually ready or dropped valid 749 | if p != handshakes[p]: 750 | prop.write("// Assert that if valid eventually ready or dropped valid\n") 751 | prop.write("as__" + name_tid + "_hsk_or_drop: assert property (" + p + "_val |-> s_eventually(!" + p + "_val || "+handshakes[p]+"));\n") 752 | # Assert liveness! 753 | prop.write("// Assert that every request has a response and that every reponse has a request\n") 754 | prop.write("as__" + name_tid + "_eventual_response: assert property (|" + name_tid + "_sampled |-> s_eventually(" + q + "_val") 755 | if size != "'0": prop.write(" && (" + q_trans_id + " == " + symb_name + ") ));\n") 756 | else: prop.write("));\n") 757 | prop.write("as__" + name_tid + "_was_a_request: assert property (" + name_tid + "_response |-> "+name_tid+"_set || "+name_tid+"_sampled);\n\n") 758 | if "p_data" in entry and "q_data" in entry: 759 | p_trans_id = p + "_" + entry["p_id"] 760 | q_trans_id = q + "_" + entry["q_id"] 761 | name_tid = name + "_" + entry["p_id"] 762 | p_data = p + "_" + entry["p_data"] 763 | q_data = q + "_" + entry["q_data"] 764 | symb_name = "symb_" + p_trans_id 765 | data_integrity(prop, name_tid, p, q, p_trans_id, q_trans_id, p_data, q_data, symb_name, size) 766 | 767 | def gen_iface_sampled (prop, name, p, q, p_trans_id, q_trans_id, symb_name, entry, count,size): 768 | prop.write("reg ["+str(count)+":0] " + name + "_sampled;\n") 769 | prop.write("wire " + name + "_set = " + p + "_hsk") 770 | if size != "'0": prop.write(" && " + p_trans_id + " == " + symb_name + ";\n") 771 | else: prop.write(";\n") 772 | prop.write("wire " + name + "_response = " + q + "_hsk") 773 | if size != "'0": prop.write(" && " + q_trans_id + " == " + symb_name + ";\n\n") 774 | else: prop.write(";\n\n") 775 | 776 | prop.write("always_ff @(posedge " + clk_sig + ") begin\n") 777 | prop.write("\tif(" + get_reset() + ") begin\n") 778 | prop.write("\t\t" + name + "_sampled <= '0;\n") 779 | prop.write("\tend else if (" + name + "_set || "+ name + "_response ) begin\n") 780 | prop.write("\t\t"+name+"_sampled <= "+name+"_sampled + "+name+"_set - "+name+"_response;\n") 781 | prop.write("\tend\n") 782 | prop.write("end\n") 783 | # do not create sampled cover if it's never going to be sampled 784 | p_rdy = p+"_rdy"; 785 | p_val = q+"_val" 786 | if not ((p_rdy in assign_wires) and (p_val in assign_wires) and (assign_wires[p_rdy] == assign_wires[p_val]) ): 787 | prop.write("co__" + name + "_sampled: cover property (|" + name + "_sampled);\n") 788 | if count > 0: # When not unique assume that this sampling structure would not overflow 789 | prop.write("if (ASSERT_INPUTS) begin\n") 790 | prop.write("\tas__" + name + "_sample_no_overflow: assert property ("+name+"_sampled != '1 || !"+name+"_set);\n") 791 | prop.write("end else begin\n") 792 | prop.write("\tam__" + name + "_sample_no_overflow: assume property ("+name+"_sampled != '1 || !"+name+"_set);\n") 793 | prop.write("end\n\n") 794 | 795 | if "active" in entry: 796 | prop.write("as__" + name + "_active: assert property (" + name + "_sampled > 0 |-> "+entry["active"]+");\n\n") 797 | else: 798 | prop.write("\n") 799 | 800 | def data_integrity(prop, name, p, q, p_trans_id, q_trans_id, p_data, q_data, symb_name, size): 801 | size_p = signals[p_data]["size"] 802 | 803 | prop.write("\n// Modeling data integrity for " + name + "\n") 804 | prop.write("reg [" + size_p + ":0] " + name + "_data_model;\n") 805 | prop.write("always_ff @(posedge " + clk_sig + ") begin\n") 806 | prop.write("\tif(" + get_reset() + ") begin\n") 807 | prop.write("\t\t" + name + "_data_model <= '0;\n") 808 | prop.write("\tend else if (" + name + "_set) begin\n") 809 | prop.write("\t\t" + name + "_data_model <= " + p_data + ";\n") 810 | prop.write("\tend\n") 811 | prop.write("end\n\n") 812 | prop.write("as__" + name + "_data_unique: assert property (|" + name + "_sampled |-> !"+name+"_set);\n") 813 | prop.write("as__" + name + "_data_integrity: assert property (|" + name + "_sampled && "+name+"_response "); 814 | prop.write("|-> (" + q_data + " == " + name + "_data_model));\n\n"); 815 | 816 | def gen_out(prop, name, entry): 817 | p = entry["p"] 818 | q = entry["q"] 819 | size = entry["size"] 820 | p_trans_id = p + "_" + entry["p_id"] 821 | q_trans_id = q + "_" + entry["q_id"] 822 | p_data = None 823 | if "p_data" in entry and "q_data" in entry: 824 | p_data = p + "_" + entry["p_data"] 825 | q_data = q + "_" + entry["q_data"] 826 | size_p = signals[p_data]["size"] 827 | 828 | symb_name = "symb_" + p_trans_id 829 | if (size == "'0"): 830 | power_size = "1" 831 | else: 832 | power_size = "2**("+ size + "+1)" 833 | prop.write("// Modeling outstanding request for " + name + "\n") 834 | prop.write("reg [" + power_size + "-1:0] " + name + "_outstanding_req_r;\n") 835 | if p_data: 836 | prop.write("reg [" + power_size + "-1:0]["+size_p+":0] " + name + "_outstanding_req_data_r;\n") 837 | prop.write("\n") 838 | prop.write("always_ff @(posedge " + clk_sig + ") begin\n") 839 | prop.write("\tif(" + get_reset() + ") begin\n") 840 | prop.write("\t\t" + name + "_outstanding_req_r <= '0;\n") 841 | prop.write("\tend else begin\n") 842 | prop.write("\t\tif (" + p + "_hsk) begin\n") 843 | if size == "'0": 844 | prop.write("\t\t\t" + name + "_outstanding_req_r <= 1'b1;\n") 845 | else: 846 | prop.write("\t\t\t" + name + "_outstanding_req_r[" + p_trans_id + "] <= 1'b1;\n") 847 | if p_data: 848 | if size == "'0": 849 | prop.write("\t\t\t" + name + "_outstanding_req_data_r <= "+p_data+";\n") 850 | else: 851 | prop.write("\t\t\t" + name + "_outstanding_req_data_r[" + p_trans_id + "] <= "+p_data+";\n") 852 | prop.write("\t\tend\n") 853 | prop.write("\t\tif (" + q + "_hsk) begin\n") 854 | if size == "'0": 855 | prop.write("\t\t\t" + name + "_outstanding_req_r <= 1'b0;\n") 856 | else: 857 | prop.write("\t\t\t" + name + "_outstanding_req_r[" + q_trans_id + "] <= 1'b0;\n") 858 | prop.write("\t\tend\n") 859 | prop.write("\tend\n") 860 | prop.write("end\n") 861 | prop.write("\n") 862 | if "active" in entry: 863 | prop.write("as__" + name + "_active: assert property (|" + name + "_outstanding_req_r |-> "+entry["active"]+");\n\n") 864 | else: 865 | prop.write("\n") 866 | 867 | prop.write("generate\n") 868 | # First Assertion (if macro defined) 869 | prop.write("if (ASSERT_INPUTS) begin : " + name+ "_gen\n") 870 | if size == "'0": 871 | prop.write("\tas__" + name + "1: assert property (!" + name + "_outstanding_req_r |-> !(" + q + "_hsk));\n") 872 | else: 873 | prop.write("\tas__" + name + "1: assert property (!" + name + "_outstanding_req_r[" + symb_name + "] ") 874 | prop.write("|-> !(" + q + "_hsk && (" + q_trans_id + " == " + symb_name + ")));\n") 875 | 876 | # Second assertion 877 | if size == "'0": 878 | prop.write("\tas__" + name + "2: assert property (" + name + "_outstanding_req_r |-> s_eventually(" + q + "_hsk") 879 | else: 880 | prop.write("\tas__" + name + "2: assert property (" + name + "_outstanding_req_r[" + symb_name + "] ") 881 | prop.write("|-> s_eventually(" + q + "_hsk && (" + q_trans_id + " == " + symb_name + ")") 882 | if p_data: 883 | if size == "'0": 884 | prop.write("&&\n\t (" + q_data + " == " + name + "_outstanding_req_data_r) ));\n") 885 | else: 886 | prop.write("&&\n\t (" + q_data + " == " + name + "_outstanding_req_data_r[" + symb_name + "]) ));\n") 887 | else: 888 | prop.write("));\n") 889 | prop.write("end else begin : " + name+ "_else_gen\n") 890 | 891 | if p != handshakes[p]: 892 | prop.write("\tam__" + name + "_fairness: assume property (" + p + "_val |-> s_eventually(" + p + "_rdy));\n") 893 | prop.write("\tfor ( j = 0; j < " + power_size + "; j = j + 1) begin : " + name+ "_for_gen\n") 894 | prop.write("\t\tco__" + name + ": cover property (" + name + "_outstanding_req_r[j]);\n") 895 | # First Assertion 896 | prop.write("\t\tam__" + name + "1: assume property (!" + name + "_outstanding_req_r[j] ") 897 | if size == "'0": 898 | prop.write("|-> !(" + q + "_val));\n") 899 | else: 900 | prop.write("|-> !(" + q + "_val && (" + q_trans_id + " == j)));\n") 901 | 902 | # Second Assertion 903 | prop.write("\t\tam__" + name + "2: assume property (" + name + "_outstanding_req_r[j] ") 904 | if size == "'0": 905 | prop.write("|-> s_eventually(" + q + "_val") 906 | else: 907 | prop.write("|-> s_eventually(" + q + "_val && (" + q_trans_id + " == j)") 908 | if p_data: 909 | prop.write("&&\n\t (" + q_data + " == " + name + "_outstanding_req_data_r[j]) ));\n") 910 | else: 911 | prop.write("));\n") 912 | prop.write("\tend\n") 913 | prop.write("end\n") 914 | prop.write("endgenerate\n") 915 | prop.write("\n") 916 | 917 | def gen_unique(prop, name, entry, p_key, q_key): 918 | p = entry["p"] 919 | q = entry["q"] 920 | p_trans_id = p + "_" + p_key[0] 921 | q_trans_id = q + "_" + q_key[0] 922 | size = p_key[1] 923 | symb_name = "symb_" + p_trans_id 924 | power_size = "2**("+ size + "+1)" 925 | prop.write("// Max 1 outstanding request for " + name + "\n") 926 | prop.write("reg [" + power_size + "-1:0] " + name + "_unique_outstanding_req_r;\n") 927 | prop.write("wire " + name + "_equal = " + p_trans_id + " == " + q_trans_id + ";\n") 928 | prop.write("\n") 929 | prop.write("always_ff @(posedge " + clk_sig + ") begin\n") 930 | prop.write("\tif(" + get_reset() + ") begin\n") 931 | prop.write("\t\t" + name + "_unique_outstanding_req_r <= '0;\n") 932 | prop.write("\tend else begin\n") 933 | prop.write("\t\tif (" + p + "_hsk) begin\n") 934 | 935 | prop.write("\t\t\t" + name + "_unique_outstanding_req_r[" + p_trans_id + "] <= 1'b1;\n") 936 | prop.write("\t\tend\n") 937 | prop.write("\t\tif (" + q + "_hsk) begin\n") 938 | prop.write("\t\t\t" + name + "_unique_outstanding_req_r[" + q_trans_id + "] <= 1'b0;\n") 939 | prop.write("\t\tend\n") 940 | prop.write("\tend\n") 941 | prop.write("end\n") 942 | prop.write("\n") 943 | 944 | prop.write("generate\n") 945 | prop.write("if (ASSERT_INPUTS) begin : " + name+ "_gen\n") 946 | prop.write("\tas__" + name + "_unique: assert property (" + name + "_unique_outstanding_req_r[" + symb_name + "] ") 947 | prop.write("|-> !(" + p + "_hsk && (" + p_trans_id + " == " + symb_name + ")));\n") 948 | prop.write("end else begin : " + name+ "_else_gen\n") 949 | prop.write("\tfor ( j = 0; j < " + power_size + "; j = j + 1) begin : " + name+ "_for_gen\n") 950 | prop.write("\t\tam__" + name + "_unique: assume property (" + name + "_unique_outstanding_req_r[j] ") 951 | prop.write("|-> !(" + p + "_val && (" + p_trans_id + " == j)));\n") 952 | prop.write("\tend\n") 953 | prop.write("end\n") 954 | prop.write("endgenerate\n") 955 | prop.write("\n") 956 | 957 | prop.write("as__" + name + "_unique1: assert property(" + name + "_unique_outstanding_req_r[" + symb_name + "] ") 958 | prop.write("|-> s_eventually(" + q + "_hsk && (" + q_trans_id + " == " + symb_name + ")));\n") 959 | prop.write("\n") 960 | 961 | def link_submodules(submodule_assert,submodule_assume): 962 | files = [] 963 | # Add binding of submodules 964 | base = os.getcwd()+"/ft_" 965 | basev = "${AUTOCC_ROOT}/ft_" 966 | for sub_name in submodule_assume: 967 | file_prop = sub_name+"/sva/"+sub_name+"_prop.sv" 968 | file_bind = sub_name+"/sva/"+sub_name+"_bind.svh" 969 | if os.path.exists(base+file_prop) and os.path.exists(base+file_bind): 970 | files.append(basev+file_prop+"\n") 971 | files.append(basev+file_bind+"\n") 972 | for sub_name in submodule_assert: 973 | file_prop = sub_name+"/sva/"+sub_name+"_prop.sv" 974 | file_bind = sub_name+"/sva/"+sub_name+"_bind.svh" 975 | if os.path.exists(base+file_prop) and os.path.exists(base+file_bind): 976 | files.append(basev+file_prop+"\n") 977 | new_bind = dut_name+"/sva/"+sub_name+"_bind.svh" 978 | files.append(basev+new_bind+"\n") 979 | # Write the new binding file from the old one 980 | old_bind_file = open(base+file_bind, "r") 981 | new_bind_file = open(base+new_bind, "w+") 982 | for line in old_bind_file: 983 | line = line.replace("INPUTS (0)", "INPUTS (1)") 984 | new_bind_file.write(line) 985 | old_bind_file.close() 986 | new_bind_file.close() 987 | return files 988 | 989 | def gen_tcl(dut_root,ft_path, dut_folder, src_list, include, dut_name, dut_name_ext, submodule_assert, submodule_assume): 990 | global clk_sig, rst_sig 991 | sub_filename = ft_path + "manual_sub.vc" 992 | vc_filename = ft_path + "files.vc" 993 | tcl_filename = ft_path + "FPV.tcl" 994 | 995 | if (not os.path.exists(tcl_filename) or override_tool_script): 996 | tcl = open(tcl_filename, "w+") 997 | tcl.write("# Set paths to DUT root and FT root (edit if needed)\n") 998 | #tcl.write("set DUT_ROOT "+dut_root+"\n") 999 | tcl.write("set DUT_ROOT $env(DUT_ROOT)\n") 1000 | #tcl.write("set AUTOCC_ROOT "+ft_path+"..\n\n") 1001 | tcl.write("set AUTOCC_ROOT $env(AUTOCC_ROOT)\n\n") 1002 | tcl.write("# Analyze design under verification files (do not edit)\n") 1003 | tcl.write("set DUT_PATH ${DUT_ROOT}/"+dut_folder+"\n") 1004 | if src_list: 1005 | index = 0 1006 | for src_folder in src_list: 1007 | tcl.write("set SRC_PATH"+str(index)+" ${DUT_ROOT}/"+src_folder+"\n") 1008 | index+=1 1009 | if include: tcl.write("set INC_PATH ${DUT_ROOT}/"+include+"\n") 1010 | tcl.write("set PROP_PATH ${AUTOCC_ROOT}/ft_"+dut_name+"/sva\n\n") 1011 | tcl.write("set_elaborate_single_run_mode off\n") 1012 | tcl.write("# Analyze property files\n") 1013 | tcl.write("analyze -clear\n") 1014 | tcl.write("analyze -sv12 -f ${AUTOCC_ROOT}/ft_"+dut_name+"/files.vc\n") 1015 | tcl.write("# Elaborate design and properties\n") 1016 | if tool_mode.startswith("autocc"): 1017 | top_module = dut_name+"_wrap" 1018 | else: 1019 | top_module = dut_name 1020 | tcl.write("elaborate -top " + top_module) 1021 | tcl.write("\n# Set up Clocks and Resets\n") 1022 | tcl.write("clock "+clk_sig+"\n") 1023 | tcl.write("reset -expression ("+get_reset()+")\n\n") 1024 | tcl.write("set_prove_time_limit 72h\n\n") 1025 | tcl.write("autoprove -all -bg\n") 1026 | tcl.close() 1027 | 1028 | if not os.path.exists(sub_filename): 1029 | vc = open(sub_filename, "w+") 1030 | vc.write("// Add here defines if needed\n +define+\n") 1031 | vc.write("// Add here further dependencies not captured automatically\n") 1032 | vc.write("//${INC_PATH}/pkg.sv\n") 1033 | vc.write("//${SRC_PATH}/submodule.sv\n") 1034 | vc.write("//${DUT_PATH}/submodule.sv\n") 1035 | vc.write("\n// Or blackbox modules like\n") 1036 | vc.write("//-bbox_m submodule\n") 1037 | vc.write("\n// Or add Macros like\n") 1038 | vc.write("//+define+XPROP=1\n") 1039 | 1040 | if (not os.path.exists(vc_filename) or override_tool_script): 1041 | vc = open(vc_filename, "w+") 1042 | vc.write("+libext+.v\n") 1043 | vc.write("+libext+.h\n") 1044 | vc.write("+libext+.sv\n") 1045 | vc.write("+libext+.tmp.v\n") 1046 | vc.write("+librescan\n") 1047 | 1048 | vc.write("+incdir+${DUT_PATH}\n") 1049 | vc.write("-y ${DUT_PATH}\n") 1050 | if src_list: 1051 | index = 0 1052 | for src_folder in src_list: 1053 | string = "SRC_PATH"+str(index) 1054 | index+=1 1055 | vc.write("+incdir+${"+string+"}\n") 1056 | vc.write("-y ${"+string+"}\n") 1057 | for root, subdirs, files in os.walk(src_folder): 1058 | if (verbose): print("--"+string+" = " + root) 1059 | vc.write("-y "+root+"\n") 1060 | 1061 | if include: 1062 | vc.write("+incdir+${INC_PATH}\n") 1063 | vc.write("-y ${INC_PATH}\n") 1064 | vc.write("${INC_PATH}\n") 1065 | vc.write("-f ${PROP_PATH}/../manual_sub.vc\n") 1066 | vc.write("${PROP_PATH}/"+ dut_name + "_prop.sv\n") 1067 | vc.write("${PROP_PATH}/"+ dut_name + "_bind.svh\n") 1068 | 1069 | for line in link_submodules(submodule_assert,submodule_assume): 1070 | vc.write(line) 1071 | vc.write("${DUT_ROOT}/"+dut_folder+ dut_name+"."+dut_name_ext.split(".")[1]+"\n"); 1072 | if tool_mode.startswith("autocc"): 1073 | vc.write("${DUT_ROOT}/"+dut_folder+ dut_name+"_wrap.sv\n"); 1074 | vc.close() 1075 | 1076 | def gen_sby(dut_root, ft_path, dut_folder, src_list, include, dut_name, dut_name_ext, submodule_assert, submodule_assume): 1077 | global clk_sig, rst_sig 1078 | sby_filename = ft_path + "FPV.sby" 1079 | sva_path = ft_path+"sva" 1080 | 1081 | if (not os.path.exists(sby_filename)): 1082 | sby = open(sby_filename, "w+") 1083 | sby.write("[tasks]\n") 1084 | sby.write("cvr\n") 1085 | sby.write("prv\n") 1086 | #sby.write("live\n\n") 1087 | sby.write("[options]\n") 1088 | sby.write("cvr: mode cover\n") 1089 | sby.write("prv: mode prove\n") 1090 | #sby.write("live: mode live\n") 1091 | #sby.write("depth 100\n\n") 1092 | sby.write("[engines]\n") 1093 | sby.write("cvr: smtbmc z3\n") 1094 | sby.write("prv: abc pdr\n") 1095 | #sby.write("live: aiger suprove\n\n") 1096 | sby.write("[script]\n") 1097 | sby.write("read -verific\n"); 1098 | # Link submodule property and bind files 1099 | link_files = link_submodules(submodule_assert,submodule_assume) 1100 | for line in link_files: 1101 | strings = line.split("/") 1102 | sby.write("read -sv "+strings[len(strings)-1]) 1103 | # Add other file dependencies 1104 | if not recursive: 1105 | # Only explicitely add the DUT top when it will not be added in the recursive search 1106 | dut_full_name = dut_name+"."+dut_name_ext.split(".")[1] 1107 | sby.write("read -sv "+dut_full_name+"\n"); 1108 | else: 1109 | file_list = [] 1110 | read_list = [] 1111 | if src_list: src_list.append(dut_folder) 1112 | else: src_list = [dut_folder] 1113 | if include: 1114 | src_list.insert(0, include) 1115 | for src_folder in src_list: 1116 | abs_path = dut_root+"/"+src_folder 1117 | len_dut_root = len(dut_root) 1118 | print(abs_path) 1119 | for root, subdirs, files in os.walk(abs_path): 1120 | rel_path = "$DUT_ROOT"+root[len_dut_root:] 1121 | if (verbose): print("--"+src_folder+" = " + rel_path) 1122 | for name in files: 1123 | if name.endswith(".sv") or name.endswith(".v"): 1124 | file_list.append(rel_path+"/"+name) 1125 | read_list.append(name) 1126 | for filename in read_list: sby.write("read -sv "+filename+"\n") 1127 | 1128 | sby.write("read -sv "+dut_name+"_prop.sv\n") 1129 | sby.write("read -sv "+dut_name+"_bind.svh\n") 1130 | sby.write("prep -top "+dut_name+"\n\n"); 1131 | sby.write("[files]\n") 1132 | 1133 | for line in link_files: 1134 | sby.write(line) 1135 | sby.write("$AUTOCC_ROOT/ft_"+dut_name+"/sva/"+ dut_name + "_prop.sv\n") 1136 | sby.write("$AUTOCC_ROOT/ft_"+dut_name+"/sva/"+ dut_name + "_bind.svh\n") 1137 | if not recursive: 1138 | # No need to explicitely add the DUT top since it will be added in the recursive search 1139 | sby.write("$DUT_ROOT/"+dut_folder+dut_full_name+"\n"); 1140 | else: 1141 | for filename in file_list: sby.write(filename+"\n") 1142 | sby.close() 1143 | 1144 | def parse_former_prop(prop, prop_backup): 1145 | former_sva = [] 1146 | save = False 1147 | for orig_line in prop: 1148 | prop_backup.write(orig_line) 1149 | if (not save): 1150 | line = clean(orig_line) 1151 | if line.startswith("//====DESIGNER-ADDED-SVA====//"): 1152 | save = True 1153 | else: 1154 | former_sva.append(orig_line) 1155 | if (verbose): print("Saving former designer SVA: " + orig_line) 1156 | return former_sva 1157 | 1158 | 1159 | def main(): 1160 | # Variable declaration 1161 | global verbose, prop_filename_backup 1162 | former_sva = ["endmodule"] 1163 | 1164 | # Extract arguments 1165 | args = parse_args() 1166 | verbose = args.verbose 1167 | src_list = args.source 1168 | include = args.include 1169 | tool_mode = args.mode 1170 | submodule_assert = args.submodule_assert 1171 | submodule_assume = args.submodule_assume 1172 | dut_folder = args.filename 1173 | xprop = args.xprop_macro 1174 | tool = args.tool 1175 | # Get absolute Paths 1176 | dut_root = os.getenv('DUT_ROOT') 1177 | if not dut_root: 1178 | print("You must define DUT_ROOT") 1179 | sys.exit(1) 1180 | autocc_root = os.getenv('AUTOCC_ROOT') 1181 | if not autocc_root: 1182 | print("You must define AUTOCC_ROOT") 1183 | sys.exit(1) 1184 | dut_path = os.path.abspath(dut_root+"/"+dut_folder) 1185 | 1186 | 1187 | # Parse DUT folder and name 1188 | dut_name = os.path.basename(dut_path).split(".")[0] 1189 | # Create FT folder and SVA folder inside it 1190 | ft_path = os.getcwd()+"/ft_"+dut_name+"/" 1191 | sva_path = ft_path + "sva/" 1192 | 1193 | # Property and Bind files 1194 | prop_filename = sva_path + dut_name + "_prop.sv" 1195 | prop_filename_backup = sva_path + dut_name + "_prop_old.sv" 1196 | bind_filename = sva_path + dut_name + "_bind.svh" 1197 | 1198 | create_dir(ft_path) 1199 | create_dir(sva_path) 1200 | dut_folder = dut_folder.split(".")[0] 1201 | dut_folder = dut_folder[0:-len(dut_name)] 1202 | 1203 | if (os.path.exists(prop_filename)): 1204 | #extract handwritten properties to the previous prop file 1205 | prop_old = open(prop_filename, "r+") 1206 | prop_backup = open(prop_filename_backup, "w+") 1207 | former_sva = parse_former_prop(prop_old, prop_backup) 1208 | prop_old.close() 1209 | prop_backup.close() 1210 | 1211 | # Open files RTL, Bind, Property files 1212 | rtl = open(dut_path, "r+") 1213 | prop = open(prop_filename, "w+") 1214 | bind = open(bind_filename, "w+") 1215 | 1216 | # Parse header file and generate SVA 1217 | parse_global(rtl, prop, bind) 1218 | gen_vars(tool,prop) 1219 | gen_models(prop) 1220 | 1221 | if tool_mode.startswith("autocc"): 1222 | rtl = open(dut_path, "r+") 1223 | wrap = open(dut_root+"/"+ dut_name + "_wrap.sv", "w+") 1224 | create_wrapper(rtl, wrap) 1225 | rtl.close() 1226 | 1227 | if tool_mode != "autocc_only_wrap": 1228 | # Add the new write assignments 1229 | for key in assign_wires: 1230 | prop.write("assign "+key+" = "+assign_wires[key]+"\n") 1231 | #define macro for simulation if needed 1232 | if (xprop): 1233 | prop.write("\n//X PROPAGATION ASSERTIONS\n") 1234 | if xprop != "NONE": 1235 | prop.write("`ifdef "+xprop+"\n") 1236 | for iface_name in suffixes: 1237 | valid_name = iface_name+"_val" 1238 | prop.write("\t as__no_x_"+valid_name+": assert property(!$isunknown("+valid_name+"));\n") 1239 | iface_list = suffixes[iface_name] 1240 | for suffix in iface_list: 1241 | signal_name = iface_name+"_"+suffix 1242 | prop.write("\t as__no_x_"+signal_name+": assert property("+valid_name+" |-> !$isunknown("+signal_name+"));\n") 1243 | if xprop != "NONE": 1244 | prop.write("`endif\n") 1245 | 1246 | prop.write("\n//====DESIGNER-ADDED-SVA====//\n") 1247 | 1248 | # Add handwritten SVA properties extracted from old version of prop file 1249 | num_lines = 0 1250 | for line in former_sva: 1251 | prop.write(line) 1252 | num_lines += 1 1253 | 1254 | if (num_lines == 0) and (tool_mode=="autocc"): 1255 | prop.write("wire architectural_state_eq = 1'b1;\n") 1256 | 1257 | 1258 | # Close RTL and Property files 1259 | rtl.close() 1260 | prop.close() 1261 | 1262 | # Write VC (path file) and TCL (command file) 1263 | if tool == "sby": 1264 | gen_sby(dut_root, ft_path, dut_folder, src_list, include, dut_name, dut_path, submodule_assert, submodule_assume) 1265 | else: 1266 | gen_tcl(dut_root,ft_path, dut_folder, src_list, include, dut_name, dut_path, submodule_assert, submodule_assume) 1267 | 1268 | print("\nSUCCESS!\nYou can now run the following command to start the formal verification:") 1269 | print("jg ft_"+dut_name+"/FPV.tcl\n") 1270 | main() -------------------------------------------------------------------------------- /fixes/VSCALE_CEX_FIX: -------------------------------------------------------------------------------- 1 | 2 | am__csr6: assume property (spy_mode |-> u_vscale_core.pipeline.htif_pcr_req_ready == u_vscale_core2.pipeline.htif_pcr_req_ready); 3 | am__csr7: assume property (spy_mode |-> u_vscale_core.pipeline.htif_pcr_resp_valid == u_vscale_core2.pipeline.htif_pcr_resp_valid); 4 | am__csr8: assume property (spy_mode |-> u_vscale_core.pipeline.htif_pcr_resp_data == u_vscale_core2.pipeline.htif_pcr_resp_data); 5 | 6 | //If we blackbox a module, we can assume outputs are equal after flush. Assert that that inputs are equal. 7 | //Basically treat these blackboxed module as outside the DUT! 8 | am__csr1: assume property (spy_mode |-> u_vscale_core.pipeline.prv == u_vscale_core2.pipeline.prv); 9 | am__csr2: assume property (spy_mode |-> u_vscale_core.pipeline.illegal_csr_access == u_vscale_core2.pipeline.illegal_csr_access); 10 | am__csr3: assume property (spy_mode |-> u_vscale_core.pipeline.csr_rdata == u_vscale_core2.pipeline.csr_rdata); 11 | am__csr4: assume property (spy_mode |-> u_vscale_core.pipeline.handler_PC == u_vscale_core2.pipeline.handler_PC); 12 | am__csr5: assume property (spy_mode |-> u_vscale_core.pipeline.epc == u_vscale_core2.pipeline.epc); 13 | 14 | wire csr_equal = (u_vscale_core.pipeline.prv == u_vscale_core2.pipeline.prv) && 15 | (u_vscale_core.pipeline.illegal_csr_access == u_vscale_core2.pipeline.illegal_csr_access) && 16 | (u_vscale_core.pipeline.csr_rdata == u_vscale_core2.pipeline.csr_rdata) && 17 | (u_vscale_core.pipeline.handler_PC == u_vscale_core2.pipeline.handler_PC) && 18 | (u_vscale_core.pipeline.epc == u_vscale_core2.pipeline.epc); 19 | 20 | wire reg_file_same = (u_vscale_core.pipeline.regfile.data == u_vscale_core2.pipeline.regfile.data); 21 | wire PC_equal = (u_vscale_core.pipeline.PC_PIF == u_vscale_core2.pipeline.PC_PIF) && 22 | (u_vscale_core.pipeline.PC_IF == u_vscale_core2.pipeline.PC_IF) && 23 | (u_vscale_core.pipeline.PC_DX == u_vscale_core2.pipeline.PC_DX) && 24 | (u_vscale_core.pipeline.PC_WB == u_vscale_core2.pipeline.PC_WB); 25 | 26 | wire dx_stage = u_vscale_core.pipeline.rs1_data == u_vscale_core2.pipeline.rs1_data && 27 | u_vscale_core.pipeline.inst_DX == u_vscale_core2.pipeline.inst_DX; 28 | wire writeback = !u_vscale_core.pipeline.stall_WB && !u_vscale_core2.pipeline.stall_WB; 29 | 30 | assign architectural_state_eq = reg_file_same && csr_equal && PC_equal && dx_stage && writeback; 31 | 32 | endmodule -------------------------------------------------------------------------------- /fixes/fix_combo_loop_vscale_rtl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Define the directories 5 | DIR=$DUT_ROOT 6 | 7 | # Define the filename 8 | FILENAME=vscale_ctrl.v 9 | 10 | # Define the old and new lines 11 | OLD_LINE='|| (fence_i && store_in_WB) || (uses_md && !md_req_ready);' 12 | NEW_LINES='|| (fence_i && store_in_WB) || (uses_md_unkilled && !md_req_ready)\n|| (dmem_en_unkilled && dmem_wait);' 13 | 14 | # Escape ampersand characters 15 | OLD_LINE=$(echo "$OLD_LINE" | sed 's/&/\\&/g') 16 | NEW_LINES=$(echo "$NEW_LINES" | sed 's/&/\\&/g') 17 | 18 | # Replace the old line with new lines in the file in DIR 19 | sed -i "s#${OLD_LINE}#${NEW_LINES}#g" "$DIR/$FILENAME" 20 | 21 | echo "The file $FILENAME in $DIR has been updated." 22 | -------------------------------------------------------------------------------- /fixes/fix_underconstrain_vscale.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check that $AUTOCC_ROOT is set 4 | if [ -z "$AUTOCC_ROOT" ]; then 5 | echo "ERROR: \$AUTOCC_ROOT is not set" 6 | exit 1 7 | fi 8 | 9 | # Check if the last two lines of the file $AUTOCC_ROOT/ft_vscale_core/sva/vscale_core_prop.sv are : //====DESIGNER-ADDED-SVA====// endmodule 10 | # If not, add them 11 | tail -n 3 $AUTOCC_ROOT/ft_vscale_core/sva/vscale_core_prop.sv | grep "====DESIGNER-ADDED-SVA====" 12 | if [ $? -ne 0 ]; then 13 | echo "NOTHING TO DO, PROPERTIES ALREADY ADDED" 14 | else 15 | sed -i '$d' $AUTOCC_ROOT/ft_vscale_core/sva/vscale_core_prop.sv 16 | cat $AUTOCC_ROOT/fixes/VSCALE_CEX_FIX >> $AUTOCC_ROOT/ft_vscale_core/sva/vscale_core_prop.sv 17 | echo "PROPERTIES ADDED" 18 | fi -------------------------------------------------------------------------------- /ft_aes/FPV.tcl: -------------------------------------------------------------------------------- 1 | # Set paths to DUT root and FT root (edit if needed) 2 | set AUTOCC_ROOT $env(AUTOCC_ROOT) 3 | set DUT_ROOT ${AUTOCC_ROOT}/aes 4 | 5 | # Analyze design under verification files (no edit) 6 | set DUT_PATH ${DUT_ROOT}/ 7 | set PROP_PATH ${AUTOCC_ROOT}/ft_aes/sva 8 | 9 | set_elaborate_single_run_mode off 10 | 11 | # Analyze property files 12 | analyze -clear 13 | analyze -sv12 -f ${AUTOCC_ROOT}/ft_aes/files.vc 14 | 15 | # Elaborate design and properties 16 | elaborate -top aes_wrap 17 | 18 | # Set up Clocks and Resets 19 | clock clk 20 | reset -expression (!reset_n) 21 | 22 | set_prove_time_limit 72h 23 | 24 | autoprove -all -bg 25 | -------------------------------------------------------------------------------- /ft_aes/files.vc: -------------------------------------------------------------------------------- 1 | +libext+.v 2 | +libext+.h 3 | +libext+.sv 4 | +libext+.tmp.v 5 | +librescan 6 | +incdir+${DUT_PATH} 7 | -y ${DUT_PATH} 8 | ${PROP_PATH}/aes_wrap_prop.sv 9 | ${PROP_PATH}/aes_wrap_bind.svh 10 | ${DUT_ROOT}/aes_wrap.v 11 | -------------------------------------------------------------------------------- /ft_aes/sva/aes_wrap_bind.svh: -------------------------------------------------------------------------------- 1 | bind aes_wrap aes_wrap_prop 2 | #( 3 | .DATA_W (DATA_W), 4 | .KEY_L (KEY_L), 5 | .NO_ROUNDS (NO_ROUNDS), 6 | .ASSERT_INPUTS (0) 7 | ) u_aes_wrap_sva(.*); -------------------------------------------------------------------------------- /ft_aes/sva/aes_wrap_prop.sv: -------------------------------------------------------------------------------- 1 | module aes_wrap_prop 2 | #( 3 | parameter ASSERT_INPUTS = 0, 4 | parameter DATA_W = 128, //data width 5 | parameter KEY_L = 128, //key length 6 | parameter NO_ROUNDS = 10 //number of rounds 7 | )( 8 | input clk, //system clock 9 | input reset_n, //asynch reset_n 10 | input flush, 11 | 12 | input data_valid_in, //data valid signal 13 | input cipherkey_valid_in, //cipher key valid signal 14 | input [KEY_L-1:0] cipher_key, //cipher key 15 | input [DATA_W-1:0] plain_text, //plain text 16 | input valid_out, //input valid signal //output 17 | input [DATA_W-1:0] cipher_text, //cipher text //output 18 | 19 | input data_valid_in2, //data valid signal 20 | input cipherkey_valid_in2, //cipher key valid signal 21 | input [KEY_L-1:0] cipher_key2, //cipher key 22 | input [DATA_W-1:0] plain_text2, //plain text 23 | input valid_out2, //input valid signal //output 24 | input [DATA_W-1:0] cipher_text2 //cipher text //output 25 | ); 26 | 27 | //============================================================================== 28 | // Local Parameters 29 | //============================================================================== 30 | 31 | genvar j; 32 | default clocking cb @(posedge clk); 33 | endclocking 34 | default disable iff (!reset_n); 35 | 36 | // Re-defined wires 37 | 38 | // Symbolics and Handshake signals 39 | 40 | //============================================================================== 41 | // Modeling 42 | //============================================================================== 43 | 44 | 45 | //====DESIGNER-ADDED-SVA====// 46 | 47 | wire architectural_state_eq = flush && aes_top.valid_round_data=='0 && aes_top2.valid_round_data=='0 && 48 | aes_top.valid_sub2shift=='0 && aes_top2.valid_sub2shift=='0 && 49 | aes_top.valid_shift2key=='0 && aes_top2.valid_shift2key=='0 && 50 | aes_top.ROUND[0].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[0].U_ROUND.valid_mix2key=='0 && 51 | aes_top.ROUND[0].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[0].U_ROUND.valid_sub2shift=='0 && 52 | aes_top.ROUND[0].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[0].U_ROUND.valid_shift2mix=='0 && 53 | aes_top.ROUND[1].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[1].U_ROUND.valid_mix2key=='0 && 54 | aes_top.ROUND[1].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[1].U_ROUND.valid_sub2shift=='0 && 55 | aes_top.ROUND[1].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[1].U_ROUND.valid_shift2mix=='0 && 56 | aes_top.ROUND[2].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[2].U_ROUND.valid_mix2key=='0 && 57 | aes_top.ROUND[2].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[2].U_ROUND.valid_sub2shift=='0 && 58 | aes_top.ROUND[2].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[2].U_ROUND.valid_shift2mix=='0 && 59 | aes_top.ROUND[3].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[3].U_ROUND.valid_mix2key=='0 && 60 | aes_top.ROUND[3].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[3].U_ROUND.valid_sub2shift=='0 && 61 | aes_top.ROUND[3].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[3].U_ROUND.valid_shift2mix=='0 && 62 | aes_top.ROUND[4].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[4].U_ROUND.valid_mix2key=='0 && 63 | aes_top.ROUND[4].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[4].U_ROUND.valid_sub2shift=='0 && 64 | aes_top.ROUND[4].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[4].U_ROUND.valid_shift2mix=='0 && 65 | aes_top.ROUND[5].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[5].U_ROUND.valid_mix2key=='0 && 66 | aes_top.ROUND[5].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[5].U_ROUND.valid_sub2shift=='0 && 67 | aes_top.ROUND[5].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[5].U_ROUND.valid_shift2mix=='0 && 68 | aes_top.ROUND[6].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[6].U_ROUND.valid_mix2key=='0 && 69 | aes_top.ROUND[6].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[6].U_ROUND.valid_sub2shift=='0 && 70 | aes_top.ROUND[6].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[6].U_ROUND.valid_shift2mix=='0 && 71 | aes_top.ROUND[7].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[7].U_ROUND.valid_mix2key=='0 && 72 | aes_top.ROUND[7].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[7].U_ROUND.valid_sub2shift=='0 && 73 | aes_top.ROUND[7].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[7].U_ROUND.valid_shift2mix=='0 && 74 | aes_top.ROUND[8].U_ROUND.valid_mix2key=='0 && aes_top2.ROUND[8].U_ROUND.valid_mix2key=='0 && 75 | aes_top.ROUND[8].U_ROUND.valid_sub2shift=='0 && aes_top2.ROUND[8].U_ROUND.valid_sub2shift=='0 && 76 | aes_top.ROUND[8].U_ROUND.valid_shift2mix=='0 && aes_top2.ROUND[8].U_ROUND.valid_shift2mix=='0 && 77 | aes_top.valid_shift2key_delayed=='0 && aes_top2.valid_shift2key_delayed=='0; 78 | 79 | wire io_equal = aes_top.valid_out=='0 && aes_top2.valid_out=='0 && aes_top.data_valid_in=='0 && aes_top2.data_valid_in=='0; 80 | 81 | wire transfer_cond = architectural_state_eq && io_equal; 82 | 83 | localparam THRESHOLD = 1; 84 | reg [$clog2(THRESHOLD):0] equal_cnt; 85 | wire spy_starts = transfer_cond && equal_cnt >= THRESHOLD; 86 | reg spy_mode; 87 | wire flush_done; //Set free by default (anytime) USER may set the conditions that indicate the flush has finished for both 88 | 89 | always_ff @(posedge clk) begin 90 | if (!reset_n) begin 91 | spy_mode <= '0; 92 | equal_cnt <= '0; 93 | end else begin 94 | spy_mode <= spy_starts || spy_mode; 95 | equal_cnt <= (flush_done || equal_cnt>0) && transfer_cond ? equal_cnt + 1 : '0; 96 | end 97 | end 98 | 99 | // Make sure that cores are making the same AXI requests after the flush. 100 | as__valid_out_same: assert property (spy_mode |-> (valid_out == valid_out2)); 101 | as__cipher_text_same: assert property (spy_mode && valid_out |-> (cipher_text == cipher_text2)); 102 | 103 | am__data_valid_in_same: assume property (spy_mode |-> (data_valid_in == data_valid_in2)); 104 | am__cipherkey_valid_in_same: assume property (spy_mode |-> (cipherkey_valid_in == cipherkey_valid_in2)); 105 | am__cipher_key_same: assume property (spy_mode |-> (cipher_key == cipher_key2)); 106 | am__plain_text_same: assume property (spy_mode |-> (plain_text == plain_text2)); 107 | 108 | endmodule -------------------------------------------------------------------------------- /ft_cva6/FPV.tcl: -------------------------------------------------------------------------------- 1 | # Set paths to DUT root and FT root (edit if needed) 2 | set AUTOCC_ROOT $env(AUTOCC_ROOT) 3 | set DUT_ROOT ${AUTOCC_ROOT}/cva6/core 4 | 5 | # Analyze design under verification files (no edit) 6 | set DUT_PATH ${DUT_ROOT}/ 7 | set SRC_PATH0 ${DUT_ROOT}/../corev_apu 8 | set SRC_PATH1 ${DUT_ROOT}/../common/local/util 9 | set SRC_PATH2 ${DUT_ROOT}/../vendor/pulp-platform/common_cells/src 10 | set SRC_PATH3 ${DUT_ROOT}/mmu_sv39 11 | set INC_PATH ${DUT_ROOT}/include 12 | set PROP_PATH ${AUTOCC_ROOT}/ft_cva6/sva 13 | 14 | set_elaborate_single_run_mode off 15 | 16 | # Analyze property files 17 | analyze -clear 18 | analyze -sv12 -f ${AUTOCC_ROOT}/ft_cva6/files.vc 19 | 20 | # Elaborate design and properties 21 | elaborate -top cva6_wrap 22 | 23 | # Set up Clocks and Resets 24 | clock clk_i 25 | reset -expression (!rst_ni) 26 | 27 | set_prove_time_limit 72h 28 | autoprove -all -bg 29 | report 30 | -------------------------------------------------------------------------------- /ft_cva6/files.vc: -------------------------------------------------------------------------------- 1 | +libext+.v 2 | +libext+.h 3 | +libext+.sv 4 | +libext+.tmp.v 5 | +librescan 6 | +incdir+${DUT_PATH} 7 | -y ${DUT_PATH} 8 | +incdir+${SRC_PATH0} 9 | -y ${SRC_PATH0} 10 | +incdir+${SRC_PATH1} 11 | -y ${SRC_PATH1} 12 | +incdir+${SRC_PATH2} 13 | -y ${SRC_PATH2} 14 | +incdir+${SRC_PATH3} 15 | -y ${SRC_PATH3} 16 | +incdir+${INC_PATH} 17 | -y ${INC_PATH} 18 | -f ${PROP_PATH}/../manual_sub.vc 19 | ${PROP_PATH}/cva6_prop.sv 20 | ${PROP_PATH}/cva6_bind.svh 21 | ${DUT_ROOT}/cva6.sv 22 | ${DUT_ROOT}/cva6_wrap.sv 23 | -------------------------------------------------------------------------------- /ft_cva6/manual_sub.vc: -------------------------------------------------------------------------------- 1 | +define+WT_DCACHE=1 2 | 3 | // Not needed for now 4 | -bbox_m perf_counters 5 | -bbox_m mult 6 | -bbox_m fpu_wrap 7 | -bbox_m csr_regfile 8 | 9 | ${DUT_PATH}/axi/src/axi_pkg.sv 10 | ${INC_PATH}/cv64a6_imafdc_sv39_config_pkg.sv 11 | ${INC_PATH}/riscv_pkg.sv 12 | ${INC_PATH}/ariane_dm_pkg.sv 13 | ${INC_PATH}/../../vendor/pulp-platform/axi/src/axi_pkg.sv 14 | ${INC_PATH}/../../vendor/pulp-platform/tech_cells_generic/src/rtl/tc_sram.sv 15 | ${INC_PATH}/ariane_pkg.sv 16 | ${INC_PATH}/ariane_rvfi_pkg.sv 17 | ${INC_PATH}/cvxif_pkg.sv 18 | 19 | ${INC_PATH}/../tb/ariane_soc_pkg.sv 20 | ${INC_PATH}/ariane_axi_pkg.sv 21 | ${DUT_PATH}/fpu/src/fpnew_pkg.sv 22 | ${SRC_PATH2}/cf_math_pkg.sv 23 | #${SRC_PATH2}/../../tech_cells_generic/src/rtl/tc_sram.sv 24 | ${SRC_PATH1}/sram.sv 25 | ${DUT_PATH}/ariane_regfile_ff.sv 26 | ${DUT_PATH}/pmp/src/pmp.sv 27 | ${DUT_PATH}/pmp/src/pmp_entry.sv 28 | -y ${DUT_PATH}/axi/include 29 | -y ${DUT_PATH}/cache_subsystem 30 | -y ${DUT_PATH}/frontend/ 31 | -y ${DUT_PATH}/register_interface/src/ 32 | ${INC_PATH}/std_cache_pkg.sv 33 | ${INC_PATH}/wt_cache_pkg.sv -------------------------------------------------------------------------------- /ft_cva6/sva/cva6_bind.svh: -------------------------------------------------------------------------------- 1 | bind cva6_wrap cva6_prop 2 | #( 3 | .ASSERT_INPUTS (0) 4 | ) u_cva6_sva(.*); -------------------------------------------------------------------------------- /ft_cva6/sva/cva6_prop.sv: -------------------------------------------------------------------------------- 1 | import ariane_pkg::*; 2 | module cva6_prop 3 | #( 4 | parameter ASSERT_INPUTS = 0, 5 | parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig, 6 | parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth, 7 | parameter int unsigned AxiDataWidth = ariane_axi::DataWidth, 8 | parameter int unsigned AxiIdWidth = ariane_axi::IdWidth, 9 | parameter type axi_ar_chan_t = ariane_axi::ar_chan_t, 10 | parameter type axi_aw_chan_t = ariane_axi::aw_chan_t, 11 | parameter type axi_w_chan_t = ariane_axi::w_chan_t, 12 | parameter type axi_req_t = ariane_axi::req_t, 13 | parameter type axi_rsp_t = ariane_axi::resp_t 14 | ) ( 15 | input logic clk_i, 16 | input logic rst_ni, 17 | // Core ID, Cluster ID and boot address are considered more or less static 18 | input logic [riscv::VLEN-1:0] boot_addr_i, // reset boot address 19 | input logic [riscv::XLEN-1:0] hart_id_i, // hart id in a multicore environment (reflected in a CSR) 20 | 21 | // Interrupt inputs 22 | input logic [1:0] irq_i, // level sensitive IR lines, mip & sip (async) 23 | input logic ipi_i, // inter-processor interrupts (async) 24 | // Timer facilities 25 | input logic time_irq_i, // timer interrupt in (async) 26 | input logic debug_req_i, // debug request (async) 27 | // RISC-V formal interface port (`rvfi`): 28 | // Can be left open when formal tracing is not needed. 29 | input ariane_rvfi_pkg::rvfi_port_t rvfi_o_2, 30 | input ariane_rvfi_pkg::rvfi_port_t rvfi_o, //output 31 | input cvxif_pkg::cvxif_req_t cvxif_req_o_2, 32 | input cvxif_pkg::cvxif_req_t cvxif_req_o, //output 33 | input cvxif_pkg::cvxif_resp_t cvxif_resp_i_2, 34 | input cvxif_pkg::cvxif_resp_t cvxif_resp_i, 35 | // L15 (memory side) 36 | input wt_cache_pkg::l15_req_t l15_req_o_2, 37 | input wt_cache_pkg::l15_req_t l15_req_o, //output 38 | input wt_cache_pkg::l15_rtrn_t l15_rtrn_i_2, 39 | input wt_cache_pkg::l15_rtrn_t l15_rtrn_i, 40 | // memory side, AXI Master 41 | input axi_req_t axi_req_o_2, 42 | input axi_req_t axi_req_o, //output 43 | input axi_rsp_t axi_resp_i_2, 44 | input axi_rsp_t axi_resp_i 45 | ); 46 | 47 | //============================================================================== 48 | // Local Parameters 49 | //============================================================================== 50 | 51 | genvar j; 52 | default clocking cb @(posedge clk_i); 53 | endclocking 54 | default disable iff (!rst_ni); 55 | 56 | 57 | //====DESIGNER-ADDED-SVA====// 58 | 59 | // Assumptions to account for the lack of an OS: 60 | // Force RF contents to be the same: 61 | wire rf_same = ariane1.issue_stage_i.i_issue_read_operands.gen_asic_regfile.i_ariane_regfile.mem == ariane2.issue_stage_i.i_issue_read_operands.gen_asic_regfile.i_ariane_regfile.mem; 62 | 63 | 64 | // The architectural state (RFs, CSRs) should be properly restored on the cycle the flush completes. 65 | wire arch_restored = (ariane1.i_frontend.i_instr_queue.pc_q == ariane2.i_frontend.i_instr_queue.pc_q) && 66 | (ariane1.i_frontend.npc_q == ariane2.i_frontend.npc_q) && 67 | rf_same && 68 | (ariane1.i_frontend.i_instr_queue.addr_i[0] == ariane2.i_frontend.i_instr_queue.addr_i[0]) && 69 | (ariane1.i_frontend.i_instr_queue.addr_i[1] == ariane2.i_frontend.i_instr_queue.addr_i[1]); 70 | 71 | 72 | // Asserted when CSR inputs and outputs are the same. 73 | wire csr_equal = // INPUTS 74 | (ariane1.commit_instr_id_commit == ariane2.commit_instr_id_commit) && 75 | (ariane1.commit_ack == ariane2.commit_ack) && 76 | (ariane1.boot_addr_i == ariane2.boot_addr_i) && 77 | (ariane1.ex_commit == ariane2.ex_commit) && 78 | (ariane1.csr_op_commit_csr == ariane2.csr_op_commit_csr) && 79 | (ariane1.csr_write_fflags_commit_cs == ariane2.csr_write_fflags_commit_cs) && 80 | (ariane1.dirty_fp_state == ariane2.dirty_fp_state) && 81 | (ariane1.csr_addr_ex_csr == ariane2.csr_addr_ex_csr) && 82 | (ariane1.csr_wdata_commit_csr == ariane2.csr_wdata_commit_csr) && 83 | (ariane1.pc_commit == ariane2.pc_commit) && 84 | (ariane1.data_perf_csr == ariane2.data_perf_csr) && 85 | 86 | // OUTPUTS 87 | (ariane1.flush_csr_ctrl == ariane2.flush_csr_ctrl) && 88 | (ariane1.halt_csr_ctrl == ariane2.halt_csr_ctrl) && 89 | (ariane1.csr_rdata_csr_commit == ariane2.csr_rdata_csr_commit) && 90 | (ariane1.csr_exception_csr_commit == ariane2.csr_exception_csr_commit) && 91 | (ariane1.epc_commit_pcgen == ariane2.epc_commit_pcgen) && 92 | (ariane1.eret == ariane2.eret) && 93 | (ariane1.set_debug_pc == ariane2.set_debug_pc) && 94 | (ariane1.trap_vector_base_commit_pcgen == ariane2.trap_vector_base_commit_pcgen) && 95 | (ariane1.priv_lvl == ariane2.priv_lvl) && 96 | (ariane1.fs == ariane2.fs) && 97 | (ariane1.fflags_csr_commit == ariane2.fflags_csr_commit) && 98 | (ariane1.frm_csr_id_issue_ex == ariane2.frm_csr_id_issue_ex) && 99 | (ariane1.fprec_csr_ex == ariane2.fprec_csr_ex) && 100 | (ariane1.irq_ctrl_csr_id == ariane2.irq_ctrl_csr_id) && 101 | (ariane1.ld_st_priv_lvl_csr_ex == ariane2.ld_st_priv_lvl_csr_ex) && 102 | (ariane1.enable_translation_csr_ex == ariane2.enable_translation_csr_ex) && 103 | (ariane1.en_ld_st_translation_csr_ex == ariane2.en_ld_st_translation_csr_ex) && 104 | (ariane1.sum_csr_ex == ariane2.sum_csr_ex) && 105 | (ariane1.mxr_csr_ex == ariane2.mxr_csr_ex) && 106 | (ariane1.satp_ppn_csr_ex == ariane2.satp_ppn_csr_ex) && 107 | (ariane1.asid_csr_ex == ariane2.asid_csr_ex) && 108 | (ariane1.tvm_csr_id == ariane2.tvm_csr_id) && 109 | (ariane1.tw_csr_id == ariane2.tw_csr_id) && 110 | (ariane1.tsr_csr_id == ariane2.tsr_csr_id) && 111 | (ariane1.debug_mode == ariane2.debug_mode) && 112 | (ariane1.single_step_csr_commit == ariane2.single_step_csr_commit) && 113 | (ariane1.dcache_en_csr_nbdcache == ariane2.dcache_en_csr_nbdcache) && 114 | (ariane1.icache_en_csr == ariane2.icache_en_csr) && 115 | (ariane1.addr_csr_perf == ariane2.addr_csr_perf) && 116 | (ariane1.data_csr_perf == ariane2.data_csr_perf) && 117 | (ariane1.we_csr_perf == ariane2.we_csr_perf) && 118 | (ariane1.fence_t_src_sel_csr_ctrl == ariane2.fence_t_src_sel_csr_ctrl) && 119 | (ariane1.fence_t_pad_csr_ctrl == ariane2.fence_t_pad_csr_ctrl) && 120 | (ariane1.pmpcfg == ariane2.pmpcfg) && 121 | (ariane1.pmpaddr == ariane2.pmpaddr); 122 | 123 | wire flush1_done = ariane1.controller_i.fence_t_state_q==ariane1.controller_i.RST_UARCH && ariane1.controller_i.fence_t_state_d==ariane1.controller_i.IDLE; 124 | wire flush2_done = ariane2.controller_i.fence_t_state_q==ariane2.controller_i.RST_UARCH && ariane2.controller_i.fence_t_state_d==ariane2.controller_i.IDLE; 125 | 126 | co__state1: cover property (ariane1.controller_i.fence_t_state_q==ariane1.controller_i.FLUSH_DCACHE); 127 | co__state3: cover property (ariane1.controller_i.fence_t_state_q==ariane1.controller_i.RST_UARCH); 128 | co__state4: cover property (ariane1.controller_i.fence_t_state_q==ariane1.controller_i.PAD); 129 | co__fence_active: cover property (ariane1.controller_i.fence_active_q); 130 | co__fence_t: cover property (ariane1.controller_i.fence_t_i); 131 | 132 | wire both_flush_done = flush1_done && flush2_done; 133 | // Latches a 1 when the flush has completed. 134 | reg spy_mode; 135 | reg [4:0] equal_cnt; 136 | wire io_equal; 137 | wire precondition_equal = io_equal && csr_equal && arch_restored; 138 | 139 | wire still_equal_after_period = precondition_equal && (equal_cnt >= 5'd6); 140 | 141 | always_ff @(posedge clk_i) begin 142 | if (!rst_ni) begin 143 | spy_mode <= '0; 144 | equal_cnt <= '0; 145 | end else begin 146 | spy_mode <= still_equal_after_period || spy_mode; 147 | equal_cnt <= ((both_flush_done || equal_cnt>0) && precondition_equal) ? equal_cnt + 1 : '0; 148 | end 149 | end 150 | 151 | // Assert that inputs are equal: 152 | as__commit_instr_i: assert property (spy_mode |-> (ariane1.commit_instr_id_commit == ariane2.commit_instr_id_commit)); 153 | as__commit_ack_i: assert property (spy_mode |-> (ariane1.commit_ack == ariane2.commit_ack)); 154 | as__boot_addr_i: assert property (spy_mode |-> (ariane1.boot_addr_i == ariane2.boot_addr_i)); 155 | as__ex_i: assert property (spy_mode |-> (ariane1.ex_commit == ariane2.ex_commit)); 156 | as__csr_op_i: assert property (spy_mode |-> (ariane1.csr_op_commit_csr == ariane2.csr_op_commit_csr)); 157 | as__csr_write_fflags_i: assert property (spy_mode |-> (ariane1.csr_write_fflags_commit_cs == ariane2.csr_write_fflags_commit_cs)); 158 | as__dirty_fp_state_i: assert property (spy_mode |-> (ariane1.dirty_fp_state == ariane2.dirty_fp_state)); 159 | as__csr_addr_i: assert property (spy_mode |-> (ariane1.csr_addr_ex_csr == ariane2.csr_addr_ex_csr)); 160 | as__csr_wdata_i: assert property (spy_mode |-> (ariane1.csr_wdata_commit_csr == ariane2.csr_wdata_commit_csr)); 161 | as__pc_i: assert property (spy_mode |-> (ariane1.pc_commit == ariane2.pc_commit)); 162 | 163 | 164 | 165 | wire assume_csr = spy_mode || ariane1.controller_i.fence_t_state_q!=ariane1.controller_i.IDLE || ariane2.controller_i.fence_t_state_q!=ariane2.controller_i.IDLE; 166 | // Assume that the input from the performance counters are equal (perf_counters blackboxed): 167 | am__perf_data_i: assume property (assume_csr |-> (ariane1.data_perf_csr == ariane2.data_perf_csr)); 168 | // Assume that the outputs are equal: 169 | am__flush_o: assume property (assume_csr |-> (ariane1.flush_csr_ctrl == ariane2.flush_csr_ctrl)); 170 | am__halt_csr_o: assume property (assume_csr |-> (ariane1.halt_csr_ctrl == ariane2.halt_csr_ctrl)); 171 | am__csr_rdata_o: assume property (assume_csr |-> (ariane1.csr_rdata_csr_commit == ariane2.csr_rdata_csr_commit)); 172 | am__csr_exception_o: assume property (assume_csr |-> (ariane1.csr_exception_csr_commit == ariane2.csr_exception_csr_commit)); 173 | am__epc_o: assume property (assume_csr |-> (ariane1.epc_commit_pcgen == ariane2.epc_commit_pcgen)); 174 | am__eret_o: assume property (assume_csr |-> (ariane1.eret == ariane2.eret)); 175 | am__set_debug_pc_o: assume property (assume_csr |-> (ariane1.set_debug_pc == ariane2.set_debug_pc)); 176 | am__trap_vector_base_o: assume property (assume_csr |-> (ariane1.trap_vector_base_commit_pcgen == ariane2.trap_vector_base_commit_pcgen)); 177 | am__priv_lvl_o: assume property (assume_csr |-> (ariane1.priv_lvl == ariane2.priv_lvl)); 178 | am__fs_o: assume property (assume_csr |-> (ariane1.fs == ariane2.fs)); 179 | am__fflags_o: assume property (assume_csr |-> (ariane1.fflags_csr_commit == ariane2.fflags_csr_commit)); 180 | am__frm_o: assume property (assume_csr |-> (ariane1.frm_csr_id_issue_ex == ariane2.frm_csr_id_issue_ex)); 181 | am__fprec_o: assume property (assume_csr |-> (ariane1.fprec_csr_ex == ariane2.fprec_csr_ex)); 182 | am__irq_ctrl_o: assume property (assume_csr |-> (ariane1.irq_ctrl_csr_id == ariane2.irq_ctrl_csr_id)); 183 | am__ld_st_priv_lvl_o: assume property (assume_csr |-> (ariane1.ld_st_priv_lvl_csr_ex == ariane2.ld_st_priv_lvl_csr_ex)); 184 | am__en_translation_o: assume property (assume_csr |-> (ariane1.enable_translation_csr_ex == ariane2.enable_translation_csr_ex)); 185 | am__en_ld_st_translation_o: assume property (assume_csr |-> (ariane1.en_ld_st_translation_csr_ex == ariane2.en_ld_st_translation_csr_ex)); 186 | am__sum_o: assume property (assume_csr |-> (ariane1.sum_csr_ex == ariane2.sum_csr_ex)); 187 | am__mxr_o: assume property (assume_csr |-> (ariane1.mxr_csr_ex == ariane2.mxr_csr_ex)); 188 | am__satp_ppn_o: assume property (assume_csr |-> (ariane1.satp_ppn_csr_ex == ariane2.satp_ppn_csr_ex)); 189 | am__asid_o: assume property (assume_csr |-> (ariane1.asid_csr_ex == ariane2.asid_csr_ex)); 190 | am__tvm_o: assume property (assume_csr |-> (ariane1.tvm_csr_id == ariane2.tvm_csr_id)); 191 | am__tw_o: assume property (assume_csr |-> (ariane1.tw_csr_id == ariane2.tw_csr_id)); 192 | am__tsr_o: assume property (assume_csr |-> (ariane1.tsr_csr_id == ariane2.tsr_csr_id)); 193 | am__debug_mode_o: assume property (assume_csr |-> (ariane1.debug_mode == ariane2.debug_mode)); 194 | am__single_step_o: assume property (assume_csr |-> (ariane1.single_step_csr_commit == ariane2.single_step_csr_commit)); 195 | am__dcache_en_o: assume property (assume_csr |-> (ariane1.dcache_en_csr_nbdcache == ariane2.dcache_en_csr_nbdcache)); 196 | am__icache_en_o: assume property (assume_csr |-> (ariane1.icache_en_csr == ariane2.icache_en_csr)); 197 | am__perf_addr_o: assume property (assume_csr |-> (ariane1.addr_csr_perf == ariane2.addr_csr_perf)); 198 | am__perf_data_o: assume property (assume_csr |-> (ariane1.data_csr_perf == ariane2.data_csr_perf)); 199 | am__perf_we_o: assume property (assume_csr |-> (ariane1.we_csr_perf == ariane2.we_csr_perf)); 200 | am__perf_en_o: assume property (assume_csr |-> (ariane1.fence_t_pad_csr_ctrl == ariane2.fence_t_pad_csr_ctrl)); 201 | am__fence_t_src_sel_o: assume property (assume_csr |-> (ariane1.fence_t_src_sel_csr_ctrl == ariane2.fence_t_src_sel_csr_ctrl)); 202 | am__pmpcfg_o: assume property (assume_csr |-> (ariane1.pmpcfg == ariane2.pmpcfg)); 203 | am__pmpaddr_o: assume property (assume_csr |-> (ariane1.pmpaddr == ariane2.pmpaddr)); 204 | 205 | 206 | wire axi_input_equal = (axi_resp_i == axi_resp_i_2); 207 | wire cvxif_input_equal = (cvxif_resp_i == cvxif_resp_i_2); 208 | assign io_equal = (axi_req_o == axi_req_o_2) && axi_input_equal && cvxif_input_equal; 209 | 210 | // ASSERT ALL OUTPUTS 211 | as__AXI_w_valid_equal: assert property (spy_mode |-> axi_req_o.w_valid == axi_req_o_2.w_valid); 212 | as__AXI_w_equal: assert property (spy_mode && axi_req_o.w_valid |-> axi_req_o.w == axi_req_o_2.w); 213 | as__AXI_ar_valid_equal: assert property (spy_mode |-> axi_req_o.ar_valid == axi_req_o_2.ar_valid); 214 | as__AXI_ar_equal: assert property (spy_mode && axi_req_o.ar_valid |-> axi_req_o_2.ar == axi_req_o_2.ar); 215 | as__AXI_aw_valid_equal: assert property (spy_mode |-> axi_req_o.aw_valid == axi_req_o_2.aw_valid); 216 | as__AXI_aw_equal: assert property (spy_mode && axi_req_o.aw_valid |-> axi_req_o.aw == axi_req_o_2.aw); 217 | 218 | wire arch_same_post = (ariane1.i_frontend.i_instr_queue.pc_q == ariane2.i_frontend.i_instr_queue.pc_q); 219 | as__PC_equal: assert property (spy_mode |-> arch_same_post); 220 | 221 | 222 | // Inputs are the same to both cores after the flush. 223 | am__AXI_input_same: assume property (spy_mode |-> axi_input_equal); 224 | am_XIF_input_same: assume property (spy_mode |-> cvxif_input_equal); 225 | 226 | 227 | ////////////////////////// 228 | //// OTHER ASSUMPIONS //// 229 | ////////////////////////// 230 | 231 | // Have val and rdy come on the same cycle for reads. 232 | am__axi_ready1: assume property (ariane1.axi_req_o.ar_valid |-> ariane1.axi_resp_i.ar_ready); 233 | am__axi_ready2: assume property (ariane2.axi_req_o.ar_valid |-> ariane2.axi_resp_i.ar_ready); 234 | 235 | // Forbid usage of the MUL unit. 236 | 237 | am__m0a: assume property (1'b0 == ariane1.ex_stage_i.mult_valid_i); 238 | am__m0b: assume property (1'b0 == ariane2.ex_stage_i.mult_valid_i); 239 | am__m1a: assume property (1'b0 == ariane1.ex_stage_i.mult_valid); 240 | am__m1b: assume property (1'b0 == ariane2.ex_stage_i.mult_valid); 241 | 242 | // Assume output from the MUL unit is the same. 243 | am__m2: assume property (spy_mode |-> ariane1.ex_stage_i.mult_result == ariane2.ex_stage_i.mult_result); 244 | am__m3: assume property (spy_mode |-> ariane1.ex_stage_i.mult_ready == ariane2.ex_stage_i.mult_ready); 245 | am__m4: assume property (spy_mode |-> ariane1.ex_stage_i.mult_trans_id == ariane2.ex_stage_i.mult_trans_id); 246 | 247 | 248 | // Assume outputs from perf_counters are the same (perf_counters is blackboxed). 249 | am__f1: assume property (spy_mode |-> ariane1.ex_stage_i.fpu_trans_id_o == ariane2.ex_stage_i.fpu_trans_id_o); 250 | am__f2: assume property (spy_mode |-> ariane1.ex_stage_i.fpu_result_o == ariane2.ex_stage_i.fpu_result_o); 251 | am__f3: assume property (spy_mode |-> ariane1.ex_stage_i.fpu_valid_o == ariane2.ex_stage_i.fpu_valid_o); 252 | am__f4: assume property (spy_mode |-> ariane1.ex_stage_i.fpu_exception_o == ariane2.ex_stage_i.fpu_exception_o); 253 | am__f5: assume property (spy_mode |-> ariane1.ex_stage_i.fpu_ready_o == ariane2.ex_stage_i.fpu_ready_o); 254 | 255 | endmodule -------------------------------------------------------------------------------- /ft_maple/FPV.tcl: -------------------------------------------------------------------------------- 1 | # Set paths to DUT root and FT root (edit if needed) 2 | set AUTOCC_ROOT $env(AUTOCC_ROOT) 3 | set DUT_ROOT ${AUTOCC_ROOT}/openpiton/maple/rtl 4 | 5 | # Analyze design under verification files (no edit) 6 | set DUT_PATH ${DUT_ROOT}/ 7 | set SRC_PATH0 ${DUT_ROOT}/../../piton/design/common/rtl 8 | set SRC_PATH1 ${DUT_ROOT}/../../piton/design/chip/tile/common/rtl 9 | set SRC_PATH2 ${DUT_ROOT}/../../piton/design/chip/tile/l15/rtl 10 | set SRC_PATH3 ${DUT_ROOT}/../../piton/design/chip/tile/ariane/src/common_cells/src 11 | set INC_PATH ${DUT_ROOT}/../../piton/design/include 12 | set PROP_PATH ${AUTOCC_ROOT}/ft_maple/sva 13 | 14 | set_elaborate_single_run_mode off 15 | 16 | # Analyze property files 17 | analyze -clear 18 | analyze -sv12 -f ${AUTOCC_ROOT}/ft_maple/files.vc 19 | 20 | # Elaborate design and properties 21 | elaborate -top is_core_wrap 22 | 23 | # Set up Clocks and Resets 24 | clock clk_gated 25 | reset -expression (!rst_n_f) 26 | 27 | # Get design information to check general complexity 28 | get_design_info 29 | 30 | set_word_level_reduction on 31 | set_prove_time_limit 72h 32 | 33 | autoprove -all -bg 34 | 35 | # Report proof results 36 | report 37 | -------------------------------------------------------------------------------- /ft_maple/files.vc: -------------------------------------------------------------------------------- 1 | +libext+.v 2 | +libext+.h 3 | +libext+.sv 4 | +libext+.tmp.v 5 | +librescan 6 | +incdir+${DUT_PATH} 7 | -y ${DUT_PATH} 8 | +incdir+${SRC_PATH0} 9 | -y ${SRC_PATH0} 10 | +incdir+${SRC_PATH1} 11 | -y ${SRC_PATH1} 12 | +incdir+${SRC_PATH2} 13 | -y ${SRC_PATH2} 14 | +incdir+${SRC_PATH3} 15 | -y ${SRC_PATH3} 16 | +incdir+${INC_PATH} 17 | -y ${INC_PATH} 18 | ${PROP_PATH}/is_core_prop.sv 19 | ${PROP_PATH}/is_core_bind.svh 20 | ${AUTOCC_ROOT}/ft_maple/ft_dcp_pipe/sva/dcp_pipe_prop.sv 21 | ${AUTOCC_ROOT}/ft_maple/ft_dcp_pipe/sva/dcp_pipe_bind.svh 22 | ${DUT_ROOT}/is_core.v 23 | ${DUT_ROOT}/is_core_wrap.sv 24 | -------------------------------------------------------------------------------- /ft_maple/ft_dcp_pipe/files.vc: -------------------------------------------------------------------------------- 1 | +libext+.v 2 | +libext+.h 3 | +libext+.sv 4 | +libext+.tmp.v 5 | +librescan 6 | +incdir+${DUT_PATH} 7 | -y ${DUT_PATH} 8 | +incdir+${SRC_PATH0} 9 | -y ${SRC_PATH0} 10 | +incdir+${SRC_PATH1} 11 | -y ${SRC_PATH1} 12 | +incdir+${SRC_PATH2} 13 | -y ${SRC_PATH2} 14 | +incdir+${SRC_PATH3} 15 | -y ${SRC_PATH3} 16 | +incdir+${INC_PATH} 17 | -y ${INC_PATH} 18 | -f ${PROP_PATH}/../manual_sub.vc 19 | ${PROP_PATH}/dcp_pipe_prop.sv 20 | ${PROP_PATH}/dcp_pipe_bind.svh 21 | ${DUT_ROOT}/dcp_pipe.sv 22 | -------------------------------------------------------------------------------- /ft_maple/ft_dcp_pipe/sva/dcp_pipe_bind.svh: -------------------------------------------------------------------------------- 1 | bind dcp_pipe dcp_pipe_prop 2 | #( 3 | .ASSERT_INPUTS (0) 4 | ) u_dcp_pipe_sva(.*); -------------------------------------------------------------------------------- /ft_maple/ft_dcp_pipe/sva/dcp_pipe_prop.sv: -------------------------------------------------------------------------------- 1 | `include "dcp.h" 2 | 3 | 4 | module dcp_pipe_prop 5 | #( 6 | parameter ASSERT_INPUTS = 0) 7 | ( 8 | input wire clk, 9 | input wire rst_n, 10 | input wire [`HOME_ALLOC_METHOD_WIDTH-1:0] home_alloc_method, 11 | input wire [`HOME_ID_WIDTH-1:0] system_tile_count, 12 | 13 | 14 | // Update TLB from DCP 15 | input wire tlb_update, //output 16 | input wire tlb_conf_ptbase, //output 17 | input wire tlb_disable, //output 18 | input wire tlb_flush, //output 19 | 20 | input wire [63:0] conf_data, //output 21 | 22 | // TLB req/res iface 23 | input wire tlb_req, //output 24 | input wire tlb_ack, 25 | input wire tlb_exc_val, 26 | input wire [`TLB_SRC_NUM -1:0] tlb_ptw_src, 27 | input wire [`DCP_VADDR -1:0] tlb_vaddr, //output 28 | input wire [`DCP_PADDR -1:0] tlb_paddr, 29 | 30 | // Snoop TLB entries from DCP 31 | input wire tlb_snoop_val, //output 32 | input wire [63:0] tlb_snoop_entry, 33 | 34 | 35 | // NOC1 - Outgoing Atomic op request to L2 36 | input wire dcp_noc1buffer_rdy, 37 | input wire dcp_noc1buffer_val, //output 38 | input wire [`MSG_TYPE_WIDTH-1:0] dcp_noc1buffer_type, //output 39 | input wire [`DCP_MSHRID_WIDTH -1:0] dcp_noc1buffer_mshrid, //output 40 | input wire [`DCP_PADDR_MASK ] dcp_noc1buffer_address, //output 41 | input wire [`DCP_UNPARAM_2_0 ] dcp_noc1buffer_size, //output 42 | input wire [`PACKET_HOME_ID_WIDTH-1:0] dcp_noc1buffer_homeid, //output 43 | input wire [`MSG_AMO_MASK_WIDTH-1:0] dcp_noc1buffer_write_mask, //output 44 | input wire [`DCP_UNPARAM_63_0 ] dcp_noc1buffer_data_0, //output 45 | input wire [`DCP_UNPARAM_63_0 ] dcp_noc1buffer_data_1, //output 46 | 47 | // NOC2 - Outgoing TLoad op request to DRAM or Store ACK 48 | input wire dcp_noc2buffer_rdy, 49 | input wire dcp_noc2buffer_val, //output 50 | input wire [`MSG_TYPE_WIDTH -1:0] dcp_noc2buffer_type, //output 51 | input wire [`DCP_MSHRID_WIDTH -1:0] dcp_noc2buffer_mshrid, //output 52 | input wire [`DCP_PADDR_MASK ] dcp_noc2buffer_address, //output 53 | input wire [`DCP_UNPARAM_63_0 ] dcp_noc2buffer_data, //output 54 | input wire [`PACKET_HOME_ID_WIDTH-1:0] dcp_noc2buffer_homeid, //output 55 | input wire [`MSG_SRC_FBITS_WIDTH -1:0] dcp_noc2buffer_fbits, //output 56 | 57 | // NOC1 - Incoming Load/Store requests 58 | input wire noc1decoder_dcp_val, 59 | input wire noc1decoder_dcp_ack, //output 60 | input wire [`DCP_MSHRID_WIDTH -1:0] noc1decoder_dcp_mshrid, 61 | input wire [`MSG_TYPE_WIDTH -1:0] noc1decoder_dcp_reqtype, 62 | input wire [`DCP_UNPARAM_63_0 ] noc1decoder_dcp_data, 63 | input wire [`DCP_PADDR_MASK ] noc1decoder_dcp_address, 64 | input wire [`MSG_DATA_SIZE_WIDTH-1:0] noc1decoder_dcp_size, 65 | input wire [`MSG_SRC_X_WIDTH -1:0] noc1decoder_dcp_src_x, 66 | input wire [`MSG_SRC_Y_WIDTH -1:0] noc1decoder_dcp_src_y, 67 | input wire [`MSG_SRC_CHIPID_WIDTH-1:0] noc1decoder_dcp_chipid, 68 | input wire [`MSG_SRC_FBITS_WIDTH- 1:0] noc1decoder_dcp_fbits, 69 | 70 | // NOC2 - Atomic op response from L2 71 | input wire noc2decoder_dcp_val, 72 | input wire noc2decoder_dcp_ack, //output 73 | input wire [`DCP_MSHRID_WIDTH -1:0] noc2decoder_dcp_mshrid, 74 | input wire [`MSG_LENGTH_WIDTH -1:0] noc2decoder_dcp_length, 75 | input wire [`MSG_TYPE_WIDTH -1:0] noc2decoder_dcp_reqtype, 76 | input wire [`DCP_NOC_RES_DATA_SIZE-1:0] noc2decoder_dcp_data, 77 | 78 | // NOC3 - TLoad response from DRAM 79 | input wire noc3decoder_dcp_val, 80 | input wire noc3decoder_dcp_ack, //output 81 | input wire [`DCP_MSHRID_WIDTH -1:0] noc3decoder_dcp_mshrid, 82 | input wire [`MSG_TYPE_WIDTH -1:0] noc3decoder_dcp_reqtype, 83 | input wire [`DCP_NOC_RES_DATA_SIZE-1:0] noc3decoder_dcp_data 84 | ); 85 | 86 | //============================================================================== 87 | // Local Parameters 88 | //============================================================================== 89 | 90 | genvar j; 91 | default clocking cb @(posedge clk); 92 | endclocking 93 | default disable iff (!rst_n); 94 | 95 | // Re-defined wires 96 | wire store_val; 97 | wire store_rdy; 98 | wire load_val; 99 | wire load_rdy; 100 | wire tlb_exc_transid; 101 | wire tlb_get_val; 102 | wire tlb_get_transid; 103 | wire [1:0] tlb_get_data; 104 | wire tlb_set_val; 105 | wire tlb_set_transid; 106 | wire [1:0] tlb_set_data; 107 | wire dcp_noc2bufferack_val; 108 | wire dcp_noc2bufferack_rdy; 109 | wire [`DCP_MSHRID_WIDTH-1:0] dcp_noc2bufferack_transid; 110 | wire dcp_noc1bufferout_val; 111 | wire dcp_noc1bufferout_rdy; 112 | wire [`DCP_MSHRID_WIDTH-1:0] dcp_noc1bufferout_transid; 113 | wire [`DCP_MSHRID_WIDTH-1:0] noc2decoder_dcp_transid; 114 | wire dcp_noc2bufferout_val; 115 | wire dcp_noc2bufferout_rdy; 116 | wire [`DCP_MSHRID_WIDTH-1:0] dcp_noc2bufferout_transid; 117 | 118 | // Symbolics and Handshake signals 119 | wire [0:0] symb_tlb_get_transid; 120 | am__symb_tlb_get_transid_stable: assume property($stable(symb_tlb_get_transid)); 121 | wire tlb_set_hsk = tlb_set_val; 122 | wire tlb_get_hsk = tlb_get_val; 123 | wire [`DCP_MSHRID_WIDTH-1:0] symb_noc1decoder_dcp_mshrid; 124 | am__symb_noc1decoder_dcp_mshrid_stable: assume property($stable(symb_noc1decoder_dcp_mshrid)); 125 | wire dcp_noc2bufferack_hsk = dcp_noc2bufferack_val && dcp_noc2bufferack_rdy; 126 | wire noc1decoder_dcp_hsk = noc1decoder_dcp_val && noc1decoder_dcp_ack; 127 | wire [`DCP_MSHRID_WIDTH-1:0] symb_dcp_noc1bufferout_transid; 128 | am__symb_dcp_noc1bufferout_transid_stable: assume property($stable(symb_dcp_noc1bufferout_transid)); 129 | wire noc2decoder_dcp_hsk = noc2decoder_dcp_val && noc2decoder_dcp_ack; 130 | wire dcp_noc1bufferout_hsk = dcp_noc1bufferout_val && dcp_noc1bufferout_rdy; 131 | wire [0:0] symb_tlb_exc_transid; 132 | am__symb_tlb_exc_transid_stable: assume property($stable(symb_tlb_exc_transid)); 133 | wire tlb_exc_hsk = tlb_exc_val; 134 | wire [`DCP_MSHRID_WIDTH-1:0] symb_dcp_noc2bufferout_transid; 135 | am__symb_dcp_noc2bufferout_transid_stable: assume property($stable(symb_dcp_noc2bufferout_transid)); 136 | wire noc3decoder_dcp_hsk = noc3decoder_dcp_val && noc3decoder_dcp_ack; 137 | wire dcp_noc2bufferout_hsk = dcp_noc2bufferout_val && dcp_noc2bufferout_rdy; 138 | 139 | //============================================================================== 140 | // Modeling 141 | //============================================================================== 142 | 143 | // Modeling outstanding request for exc_req 144 | reg [2**(0+1)-1:0] exc_req_outstanding_req_r; 145 | reg [2**(0+1)-1:0][1:0] exc_req_outstanding_req_data_r; 146 | 147 | always_ff @(posedge clk) begin 148 | if(!rst_n) begin 149 | exc_req_outstanding_req_r <= '0; 150 | end else begin 151 | if (tlb_get_hsk) begin 152 | exc_req_outstanding_req_r[tlb_get_transid] <= 1'b1; 153 | exc_req_outstanding_req_data_r[tlb_get_transid] <= tlb_get_data; 154 | end 155 | if (tlb_set_hsk) begin 156 | exc_req_outstanding_req_r[tlb_set_transid] <= 1'b0; 157 | end 158 | end 159 | end 160 | 161 | 162 | generate 163 | if (ASSERT_INPUTS) begin : exc_req_gen 164 | as__exc_req1: assert property (!exc_req_outstanding_req_r[symb_tlb_get_transid] |-> !(tlb_set_hsk && (tlb_set_transid == symb_tlb_get_transid))); 165 | as__exc_req2: assert property (exc_req_outstanding_req_r[symb_tlb_get_transid] |-> s_eventually(tlb_set_hsk && (tlb_set_transid == symb_tlb_get_transid)&& 166 | (tlb_set_data == exc_req_outstanding_req_data_r[symb_tlb_get_transid]) )); 167 | end else begin : exc_req_else_gen 168 | for ( j = 0; j < 2**(0+1); j = j + 1) begin : exc_req_for_gen 169 | // co__exc_req: cover property (exc_req_outstanding_req_r[j]); 170 | am__exc_req1: assume property (!exc_req_outstanding_req_r[j] |-> !(tlb_set_val && (tlb_set_transid == j))); 171 | am__exc_req2: assume property (exc_req_outstanding_req_r[j] |-> s_eventually(tlb_set_val && (tlb_set_transid == j)&& 172 | (tlb_set_data == exc_req_outstanding_req_data_r[j]) )); 173 | end 174 | end 175 | endgenerate 176 | 177 | // Modeling incoming request for noc1in 178 | if (ASSERT_INPUTS) begin 179 | as__noc1in_fairness: assert property (dcp_noc2bufferack_val |-> s_eventually(dcp_noc2bufferack_rdy)); 180 | end else begin 181 | am__noc1in_fairness: assume property (dcp_noc2bufferack_val |-> s_eventually(dcp_noc2bufferack_rdy)); 182 | end 183 | 184 | // Generate sampling signals and model 185 | reg [3:0] noc1in_mshrid_sampled; 186 | wire noc1in_mshrid_set = noc1decoder_dcp_hsk && noc1decoder_dcp_mshrid == symb_noc1decoder_dcp_mshrid; 187 | wire noc1in_mshrid_response = dcp_noc2bufferack_hsk && dcp_noc2bufferack_transid == symb_noc1decoder_dcp_mshrid; 188 | 189 | always_ff @(posedge clk) begin 190 | if(!rst_n) begin 191 | noc1in_mshrid_sampled <= '0; 192 | end else if (noc1in_mshrid_set || noc1in_mshrid_response ) begin 193 | noc1in_mshrid_sampled <= noc1in_mshrid_sampled + noc1in_mshrid_set - noc1in_mshrid_response; 194 | end 195 | end 196 | // co__noc1in_mshrid_sampled: cover property (|noc1in_mshrid_sampled); 197 | if (ASSERT_INPUTS) begin 198 | as__noc1in_mshrid_sample_no_overflow: assert property (noc1in_mshrid_sampled != '1 || !noc1in_mshrid_set); 199 | end else begin 200 | am__noc1in_mshrid_sample_no_overflow: assume property (noc1in_mshrid_sampled != '1 || !noc1in_mshrid_set); 201 | end 202 | 203 | 204 | // Assert that if valid eventually ready or dropped valid 205 | as__noc1in_mshrid_hsk_or_drop: assert property (noc1decoder_dcp_val |-> s_eventually(!noc1decoder_dcp_val || noc1decoder_dcp_ack)); 206 | // Assert that every request has a response and that every reponse has a request 207 | as__noc1in_mshrid_eventual_response: assert property (|noc1in_mshrid_sampled |-> s_eventually(dcp_noc2bufferack_val && (dcp_noc2bufferack_transid == symb_noc1decoder_dcp_mshrid) )); 208 | as__noc1in_mshrid_was_a_request: assert property (noc1in_mshrid_response |-> noc1in_mshrid_set || noc1in_mshrid_sampled); 209 | 210 | // Modeling outstanding request for noc1out 211 | reg [2**(`DCP_MSHRID_WIDTH-1+1)-1:0] noc1out_outstanding_req_r; 212 | 213 | always_ff @(posedge clk) begin 214 | if(!rst_n) begin 215 | noc1out_outstanding_req_r <= '0; 216 | end else begin 217 | if (dcp_noc1bufferout_hsk) begin 218 | noc1out_outstanding_req_r[dcp_noc1bufferout_transid] <= 1'b1; 219 | end 220 | if (noc2decoder_dcp_hsk) begin 221 | noc1out_outstanding_req_r[noc2decoder_dcp_transid] <= 1'b0; 222 | end 223 | end 224 | end 225 | 226 | 227 | generate 228 | if (ASSERT_INPUTS) begin : noc1out_gen 229 | as__noc1out1: assert property (!noc1out_outstanding_req_r[symb_dcp_noc1bufferout_transid] |-> !(noc2decoder_dcp_hsk && (noc2decoder_dcp_transid == symb_dcp_noc1bufferout_transid))); 230 | as__noc1out2: assert property (noc1out_outstanding_req_r[symb_dcp_noc1bufferout_transid] |-> s_eventually(noc2decoder_dcp_hsk && (noc2decoder_dcp_transid == symb_dcp_noc1bufferout_transid))); 231 | end else begin : noc1out_else_gen 232 | am__noc1out_fairness: assume property (dcp_noc1bufferout_val |-> s_eventually(dcp_noc1bufferout_rdy)); 233 | for ( j = 0; j < 2**(`DCP_MSHRID_WIDTH-1+1); j = j + 1) begin : noc1out_for_gen 234 | // co__noc1out: cover property (noc1out_outstanding_req_r[j]); 235 | am__noc1out1: assume property (!noc1out_outstanding_req_r[j] |-> !(noc2decoder_dcp_val && (noc2decoder_dcp_transid == j))); 236 | am__noc1out2: assume property (noc1out_outstanding_req_r[j] |-> s_eventually(noc2decoder_dcp_val && (noc2decoder_dcp_transid == j))); 237 | end 238 | end 239 | endgenerate 240 | 241 | // Modeling outstanding request for exc_val 242 | reg [2**(0+1)-1:0] exc_val_outstanding_req_r; 243 | 244 | always_ff @(posedge clk) begin 245 | if(!rst_n) begin 246 | exc_val_outstanding_req_r <= '0; 247 | end else begin 248 | if (tlb_exc_hsk) begin 249 | exc_val_outstanding_req_r[tlb_exc_transid] <= 1'b1; 250 | end 251 | if (tlb_get_hsk) begin 252 | exc_val_outstanding_req_r[tlb_get_transid] <= 1'b0; 253 | end 254 | end 255 | end 256 | 257 | 258 | generate 259 | if (ASSERT_INPUTS) begin : exc_val_gen 260 | as__exc_val1: assert property (!exc_val_outstanding_req_r[symb_tlb_exc_transid] |-> !(tlb_get_hsk && (tlb_get_transid == symb_tlb_exc_transid))); 261 | as__exc_val2: assert property (exc_val_outstanding_req_r[symb_tlb_exc_transid] |-> s_eventually(tlb_get_hsk && (tlb_get_transid == symb_tlb_exc_transid))); 262 | end else begin : exc_val_else_gen 263 | for ( j = 0; j < 2**(0+1); j = j + 1) begin : exc_val_for_gen 264 | // co__exc_val: cover property (exc_val_outstanding_req_r[j]); 265 | am__exc_val1: assume property (!exc_val_outstanding_req_r[j] |-> !(tlb_get_val && (tlb_get_transid == j))); 266 | am__exc_val2: assume property (exc_val_outstanding_req_r[j] |-> s_eventually(tlb_get_val && (tlb_get_transid == j))); 267 | end 268 | end 269 | endgenerate 270 | 271 | // Modeling outstanding request for noc2out 272 | reg [2**(`DCP_MSHRID_WIDTH-1+1)-1:0] noc2out_outstanding_req_r; 273 | 274 | always_ff @(posedge clk) begin 275 | if(!rst_n) begin 276 | noc2out_outstanding_req_r <= '0; 277 | end else begin 278 | if (dcp_noc2bufferout_hsk) begin 279 | noc2out_outstanding_req_r[dcp_noc2bufferout_transid] <= 1'b1; 280 | end 281 | if (noc3decoder_dcp_hsk) begin 282 | noc2out_outstanding_req_r[noc3decoder_dcp_mshrid] <= 1'b0; 283 | end 284 | end 285 | end 286 | 287 | 288 | generate 289 | if (ASSERT_INPUTS) begin : noc2out_gen 290 | as__noc2out1: assert property (!noc2out_outstanding_req_r[symb_dcp_noc2bufferout_transid] |-> !(noc3decoder_dcp_hsk && (noc3decoder_dcp_mshrid == symb_dcp_noc2bufferout_transid))); 291 | as__noc2out2: assert property (noc2out_outstanding_req_r[symb_dcp_noc2bufferout_transid] |-> s_eventually(noc3decoder_dcp_hsk && (noc3decoder_dcp_mshrid == symb_dcp_noc2bufferout_transid))); 292 | end else begin : noc2out_else_gen 293 | am__noc2out_fairness: assume property (dcp_noc2bufferout_val |-> s_eventually(dcp_noc2bufferout_rdy)); 294 | for ( j = 0; j < 2**(`DCP_MSHRID_WIDTH-1+1); j = j + 1) begin : noc2out_for_gen 295 | // co__noc2out: cover property (noc2out_outstanding_req_r[j]); 296 | am__noc2out1: assume property (!noc2out_outstanding_req_r[j] |-> !(noc3decoder_dcp_val && (noc3decoder_dcp_mshrid == j))); 297 | am__noc2out2: assume property (noc2out_outstanding_req_r[j] |-> s_eventually(noc3decoder_dcp_val && (noc3decoder_dcp_mshrid == j))); 298 | end 299 | end 300 | endgenerate 301 | 302 | assign load_val = dcp_noc2buffer_val && dcp_noc2buffer_type == `DCP_NOC2_LOAD_ACK; 303 | assign tlb_get_transid = dcp_pipe.tlb_exc_src; 304 | assign tlb_exc_transid = tlb_ptw_src[1]; 305 | assign tlb_set_transid = dcp_pipe.tlb_mmpage_src_oh[1]; 306 | assign dcp_noc2bufferout_transid = dcp_noc2buffer_mshrid; 307 | assign tlb_get_data = dcp_pipe.tlb_exc_src_oh; 308 | assign dcp_noc1bufferout_transid = dcp_noc1buffer_mshrid[`DCP_MSHRID_WIDTH-1:0]; 309 | assign tlb_set_data = dcp_pipe.tlb_mmpage_src_oh; 310 | assign tlb_get_val = dcp_pipe.tlb_get_pfault; 311 | assign dcp_noc1bufferout_rdy = dcp_noc1buffer_rdy; 312 | assign dcp_noc2bufferack_transid = dcp_noc2buffer_mshrid; 313 | assign noc2decoder_dcp_transid = noc2decoder_dcp_mshrid[`DCP_MSHRID_WIDTH-1:0]; 314 | assign tlb_set_val = dcp_pipe.tlb_conf_mmpage; 315 | assign dcp_noc2bufferout_val = dcp_noc2buffer_val && dcp_noc2buffer_type == `DCP_NOC2_LOAD_REQ64; 316 | assign store_rdy = dcp_noc2buffer_rdy; 317 | assign dcp_noc1bufferout_val = dcp_noc1buffer_val; 318 | assign dcp_noc2bufferack_rdy = dcp_noc2buffer_rdy; 319 | assign store_val = dcp_noc2buffer_val && dcp_noc2buffer_type == `DCP_NOC2_STORE_ACK; 320 | assign dcp_noc2bufferout_rdy = dcp_noc2buffer_rdy; 321 | assign dcp_noc2bufferack_val = dcp_noc2buffer_val && (dcp_noc2buffer_type==`DCP_NOC2_STORE_ACK || dcp_noc2buffer_type == `DCP_NOC2_LOAD_ACK); 322 | assign load_rdy = dcp_noc2buffer_rdy; 323 | 324 | //====DESIGNER-ADDED-SVA====// 325 | endmodule -------------------------------------------------------------------------------- /ft_maple/sva/is_core_bind.svh: -------------------------------------------------------------------------------- 1 | bind is_core_wrap is_core_prop 2 | #( 3 | .ASSERT_INPUTS (0) 4 | ) u_is_core_sva(.*); -------------------------------------------------------------------------------- /ft_maple/sva/is_core_prop.sv: -------------------------------------------------------------------------------- 1 | `include "define.tmp.h" 2 | `include "dmbr_define.v" 3 | `include "l15.tmp.h" 4 | `include "jtag.vh" 5 | `include "dcp.h" 6 | `include "is.h" 7 | 8 | module is_core_prop 9 | #( 10 | parameter ASSERT_INPUTS = 0) 11 | ( 12 | 13 | input wire clk_gated, 14 | input wire rst_n_f, 15 | input wire [31:0] config_system_tile_count, 16 | input wire [`HOME_ALLOC_METHOD_WIDTH-1:0] config_home_alloc_method, 17 | input wire [`NOC_CHIPID_WIDTH-1:0] config_chipid, 18 | input wire [`NOC_X_WIDTH-1:0] config_coreid_x, 19 | input wire [`NOC_Y_WIDTH-1:0] config_coreid_y, 20 | input wire splitter_dev1_vr_noc1_val_2, 21 | input wire splitter_dev1_vr_noc1_val, 22 | input wire [`NOC_DATA_WIDTH-1:0] splitter_dev1_vr_noc1_dat_2, 23 | input wire [`NOC_DATA_WIDTH-1:0] splitter_dev1_vr_noc1_dat, 24 | input wire splitter_dev1_vr_noc1_rdy_2, 25 | input wire splitter_dev1_vr_noc1_rdy, //output 26 | input wire dev1_merger_vr_noc1_val_2, 27 | input wire dev1_merger_vr_noc1_val, //output 28 | input wire [`NOC_DATA_WIDTH-1:0] dev1_merger_vr_noc1_dat_2, 29 | input wire [`NOC_DATA_WIDTH-1:0] dev1_merger_vr_noc1_dat, //output 30 | input wire dev1_merger_vr_noc1_rdy_2, 31 | input wire dev1_merger_vr_noc1_rdy, 32 | input wire splitter_dev1_vr_noc2_val_2, 33 | input wire splitter_dev1_vr_noc2_val, 34 | input wire [`NOC_DATA_WIDTH-1:0] splitter_dev1_vr_noc2_dat_2, 35 | input wire [`NOC_DATA_WIDTH-1:0] splitter_dev1_vr_noc2_dat, 36 | input wire splitter_dev1_vr_noc2_rdy_2, 37 | input wire splitter_dev1_vr_noc2_rdy, //output 38 | input wire dev1_merger_vr_noc2_val_2, 39 | input wire dev1_merger_vr_noc2_val, //output 40 | input wire [`NOC_DATA_WIDTH-1:0] dev1_merger_vr_noc2_dat_2, 41 | input wire [`NOC_DATA_WIDTH-1:0] dev1_merger_vr_noc2_dat, //output 42 | input wire dev1_merger_vr_noc2_rdy_2, 43 | input wire dev1_merger_vr_noc2_rdy, 44 | input wire splitter_dev1_vr_noc3_val_2, 45 | input wire splitter_dev1_vr_noc3_val, 46 | input wire [`NOC_DATA_WIDTH-1:0] splitter_dev1_vr_noc3_dat_2, 47 | input wire [`NOC_DATA_WIDTH-1:0] splitter_dev1_vr_noc3_dat, 48 | input wire splitter_dev1_vr_noc3_rdy_2, 49 | input wire splitter_dev1_vr_noc3_rdy, //output 50 | input wire l15_transducer_ack_2, 51 | input wire l15_transducer_ack, 52 | input wire l15_transducer_header_ack_2, 53 | input wire l15_transducer_header_ack, 54 | 55 | input wire transducer_l15_val_2, 56 | input wire transducer_l15_val, //output 57 | input wire [`PCX_REQTYPE_WIDTH-1:0] transducer_l15_rqtype_2, 58 | input wire [`PCX_REQTYPE_WIDTH-1:0] transducer_l15_rqtype, //output 59 | input wire [`L15_AMO_OP_WIDTH-1:0] transducer_l15_amo_op_2, 60 | input wire [`L15_AMO_OP_WIDTH-1:0] transducer_l15_amo_op, //output 61 | input wire [`PCX_SIZE_FIELD_WIDTH-1:0] transducer_l15_size_2, 62 | input wire [`PCX_SIZE_FIELD_WIDTH-1:0] transducer_l15_size, //output 63 | input wire [`L15_PADDR_HI:0] transducer_l15_address_2, 64 | input wire [`L15_PADDR_HI:0] transducer_l15_address, //output 65 | input wire [63:0] transducer_l15_data_2, 66 | input wire [63:0] transducer_l15_data, //output 67 | input wire transducer_l15_nc_2, 68 | input wire transducer_l15_nc, //output 69 | input wire [`L15_THREADID_MASK] transducer_l15_threadid_2, 70 | input wire [`L15_THREADID_MASK] transducer_l15_threadid, //output 71 | input wire transducer_l15_prefetch_2, 72 | input wire transducer_l15_prefetch, //output 73 | input wire transducer_l15_blockstore_2, 74 | input wire transducer_l15_blockstore, //output 75 | input wire transducer_l15_blockinitstore_2, 76 | input wire transducer_l15_blockinitstore, //output 77 | input wire [1:0] transducer_l15_l1rplway_2, 78 | input wire [1:0] transducer_l15_l1rplway, //output 79 | input wire transducer_l15_invalidate_cacheline_2, 80 | input wire transducer_l15_invalidate_cacheline, //output 81 | input wire [`TLB_CSM_WIDTH-1:0] transducer_l15_csm_data_2, 82 | input wire [`TLB_CSM_WIDTH-1:0] transducer_l15_csm_data, //output 83 | input wire [63:0] transducer_l15_data_next_entry_2, 84 | input wire [63:0] transducer_l15_data_next_entry, //output 85 | input wire transducer_l15_req_ack_2, 86 | input wire transducer_l15_req_ack, //output 87 | 88 | 89 | input wire l15_transducer_val_2, 90 | input wire l15_transducer_val, 91 | input wire [3:0] l15_transducer_returntype_2, 92 | input wire [3:0] l15_transducer_returntype, 93 | input wire [`L15_THREADID_MASK] l15_transducer_threadid_2, 94 | input wire [`L15_THREADID_MASK] l15_transducer_threadid, 95 | input wire [63:0] l15_transducer_data_0_2, 96 | input wire [63:0] l15_transducer_data_0, 97 | input wire [63:0] l15_transducer_data_1_2, 98 | input wire [63:0] l15_transducer_data_1 99 | 100 | ); 101 | 102 | //============================================================================== 103 | // Local Parameters 104 | //============================================================================== 105 | 106 | genvar j; 107 | default clocking cb @(posedge clk_gated); 108 | endclocking 109 | default disable iff (!rst_n_f); 110 | 111 | 112 | wire flush_begin, flush_end, io_equal; 113 | reg flush_began; 114 | reg flush_ended; 115 | reg [4:0] equal_cnt; 116 | always_ff @(posedge clk_gated) begin 117 | if (!rst_n_f) begin 118 | flush_began <= '0; 119 | flush_ended <= '0; 120 | equal_cnt <= '0; 121 | end else begin 122 | flush_began <= flush_begin || flush_began; 123 | flush_ended <= flush_began && flush_end || flush_ended; 124 | equal_cnt <= io_equal ? equal_cnt + 1 : '0; 125 | end 126 | end 127 | 128 | as__dev1_merger_vr_noc1_val: assert property (flush_ended |-> (dev1_merger_vr_noc1_val == dev1_merger_vr_noc1_val_2)); 129 | as__dev1_merger_vr_noc2_val: assert property (flush_ended |-> (dev1_merger_vr_noc2_val == dev1_merger_vr_noc2_val_2)); 130 | 131 | 132 | am__splitter_dev1_vr_noc2_dat: assume property (flush_began |-> (splitter_dev1_vr_noc2_dat == splitter_dev1_vr_noc2_dat_2)); 133 | am__l15_transducer_data_1: assume property (flush_began |-> (l15_transducer_data_1 == l15_transducer_data_1_2)); 134 | am__l15_transducer_data_0: assume property (flush_began |-> (l15_transducer_data_0 == l15_transducer_data_0_2)); 135 | am__l15_transducer_val: assume property (flush_began |-> (l15_transducer_val == l15_transducer_val_2)); 136 | am__splitter_dev1_vr_noc3_val: assume property (flush_began |-> (splitter_dev1_vr_noc3_val == splitter_dev1_vr_noc3_val_2)); 137 | am__splitter_dev1_vr_noc3_dat: assume property (flush_began |-> (splitter_dev1_vr_noc3_dat == splitter_dev1_vr_noc3_dat_2)); 138 | am__dev1_merger_vr_noc2_rdy: assume property (flush_began |-> (dev1_merger_vr_noc2_rdy == dev1_merger_vr_noc2_rdy_2)); 139 | am__l15_transducer_ack: assume property (flush_began |-> (l15_transducer_ack == l15_transducer_ack_2)); 140 | am__l15_transducer_returntype: assume property (flush_began |-> (l15_transducer_returntype == l15_transducer_returntype_2)); 141 | am__splitter_dev1_vr_noc1_val: assume property (flush_began |-> (splitter_dev1_vr_noc1_val == splitter_dev1_vr_noc1_val_2)); 142 | am__l15_transducer_threadid: assume property (flush_began |-> (l15_transducer_threadid == l15_transducer_threadid_2)); 143 | am__splitter_dev1_vr_noc1_dat: assume property (flush_began |-> (splitter_dev1_vr_noc1_dat == splitter_dev1_vr_noc1_dat_2)); 144 | am__l15_transducer_header_ack: assume property (flush_began |-> (l15_transducer_header_ack == l15_transducer_header_ack_2)); 145 | am__splitter_dev1_vr_noc2_val: assume property (flush_began |-> (splitter_dev1_vr_noc2_val == splitter_dev1_vr_noc2_val_2)); 146 | am__dev1_merger_vr_noc1_rdy: assume property (flush_began |-> (dev1_merger_vr_noc1_rdy == dev1_merger_vr_noc1_rdy_2)); 147 | 148 | assign io_equal = splitter_dev1_vr_noc2_rdy == splitter_dev1_vr_noc2_rdy_2 && 149 | transducer_l15_data == transducer_l15_data_2 && 150 | splitter_dev1_vr_noc2_dat == splitter_dev1_vr_noc2_dat_2 && 151 | transducer_l15_address == transducer_l15_address_2 && 152 | transducer_l15_threadid == transducer_l15_threadid_2 && 153 | l15_transducer_data_1 == l15_transducer_data_1_2 && 154 | dev1_merger_vr_noc2_val == dev1_merger_vr_noc2_val_2 && 155 | dev1_merger_vr_noc1_dat == dev1_merger_vr_noc1_dat_2 && 156 | splitter_dev1_vr_noc1_rdy == splitter_dev1_vr_noc1_rdy_2 && 157 | l15_transducer_data_0 == l15_transducer_data_0_2 && 158 | transducer_l15_blockinitstore == transducer_l15_blockinitstore_2 && 159 | l15_transducer_val == l15_transducer_val_2 && 160 | transducer_l15_l1rplway == transducer_l15_l1rplway_2 && 161 | splitter_dev1_vr_noc3_val == splitter_dev1_vr_noc3_val_2 && 162 | splitter_dev1_vr_noc3_dat == splitter_dev1_vr_noc3_dat_2 && 163 | dev1_merger_vr_noc2_dat == dev1_merger_vr_noc2_dat_2 && 164 | transducer_l15_blockstore == transducer_l15_blockstore_2 && 165 | dev1_merger_vr_noc2_rdy == dev1_merger_vr_noc2_rdy_2 && 166 | transducer_l15_amo_op == transducer_l15_amo_op_2 && 167 | dev1_merger_vr_noc1_val == dev1_merger_vr_noc1_val_2 && 168 | transducer_l15_invalidate_cacheline == transducer_l15_invalidate_cacheline_2 && 169 | transducer_l15_data_next_entry == transducer_l15_data_next_entry_2 && 170 | transducer_l15_size == transducer_l15_size_2 && 171 | transducer_l15_prefetch == transducer_l15_prefetch_2 && 172 | l15_transducer_ack == l15_transducer_ack_2 && 173 | splitter_dev1_vr_noc3_rdy == splitter_dev1_vr_noc3_rdy_2 && 174 | transducer_l15_nc == transducer_l15_nc_2 && 175 | transducer_l15_req_ack == transducer_l15_req_ack_2 && 176 | l15_transducer_returntype == l15_transducer_returntype_2 && 177 | splitter_dev1_vr_noc1_val == splitter_dev1_vr_noc1_val_2 && 178 | transducer_l15_csm_data == transducer_l15_csm_data_2 && 179 | l15_transducer_threadid == l15_transducer_threadid_2 && 180 | transducer_l15_rqtype == transducer_l15_rqtype_2 && 181 | splitter_dev1_vr_noc1_dat == splitter_dev1_vr_noc1_dat_2 && 182 | l15_transducer_header_ack == l15_transducer_header_ack_2 && 183 | splitter_dev1_vr_noc2_val == splitter_dev1_vr_noc2_val_2 && 184 | transducer_l15_val == transducer_l15_val_2 && 185 | dev1_merger_vr_noc1_rdy == dev1_merger_vr_noc1_rdy_2 && 186 | 1'b1; 187 | //============================================================================== 188 | // Modeling 189 | //============================================================================== 190 | 191 | 192 | //====DESIGNER-ADDED-SVA====// 193 | assign flush_begin = (equal_cnt>5'd8) && io_equal && u_is_core.dcp.u_pipe.c0_invalidate && u_is_core2.dcp.u_pipe.c0_invalidate; 194 | wire inv_done = !u_is_core.dcp.u_pipe.invalidate && !u_is_core2.dcp.u_pipe.invalidate; 195 | wire no_noc1 = u_is_core.dcp.u_pipe.u_dcp_pipe_sva.noc1out_outstanding_req_r=='0 && u_is_core2.dcp.u_pipe.u_dcp_pipe_sva.noc1out_outstanding_req_r=='0; 196 | wire no_noc2 = u_is_core.dcp.u_pipe.u_dcp_pipe_sva.noc2out_outstanding_req_r=='0 && u_is_core2.dcp.u_pipe.u_dcp_pipe_sva.noc2out_outstanding_req_r=='0; 197 | wire no_req = !transducer_l15_val && !transducer_l15_val_2 && !dev1_merger_vr_noc2_val && !dev1_merger_vr_noc2_val_2 && !dev1_merger_vr_noc1_val && !dev1_merger_vr_noc1_val_2; 198 | 199 | assign flush_end = inv_done && no_noc2 && no_noc1 && no_req; 200 | 201 | endmodule -------------------------------------------------------------------------------- /maple_setup_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Make sure that PITON_ROOT is set 4 | if [ -z "$PITON_ROOT" ]; then 5 | echo "ERROR: \$PITON_ROOT is not set" 6 | echo "Source ariane_setup.sh first" 7 | else 8 | # Make sure that AUTOCC_ROOT is set 9 | if [ -z "$AUTOCC_ROOT" ]; then 10 | echo "ERROR: \$AUTOCC_ROOT is not set" 11 | echo "Set AUTOCC_ROOT to the root of the AutoCC repository" 12 | else 13 | export DUT_ROOT=$PITON_ROOT/maple/rtl 14 | echo "DUT_ROOT set to $DUT_ROOT" 15 | 16 | cd $PITON_ROOT; 17 | 18 | # if maple folder does not exist 19 | if [ ! -d "maple" ]; then 20 | git clone https://github.com/PrincetonUniversity/maple.git 21 | cd maple; git checkout 91ebe23a052869f27b48318c96d6ef1978aa9b56 22 | cd $AUTOCC_ROOT 23 | python autocc.py -f is_core.v -m autocc_only_wrap 24 | rm -rf $AUTOCC_ROOT/ft_is_core 25 | fi 26 | 27 | cd $PITON_ROOT; 28 | sed -i 's/python$/python2/' piton/design/chip/tile/ariane/bootrom/Makefile; 29 | sed -i 's/python$/python2/' piton/design/chip/tile/ariane/openpiton/bootrom/linux/Makefile; 30 | 31 | cd $PITON_ROOT/build; 32 | sims -sys=manycore -ariane -decoupling -vcs_build -x_tiles=4 -y_tiles=1 -config_rtl=MINIMAL_MONITORING; 33 | echo "" 34 | echo "Finished BUILDING RTL" 35 | echo "" 36 | cd $PITON_ROOT/maple 37 | fi 38 | fi -------------------------------------------------------------------------------- /projs/README.md: -------------------------------------------------------------------------------- 1 | 2 | # For temporal files of JG projects -------------------------------------------------------------------------------- /sigs/aes.sig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 4 | 5 | clk 6 | 9 | 10 | aes_top.ROUND[0].U_ROUND.valid_sub2shift 11 | 14 | 15 | aes_top.ROUND[0].U_ROUND.valid_shift2mix 16 | 19 | 20 | aes_top.ROUND[0].U_ROUND.valid_mix2key 21 | 24 | 25 | aes_top.ROUND[0].U_ROUND.valid_out 26 | 29 | 30 | aes_top.reset 31 | 34 | 35 | flush 36 | 39 | 40 | u_aes_wrap_sva.flush_precondition 41 | 44 | 45 | u_aes_wrap_sva.flushed 46 | 49 | 50 | aes_top.valid_round_data 51 | 54 | 55 | aes_top2.valid_round_data 56 | 59 | 60 | aes_top.data_valid_in 61 | 64 | 65 | aes_top2.data_valid_in 66 | 69 | 70 | aes_top.cipherkey_valid_in 71 | 74 | 75 | aes_top2.cipherkey_valid_in 76 | 79 | 80 | aes_top.cond 81 | 84 | 85 | aes_top2.cond 86 | 89 | 90 | aes_top.valid_shift2key_delayed 91 | 94 | 95 | aes_top2.valid_shift2key_delayed 96 | 99 | 100 | aes_top.U_KEY.data_valid_in 101 | 104 | 105 | aes_top.valid_out 106 | 109 | 110 | aes_top2.valid_out 111 | 114 | 115 | aes_top.valid_shift2key 116 | 119 | 120 | aes_top2.valid_shift2key 121 | 124 | 125 | u_aes_wrap_sva.flush_precondition 126 | 129 | 130 | u_aes_wrap_sva.cipherkey_valid_in 131 | 134 | 135 | u_aes_wrap_sva.cipherkey_valid_in2 136 | 139 | 140 | u_aes_wrap_sva.cipher_text 141 | 144 | 145 | u_aes_wrap_sva.cipher_text2 146 | 149 | 150 | aes_top.data_r 151 | 154 | 155 | aes_top2.data_r 156 | 159 | 160 | aes_top.val_r 161 | 164 | 165 | aes_top2.val_r 166 | 169 | 170 | -------------------------------------------------------------------------------- /sigs/cva6_c1.sig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 4 | 5 | clk_i 6 | 9 | 10 | u_cva6_sva.arch_restored 11 | 14 | 15 | u_cva6_sva.csr_equal 16 | 19 | 20 | u_cva6_sva.io_equal 21 | 24 | 25 | u_cva6_sva.equal_cnt 26 | 29 | 30 | u_cva6_sva.still_equal_after_period 31 | 34 | 35 | u_cva6_sva.both_flush_done 36 | 39 | 40 | 41 | 42 | 43 | ariane1.i_frontend.i_instr_realign.instr_is_compressed[0] 44 | 47 | 48 | ariane2.i_frontend.i_instr_realign.instr_is_compressed[0] 49 | 52 | 53 | 54 | ariane1.i_frontend.i_instr_queue.pc_q 55 | 58 | 59 | ariane2.i_frontend.i_instr_queue.pc_q 60 | 63 | 64 | 65 | 66 | ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.flush_i 67 | builtin_red 68 | 69 | 70 | ariane1.genblk3.i_cache_subsystem.i_cva6_icache.mem_data_req_o 71 | builtin_red 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /sigs/cva6_c2.sig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2 4 | 5 | ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.state_d 6 | 9 | 10 | ariane2.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.state_d 11 | 14 | 15 | ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.state_q 16 | 19 | 20 | ariane2.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.state_q 21 | 24 | 25 | ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.flush_i 26 | 29 | 30 | 31 | 32 | ariane1.commit_stage_i.csr_rdata_i 33 | builtin_blue 34 | 35 | 36 | ariane1.commit_stage_i.wdata_o[0] 37 | builtin_blue 38 | 39 | 40 | ariane1.csr_regfile_i.csr_wdata_i 41 | builtin_blue 42 | 43 | 44 | ariane1.csr_regfile_i.perf_data_i 45 | builtin_blue 46 | 47 | 48 | ariane1.csr_regfile_i.perf_data_o 49 | builtin_blue 50 | 51 | 52 | ariane1.data_csr_perf 53 | builtin_blue 54 | 55 | 56 | ariane1.data_perf_csr 57 | builtin_blue 58 | 59 | 60 | ariane1.ex_stage_i.alu_i.adder_in_a 61 | builtin_blue 62 | 63 | 64 | ariane1.ex_stage_i.alu_i.adder_in_b 65 | builtin_blue 66 | 67 | 68 | ariane1.ex_stage_i.alu_i.fu_data_i.operand_a 69 | builtin_blue 70 | 71 | 72 | ariane1.ex_stage_i.branch_unit_i.resolved_branch_o.is_mispredict 73 | builtin_blue 74 | 75 | 76 | ariane1.ex_stage_i.fu_data_i 77 | builtin_blue 78 | 79 | 80 | ariane1.ex_stage_i.fu_data_i.operand_a 81 | builtin_blue 82 | 83 | 84 | ariane1.ex_stage_i.lsu_i.gen_mmu_sv39.i_cva6_mmu.i_ptw.flush_i 85 | builtin_red 86 | 87 | 88 | ariane1.fence_t_commit_controller 89 | builtin_blue 90 | 91 | 92 | ariane1.genblk3.i_cache_subsystem.i_cva6_icache.mem_data_req_o 93 | builtin_red 94 | 95 | 96 | ariane1.i_cache_subsystem.dcache_flush_ack_o 97 | builtin_orange 98 | 99 | 100 | ariane1.i_cache_subsystem.i_adapter.axi_rd_valid 101 | builtin_blue 102 | 103 | 104 | ariane1.i_cache_subsystem.i_adapter.axi_req_o 105 | builtin_blue 106 | 107 | 108 | ariane1.i_cache_subsystem.i_adapter.axi_resp_i 109 | builtin_blue 110 | 111 | 112 | ariane1.i_cache_subsystem.i_adapter.i_axi_shim.rd_req_i 113 | builtin_red 114 | 115 | 116 | ariane1.i_cache_subsystem.i_adapter.i_axi_shim.rd_valid_o 117 | builtin_orange 118 | 119 | 120 | ariane1.i_cache_subsystem.i_adapter.icache_data_req_i 121 | builtin_blue 122 | 123 | 124 | ariane1.i_cache_subsystem.i_adapter.icache_rtrn_vld_q 125 | builtin_blue 126 | 127 | 128 | ariane1.i_cache_subsystem.i_wt_icache.dreq_i.kill_s2 129 | builtin_blue 130 | 131 | 132 | ariane1.i_cache_subsystem.i_wt_icache.dreq_i.req 133 | builtin_orange 134 | 135 | 136 | ariane1.i_cache_subsystem.i_wt_icache.flush_d 137 | builtin_blue 138 | 139 | 140 | ariane1.i_cache_subsystem.i_wt_icache.flush_done 141 | builtin_orange 142 | 143 | 144 | ariane1.i_cache_subsystem.i_wt_icache.flush_i 145 | builtin_blue 146 | 147 | 148 | ariane1.i_cache_subsystem.i_wt_icache.mem_rtrn_vld_i 149 | builtin_blue 150 | 151 | 152 | ariane1.i_cache_subsystem.i_wt_icache.state_q 153 | builtin_blue 154 | 155 | 156 | ariane1.i_frontend.flush_i 157 | builtin_blue 158 | 159 | 160 | ariane1.i_frontend.i_instr_queue.fetch_entry_ready_i 161 | builtin_blue 162 | 163 | 164 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[0].i_fifo_instr_data.empty_o 165 | builtin_blue 166 | 167 | 168 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.data_i 169 | builtin_blue 170 | 171 | 172 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.data_o 173 | builtin_blue 174 | 175 | 176 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.mem_n 177 | builtin_blue 178 | 179 | 180 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.mem_q 181 | builtin_blue 182 | 183 | 184 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.read_pointer_q 185 | builtin_blue 186 | 187 | 188 | ariane1.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.write_pointer_q 189 | builtin_blue 190 | 191 | 192 | ariane1.i_frontend.i_instr_queue.instr_queue_empty 193 | builtin_blue 194 | 195 | 196 | ariane1.i_frontend.i_instr_queue.pc_q 197 | builtin_blue 198 | 199 | 200 | ariane1.i_frontend.resolved_branch_i.is_mispredict 201 | builtin_blue 202 | 203 | 204 | ariane1.i_perf_counters.rst_ni 205 | builtin_blue 206 | 207 | 208 | ariane1.id_stage_i.decoder_i.imm_i_type 209 | builtin_blue 210 | 211 | 212 | ariane1.id_stage_i.decoder_i.imm_select 213 | builtin_blue 214 | 215 | 216 | ariane1.id_stage_i.decoder_i.imm_u_type 217 | builtin_blue 218 | 219 | 220 | ariane1.id_stage_i.decoder_i.instruction_i 221 | builtin_blue 222 | 223 | 224 | ariane1.id_stage_i.decoder_i.instruction_o.fu 225 | builtin_blue 226 | 227 | 228 | ariane1.id_stage_i.decoder_i.instruction_o.op 229 | builtin_blue 230 | 231 | 232 | ariane1.id_stage_i.decoder_i.instruction_o.rd 233 | builtin_blue 234 | 235 | 236 | ariane1.id_stage_i.decoder_i.instruction_o.rs1 237 | builtin_blue 238 | 239 | 240 | ariane1.id_stage_i.decoder_i.instruction_o.rs2 241 | builtin_blue 242 | 243 | 244 | ariane1.id_stage_i.fetch_entry_i.address 245 | builtin_blue 246 | 247 | 248 | ariane1.id_stage_i.fetch_entry_i.instruction[15:0] 249 | builtin_blue 250 | 251 | 252 | ariane1.id_stage_i.fetch_entry_ready_o 253 | builtin_blue 254 | 255 | 256 | ariane1.id_stage_i.fetch_entry_valid_i 257 | builtin_blue 258 | 259 | 260 | ariane1.issue_stage_i.i_issue_read_operands.i_ariane_regfile.mem 261 | builtin_blue 262 | 263 | 264 | ariane1.issue_stage_i.i_issue_read_operands.i_ariane_regfile.raddr_i 265 | builtin_blue 266 | 267 | 268 | ariane1.issue_stage_i.i_issue_read_operands.i_ariane_regfile.rdata_o 269 | builtin_blue 270 | 271 | 272 | ariane1.issue_stage_i.i_issue_read_operands.i_ariane_regfile.waddr_i 273 | builtin_blue 274 | 275 | 276 | ariane1.issue_stage_i.i_issue_read_operands.i_ariane_regfile.wdata_i 277 | builtin_blue 278 | 279 | 280 | ariane1.issue_stage_i.i_issue_read_operands.i_ariane_regfile.we_i 281 | builtin_blue 282 | 283 | 284 | ariane1.issue_stage_i.i_issue_read_operands.issue_instr_i.rs1[4:0] 285 | builtin_blue 286 | 287 | 288 | ariane1.issue_stage_i.i_issue_read_operands.issue_instr_i.rs2[4:0] 289 | builtin_blue 290 | 291 | 292 | ariane1.issue_stage_i.i_issue_read_operands.operand_a_q 293 | builtin_blue 294 | 295 | 296 | ariane1.issue_stage_i.i_issue_read_operands.operand_a_regfile 297 | builtin_blue 298 | 299 | 300 | ariane1.issue_stage_i.i_issue_read_operands.operand_b_regfile 301 | builtin_blue 302 | 303 | 304 | ariane1.issue_stage_i.i_issue_read_operands.rdata[0] 305 | builtin_blue 306 | 307 | 308 | ariane1.issue_stage_i.i_issue_read_operands.waddr_i 309 | builtin_blue 310 | 311 | 312 | ariane1.issue_stage_i.i_issue_read_operands.waddr_i[0] 313 | builtin_blue 314 | 315 | 316 | ariane1.issue_stage_i.i_issue_read_operands.waddr_i[1] 317 | builtin_blue 318 | 319 | 320 | ariane1.issue_stage_i.i_issue_read_operands.wdata_i 321 | builtin_blue 322 | 323 | 324 | ariane1.issue_stage_i.i_issue_read_operands.wdata_i[0] 325 | builtin_blue 326 | 327 | 328 | ariane1.issue_stage_i.i_issue_read_operands.wdata_i[1] 329 | builtin_blue 330 | 331 | 332 | ariane1.issue_stage_i.i_issue_read_operands.we_gpr_i 333 | builtin_blue 334 | 335 | 336 | ariane1.issue_stage_i.i_issue_read_operands.we_gpr_i[0] 337 | builtin_blue 338 | 339 | 340 | ariane1.issue_stage_i.i_issue_read_operands.we_gpr_i[1] 341 | builtin_blue 342 | 343 | 344 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i 345 | builtin_blue 346 | 347 | 348 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.bp 349 | builtin_blue 350 | 351 | 352 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.ex 353 | builtin_blue 354 | 355 | 356 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.fu 357 | builtin_blue 358 | 359 | 360 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.is_compressed 361 | builtin_blue 362 | 363 | 364 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.op 365 | builtin_blue 366 | 367 | 368 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.pc 369 | builtin_blue 370 | 371 | 372 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.rd 373 | builtin_blue 374 | 375 | 376 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.result 377 | builtin_blue 378 | 379 | 380 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.rs1 381 | builtin_blue 382 | 383 | 384 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.rs2 385 | builtin_blue 386 | 387 | 388 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.trans_id 389 | builtin_blue 390 | 391 | 392 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.use_imm 393 | builtin_blue 394 | 395 | 396 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.use_pc 397 | builtin_blue 398 | 399 | 400 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.use_zimm 401 | builtin_blue 402 | 403 | 404 | ariane1.issue_stage_i.i_scoreboard.decoded_instr_i.valid 405 | builtin_blue 406 | 407 | 408 | ariane1.resolved_branch 409 | builtin_blue 410 | 411 | 412 | ariane1.u_ariane_sva.axi_read_outstanding_req_r[0] 413 | builtin_red 414 | 415 | 416 | ariane1.u_ariane_sva.axi_read_outstanding_req_r[1] 417 | builtin_red 418 | 419 | 420 | ariane1.u_ariane_sva.axi_read_outstanding_req_r[3] 421 | builtin_red 422 | 423 | 424 | ariane1.u_ariane_sva.axi_write_outstanding_req_r[0] 425 | builtin_red 426 | 427 | 428 | ariane1.u_ariane_sva.axi_write_outstanding_req_r[1] 429 | builtin_red 430 | 431 | 432 | ariane1.u_ariane_sva.axi_write_outstanding_req_r[3] 433 | builtin_red 434 | 435 | 436 | ariane1.we_csr_perf 437 | builtin_blue 438 | 439 | 440 | ariane2.commit_stage_i.csr_rdata_i 441 | builtin_green 442 | 443 | 444 | ariane2.commit_stage_i.wdata_o[0] 445 | builtin_green 446 | 447 | 448 | ariane2.csr_regfile_i.csr_wdata_i 449 | builtin_green 450 | 451 | 452 | ariane2.csr_regfile_i.perf_data_i 453 | builtin_green 454 | 455 | 456 | ariane2.csr_regfile_i.perf_data_o 457 | builtin_green 458 | 459 | 460 | ariane2.data_csr_perf 461 | builtin_green 462 | 463 | 464 | ariane2.data_perf_csr 465 | builtin_green 466 | 467 | 468 | ariane2.ex_stage_i.alu_i.adder_in_a 469 | builtin_green 470 | 471 | 472 | ariane2.ex_stage_i.alu_i.adder_in_b 473 | builtin_green 474 | 475 | 476 | ariane2.ex_stage_i.alu_i.fu_data_i.operand_a 477 | builtin_green 478 | 479 | 480 | ariane2.ex_stage_i.branch_unit_i.fu_data_i.operator 481 | builtin_green 482 | 483 | 484 | ariane2.ex_stage_i.branch_unit_i.resolved_branch_o.is_mispredict 485 | builtin_green 486 | 487 | 488 | ariane2.ex_stage_i.fu_data_i 489 | builtin_green 490 | 491 | 492 | ariane2.ex_stage_i.fu_data_i.operand_a 493 | builtin_green 494 | 495 | 496 | ariane2.fence_t_commit_controller 497 | builtin_green 498 | 499 | 500 | ariane2.i_cache_subsystem.dcache_flush_ack_o 501 | builtin_orange 502 | 503 | 504 | ariane2.i_cache_subsystem.i_adapter.axi_rd_valid 505 | builtin_green 506 | 507 | 508 | ariane2.i_cache_subsystem.i_adapter.axi_req_o 509 | builtin_green 510 | 511 | 512 | ariane2.i_cache_subsystem.i_adapter.axi_resp_i 513 | builtin_green 514 | 515 | 516 | ariane2.i_cache_subsystem.i_adapter.i_axi_shim.rd_req_i 517 | builtin_blue 518 | 519 | 520 | ariane2.i_cache_subsystem.i_adapter.icache_data_req_i 521 | builtin_green 522 | 523 | 524 | ariane2.i_cache_subsystem.i_adapter.icache_rtrn_vld_q 525 | builtin_green 526 | 527 | 528 | ariane2.i_cache_subsystem.i_wt_icache.areq_i.fetch_valid 529 | builtin_green 530 | 531 | 532 | ariane2.i_cache_subsystem.i_wt_icache.dreq_i.kill_s2 533 | builtin_green 534 | 535 | 536 | ariane2.i_cache_subsystem.i_wt_icache.dreq_i.req 537 | builtin_green 538 | 539 | 540 | ariane2.i_cache_subsystem.i_wt_icache.flush_d 541 | builtin_green 542 | 543 | 544 | ariane2.i_cache_subsystem.i_wt_icache.flush_done 545 | builtin_orange 546 | 547 | 548 | ariane2.i_cache_subsystem.i_wt_icache.flush_i 549 | builtin_green 550 | 551 | 552 | ariane2.i_cache_subsystem.i_wt_icache.mem_rtrn_vld_i 553 | builtin_green 554 | 555 | 556 | ariane2.i_cache_subsystem.i_wt_icache.state_q 557 | builtin_green 558 | 559 | 560 | ariane2.i_frontend.flush_i 561 | builtin_green 562 | 563 | 564 | ariane2.i_frontend.i_instr_queue.fetch_entry_ready_i 565 | builtin_green 566 | 567 | 568 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[0].i_fifo_instr_data.empty_o 569 | builtin_green 570 | 571 | 572 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.data_i 573 | builtin_green 574 | 575 | 576 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.data_o 577 | builtin_green 578 | 579 | 580 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.mem_n 581 | builtin_green 582 | 583 | 584 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.mem_q 585 | builtin_green 586 | 587 | 588 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.read_pointer_q 589 | builtin_green 590 | 591 | 592 | ariane2.i_frontend.i_instr_queue.gen_instr_fifo[1].i_fifo_instr_data.write_pointer_q 593 | builtin_green 594 | 595 | 596 | ariane2.i_frontend.i_instr_queue.instr_data_in[0].instr 597 | builtin_green 598 | 599 | 600 | ariane2.i_frontend.i_instr_queue.instr_queue_empty 601 | builtin_green 602 | 603 | 604 | ariane2.i_frontend.i_instr_queue.pc_q 605 | builtin_green 606 | 607 | 608 | ariane2.i_frontend.icache_dreq_i.valid 609 | builtin_green 610 | 611 | 612 | ariane2.i_frontend.resolved_branch_i.is_mispredict 613 | builtin_green 614 | 615 | 616 | ariane2.i_perf_counters.rst_ni 617 | builtin_green 618 | 619 | 620 | ariane2.id_stage_i.decoder_i.instruction_i 621 | builtin_green 622 | 623 | 624 | ariane2.id_stage_i.decoder_i.instruction_o.fu 625 | builtin_green 626 | 627 | 628 | ariane2.id_stage_i.decoder_i.instruction_o.op 629 | builtin_green 630 | 631 | 632 | ariane2.id_stage_i.decoder_i.instruction_o.rd 633 | builtin_green 634 | 635 | 636 | ariane2.id_stage_i.decoder_i.instruction_o.rs1 637 | builtin_green 638 | 639 | 640 | ariane2.id_stage_i.decoder_i.instruction_o.rs2 641 | builtin_green 642 | 643 | 644 | ariane2.id_stage_i.fetch_entry_i.address 645 | builtin_green 646 | 647 | 648 | ariane2.id_stage_i.fetch_entry_i.instruction[15:0] 649 | builtin_green 650 | 651 | 652 | ariane2.id_stage_i.fetch_entry_ready_o 653 | builtin_green 654 | 655 | 656 | ariane2.id_stage_i.fetch_entry_valid_i 657 | builtin_green 658 | 659 | 660 | ariane2.issue_stage_i.i_issue_read_operands.i_ariane_regfile.mem 661 | builtin_green 662 | 663 | 664 | ariane2.issue_stage_i.i_issue_read_operands.i_ariane_regfile.raddr_i 665 | builtin_green 666 | 667 | 668 | ariane2.issue_stage_i.i_issue_read_operands.i_ariane_regfile.rdata_o 669 | builtin_green 670 | 671 | 672 | ariane2.issue_stage_i.i_issue_read_operands.i_ariane_regfile.waddr_i 673 | builtin_green 674 | 675 | 676 | ariane2.issue_stage_i.i_issue_read_operands.i_ariane_regfile.wdata_i 677 | builtin_green 678 | 679 | 680 | ariane2.issue_stage_i.i_issue_read_operands.i_ariane_regfile.we_i 681 | builtin_green 682 | 683 | 684 | ariane2.issue_stage_i.i_issue_read_operands.operand_a_q 685 | builtin_green 686 | 687 | 688 | ariane2.issue_stage_i.i_issue_read_operands.operand_a_regfile 689 | builtin_green 690 | 691 | 692 | ariane2.issue_stage_i.i_issue_read_operands.operand_b_regfile 693 | builtin_green 694 | 695 | 696 | ariane2.issue_stage_i.i_issue_read_operands.rdata[0] 697 | builtin_green 698 | 699 | 700 | ariane2.issue_stage_i.i_issue_read_operands.waddr_i 701 | builtin_green 702 | 703 | 704 | ariane2.issue_stage_i.i_issue_read_operands.wdata_i 705 | builtin_green 706 | 707 | 708 | ariane2.issue_stage_i.i_issue_read_operands.we_gpr_i 709 | builtin_green 710 | 711 | 712 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i 713 | builtin_green 714 | 715 | 716 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i <> ariane1.issue_stage_i.i_scoreboard.decoded_instr_i 717 | builtin_yellow 718 | 719 | 720 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.bp 721 | builtin_green 722 | 723 | 724 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.ex 725 | builtin_green 726 | 727 | 728 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.fu 729 | builtin_green 730 | 731 | 732 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.is_compressed 733 | builtin_green 734 | 735 | 736 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.op 737 | builtin_green 738 | 739 | 740 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.pc 741 | builtin_green 742 | 743 | 744 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.rd 745 | builtin_green 746 | 747 | 748 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.result 749 | builtin_green 750 | 751 | 752 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.rs1 753 | builtin_green 754 | 755 | 756 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.rs2 757 | builtin_green 758 | 759 | 760 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.trans_id 761 | builtin_green 762 | 763 | 764 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.use_imm 765 | builtin_green 766 | 767 | 768 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.use_pc 769 | builtin_green 770 | 771 | 772 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.use_zimm 773 | builtin_green 774 | 775 | 776 | ariane2.issue_stage_i.i_scoreboard.decoded_instr_i.valid 777 | builtin_green 778 | 779 | 780 | ariane2.resolved_branch 781 | builtin_green 782 | 783 | 784 | ariane2.we_csr_perf 785 | builtin_green 786 | 787 | 788 | u_ariane_wrap_sva.arch1[127:0] 789 | builtin_blue 790 | 791 | 792 | u_ariane_wrap_sva.arch2[127:0] 793 | builtin_green 794 | 795 | 796 | u_ariane_wrap_sva.arch_same_post 797 | builtin_red 798 | 799 | 800 | u_ariane_wrap_sva.axi_req_o2.ar_valid 801 | builtin_blue 802 | 803 | 804 | u_ariane_wrap_sva.check 805 | builtin_red 806 | 807 | 808 | u_ariane_wrap_sva.flushed 809 | builtin_red 810 | 811 | 812 | u_is_core.dcp.u_pipe.c0_aconfigure 813 | builtin_blue 814 | 815 | 816 | u_is_core2.dcp.u_pipe.c0_val 817 | builtin_red 818 | 819 | 820 | u_is_core2.dcp.u_pipe.c1_val 821 | builtin_red 822 | 823 | 824 | u_is_core_sva.dev1_merger_vr_noc1_val 825 | builtin_red 826 | 827 | 828 | u_vscale_pipeline_sva.mem1_val_r 829 | builtin_blue 830 | 831 | 832 | u_vscale_pipeline_sva.reg1_val_r 833 | builtin_blue 834 | 835 | 836 | 837 | -------------------------------------------------------------------------------- /sigs/vscale.sig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 4 | 5 | clk 6 | 9 | 10 | u_vscale_core.pipeline.ctrl.reset 11 | 14 | 15 | u_vscale_core_sva.io_equal 16 | 19 | 20 | u_vscale_core_sva.equal_cnt 21 | 24 | 25 | u_vscale_core_sva.spy_starts 26 | 29 | 30 | u_vscale_core_sva.spy_mode 31 | 34 | 35 | dmem_hwrite 36 | 39 | 40 | dmem_hwrite_2 41 | 44 | 45 | u_vscale_core.pipeline.ctrl.opcode 46 | 49 | 50 | u_vscale_core2.pipeline.ctrl.opcode 51 | 54 | 55 | u_vscale_core_sva.imem_haddr 56 | 59 | 60 | u_vscale_core_sva.imem_haddr_2 61 | 64 | 65 | u_vscale_core.dmem_bridge.core_mem_en 66 | 69 | 70 | u_vscale_core2.dmem_bridge.core_mem_en 71 | 74 | 75 | u_vscale_core_sva.dmem_htrans 76 | 79 | 80 | u_vscale_core_sva.dmem_htrans_2 81 | 84 | 85 | u_vscale_core.pipeline.PC_IF 86 | 89 | 90 | u_vscale_core2.pipeline.PC_IF 91 | 94 | 95 | u_vscale_core.pipeline.PC_PIF 96 | 99 | 100 | u_vscale_core2.pipeline.PC_PIF 101 | 104 | 105 | u_vscale_core.pipeline.ctrl.stall_IF 106 | 109 | 110 | u_vscale_core2.pipeline.ctrl.stall_IF 111 | 114 | 115 | u_vscale_core.pipeline.PCmux.PC_src_sel 116 | 119 | 120 | u_vscale_core2.pipeline.PCmux.PC_src_sel 121 | 124 | 125 | u_vscale_core.pipeline.kill_IF 126 | 129 | 130 | u_vscale_core2.pipeline.kill_IF 131 | 134 | 135 | u_vscale_core.pipeline.ctrl.opcode 136 | 139 | 140 | u_vscale_core2.pipeline.ctrl.opcode 141 | 144 | 145 | u_vscale_core.pipeline.ctrl.branch_taken 146 | 149 | 150 | u_vscale_core2.pipeline.ctrl.branch_taken 151 | 154 | 155 | u_vscale_core.pipeline.regfile.data 156 | 157 | 158 | u_vscale_core.pipeline.regfile.data[31] 159 | 162 | 163 | u_vscale_core.pipeline.regfile.data[30] 164 | 167 | 168 | u_vscale_core.pipeline.regfile.data[29] 169 | 172 | 173 | u_vscale_core.pipeline.regfile.data[28] 174 | 177 | 178 | u_vscale_core.pipeline.regfile.data[27] 179 | 182 | 183 | u_vscale_core.pipeline.regfile.data[26] 184 | 187 | 188 | u_vscale_core.pipeline.regfile.data[25] 189 | 192 | 193 | u_vscale_core.pipeline.regfile.data[24] 194 | 197 | 198 | u_vscale_core.pipeline.regfile.data[23] 199 | 202 | 203 | u_vscale_core.pipeline.regfile.data[22] 204 | 207 | 208 | u_vscale_core.pipeline.regfile.data[21] 209 | 212 | 213 | u_vscale_core.pipeline.regfile.data[20] 214 | 217 | 218 | u_vscale_core.pipeline.regfile.data[19] 219 | 222 | 223 | u_vscale_core.pipeline.regfile.data[18] 224 | 227 | 228 | u_vscale_core.pipeline.regfile.data[17] 229 | 232 | 233 | u_vscale_core.pipeline.regfile.data[16] 234 | 237 | 238 | u_vscale_core.pipeline.regfile.data[15] 239 | 242 | 243 | u_vscale_core.pipeline.regfile.data[14] 244 | 247 | 248 | u_vscale_core.pipeline.regfile.data[13] 249 | 252 | 253 | u_vscale_core.pipeline.regfile.data[12] 254 | 257 | 258 | u_vscale_core.pipeline.regfile.data[11] 259 | 262 | 263 | u_vscale_core.pipeline.regfile.data[10] 264 | 267 | 268 | u_vscale_core.pipeline.regfile.data[9] 269 | 272 | 273 | u_vscale_core.pipeline.regfile.data[8] 274 | 277 | 278 | u_vscale_core.pipeline.regfile.data[7] 279 | 282 | 283 | u_vscale_core.pipeline.regfile.data[6] 284 | 287 | 288 | u_vscale_core.pipeline.regfile.data[5] 289 | 292 | 293 | u_vscale_core.pipeline.regfile.data[4] 294 | 297 | 298 | u_vscale_core.pipeline.regfile.data[3] 299 | 302 | 303 | u_vscale_core.pipeline.regfile.data[2] 304 | 307 | 308 | u_vscale_core.pipeline.regfile.data[1] 309 | 312 | 313 | u_vscale_core.pipeline.regfile.data[0] 314 | 317 | 318 | 319 | u_vscale_core2.pipeline.regfile.data 320 | 321 | 322 | u_vscale_core2.pipeline.regfile.data[31] 323 | 326 | 327 | u_vscale_core2.pipeline.regfile.data[30] 328 | 331 | 332 | u_vscale_core2.pipeline.regfile.data[29] 333 | 336 | 337 | u_vscale_core2.pipeline.regfile.data[28] 338 | 341 | 342 | u_vscale_core2.pipeline.regfile.data[27] 343 | 346 | 347 | u_vscale_core2.pipeline.regfile.data[26] 348 | 351 | 352 | u_vscale_core2.pipeline.regfile.data[25] 353 | 356 | 357 | u_vscale_core2.pipeline.regfile.data[24] 358 | 361 | 362 | u_vscale_core2.pipeline.regfile.data[23] 363 | 366 | 367 | u_vscale_core2.pipeline.regfile.data[22] 368 | 371 | 372 | u_vscale_core2.pipeline.regfile.data[21] 373 | 376 | 377 | u_vscale_core2.pipeline.regfile.data[20] 378 | 381 | 382 | u_vscale_core2.pipeline.regfile.data[19] 383 | 386 | 387 | u_vscale_core2.pipeline.regfile.data[18] 388 | 391 | 392 | u_vscale_core2.pipeline.regfile.data[17] 393 | 396 | 397 | u_vscale_core2.pipeline.regfile.data[16] 398 | 401 | 402 | u_vscale_core2.pipeline.regfile.data[15] 403 | 406 | 407 | u_vscale_core2.pipeline.regfile.data[14] 408 | 411 | 412 | u_vscale_core2.pipeline.regfile.data[13] 413 | 416 | 417 | u_vscale_core2.pipeline.regfile.data[12] 418 | 421 | 422 | u_vscale_core2.pipeline.regfile.data[11] 423 | 426 | 427 | u_vscale_core2.pipeline.regfile.data[10] 428 | 431 | 432 | u_vscale_core2.pipeline.regfile.data[9] 433 | 436 | 437 | u_vscale_core2.pipeline.regfile.data[8] 438 | 441 | 442 | u_vscale_core2.pipeline.regfile.data[7] 443 | 446 | 447 | u_vscale_core2.pipeline.regfile.data[6] 448 | 451 | 452 | u_vscale_core2.pipeline.regfile.data[5] 453 | 456 | 457 | u_vscale_core2.pipeline.regfile.data[4] 458 | 461 | 462 | u_vscale_core2.pipeline.regfile.data[3] 463 | 466 | 467 | u_vscale_core2.pipeline.regfile.data[2] 468 | 471 | 472 | u_vscale_core2.pipeline.regfile.data[1] 473 | 476 | 477 | u_vscale_core2.pipeline.regfile.data[0] 478 | 481 | 482 | 483 | u_vscale_core.pipeline.PC_WB 484 | 487 | 488 | u_vscale_core2.pipeline.PC_WB 489 | 492 | 493 | 494 | 495 | u_vscale_core_sva.imem_haddr_2 496 | builtin_red 497 | 498 | 499 | 500 | --------------------------------------------------------------------------------