diff --git a/vendor/lowrisc_ip.lock.hjson b/vendor/lowrisc_ip.lock.hjson index 8eadd28d..d4e023fd 100644 --- a/vendor/lowrisc_ip.lock.hjson +++ b/vendor/lowrisc_ip.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/lowRISC/opentitan - rev: ebf4663b42a9d81d026db5821b5c8249d54f23a7 + rev: 067272a253f4eeed4ae58a9171ee266256528117 } } diff --git a/vendor/lowrisc_ip/csr_utils/csr_utils_pkg.sv b/vendor/lowrisc_ip/csr_utils/csr_utils_pkg.sv index 04e98c35..fa3a4426 100644 --- a/vendor/lowrisc_ip/csr_utils/csr_utils_pkg.sv +++ b/vendor/lowrisc_ip/csr_utils/csr_utils_pkg.sv @@ -178,12 +178,13 @@ package csr_utils_pkg; input uvm_path_e path = UVM_DEFAULT_PATH, input bit blocking = default_csr_blocking, input uint timeout_ns = default_timeout_ns, - input uvm_reg_map map = null); + input uvm_reg_map map = null, + input bit en_shadow_wr = 1); if (blocking) begin - csr_update_sub(csr, check, path, timeout_ns, map); + csr_update_sub(csr, check, path, timeout_ns, map, en_shadow_wr); end else begin fork - csr_update_sub(csr, check, path, timeout_ns, map); + csr_update_sub(csr, check, path, timeout_ns, map, en_shadow_wr); join_none // Add #0 to ensure that this thread starts executing before any subsequent call #0; @@ -195,7 +196,8 @@ package csr_utils_pkg; input uvm_check_e check = UVM_CHECK, input uvm_path_e path = UVM_DEFAULT_PATH, input uint timeout_ns = default_timeout_ns, - input uvm_reg_map map = null); + input uvm_reg_map map = null, + input bit en_shadow_wr = 1); fork begin : isolation_fork uvm_status_e status; @@ -204,7 +206,9 @@ package csr_utils_pkg; fork begin increment_outstanding_access(); + csr_pre_write_sub(csr, en_shadow_wr); csr.update(.status(status), .path(path), .map(map), .prior(100)); + csr_post_write_sub(csr, en_shadow_wr); if (check == UVM_CHECK) begin `DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id) end @@ -229,16 +233,17 @@ package csr_utils_pkg; input bit backdoor = 0, input uint timeout_ns = default_timeout_ns, input bit predict = 0, - input uvm_reg_map map = null); + input uvm_reg_map map = null, + input bit en_shadow_wr = 1); if (backdoor) begin csr_poke(csr, value, check, predict); end else if (blocking) begin - csr_wr_sub(csr, value, check, path, timeout_ns, map); + csr_wr_sub(csr, value, check, path, timeout_ns, map, en_shadow_wr); if (predict) void'(csr.predict(.value(value), .kind(UVM_PREDICT_WRITE))); end else begin fork begin - csr_wr_sub(csr, value, check, path, timeout_ns, map); + csr_wr_sub(csr, value, check, path, timeout_ns, map, en_shadow_wr); // predict after csr_wr_sub, to ensure predict after enable register overwrite the locked // registers' access information if (predict) void'(csr.predict(.value(value), .kind(UVM_PREDICT_WRITE))); @@ -255,7 +260,8 @@ package csr_utils_pkg; input uvm_check_e check = UVM_CHECK, input uvm_path_e path = UVM_DEFAULT_PATH, input uint timeout_ns = default_timeout_ns, - input uvm_reg_map map = null); + input uvm_reg_map map = null, + input bit en_shadow_wr = 1); fork begin : isolation_fork uvm_status_e status; @@ -264,7 +270,9 @@ package csr_utils_pkg; fork begin increment_outstanding_access(); + csr_pre_write_sub(csr, en_shadow_wr); csr.write(.status(status), .value(value), .path(path), .map(map), .prior(100)); + csr_post_write_sub(csr, en_shadow_wr); if (check == UVM_CHECK) begin `DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id) end @@ -281,6 +289,30 @@ package csr_utils_pkg; join endtask + task automatic csr_pre_write_sub(ref uvm_reg csr, bit en_shadow_wr); + dv_base_reg dv_reg; + `downcast(dv_reg, csr, "", fatal, msg_id) + if (dv_reg.get_is_shadowed()) begin + if (en_shadow_wr) increment_outstanding_access(); + dv_reg.atomic_en_shadow_wr.get(1); + dv_reg.set_en_shadow_wr(en_shadow_wr); + end + endtask + + task automatic csr_post_write_sub(ref uvm_reg csr, bit en_shadow_wr); + dv_base_reg dv_reg; + `downcast(dv_reg, csr, "", fatal, msg_id) + if (dv_reg.get_is_shadowed()) begin + // try setting en_shadow_wr back to default value 1, this function will only work if the + // shadow reg finished both writes + dv_reg.set_en_shadow_wr(1); + dv_reg.atomic_en_shadow_wr.put(1); + if (en_shadow_wr) begin + decrement_outstanding_access(); + end + end + endtask + // backdoor write csr task automatic csr_poke(input uvm_reg csr, input uvm_reg_data_t value, diff --git a/vendor/lowrisc_ip/dv_base_reg/dv_base_reg.sv b/vendor/lowrisc_ip/dv_base_reg/dv_base_reg.sv index 3ad45eeb..2428412e 100644 --- a/vendor/lowrisc_ip/dv_base_reg/dv_base_reg.sv +++ b/vendor/lowrisc_ip/dv_base_reg/dv_base_reg.sv @@ -8,12 +8,27 @@ class dv_base_reg extends uvm_reg; // hence, backdoor write isn't available local bit is_ext_reg; - local dv_base_reg locked_regs[$]; + local dv_base_reg locked_regs[$]; + local uvm_reg_data_t staged_shadow_val; + local bit is_shadowed; + local bit shadow_wr_staged; // stage the first shadow reg write + local bit shadow_update_err; + local bit en_shadow_wr = 1; + + // atomic_shadow_wr: semaphore to guarantee atomicity of the two writes for shadowed registers. + // In case a parallel thread writing a different value to the same reg causing an update_err + semaphore atomic_shadow_wr; + + // atomic_en_shadow_wr: semaphore to guarantee setting or resetting en_shadow_wr is unchanged + // through the 1st/2nd (or both) writes + semaphore atomic_en_shadow_wr; function new(string name = "", int unsigned n_bits, int has_coverage); super.new(name, n_bits, has_coverage); + atomic_en_shadow_wr = new(1); + atomic_shadow_wr = new(1); endfunction : new function void get_dv_base_reg_fields(ref dv_base_reg_field dv_fields[$]); @@ -63,12 +78,58 @@ class dv_base_reg extends uvm_reg; locked_regs_q = locked_regs; endfunction - // post_write callback to handle reg enables + // is_shadowed bit is only one-time programmable + // once this function is called in RAL auto-generated class, it cannot be changed + function void set_is_shadowed(); + is_shadowed = 1; + endfunction + + function void set_en_shadow_wr(bit val); + // do not update en_shadow_wr if shadow register write is in process + if ((en_shadow_wr ^ val) && shadow_wr_staged) begin + `uvm_info(`gfn, + $sformatf("unable to %s en_shadow_wr because register already completed first write", + val ? "set" : "clear"), UVM_LOW) + return; + end + en_shadow_wr = val; + endfunction + + function bit get_is_shadowed(); + return is_shadowed; + endfunction + + function bit get_shadow_update_err(); + return shadow_update_err; + endfunction + + virtual function void clear_shadow_update_err(); + shadow_update_err = 0; + endfunction + + // post_write callback to handle special regs: + // - shadow register, enable reg won't be updated until the second write has no error + // - enable register, if enable_reg is disabled, change access policy to all the locked_regs // TODO: create an `enable_field_access_policy` variable and set the template code during // automation. virtual task post_write(uvm_reg_item rw); dv_base_reg_field fields[$]; string field_access; + if (is_shadowed) begin + // first write + if (!shadow_wr_staged) begin + shadow_wr_staged = 1; + staged_shadow_val = rw.value[0]; + return; + end begin + // second write + shadow_wr_staged = 0; + if (staged_shadow_val != rw.value[0]) begin + shadow_update_err = 1; + return; + end + end + end if (is_enable_reg()) begin get_dv_base_reg_fields(fields); field_access = fields[0].get_access(); @@ -77,7 +138,7 @@ class dv_base_reg extends uvm_reg; "W1C": if (rw.value[0][0] == 1'b1) set_locked_regs_access("RO"); "W0C": if (rw.value[0][0] == 1'b0) set_locked_regs_access("RO"); "RO": ; // if RO, it's updated by design, need to predict in scb - default:`uvm_fatal(`gtn, $sformatf("enable register invalid access %s", field_access)) + default:`uvm_fatal(`gfn, $sformatf("enable register invalid access %s", field_access)) endcase end endtask @@ -90,4 +151,49 @@ class dv_base_reg extends uvm_reg; return is_ext_reg; endfunction + // if it is a shadowed register, and is enabled to write it twice, this task will write the + // register twice with the same value and address. + virtual task write(output uvm_status_e status, + input uvm_reg_data_t value, + input uvm_path_e path = UVM_DEFAULT_PATH, + input uvm_reg_map map = null, + input uvm_sequence_base parent=null, + input int prior = -1, + input uvm_object extension = null, + input string fname = "", + input int lineno = 0); + if (is_shadowed) atomic_shadow_wr.get(1); + super.write(status, value, path, map, parent, prior, extension, fname, lineno); + if (is_shadowed && en_shadow_wr) begin + super.write(status, value, path, map, parent, prior, extension, fname, lineno); + end + if (is_shadowed) atomic_shadow_wr.put(1); + endtask + + // override do_predict function to support shadow_reg: + // skip predict if it is shadow_reg's first write, or second write with an update_err + virtual function void do_predict (uvm_reg_item rw, + uvm_predict_e kind = UVM_PREDICT_DIRECT, + uvm_reg_byte_en_t be = -1); + if (is_shadowed && (shadow_wr_staged || shadow_update_err) && kind != UVM_PREDICT_READ) begin + `uvm_info(`gfn, + $sformatf("skip predict csr %s: due to shadow_reg_first_wr=%0b or update_err=%0b", + get_name(), shadow_wr_staged, shadow_update_err), UVM_HIGH) + return; + end + super.do_predict(rw, kind, be); + endfunction + + virtual function void reset(string kind = "HARD"); + super.reset(kind); + if (is_shadowed) begin + shadow_update_err = 0; + shadow_wr_staged = 0; + // in case reset is issued during shadowed writes + void'(atomic_shadow_wr.try_get(1)); + void'(atomic_en_shadow_wr.try_get(1)); + atomic_shadow_wr.put(1); + atomic_en_shadow_wr.put(1); + end + endfunction endclass diff --git a/vendor/lowrisc_ip/dv_lib/dv_base_vseq.sv b/vendor/lowrisc_ip/dv_lib/dv_base_vseq.sv index 9bbf7b92..9fb02df3 100644 --- a/vendor/lowrisc_ip/dv_lib/dv_base_vseq.sv +++ b/vendor/lowrisc_ip/dv_lib/dv_base_vseq.sv @@ -37,11 +37,30 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block, `uvm_object_new - task pre_start(); - super.pre_start(); + virtual function void set_handles(); + `DV_CHECK_NE_FATAL(p_sequencer, null, "Did you forget to call `set_sequencer()`?") cfg = p_sequencer.cfg; cov = p_sequencer.cov; ral = cfg.ral; + endfunction + + // This function is invoked in pre_randomize(). Override it in the extended classes to configure + // / control the randomization of this sequence. + virtual function void configure_vseq(); + endfunction + + function void pre_randomize(); + // Set the handles in pre_randomize(), so that the knobs in cfg are available during sequence + // randomization. This forces `p_sequencer` handle to be set before the randomization - users + // are required to call `set_sequencer()` right after creating the sequence and before + // randomizing it. + if (cfg == null) set_handles(); + configure_vseq(); + endfunction + + task pre_start(); + super.pre_start(); + if (cfg == null) set_handles(); if (do_dut_init) dut_init("HARD"); num_trans.rand_mode(0); endtask diff --git a/vendor/lowrisc_ip/dv_utils/dv_macros.svh b/vendor/lowrisc_ip/dv_utils/dv_macros.svh index 5336340e..56d8f263 100644 --- a/vendor/lowrisc_ip/dv_utils/dv_macros.svh +++ b/vendor/lowrisc_ip/dv_utils/dv_macros.svh @@ -305,7 +305,7 @@ // ... // end) `ifndef DV_SPINWAIT -`define DV_SPINWAIT(WAIT_, MSG_ = "", TIMEOUT_NS_ = default_spinwait_timeout_ns, ID_ =`gfn) \ +`define DV_SPINWAIT(WAIT_, MSG_ = "timeout occurred!", TIMEOUT_NS_ = default_spinwait_timeout_ns, ID_ =`gfn) \ begin \ fork begin \ fork \ diff --git a/vendor/lowrisc_ip/dvsim/FlowCfg.py b/vendor/lowrisc_ip/dvsim/FlowCfg.py index 876a726a..64ac88d5 100644 --- a/vendor/lowrisc_ip/dvsim/FlowCfg.py +++ b/vendor/lowrisc_ip/dvsim/FlowCfg.py @@ -13,7 +13,7 @@ import sys import hjson from Deploy import Deploy -from utils import VERBOSE, md_results_to_html, parse_hjson, print_msg_list, subst_wildcards +from utils import VERBOSE, md_results_to_html, parse_hjson, subst_wildcards # Interface class for extensions. @@ -51,15 +51,15 @@ class FlowCfg(): # are overridden with the override values. self.overrides = [] - # List of cfgs if the parsed cfg is a master cfg list + # List of cfgs if the parsed cfg is a primary cfg list self.cfgs = [] - # Add a notion of "master" cfg - this is indicated using + # Add a notion of "primary" cfg - this is indicated using # a special key 'use_cfgs' within the hjson cfg. - self.is_master_cfg = False + self.is_primary_cfg = False - # For a master cfg, it is the aggregated list of all deploy objects under self.cfgs. - # For a non-master cfg, it is the list of items slated for dispatch. + # For a primary cfg, it is the aggregated list of all deploy objects under self.cfgs. + # For a non-primary cfg, it is the list of items slated for dispatch. self.deploy = [] # Timestamp @@ -72,6 +72,7 @@ class FlowCfg(): self.errors_seen = False self.rel_path = "" self.results_title = "" + self.revision_string = "" self.results_server_prefix = "" self.results_server_url_prefix = "" self.results_server_cmd = "" @@ -83,14 +84,20 @@ class FlowCfg(): self.results_summary_server_html = "" self.results_summary_server_page = "" - # Full and summary results in md text. + # Full results in md text self.results_md = "" + # Selectively sanitized md results to be mailed out or published + self.email_results_md = "" + self.publish_results_md = "" + self.sanitize_email_results = False + self.sanitize_publish_results = False + # Summary results, generated by over-arching cfg + self.email_summary_md = "" self.results_summary_md = "" - self.email_summary_md = "" # if user wanted to customize email content def __post_init__(self): # Run some post init checks - if not self.is_master_cfg: + if not self.is_primary_cfg: # Check if self.cfgs is a list of exactly 1 item (self) if not (len(self.cfgs) == 1 and self.cfgs[0].name == self.name): log.error("Parse error!\n%s", self.cfgs) @@ -122,12 +129,12 @@ class FlowCfg(): ''' hjson_dict = parse_hjson(flow_cfg_file) - # Check if this is the master cfg, if this is the entry point cfg file + # Check if this is the primary cfg, if this is the entry point cfg file if is_entry_point: - self.is_master_cfg = self.check_if_master_cfg(hjson_dict) + self.is_primary_cfg = self.check_if_primary_cfg(hjson_dict) - # If not a master cfg, then register self with self.cfgs - if self.is_master_cfg is False: + # If not a primary cfg, then register self with self.cfgs + if self.is_primary_cfg is False: self.cfgs.append(self) # Resolve the raw hjson dict to build this object @@ -141,8 +148,8 @@ class FlowCfg(): self.rel_path = os.path.dirname(self.flow_cfg_file).replace( self.proj_root + '/', '') - def check_if_master_cfg(self, hjson_dict): - # This is a master cfg only if it has a single key called "use_cfgs" + def check_if_primary_cfg(self, hjson_dict): + # This is a primary cfg only if it has a single key called "use_cfgs" # which contains a list of actual flow cfgs. hjson_cfg_dict_keys = hjson_dict.keys() return ("use_cfgs" in hjson_cfg_dict_keys and type(hjson_dict["use_cfgs"]) is list) @@ -219,15 +226,15 @@ class FlowCfg(): import_cfgs.extend(hjson_dict[key]) rm_hjson_dict_keys.append(key) - # If this is a master cfg list and the key is 'use_cfgs' - elif self.is_master_cfg and key == "use_cfgs": + # If this is a primary cfg list and the key is 'use_cfgs' + elif self.is_primary_cfg and key == "use_cfgs": use_cfgs.extend(hjson_dict[key]) - # If this is a not master cfg list and the key is 'use_cfgs' - elif not self.is_master_cfg and key == "use_cfgs": + # If this is a not primary cfg list and the key is 'use_cfgs' + elif not self.is_primary_cfg and key == "use_cfgs": # Throw an error and exit log.error( - "Key \"use_cfgs\" encountered in a non-master cfg file list \"%s\"", + "Key \"use_cfgs\" encountered in a non-primary cfg file list \"%s\"", self.flow_cfg_file) sys.exit(1) @@ -247,8 +254,8 @@ class FlowCfg(): else: log.error("Cfg file \"%s\" has already been parsed", cfg_file) - # Parse master cfg files - if self.is_master_cfg: + # Parse primary cfg files + if self.is_primary_cfg: for entry in use_cfgs: if type(entry) is str: # Treat this as a file entry @@ -283,10 +290,10 @@ class FlowCfg(): def _conv_inline_cfg_to_hjson(self, idict): '''Dump a temp hjson file in the scratch space from input dict. - This method is to be called only by a master cfg''' + This method is to be called only by a primary cfg''' - if not self.is_master_cfg: - log.fatal("This method can only be called by a master cfg") + if not self.is_primary_cfg: + log.fatal("This method can only be called by a primary cfg") sys.exit(1) name = idict["name"] if "name" in idict.keys() else None @@ -405,7 +412,7 @@ class FlowCfg(): item._print_list() def prune_selected_cfgs(self): - '''Prune the list of configs for a master config file''' + '''Prune the list of configs for a primary config file''' # This should run after self.cfgs has been set assert self.cfgs @@ -414,10 +421,10 @@ class FlowCfg(): if self.select_cfgs is None: return - # If the user passed --select-cfgs, but this isn't a master config + # If the user passed --select-cfgs, but this isn't a primary config # file, we should probably complain. - if not self.is_master_cfg: - log.error('The configuration file at {!r} is not a master config, ' + if not self.is_primary_cfg: + log.error('The configuration file at {!r} is not a primary config, ' 'but --select-cfgs was passed on the command line.' .format(self.flow_cfg_file)) sys.exit(1) @@ -436,7 +443,7 @@ class FlowCfg(): '''Public facing API for _create_deploy_objects(). ''' self.prune_selected_cfgs() - if self.is_master_cfg: + if self.is_primary_cfg: self.deploy = [] for item in self.cfgs: item._create_deploy_objects() @@ -468,7 +475,7 @@ class FlowCfg(): results.append(result) self.errors_seen |= item.errors_seen - if self.is_master_cfg: + if self.is_primary_cfg: self.gen_results_summary() self.gen_email_html_summary() @@ -485,12 +492,12 @@ class FlowCfg(): return "[%s](%s)" % (link_text, results_page_url) def gen_email_html_summary(self): - if self.is_master_cfg: + if self.is_primary_cfg: # user can customize email content by using email_summary_md, # otherwise default to send out results_summary_md gen_results = self.email_summary_md or self.results_summary_md else: - gen_results = self.results_md + gen_results = self.email_results_md or self.results_md results_html = md_results_to_html(self.results_title, self.css_file, gen_results) results_html_file = self.scratch_root + "/email.html" f = open(results_html_file, 'w') @@ -613,14 +620,15 @@ class FlowCfg(): rm_cmd = self.results_server_cmd + " -m rm -r " + rm_cmd + "; " # Append the history to the results. - results_md = self.results_md + history_txt + publish_results_md = self.publish_results_md or self.results_md + publish_results_md = publish_results_md + history_txt # Publish the results page. # First, write the results html file temporarily to the scratch area. results_html_file = self.scratch_path + "/results_" + self.timestamp + ".html" f = open(results_html_file, 'w') f.write( - md_results_to_html(self.results_title, self.css_file, results_md)) + md_results_to_html(self.results_title, self.css_file, publish_results_md)) f.close() rm_cmd += "/bin/rm -rf " + results_html_file + "; " @@ -643,7 +651,7 @@ class FlowCfg(): for item in self.cfgs: item._publish_results() - if self.is_master_cfg: + if self.is_primary_cfg: self.publish_results_summary() def publish_results_summary(self): diff --git a/vendor/lowrisc_ip/dvsim/FpvCfg.py b/vendor/lowrisc_ip/dvsim/FpvCfg.py index 6d21ec37..3db61575 100644 --- a/vendor/lowrisc_ip/dvsim/FpvCfg.py +++ b/vendor/lowrisc_ip/dvsim/FpvCfg.py @@ -125,7 +125,10 @@ class FpvCfg(OneShotCfg): log.info("Create summary of FPV results") results_str = "## " + self.results_title + " (Summary)\n\n" - results_str += "### " + self.timestamp_long + "\n\n" + results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" + results_str += "\n" colalign = ("center", ) * len(self.summary_header) table = [self.summary_header] @@ -216,6 +219,8 @@ class FpvCfg(OneShotCfg): # } results_str = "## " + self.results_title + "\n\n" results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" results_str += "### FPV Tool: " + self.tool.upper() + "\n" results_str += "### LogFile dir: " + self.scratch_path + "/default\n\n" diff --git a/vendor/lowrisc_ip/dvsim/LintCfg.py b/vendor/lowrisc_ip/dvsim/LintCfg.py index 6683c627..f28e14fd 100644 --- a/vendor/lowrisc_ip/dvsim/LintCfg.py +++ b/vendor/lowrisc_ip/dvsim/LintCfg.py @@ -14,6 +14,7 @@ from tabulate import tabulate from OneShotCfg import OneShotCfg from utils import print_msg_list, subst_wildcards + class LintCfg(OneShotCfg): """Derivative class for linting purposes. """ @@ -46,7 +47,11 @@ class LintCfg(OneShotCfg): log.info("Create summary of lint results") results_str = "## " + self.results_title + " (Summary)\n\n" - results_str += "### " + self.timestamp_long + "\n\n" + results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" + results_str += "\n" + header = [ "Name", "Tool Warnings", "Tool Errors", "Lint Warnings", @@ -102,13 +107,15 @@ class LintCfg(OneShotCfg): # parsing script that transforms the tool output into the hjson above # needs to be adapted. # - # note that if this is a master config, the results will + # note that if this is a primary config, the results will # be generated using the _gen_results_summary function # ''' # Generate results table for runs. results_str = "## " + self.results_title + "\n\n" results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" results_str += "### Lint Tool: " + self.tool.upper() + "\n\n" header = [ @@ -133,7 +140,7 @@ class LintCfg(OneShotCfg): log.info("looking for result data file at %s", result_data) try: - with open(result_data, "r") as results_file: + with result_data.open() as results_file: self.result = hjson.load(results_file, use_decimal=True) except IOError as err: log.warning("%s", err) @@ -177,13 +184,16 @@ class LintCfg(OneShotCfg): ("Lint Warnings", "lint_warnings"), ("Lint Errors", "lint_errors")] - has_msg = False + + # Lint fails if any warning or error message has occurred + self.errors_seen = False for _, key in hdr_key_pairs: if key in self.result: - has_msg = True - break + if self.result.get(key): + self.errors_seen = True + break - if has_msg: + if self.errors_seen: fail_msgs += "\n### Errors and Warnings for Build Mode `'" + mode.name + "'`\n" for hdr, key in hdr_key_pairs: msgs = self.result.get(key) @@ -192,9 +202,21 @@ class LintCfg(OneShotCfg): if len(table) > 1: self.results_md = results_str + tabulate( table, headers="firstrow", tablefmt="pipe", - colalign=colalign) + "\n" + fail_msgs + colalign=colalign) + "\n" + + # the email and published reports will default to self.results_md if they are + # empty. in case they need to be sanitized, override them and do not append + # detailed messages. + if self.sanitize_email_results: + self.email_results_md = self.results_md + if self.sanitize_publish_results: + self.publish_results_md = self.results_md + # locally generated result always contains all details + self.results_md += fail_msgs else: self.results_md = results_str + "\nNo results to display.\n" + self.email_results_md = self.results_md + self.publish_results_md = self.results_md # Write results to the scratch area self.results_file = self.scratch_path + "/results_" + self.timestamp + ".md" diff --git a/vendor/lowrisc_ip/dvsim/OneShotCfg.py b/vendor/lowrisc_ip/dvsim/OneShotCfg.py index 578ba470..d5741330 100644 --- a/vendor/lowrisc_ip/dvsim/OneShotCfg.py +++ b/vendor/lowrisc_ip/dvsim/OneShotCfg.py @@ -93,8 +93,8 @@ class OneShotCfg(FlowCfg): self.__dict__, ignored_wildcards) - # Stuff below only pertains to individual cfg (not master cfg). - if not self.is_master_cfg: + # Stuff below only pertains to individual cfg (not primary cfg). + if not self.is_primary_cfg: # Print info log.info("[scratch_dir]: [%s]: [%s]", self.name, self.scratch_path) @@ -113,7 +113,7 @@ class OneShotCfg(FlowCfg): self._process_exports() # Create objects from raw dicts - build_modes, sim_modes, run_modes, - # tests and regressions, only if not a master cfg obj + # tests and regressions, only if not a primary cfg obj self._create_objects() # Post init checks diff --git a/vendor/lowrisc_ip/dvsim/SimCfg.py b/vendor/lowrisc_ip/dvsim/SimCfg.py index e6a23618..2060c45f 100644 --- a/vendor/lowrisc_ip/dvsim/SimCfg.py +++ b/vendor/lowrisc_ip/dvsim/SimCfg.py @@ -160,7 +160,7 @@ class SimCfg(FlowCfg): self.cov_report_deploy = None self.results_summary = OrderedDict() - # If is_master_cfg is set, then each cfg will have its own cov_deploy. + # If is_primary_cfg is set, then each cfg will have its own cov_deploy. # Maintain an array of those in cov_deploys. self.cov_deploys = [] @@ -190,19 +190,19 @@ class SimCfg(FlowCfg): self.__dict__ = find_and_substitute_wildcards(self.__dict__, self.__dict__, ignored_wildcards, - self.is_master_cfg) + self.is_primary_cfg) # Set the title for simulation results. self.results_title = self.name.upper() + " Simulation Results" - # Stuff below only pertains to individual cfg (not master cfg) + # Stuff below only pertains to individual cfg (not primary cfg) # or individual selected cfgs (if select_cfgs is configured via command line) # TODO: find a better way to support select_cfgs - if not self.is_master_cfg and (not self.select_cfgs or - self.name in self.select_cfgs): + if not self.is_primary_cfg and (not self.select_cfgs or + self.name in self.select_cfgs): # If self.tool is None at this point, there was no --tool argument on # the command line, and there is no default tool set in the config - # file. That's ok if this is a master config (where the + # file. That's ok if this is a primary config (where the # sub-configurations can choose tools themselves), but not otherwise. if self.tool is None: log.error('Config file does not specify a default tool, ' @@ -227,7 +227,7 @@ class SimCfg(FlowCfg): self._process_exports() # Create objects from raw dicts - build_modes, sim_modes, run_modes, - # tests and regressions, only if not a master cfg obj + # tests and regressions, only if not a primary cfg obj self._create_objects() # Post init checks @@ -576,6 +576,8 @@ class SimCfg(FlowCfg): # Generate results table for runs. results_str = "## " + self.results_title + "\n" results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" # Add path to testplan. if hasattr(self, "testplan_doc_path"): @@ -648,6 +650,8 @@ class SimCfg(FlowCfg): table.append(row) self.results_summary_md = "## " + self.results_title + " (Summary)\n" self.results_summary_md += "### " + self.timestamp_long + "\n" + if self.revision_string: + self.results_summary_md += "### " + self.revision_string + "\n" self.results_summary_md += tabulate(table, headers="firstrow", tablefmt="pipe", diff --git a/vendor/lowrisc_ip/dvsim/SynCfg.py b/vendor/lowrisc_ip/dvsim/SynCfg.py index 1cddae3c..f408b797 100644 --- a/vendor/lowrisc_ip/dvsim/SynCfg.py +++ b/vendor/lowrisc_ip/dvsim/SynCfg.py @@ -35,7 +35,10 @@ class SynCfg(OneShotCfg): log.info("Create summary of synthesis results") results_str = "## " + self.results_title + " (Summary)\n\n" - results_str += "### " + self.timestamp_long + "\n\n" + results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" + results_str += "\n" self.results_summary_md = results_str + "\nNot supported yet.\n" @@ -116,7 +119,7 @@ class SynCfg(OneShotCfg): # } # } # - # note that if this is a master config, the results will + # note that if this is a primary config, the results will # be generated using the _gen_results_summary function # ''' @@ -142,6 +145,8 @@ class SynCfg(OneShotCfg): # Generate results table for runs. results_str = "## " + self.results_title + "\n\n" results_str += "### " + self.timestamp_long + "\n" + if self.revision_string: + results_str += "### " + self.revision_string + "\n" results_str += "### Synthesis Tool: " + self.tool.upper() + "\n\n" # TODO: extend this to support multiple build modes @@ -155,7 +160,7 @@ class SynCfg(OneShotCfg): log.info("looking for result data file at %s", result_data) try: - with open(result_data, "r") as results_file: + with result_data.open() as results_file: self.result = hjson.load(results_file, use_decimal=True) except IOError as err: log.warning("%s", err) @@ -354,22 +359,35 @@ class SynCfg(OneShotCfg): ("Compile Warnings", "compile_warnings"), ("Compile Errors", "compile_errors")] - has_msg = False + # Synthesis fails if any warning or error message has occurred + self.errors_seen = False + fail_msgs = "" for _, key in hdr_key_pairs: if key in self.result['messages']: - has_msg = True - break + if self.result['messages'].get(key): + self.errors_seen = True + break - if has_msg and not self.args.publish: - results_str += "\n### Errors and Warnings for Build Mode `'" + mode.name + "'`\n" + if self.errors_seen: + fail_msgs += "\n### Errors and Warnings for Build Mode `'" + mode.name + "'`\n" for hdr, key in hdr_key_pairs: msgs = self.result['messages'].get(key) - results_str += print_msg_list("#### " + hdr, msgs, self.max_msg_count) + fail_msgs += print_msg_list("#### " + hdr, msgs, self.max_msg_count) + + # the email and published reports will default to self.results_md if they are + # empty. in case they need to be sanitized, override them and do not append + # detailed messages. + if self.sanitize_email_results: + self.email_results_md = results_str + if self.sanitize_publish_results: + self.publish_results_md = results_str + + # locally generated result always contains all details + self.results_md = results_str + fail_msgs # TODO: add support for pie / bar charts for area splits and # QoR history - self.results_md = results_str # Write results to the scratch area self.results_file = self.scratch_path + "/results_" + self.timestamp + ".md" log.info("Detailed results are available at %s", self.results_file) diff --git a/vendor/lowrisc_ip/dvsim/dvsim.py b/vendor/lowrisc_ip/dvsim/dvsim.py index 16c28c32..3f94485d 100755 --- a/vendor/lowrisc_ip/dvsim/dvsim.py +++ b/vendor/lowrisc_ip/dvsim/dvsim.py @@ -244,10 +244,10 @@ def parse_args(): whatg.add_argument("--select-cfgs", nargs="*", metavar="CFG", - help=('The .hjson file is a master config. Only run ' + help=('The .hjson file is a primary config. Only run ' 'the given configs from it. If this argument is ' 'not used, dvsim will process all configs listed ' - 'in a master config.')) + 'in a primary config.')) disg = parser.add_argument_group('Dispatch options') diff --git a/vendor/lowrisc_ip/dvsim/style.css b/vendor/lowrisc_ip/dvsim/style.css index 784ed717..f89293ae 100644 --- a/vendor/lowrisc_ip/dvsim/style.css +++ b/vendor/lowrisc_ip/dvsim/style.css @@ -1,7 +1,6 @@ -/* Copyright lowRISC contributors. - * Licensed under the Apache License, Version 2.0, see LICENSE for details. - * SPDX-License-Identifier: Apache-2.0 - */ +/* Copyright lowRISC contributors. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ /* CSS for reports.opentitan.org. * This is referenced by all results published to the reports server for some basic styling. diff --git a/vendor/lowrisc_ip/dvsim/testplanner/class_defs.py b/vendor/lowrisc_ip/dvsim/testplanner/class_defs.py index 63bf4a82..ee84e7e5 100644 --- a/vendor/lowrisc_ip/dvsim/testplanner/class_defs.py +++ b/vendor/lowrisc_ip/dvsim/testplanner/class_defs.py @@ -304,10 +304,14 @@ class Testplan(): if fmt == "html": desc = mistletoe.markdown(desc) table.append([entry.milestone, entry.name, desc, tests]) - return tabulate(table, - headers="firstrow", - tablefmt=fmt, - colalign=colalign) + result = tabulate(table, + headers="firstrow", + tablefmt=fmt, + colalign=colalign) + result = result.replace("<", "<") + result = result.replace(">", ">") + return result + def results_table(self, regr_results, map_full_testplan=True, fmt="pipe"): '''Print the mapped regression results into a table in the format diff --git a/vendor/lowrisc_ip/lint/data/lint.mk b/vendor/lowrisc_ip/lint/data/lint.mk index 584541b6..ede5374d 100644 --- a/vendor/lowrisc_ip/lint/data/lint.mk +++ b/vendor/lowrisc_ip/lint/data/lint.mk @@ -29,10 +29,6 @@ compile_result: post_compile @echo "[make]: compile_result" ${report_cmd} ${report_opts} -clean: - echo "[make]: clean" - rm -rf ${scratch_root}/${dut}/* - .PHONY: build \ run \ pre_compile \ diff --git a/vendor/lowrisc_ip/lint/doc/README.md b/vendor/lowrisc_ip/lint/doc/README.md index e62401fd..61a07db1 100644 --- a/vendor/lowrisc_ip/lint/doc/README.md +++ b/vendor/lowrisc_ip/lint/doc/README.md @@ -100,7 +100,7 @@ $ util/dvsim/dvsim.py hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson --tool a where the `top_earlgrey_lint_cfgs.hjson` file contains all the lint targets to be run in that regression (currently all available comportable IPs and the top-level are run). The `purge` option ensures that the scratch directory is fully erased before starting the build, and `mp 1` sets the number of parallel workers to one (should be set depending on your licensing situation). -The batch regression is regularly run on the master branch at eight-hour intervals, and the results are published on a public dashboard such that everybody can inspect the current lint status of all IPs on the project website. +The batch regression is regularly run on the `master` branch at eight-hour intervals, and the results are published on a public dashboard such that everybody can inspect the current lint status of all IPs on the project website. The dashboard can be found by following the appropriate link on the [hardware IP overview page](https://docs.opentitan.org/hw). # CDC Linting diff --git a/vendor/lowrisc_ip/lint/tools/veriblelint/parse-lint-report.py b/vendor/lowrisc_ip/lint/tools/veriblelint/parse-lint-report.py index 7afc4ace..1077b9e0 100755 --- a/vendor/lowrisc_ip/lint/tools/veriblelint/parse-lint-report.py +++ b/vendor/lowrisc_ip/lint/tools/veriblelint/parse-lint-report.py @@ -56,6 +56,9 @@ def get_results(resdir): # support for JasperGold and "formal" targets ("warnings", r"^(?!WARNING: Unknown item formal in section Target)WARNING: .*" + # TODO(https://github.com/lowRISC/ibex/issues/1033): + # remove once this has been fixed in Edalize or in the corefile. + r"^(?!WARNING: Unknown item symbiyosis in section Target)WARNING: .*" ), ("warnings", r"^Warning: .* "), ("warnings", r"^W .*"), diff --git a/vendor/lowrisc_ip/prim/dv/prim_present/data/cover.cfg b/vendor/lowrisc_ip/prim/dv/prim_present/data/cover.cfg new file mode 100644 index 00000000..20079e3e --- /dev/null +++ b/vendor/lowrisc_ip/prim/dv/prim_present/data/cover.cfg @@ -0,0 +1,5 @@ ++module prim_present +begin tgl(portsonly) + -tree prim_present_tb + +module prim_present +end diff --git a/vendor/lowrisc_ip/prim/dv/prim_present/prim_present_testplan.hjson b/vendor/lowrisc_ip/prim/dv/prim_present/data/prim_present_testplan.hjson similarity index 71% rename from vendor/lowrisc_ip/prim/dv/prim_present/prim_present_testplan.hjson rename to vendor/lowrisc_ip/prim/dv/prim_present/data/prim_present_testplan.hjson index dda6befd..9ff63283 100644 --- a/vendor/lowrisc_ip/prim/dv/prim_present/prim_present_testplan.hjson +++ b/vendor/lowrisc_ip/prim/dv/prim_present/data/prim_present_testplan.hjson @@ -1,3 +1,6 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 { name: "prim_present" import_testplans: [] diff --git a/vendor/lowrisc_ip/prim/dv/prim_present/prim_present_sim_cfg.hjson b/vendor/lowrisc_ip/prim/dv/prim_present/prim_present_sim_cfg.hjson index 1983c389..2ffe4d4f 100644 --- a/vendor/lowrisc_ip/prim/dv/prim_present/prim_present_sim_cfg.hjson +++ b/vendor/lowrisc_ip/prim/dv/prim_present/prim_present_sim_cfg.hjson @@ -18,30 +18,20 @@ fusesoc_core: lowrisc:dv:prim_present_sim:0.1 // Testplan hjson file. - testplan: "{proj_root}/hw/ip/prim/dv/prim_present/prim_present_testplan.hjson" + testplan: "{proj_root}/hw/ip/prim/dv/prim_present/data/prim_present_testplan.hjson" // Import additional common sim cfg files. import_cfgs: ["{proj_root}/hw/dv/data/common_sim_cfg.hjson"] - // Add additional tops for simulation. - //sim_tops: ["-top prim_present_bind"] - sim_tops: [] - // Default iterations for all tests - each test entry can override this. reseed: 50 - // Add excl files to tool_srcs so that it gets copied over to the scratch area. - //tool_srcs: ["{proj_root}/hw/ip/prim/dv/prim_present/prim_present_cov_excl.el"] - tool_srcs: [] - - // Refer to the excl file with vcs_cov_excl_files var with the rel path from tool_srcs_dir - // so the VCS can find it. - //vcs_cov_excl_files: ["{tool_srcs_dir}/prim_present_cov_excl.el"] - vcs_cov_excl_files: [] - - // Default UVM test and seq class name. - uvm_test: "" - uvm_test_seq: "" + overrides: [ + { + name: vcs_cov_hier + value: "-cm_hier {proj_root}/hw/ip/prim/dv/prim_present/data/cover.cfg" + } + ] // List of test specifications. tests: [ diff --git a/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_bind_fpv.sv b/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_bind_fpv.sv index 1b70d743..e734d980 100644 --- a/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_bind_fpv.sv +++ b/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_bind_fpv.sv @@ -23,13 +23,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_nopass7 prim_fifo_sync_assert_fpv #( @@ -41,13 +41,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_nopass8 prim_fifo_sync_assert_fpv #( @@ -59,13 +59,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_nopass15 prim_fifo_sync_assert_fpv #( @@ -77,13 +77,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_nopass16 prim_fifo_sync_assert_fpv #( @@ -95,13 +95,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); //////////////// @@ -117,13 +117,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_pass1 prim_fifo_sync_assert_fpv #( @@ -135,13 +135,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_pass7 prim_fifo_sync_assert_fpv #( @@ -153,13 +153,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_pass8 prim_fifo_sync_assert_fpv #( @@ -171,13 +171,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_pass15 prim_fifo_sync_assert_fpv #( @@ -189,13 +189,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); bind i_pass16 prim_fifo_sync_assert_fpv #( @@ -207,13 +207,13 @@ module prim_fifo_sync_bind_fpv; .clk_i, .rst_ni, .clr_i, - .wvalid, - .wready, - .wdata, - .rvalid, - .rready, - .rdata, - .depth + .wvalid_i, + .wready_o, + .wdata_i, + .rvalid_o, + .rready_i, + .rdata_o, + .depth_o ); endmodule : prim_fifo_sync_bind_fpv diff --git a/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_fpv.sv b/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_fpv.sv index 4c0c1d1d..808df8bb 100644 --- a/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_fpv.sv +++ b/vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_fpv.sv @@ -25,13 +25,13 @@ module prim_fifo_sync_fpv #( input clk_i, input rst_ni, input clr_i, - input wvalid [NumDuts], - output wready [NumDuts], - input [Width-1:0] wdata [NumDuts], - output rvalid [NumDuts], - input rready [NumDuts], - output [Width-1:0] rdata [NumDuts], - output [DepthW-1:0] depth [NumDuts] + input wvalid_i[NumDuts], + output wready_o[NumDuts], + input [Width-1:0] wdata_i [NumDuts], + output rvalid_o[NumDuts], + input rready_i[NumDuts], + output [Width-1:0] rdata_o [NumDuts], + output [DepthW-1:0] depth_o [NumDuts] ); // need to instantiate by hand since bind statements inside @@ -49,13 +49,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[0]), - .wready(wready[0]), - .wdata(wdata[0]), - .rvalid(rvalid[0]), - .rready(rready[0]), - .rdata(rdata[0]), - .depth(depth[0][0]) + .wvalid_i(wvalid_i[0]), + .wready_o(wready_o[0]), + .wdata_i(wdata_i[0]), + .rvalid_o(rvalid_o[0]), + .rready_i(rready_i[0]), + .rdata_o(rdata_o[0]), + .depth_o(depth_o[0][0]) ); prim_fifo_sync #( @@ -66,13 +66,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[1]), - .wready(wready[1]), - .wdata(wdata[1]), - .rvalid(rvalid[1]), - .rready(rready[1]), - .rdata(rdata[1]), - .depth(depth[1][2:0]) + .wvalid_i(wvalid_i[1]), + .wready_o(wready_o[1]), + .wdata_i(wdata_i[1]), + .rvalid_o(rvalid_o[1]), + .rready_i(rready_i[1]), + .rdata_o(rdata_o[1]), + .depth_o(depth_o[1][2:0]) ); prim_fifo_sync #( @@ -83,13 +83,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[2]), - .wready(wready[2]), - .wdata(wdata[2]), - .rvalid(rvalid[2]), - .rready(rready[2]), - .rdata(rdata[2]), - .depth(depth[2][3:0]) + .wvalid_i(wvalid_i[2]), + .wready_o(wready_o[2]), + .wdata_i(wdata_i[2]), + .rvalid_o(rvalid_o[2]), + .rready_i(rready_i[2]), + .rdata_o(rdata_o[2]), + .depth_o(depth_o[2][3:0]) ); prim_fifo_sync #( @@ -100,13 +100,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[3]), - .wready(wready[3]), - .wdata(wdata[3]), - .rvalid(rvalid[3]), - .rready(rready[3]), - .rdata(rdata[3]), - .depth(depth[3][3:0]) + .wvalid_i(wvalid_i[3]), + .wready_o(wready_o[3]), + .wdata_i(wdata_i[3]), + .rvalid_o(rvalid_o[3]), + .rready_i(rready_i[3]), + .rdata_o(rdata_o[3]), + .depth_o(depth_o[3][3:0]) ); prim_fifo_sync #( @@ -117,20 +117,20 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[4]), - .wready(wready[4]), - .wdata(wdata[4]), - .rvalid(rvalid[4]), - .rready(rready[4]), - .rdata(rdata[4]), - .depth(depth[4][4:0]) + .wvalid_i(wvalid_i[4]), + .wready_o(wready_o[4]), + .wdata_i(wdata_i[4]), + .rvalid_o(rvalid_o[4]), + .rready_i(rready_i[4]), + .rdata_o(rdata_o[4]), + .depth_o(depth_o[4][4:0]) ); //////////////// // pass FIFOs // //////////////// - // depth-zero is per definition a pass-through FIFO + // depth_o-zero is per definition a pass-through FIFO prim_fifo_sync #( .Width(Width), .Pass(1'b1), @@ -139,13 +139,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[5]), - .wready(wready[5]), - .wdata(wdata[5]), - .rvalid(rvalid[5]), - .rready(rready[5]), - .rdata(rdata[5]), - .depth(depth[5][0]) + .wvalid_i(wvalid_i[5]), + .wready_o(wready_o[5]), + .wdata_i(wdata_i[5]), + .rvalid_o(rvalid_o[5]), + .rready_i(rready_i[5]), + .rdata_o(rdata_o[5]), + .depth_o(depth_o[5][0]) ); prim_fifo_sync #( @@ -156,13 +156,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[6]), - .wready(wready[6]), - .wdata(wdata[6]), - .rvalid(rvalid[6]), - .rready(rready[6]), - .rdata(rdata[6]), - .depth(depth[6][0]) + .wvalid_i(wvalid_i[6]), + .wready_o(wready_o[6]), + .wdata_i(wdata_i[6]), + .rvalid_o(rvalid_o[6]), + .rready_i(rready_i[6]), + .rdata_o(rdata_o[6]), + .depth_o(depth_o[6][0]) ); prim_fifo_sync #( @@ -173,13 +173,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[7]), - .wready(wready[7]), - .wdata(wdata[7]), - .rvalid(rvalid[7]), - .rready(rready[7]), - .rdata(rdata[7]), - .depth(depth[7][2:0]) + .wvalid_i(wvalid_i[7]), + .wready_o(wready_o[7]), + .wdata_i(wdata_i[7]), + .rvalid_o(rvalid_o[7]), + .rready_i(rready_i[7]), + .rdata_o(rdata_o[7]), + .depth_o(depth_o[7][2:0]) ); prim_fifo_sync #( @@ -190,13 +190,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[8]), - .wready(wready[8]), - .wdata(wdata[8]), - .rvalid(rvalid[8]), - .rready(rready[8]), - .rdata(rdata[8]), - .depth(depth[8][3:0]) + .wvalid_i(wvalid_i[8]), + .wready_o(wready_o[8]), + .wdata_i(wdata_i[8]), + .rvalid_o(rvalid_o[8]), + .rready_i(rready_i[8]), + .rdata_o(rdata_o[8]), + .depth_o(depth_o[8][3:0]) ); prim_fifo_sync #( @@ -207,13 +207,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[9]), - .wready(wready[9]), - .wdata(wdata[9]), - .rvalid(rvalid[9]), - .rready(rready[9]), - .rdata(rdata[9]), - .depth(depth[9][3:0]) + .wvalid_i(wvalid_i[9]), + .wready_o(wready_o[9]), + .wdata_i(wdata_i[9]), + .rvalid_o(rvalid_o[9]), + .rready_i(rready_i[9]), + .rdata_o(rdata_o[9]), + .depth_o(depth_o[9][3:0]) ); prim_fifo_sync #( @@ -224,13 +224,13 @@ module prim_fifo_sync_fpv #( .clk_i, .rst_ni, .clr_i, - .wvalid(wvalid[10]), - .wready(wready[10]), - .wdata(wdata[10]), - .rvalid(rvalid[10]), - .rready(rready[10]), - .rdata(rdata[10]), - .depth(depth[10][4:0]) + .wvalid_i(wvalid_i[10]), + .wready_o(wready_o[10]), + .wdata_i(wdata_i[10]), + .rvalid_o(rvalid_o[10]), + .rready_i(rready_i[10]), + .rdata_o(rdata_o[10]), + .depth_o(depth_o[10][4:0]) ); endmodule : prim_fifo_sync_fpv diff --git a/vendor/lowrisc_ip/prim/fpv/vip/prim_fifo_sync_assert_fpv.sv b/vendor/lowrisc_ip/prim/fpv/vip/prim_fifo_sync_assert_fpv.sv index 9090e4c0..e3fa4e16 100644 --- a/vendor/lowrisc_ip/prim/fpv/vip/prim_fifo_sync_assert_fpv.sv +++ b/vendor/lowrisc_ip/prim/fpv/vip/prim_fifo_sync_assert_fpv.sv @@ -19,13 +19,13 @@ module prim_fifo_sync_assert_fpv #( input clk_i, input rst_ni, input clr_i, - input wvalid, - input wready, - input [Width-1:0] wdata, - input rvalid, - input rready, - input [Width-1:0] rdata, - input [DepthW-1:0] depth + input wvalid_i, + input wready_o, + input [Width-1:0] wdata_i, + input rvalid_o, + input rready_i, + input [Width-1:0] rdata_o, + input [DepthW-1:0] depth_o ); ///////////////// @@ -34,7 +34,7 @@ module prim_fifo_sync_assert_fpv #( // no need to consider all possible input words // 2-3 different values suffice - `ASSUME(WdataValues_M, wdata inside {Width'(1'b0), Width'(1'b1), {Width{1'b1}}}, clk_i, !rst_ni) + `ASSUME(WdataValues_M, wdata_i inside {Width'(1'b0), Width'(1'b1), {Width{1'b1}}}, clk_i, !rst_ni) //////////////////////////////// // Data and Depth Value Check // @@ -59,12 +59,12 @@ module prim_fifo_sync_assert_fpv #( if (clr_i) begin ref_depth <= 0; end else begin - if (wvalid && wready && rvalid && rready) begin - fifo <= wdata; - end else if (wvalid && wready) begin - fifo <= wdata; + if (wvalid_i && wready_o && rvalid_o && rready_i) begin + fifo <= wdata_i; + end else if (wvalid_i && wready_o) begin + fifo <= wdata_i; ref_depth <= ref_depth + 1; - end else if (rvalid && rready) begin + end else if (rvalid_o && rready_i) begin ref_depth <= ref_depth - 1; end end @@ -72,7 +72,7 @@ module prim_fifo_sync_assert_fpv #( end if (Pass) begin : gen_pass - assign ref_rdata = (ref_depth == 0) ? wdata : fifo; + assign ref_rdata = (ref_depth == 0) ? wdata_i : fifo; end else begin : no_pass assign ref_rdata = fifo; end @@ -101,15 +101,15 @@ module prim_fifo_sync_assert_fpv #( rptr <= 0; ref_depth <= 0; end else begin - if (wvalid && wready && rvalid && rready) begin - fifo[wptr] <= wdata; + if (wvalid_i && wready_o && rvalid_o && rready_i) begin + fifo[wptr] <= wdata_i; wptr <= modinc(wptr, Depth); rptr <= modinc(rptr, Depth); - end else if (wvalid && wready) begin - fifo[wptr] <= wdata; + end else if (wvalid_i && wready_o) begin + fifo[wptr] <= wdata_i; wptr <= modinc(wptr, Depth); ref_depth <= ref_depth + 1; - end else if (rvalid && rready) begin + end else if (rvalid_o && rready_i) begin rptr <= modinc(rptr, Depth); ref_depth <= ref_depth - 1; end @@ -118,7 +118,7 @@ module prim_fifo_sync_assert_fpv #( end if (Pass) begin : gen_pass - assign ref_rdata = (ref_depth == 0) ? wdata : fifo[rptr]; + assign ref_rdata = (ref_depth == 0) ? wdata_i : fifo[rptr]; end else begin : no_pass assign ref_rdata = fifo[rptr]; end @@ -126,9 +126,9 @@ module prim_fifo_sync_assert_fpv #( end // check the data - `ASSERT(DataCheck_A, rvalid |-> rdata == ref_rdata) + `ASSERT(DataCheck_A, rvalid_o |-> rdata_o == ref_rdata) // check the depth - `ASSERT(DepthCheck_A, ref_depth == depth) + `ASSERT(DepthCheck_A, ref_depth == depth_o) end @@ -137,20 +137,20 @@ module prim_fifo_sync_assert_fpv #( //////////////////////// // assert depth of FIFO - `ASSERT(Depth_A, depth <= Depth) + `ASSERT(Depth_A, depth_o <= Depth) // if we clear the FIFO, it must be empty in the next cycle - `ASSERT(CheckClrDepth_A, clr_i |=> depth == 0) + `ASSERT(CheckClrDepth_A, clr_i |=> depth_o == 0) // check write on full - `ASSERT(WriteFull_A, depth == Depth && wvalid && !rready |=> depth == $past(depth), + `ASSERT(WriteFull_A, depth_o == Depth && wvalid_i && !rready_i |=> depth_o == $past(depth_o), clk_i, !rst_ni || clr_i) // read empty - `ASSERT(ReadEmpty_A, depth == 0 && rready && !wvalid |=> depth == 0, + `ASSERT(ReadEmpty_A, depth_o == 0 && rready_i && !wvalid_i |=> depth_o == 0, clk_i, !rst_ni || clr_i) // this is unreachable in depth 1 no-pass through mode if (Depth == 1 && Pass) begin : gen_d1_passthru // check simultaneous write and read - `ASSERT(WriteAndRead_A, wready && wvalid && rvalid && rready |=> depth == $past(depth), + `ASSERT(WriteAndRead_A, wready_o && wvalid_i && rvalid_o && rready_i |=> depth_o == $past(depth_o), clk_i, !rst_ni || clr_i) end @@ -158,35 +158,35 @@ module prim_fifo_sync_assert_fpv #( // if there is no register, the FIFO is per definition pass-through `ASSERT_INIT(ZeroDepthNeedsPass_A, Pass == 1) // depth must remain zero - `ASSERT(DepthAlwaysZero_A, depth == 0) + `ASSERT(DepthAlwaysZero_A, depth_o == 0) // data is just passed through - `ASSERT(DataPassThru_A, wdata == rdata) + `ASSERT(DataPassThru_A, wdata_i == rdata_o) // FIFO is ready if downstream logic is ready - `ASSERT(Wready_A, rready == wready) + `ASSERT(Wready_A, rready_i == wready_o) // valid input is valid output - `ASSERT(Rvalid_A, rvalid == wvalid) + `ASSERT(Rvalid_A, rvalid_o == wvalid_i) // ensure full coverage `ASSERT(UnusedClr_A, prim_fifo_sync.gen_passthru_fifo.unused_clr == clr_i) end else begin : gen_depth_gt0 // check wready - `ASSERT(Wready_A, depth < Depth |-> wready) + `ASSERT(Wready_A, depth_o < Depth |-> wready_o) // check rvalid - `ASSERT(Rvalid_A, depth > 0 |-> rvalid) + `ASSERT(Rvalid_A, depth_o > 0 |-> rvalid_o) // check write only - `ASSERT(WriteOnly_A, wvalid && wready && !rready && depth < Depth |=> - depth == $past(depth) + 1, clk_i, !rst_ni || clr_i) + `ASSERT(WriteOnly_A, wvalid_i && wready_o && !rready_i && depth_o < Depth |=> + depth_o == $past(depth_o) + 1, clk_i, !rst_ni || clr_i) // check read only - `ASSERT(ReadOnly_A, !wvalid && rready && rvalid && depth > 0 |=> - depth == $past(depth) - 1, clk_i, !rst_ni || clr_i) + `ASSERT(ReadOnly_A, !wvalid_i && rready_i && rvalid_o && depth_o > 0 |=> + depth_o == $past(depth_o) - 1, clk_i, !rst_ni || clr_i) end if (Pass) begin : gen_pass_fwd // if we clear the FIFO, it must be empty in the next cycle // but we may also get a pass through - `ASSERT(CheckClrValid_A, clr_i |=> wvalid == rvalid) + `ASSERT(CheckClrValid_A, clr_i |=> wvalid_i == rvalid_o) end else begin : gen_nopass_fwd // if we clear the FIFO, it must be empty in the next cycle - `ASSERT(CheckClrValid_A, clr_i |=> !rvalid) + `ASSERT(CheckClrValid_A, clr_i |=> !rvalid_o) end ///////////////////////// @@ -195,19 +195,19 @@ module prim_fifo_sync_assert_fpv #( if (Pass) begin : gen_pass_bkwd // there is still space in the FIFO or downstream logic is ready - `ASSERT(WreadySpacekBkwd_A, wready |-> depth < Depth || rready) + `ASSERT(WreadySpacekBkwd_A, wready_o |-> depth_o < Depth || rready_i) // elements ready to be read or upstream data is valid - `ASSERT(RvalidElemskBkwd_A, rvalid |-> depth > 0 || wvalid) + `ASSERT(RvalidElemskBkwd_A, rvalid_o |-> depth_o > 0 || wvalid_i) end else begin : gen_nopass_bkwd // there is still space in the FIFO - `ASSERT(WreadySpacekBkwd_A, wready |-> depth < Depth) + `ASSERT(WreadySpacekBkwd_A, wready_o |-> depth_o < Depth) // elements ready to be read - `ASSERT(RvalidElemskBkwd_A, rvalid |-> depth > 0) + `ASSERT(RvalidElemskBkwd_A, rvalid_o |-> depth_o > 0) end // no more space in the FIFO - `ASSERT(WreadyNoSpaceBkwd_A, !wready |-> depth == Depth) + `ASSERT(WreadyNoSpaceBkwd_A, !wready_o |-> depth_o == Depth) // elements ready to be read - `ASSERT(RvalidNoElemskBkwd_A, !rvalid |-> depth == 0) + `ASSERT(RvalidNoElemskBkwd_A, !rvalid_o |-> depth_o == 0) endmodule : prim_fifo_sync_assert_fpv diff --git a/vendor/lowrisc_ip/prim/prim.core b/vendor/lowrisc_ip/prim/prim.core index 11027e43..eee3a5d9 100644 --- a/vendor/lowrisc_ip/prim/prim.core +++ b/vendor/lowrisc_ip/prim/prim.core @@ -15,8 +15,9 @@ filesets: - lowrisc:prim:pad_wrapper - lowrisc:prim:prim_pkg - lowrisc:prim:clock_mux2 + - lowrisc:prim:flop + - lowrisc:prim:flop_2sync files: - - rtl/prim_clock_inverter.sv - rtl/prim_clock_gating_sync.sv - rtl/prim_alert_pkg.sv - rtl/prim_alert_receiver.sv @@ -29,7 +30,6 @@ filesets: - rtl/prim_sram_arbiter.sv - rtl/prim_fifo_async.sv - rtl/prim_fifo_sync.sv - - rtl/prim_flop_2sync.sv - rtl/prim_sync_reqack.sv - rtl/prim_keccak.sv - rtl/prim_packer.sv @@ -41,8 +41,10 @@ filesets: - rtl/prim_pulse_sync.sv - rtl/prim_filter.sv - rtl/prim_filter_ctr.sv + - rtl/prim_subreg_arb.sv - rtl/prim_subreg.sv - rtl/prim_subreg_ext.sv + - rtl/prim_subreg_shadow.sv - rtl/prim_intr_hw.sv file_type: systemVerilogSource diff --git a/vendor/lowrisc_ip/prim/prim_clock_buf.core b/vendor/lowrisc_ip/prim/prim_clock_buf.core new file mode 100644 index 00000000..724a29e5 --- /dev/null +++ b/vendor/lowrisc_ip/prim/prim_clock_buf.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim:clock_buf" +description: "Generic clock buffer" +filesets: + primgen_dep: + depend: + - lowrisc:prim:prim_pkg + - lowrisc:prim:primgen + +generate: + impl: + generator: primgen + parameters: + prim_name: clock_buf + +targets: + default: + filesets: + - primgen_dep + generate: + - impl diff --git a/vendor/lowrisc_ip/prim/prim_clock_inv.core b/vendor/lowrisc_ip/prim/prim_clock_inv.core new file mode 100644 index 00000000..96227eb9 --- /dev/null +++ b/vendor/lowrisc_ip/prim/prim_clock_inv.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim:clock_inv" +description: "Clock inverter with scanmode bypass mux" +filesets: + primgen_dep: + depend: + - lowrisc:prim:prim_pkg + - lowrisc:prim:primgen + +generate: + impl: + generator: primgen + parameters: + prim_name: clock_inv + +targets: + default: + filesets: + - primgen_dep + generate: + - impl diff --git a/vendor/lowrisc_ip/prim/prim_flop.core b/vendor/lowrisc_ip/prim/prim_flop.core new file mode 100644 index 00000000..e007e9fa --- /dev/null +++ b/vendor/lowrisc_ip/prim/prim_flop.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim:flop" +description: "Generic flop" +filesets: + primgen_dep: + depend: + - lowrisc:prim:prim_pkg + - lowrisc:prim:primgen + +generate: + impl: + generator: primgen + parameters: + prim_name: flop + +targets: + default: + filesets: + - primgen_dep + generate: + - impl diff --git a/vendor/lowrisc_ip/prim/prim_flop_2sync.core b/vendor/lowrisc_ip/prim/prim_flop_2sync.core new file mode 100644 index 00000000..b814a781 --- /dev/null +++ b/vendor/lowrisc_ip/prim/prim_flop_2sync.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim:flop_2sync" +description: "Primitive synchronizer" +filesets: + primgen_dep: + depend: + - lowrisc:prim:prim_pkg + - lowrisc:prim:primgen + +generate: + impl: + generator: primgen + parameters: + prim_name: flop_2sync + +targets: + default: + filesets: + - primgen_dep + generate: + - impl diff --git a/vendor/lowrisc_ip/prim/rtl/prim_cipher_pkg.sv b/vendor/lowrisc_ip/prim/rtl/prim_cipher_pkg.sv index f3bf0273..80929d10 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_cipher_pkg.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_cipher_pkg.sv @@ -30,15 +30,15 @@ package prim_cipher_pkg; 4'h9, 4'h8, 4'hD, 4'hF, 4'h2, 4'h3, 4'h7, 4'hB}; // nibble permutations - parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64 = '{4'hB, 4'h6, 4'h1, 4'hC, + parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64 = '{4'hF, 4'hA, 4'h5, 4'h0, + 4'hB, 4'h6, 4'h1, 4'hC, 4'h7, 4'h2, 4'hD, 4'h8, - 4'h3, 4'hE, 4'h9, 4'h4, - 4'hF, 4'hA, 4'h5, 4'h0}; + 4'h3, 4'hE, 4'h9, 4'h4}; - parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64_INV = '{4'h3, 4'h6, 4'h9, 4'hC, - 4'hF, 4'h2, 4'h5, 4'h8, + parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64_INV = '{4'hF, 4'h2, 4'h5, 4'h8, 4'hB, 4'hE, 4'h1, 4'h4, - 4'h7, 4'hA, 4'hD, 4'h0}; + 4'h7, 4'hA, 4'hD, 4'h0, + 4'h3, 4'h6, 4'h9, 4'hC}; // these are the round constants parameter logic [11:0][63:0] PRINCE_ROUND_CONST = {64'hC0AC29B7C97C50DD, @@ -58,10 +58,10 @@ package prim_cipher_pkg; parameter logic [63:0] PRINCE_ALPHA_CONST = 64'hC0AC29B7C97C50DD; // masking constants for shift rows function below - parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST0 = 16'hEDB7; - parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST1 = 16'h7EDB; - parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST2 = 16'hB7ED; - parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST3 = 16'hDB7E; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST0 = 16'h7BDE; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST1 = 16'hBDE7; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST2 = 16'hDE7B; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST3 = 16'hE7BD; // nibble shifts function automatic logic [31:0] prince_shiftrows_32bit(logic [31:0] state_in, @@ -94,15 +94,15 @@ package prim_cipher_pkg; function automatic logic [31:0] prince_mult_prime_32bit(logic [31:0] state_in); logic [31:0] state_out; // M0 - state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); - state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); - state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); - state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); // M1 - state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); - state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); - state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); - state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); return state_out; endfunction : prince_mult_prime_32bit @@ -110,25 +110,25 @@ package prim_cipher_pkg; function automatic logic [63:0] prince_mult_prime_64bit(logic [63:0] state_in); logic [63:0] state_out; // M0 - state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); - state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); - state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); - state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); // M1 - state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); - state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); - state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); - state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); // M1 - state_out[32 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST1); - state_out[36 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST2); - state_out[40 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST3); - state_out[44 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[32 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[36 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[40 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[44 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST1); // M0 - state_out[48 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST0); - state_out[52 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST1); - state_out[56 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST2); - state_out[60 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[48 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[52 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[56 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[60 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST0); return state_out; endfunction : prince_mult_prime_64bit diff --git a/vendor/lowrisc_ip/prim/rtl/prim_clock_gating_sync.sv b/vendor/lowrisc_ip/prim/rtl/prim_clock_gating_sync.sv index aca0d5a9..bcc8f75f 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_clock_gating_sync.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_clock_gating_sync.sv @@ -19,8 +19,8 @@ module prim_clock_gating_sync ( ) i_sync ( .clk_i, .rst_ni, - .d(async_en_i), - .q(en_o) + .d_i(async_en_i), + .q_o(en_o) ); prim_clock_gating i_cg ( diff --git a/vendor/lowrisc_ip/prim/rtl/prim_diff_decode.sv b/vendor/lowrisc_ip/prim/rtl/prim_diff_decode.sv index f5b4dd17..c06a77d7 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_diff_decode.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_diff_decode.sv @@ -57,8 +57,8 @@ module prim_diff_decode #( ) i_sync_p ( .clk_i, .rst_ni, - .d(diff_pi), - .q(diff_pd) + .d_i(diff_pi), + .q_o(diff_pd) ); prim_flop_2sync #( @@ -67,8 +67,8 @@ module prim_diff_decode #( ) i_sync_n ( .clk_i, .rst_ni, - .d(diff_ni), - .q(diff_nd) + .d_i(diff_ni), + .q_o(diff_nd) ); // detect level transitions diff --git a/vendor/lowrisc_ip/prim/rtl/prim_esc_sender.sv b/vendor/lowrisc_ip/prim/rtl/prim_esc_sender.sv index 0db75411..960461f9 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_esc_sender.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_esc_sender.sv @@ -26,8 +26,7 @@ module prim_esc_sender ( input clk_i, input rst_ni, - // this triggers a ping test. keep asserted - // until either ping_ok_o or ping_fail_o is asserted. + // this triggers a ping test. keep asserted until ping_ok_o is pulsed high. input ping_en_i, output logic ping_ok_o, // asserted if signal integrity issue detected @@ -174,12 +173,6 @@ module prim_esc_sender default : state_d = Idle; endcase - // escalation takes precedence, - // immediately return ok in that case - if ((esc_en_i || esc_en_q || esc_en_q1) && ping_en_i) begin - ping_ok_o = 1'b1; - end - // a sigint error will reset the state machine // and have it pause for two cycles to let the // receiver recover @@ -187,6 +180,12 @@ module prim_esc_sender ping_ok_o = 1'b0; state_d = Idle; end + + // escalation takes precedence, + // immediately return ok in that case + if ((esc_en_i || esc_en_q || esc_en_q1) && ping_en_i) begin + ping_ok_o = 1'b1; + end end /////////////// @@ -245,7 +244,7 @@ module prim_esc_sender // check that escalation signal is at least 2 cycles high `ASSERT(EscCheck_A, esc_en_i |-> esc_tx_o.esc_p [*2] ) // escalation / ping collision - `ASSERT(EscPingCheck_A, esc_en_i && ping_en_i |-> ping_ok_o, clk_i, !rst_ni || integ_fail_o) + `ASSERT(EscPingCheck_A, esc_en_i && ping_en_i |-> ping_ok_o) // check that ping request results in only a single cycle pulse `ASSERT(PingCheck_A, ##1 $rose(ping_en_i) |-> esc_tx_o.esc_p ##1 !esc_tx_o.esc_p , clk_i, !rst_ni || esc_en_i || integ_fail_o) diff --git a/vendor/lowrisc_ip/prim/rtl/prim_fifo_async.sv b/vendor/lowrisc_ip/prim/rtl/prim_fifo_async.sv index 616cba9f..82b427f4 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_fifo_async.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_fifo_async.sv @@ -14,18 +14,18 @@ module prim_fifo_async #( // write port input clk_wr_i, input rst_wr_ni, - input wvalid, - output wready, - input [Width-1:0] wdata, - output [DepthW-1:0] wdepth, + input wvalid_i, + output wready_o, + input [Width-1:0] wdata_i, + output [DepthW-1:0] wdepth_o, // read port input clk_rd_i, input rst_rd_ni, - output rvalid, - input rready, - output [Width-1:0] rdata, - output [DepthW-1:0] rdepth + output rvalid_o, + input rready_i, + output [Width-1:0] rdata_o, + output [DepthW-1:0] rdepth_o ); `ASSERT_INIT(paramCheckDepth, Depth >= 3) @@ -42,13 +42,13 @@ module prim_fifo_async #( logic full_wclk, full_rclk; - assign wready = !full_wclk; - assign rvalid = !empty; + assign wready_o = !full_wclk; + assign rvalid_o = !empty; // create the write and read pointers - assign fifo_incr_wptr = wvalid & wready; - assign fifo_incr_rptr = rvalid & rready; + assign fifo_incr_wptr = wvalid_i & wready_o; + assign fifo_incr_rptr = rvalid_o & rready_i; /////////////////// // write pointer // @@ -80,8 +80,8 @@ module prim_fifo_async #( prim_flop_2sync #(.Width(PTR_WIDTH)) sync_wptr ( .clk_i (clk_rd_i), .rst_ni (rst_rd_ni), - .d (fifo_wptr_gray), - .q (fifo_wptr_gray_sync)); + .d_i (fifo_wptr_gray), + .q_o (fifo_wptr_gray_sync)); assign fifo_wptr_sync_combi = gray2dec(fifo_wptr_gray_sync); @@ -115,8 +115,8 @@ module prim_fifo_async #( prim_flop_2sync #(.Width(PTR_WIDTH)) sync_rptr ( .clk_i (clk_wr_i), .rst_ni (rst_wr_ni), - .d (fifo_rptr_gray), - .q (fifo_rptr_gray_sync)); + .d_i (fifo_rptr_gray), + .q_o (fifo_rptr_gray_sync)); always_ff @(posedge clk_wr_i or negedge rst_wr_ni) if (!rst_wr_ni) begin @@ -141,9 +141,9 @@ module prim_fifo_async #( assign rptr_sync_msb = fifo_rptr_sync[PTR_WIDTH-1]; assign wptr_value = fifo_wptr[0+:PTRV_W]; assign rptr_sync_value = fifo_rptr_sync[0+:PTRV_W]; - assign wdepth = (full_wclk) ? DepthW'(Depth) : - (wptr_msb == rptr_sync_msb) ? DepthW'(wptr_value) - DepthW'(rptr_sync_value) : - (DepthW'(Depth) - DepthW'(rptr_sync_value) + DepthW'(wptr_value)) ; + assign wdepth_o = (full_wclk) ? DepthW'(Depth) : + (wptr_msb == rptr_sync_msb) ? DepthW'(wptr_value) - DepthW'(rptr_sync_value) : + (DepthW'(Depth) - DepthW'(rptr_sync_value) + DepthW'(wptr_value)) ; // Same again in the read clock side assign empty = (fifo_wptr_sync_combi == fifo_rptr); @@ -155,9 +155,9 @@ module prim_fifo_async #( assign rptr_msb = fifo_rptr[PTR_WIDTH-1]; assign wptr_sync_value = fifo_wptr_sync_combi[0+:PTRV_W]; assign rptr_value = fifo_rptr[0+:PTRV_W]; - assign rdepth = (full_rclk) ? DepthW'(Depth) : - (wptr_sync_msb == rptr_msb) ? DepthW'(wptr_sync_value) - DepthW'(rptr_value) : - (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_sync_value)) ; + assign rdepth_o = (full_rclk) ? DepthW'(Depth) : + (wptr_sync_msb == rptr_msb) ? DepthW'(wptr_sync_value) - DepthW'(rptr_value) : + (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_sync_value)) ; ///////////// // storage // @@ -167,10 +167,10 @@ module prim_fifo_async #( always_ff @(posedge clk_wr_i) if (fifo_incr_wptr) begin - storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata; + storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata_i; end - assign rdata = storage[fifo_rptr[PTR_WIDTH-2:0]]; + assign rdata_o = storage[fifo_rptr[PTR_WIDTH-2:0]]; // gray code conversion functions. algorithm walks up from 0..N-1 // then flips the upper bit and walks down from N-1 to 0. diff --git a/vendor/lowrisc_ip/prim/rtl/prim_fifo_sync.sv b/vendor/lowrisc_ip/prim/rtl/prim_fifo_sync.sv index d952ba66..c8e0aba0 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_fifo_sync.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_fifo_sync.sv @@ -19,29 +19,29 @@ module prim_fifo_sync #( // synchronous clear / flush port input clr_i, // write port - input wvalid, - output wready, - input [Width-1:0] wdata, + input wvalid_i, + output wready_o, + input [Width-1:0] wdata_i, // read port - output rvalid, - input rready, - output [Width-1:0] rdata, + output rvalid_o, + input rready_i, + output [Width-1:0] rdata_o, // occupancy - output [DepthW-1:0] depth + output [DepthW-1:0] depth_o ); // FIFO is in complete passthrough mode if (Depth == 0) begin : gen_passthru_fifo `ASSERT_INIT(paramCheckPass, Pass == 1) - assign depth = 1'b0; //output is meaningless + assign depth_o = 1'b0; //output is meaningless // devie facing - assign rvalid = wvalid; - assign rdata = wdata; + assign rvalid_o = wvalid_i; + assign rdata_o = wdata_i; // host facing - assign wready = rready; + assign wready_o = rready_i; // this avoids lint warnings logic unused_clr; @@ -67,15 +67,15 @@ module prim_fifo_sync #( assign rptr_msb = fifo_rptr[PTR_WIDTH-1]; assign wptr_value = fifo_wptr[0+:PTRV_W]; assign rptr_value = fifo_rptr[0+:PTRV_W]; - assign depth = (full) ? DepthW'(Depth) : - (wptr_msb == rptr_msb) ? DepthW'(wptr_value) - DepthW'(rptr_value) : - (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_value)) ; + assign depth_o = (full) ? DepthW'(Depth) : + (wptr_msb == rptr_msb) ? DepthW'(wptr_value) - DepthW'(rptr_value) : + (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_value)) ; - assign fifo_incr_wptr = wvalid & wready; - assign fifo_incr_rptr = rvalid & rready; + assign fifo_incr_wptr = wvalid_i & wready_o; + assign fifo_incr_rptr = rvalid_o & rready_i; - assign wready = ~full; - assign rvalid = ~empty; + assign wready_o = ~full; + assign rvalid_o = ~empty; always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin @@ -118,7 +118,7 @@ module prim_fifo_sync #( always_ff @(posedge clk_i) if (fifo_incr_wptr) begin - storage[0] <= wdata; + storage[0] <= wdata_i; end // fifo with more than one storage element end else begin : gen_depth_gt1 @@ -126,26 +126,26 @@ module prim_fifo_sync #( always_ff @(posedge clk_i) if (fifo_incr_wptr) begin - storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata; + storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata_i; end end logic [Width-1:0] rdata_int; if (Pass == 1'b1) begin : gen_pass - assign rdata_int = (fifo_empty && wvalid) ? wdata : storage_rdata; - assign empty = fifo_empty & ~wvalid; + assign rdata_int = (fifo_empty && wvalid_i) ? wdata_i : storage_rdata; + assign empty = fifo_empty & ~wvalid_i; end else begin : gen_nopass assign rdata_int = storage_rdata; assign empty = fifo_empty; end if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero - assign rdata = empty ? 'b0 : rdata_int; + assign rdata_o = empty ? 'b0 : rdata_int; end else begin : gen_no_output_zero - assign rdata = rdata_int; + assign rdata_o = rdata_int; end - `ASSERT(depthShallNotExceedParamDepth, !empty |-> depth <= DepthW'(Depth)) + `ASSERT(depthShallNotExceedParamDepth, !empty |-> depth_o <= DepthW'(Depth)) end // block: gen_normal_fifo @@ -153,9 +153,9 @@ module prim_fifo_sync #( // Known Assertions // ////////////////////// - `ASSERT(DataKnown_A, rvalid |-> !$isunknown(rdata)) - `ASSERT_KNOWN(DepthKnown_A, depth) - `ASSERT_KNOWN(RvalidKnown_A, rvalid) - `ASSERT_KNOWN(WreadyKnown_A, wready) + `ASSERT(DataKnown_A, rvalid_o |-> !$isunknown(rdata_o)) + `ASSERT_KNOWN(DepthKnown_A, depth_o) + `ASSERT_KNOWN(RvalidKnown_A, rvalid_o) + `ASSERT_KNOWN(WreadyKnown_A, wready_o) endmodule diff --git a/vendor/lowrisc_ip/prim/rtl/prim_filter.sv b/vendor/lowrisc_ip/prim/rtl/prim_filter.sv index 214e0c31..876e11df 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_filter.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_filter.sv @@ -1,6 +1,6 @@ -// Copyright 2018 lowRISC contributors. +// Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Indentifier: Apache-2.0 +// SPDX-License-Identifier: Apache-2.0 // // Primitive input filter, with enable. Configurable number of cycles. // diff --git a/vendor/lowrisc_ip/prim/rtl/prim_filter_ctr.sv b/vendor/lowrisc_ip/prim/rtl/prim_filter_ctr.sv index 941ad270..ec635b80 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_filter_ctr.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_filter_ctr.sv @@ -1,6 +1,6 @@ -// Copyright 2018 lowRISC contributors. +// Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Indentifier: Apache-2.0 +// SPDX-License-Identifier: Apache-2.0 // // Primitive counter-based input filter, with enable. // Configurable number of cycles. Cheaper version of filter for diff --git a/vendor/lowrisc_ip/prim/rtl/prim_flop_2sync.sv b/vendor/lowrisc_ip/prim/rtl/prim_flop_2sync.sv deleted file mode 100644 index 757fe18d..00000000 --- a/vendor/lowrisc_ip/prim/rtl/prim_flop_2sync.sv +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Generic double-synchronizer flop - -module prim_flop_2sync #( - parameter int Width = 16, - parameter logic [Width-1:0] ResetValue = '0 -) ( - input clk_i, // receive clock - input rst_ni, - input [Width-1:0] d, - output logic [Width-1:0] q -); - - logic [Width-1:0] intq; - - always_ff @(posedge clk_i or negedge rst_ni) - if (!rst_ni) begin - intq <= ResetValue; - q <= ResetValue; - end else begin - intq <= d; - q <= intq; - end - -endmodule diff --git a/vendor/lowrisc_ip/prim/rtl/prim_gate_gen.sv b/vendor/lowrisc_ip/prim/rtl/prim_gate_gen.sv index e97c7d50..dac761fd 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_gate_gen.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_gate_gen.sv @@ -2,50 +2,36 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // -// Simple parameterizable gate generator. Used to fill up the netlist -// with gates that cannot be optimized away. +// Simple parameterizable gate generator. Used to fill up the netlist with gates that cannot be +// optimized away. // -// The module leverages 4bit SBoxes from the PRINCE cipher, and interleaves -// them with registers, resulting in a split of around 50/50 between logic and -// sequential cells. +// The module leverages 4bit SBoxes from the PRINCE cipher, and interleaves them with registers, +// resulting in a split of around 50/50 between logic and sequential cells. // -// This generator has been tested with 32bit wide data, and produces -// the following results: +// This generator has been tested with 32bit wide data, and produces the following results: // -// if valid_i constantly set to 1'b1: // -------------+-----------+---------- // requested GE | actual GE | GE error // -------------+-----------+---------- -// 500 | 679 | 179 -// 1000 | 1018 | 18 -// 1500 | 1696 | 196 -// 2500 | 2714 | 214 -// 5000 | 5210 | 210 -// 7500 | 7456 | -44 -// 10000 | 10015 | 15 -// 15000 | 15191 | 191 -// 25000 | 25228 | 228 -// 50000 | 50485 | 485 +// 500 | 483 | -17 +// 1000 | 964 | -36 +// 1500 | 1447 | -53 +// 2500 | 2892 | 392 +// 5000 | 5299 | 299 +// 7500 | 8030 | 530 +// 10000 | 10393 | 393 +// 15000 | 15575 | 575 +// 25000 | 26422 | 1422 +// 50000 | 52859 | 2859 +// 100000 | 105270 | 5270 // -// otherwise, with clock gating enabled: -// -------------+-----------+---------- -// requested GE | actual GE | GE error -// -------------+-----------+---------- -// 500 | 696 | 196 -// 1000 | 1043 | 43 -// 1500 | 1737 | 237 -// 2500 | 2779 | 279 -// 5000 | 5340 | 340 -// 7500 | 7634 | 134 -// 10000 | 10284 | 284 -// 15000 | 15585 | 585 -// 25000 | 25855 | 855 -// 50000 | 51732 | 1732 +// Note that the generator is not very accurate for smaller gate counts due to the generate loop +// granularity. Hence, do not use for fever than 500 GE. // -// Note that the generator is not very accurate for smaller gate counts due -// to the generate loop granularity. Hence, do not use for fever than 500 GE. - +// If valid_i constantly set to 1'b1, the gate generator produces around 2.5% smaller designs for +// the configurations listed in the table above. +`include "prim_assert.sv" module prim_gate_gen #( parameter int DataWidth = 32, parameter int NumGates = 1000 @@ -66,7 +52,7 @@ module prim_gate_gen #( // technology specific tuning, do not modify. // an inner round is comprised of a 2bit rotation, followed by a 4bit SBox Layer. localparam int NumInnerRounds = 2; - localparam int GatesPerRound = DataWidth * 10; + localparam int GatesPerRound = DataWidth * 14; // an outer round consists of NumInnerRounds, followed by a register. localparam int NumOuterRounds = (NumGates + GatesPerRound / 2) / GatesPerRound; diff --git a/vendor/lowrisc_ip/prim/rtl/prim_intr_hw.sv b/vendor/lowrisc_ip/prim/rtl/prim_intr_hw.sv index 950c3372..6198b318 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_intr_hw.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_intr_hw.sv @@ -1,6 +1,6 @@ // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Indentifier: Apache-2.0 +// SPDX-License-Identifier: Apache-2.0 // // Primitive interrupt handler. This assumes the existence of three // controller registers: INTR_ENABLE, INTR_STATE, INTR_TEST. diff --git a/vendor/lowrisc_ip/prim/rtl/prim_keccak.sv b/vendor/lowrisc_ip/prim/rtl/prim_keccak.sv index 7c3a526e..d247078f 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_keccak.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_keccak.sv @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // // prim_keccak is single round permutation module - +`include "prim_assert.sv" module prim_keccak #( parameter int Width = 1600, // b= {25, 50, 100, 200, 400, 800, 1600} diff --git a/vendor/lowrisc_ip/prim/rtl/prim_present.sv b/vendor/lowrisc_ip/prim/rtl/prim_present.sv index bf3321c1..67279140 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_present.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_present.sv @@ -22,7 +22,7 @@ // TODO: this module has not been verified yet, and has only been used in // synthesis experiments. - +`include "prim_assert.sv" module prim_present #( parameter int DataWidth = 64, // {32, 64} parameter int KeyWidth = 128, // {64, 80, 128} diff --git a/vendor/lowrisc_ip/prim/rtl/prim_prince.sv b/vendor/lowrisc_ip/prim/rtl/prim_prince.sv index 655835fd..423a7ca2 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_prince.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_prince.sv @@ -24,7 +24,7 @@ // TODO: this module has not been verified yet, and has only been used in // synthesis experiments. - +`include "prim_assert.sv" module prim_prince #( parameter int DataWidth = 64, parameter int KeyWidth = 128, diff --git a/vendor/lowrisc_ip/prim/rtl/prim_pulse_sync.sv b/vendor/lowrisc_ip/prim/rtl/prim_pulse_sync.sv index 143b0884..ad275fd9 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_pulse_sync.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_pulse_sync.sv @@ -39,11 +39,11 @@ module prim_pulse_sync ( prim_flop_2sync #(.Width(1)) prim_flop_2sync ( // source clock domain - .d (src_level), + .d_i (src_level), // destination clock domain .clk_i (clk_dst_i), .rst_ni (rst_dst_ni), - .q (dst_level) + .q_o (dst_level) ); //////////////////////////////////////// diff --git a/vendor/lowrisc_ip/prim/rtl/prim_sram_arbiter.sv b/vendor/lowrisc_ip/prim/rtl/prim_sram_arbiter.sv index 4ba0ebba..bd803496 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_sram_arbiter.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_sram_arbiter.sv @@ -20,24 +20,24 @@ module prim_sram_arbiter #( input clk_i, input rst_ni, - input [ N-1:0] req, - input [SramAw-1:0] req_addr [N], - input req_write [N], - input [SramDw-1:0] req_wdata [N], - output logic [ N-1:0] gnt, + input [ N-1:0] req_i, + input [SramAw-1:0] req_addr_i [N], + input req_write_i[N], + input [SramDw-1:0] req_wdata_i[N], + output logic [ N-1:0] gnt_o, - output logic [ N-1:0] rsp_rvalid, // Pulse - output logic [SramDw-1:0] rsp_rdata [N], - output logic [ 1:0] rsp_error [N], + output logic [ N-1:0] rsp_rvalid_o, // Pulse + output logic [SramDw-1:0] rsp_rdata_o[N], + output logic [ 1:0] rsp_error_o[N], // SRAM Interface - output logic sram_req, - output logic [SramAw-1:0] sram_addr, - output logic sram_write, - output logic [SramDw-1:0] sram_wdata, - input sram_rvalid, - input [SramDw-1:0] sram_rdata, - input [1:0] sram_rerror + output logic sram_req_o, + output logic [SramAw-1:0] sram_addr_o, + output logic sram_write_o, + output logic [SramDw-1:0] sram_wdata_o, + input sram_rvalid_i, + input [SramDw-1:0] sram_rdata_i, + input [1:0] sram_rerror_i ); @@ -52,13 +52,13 @@ module prim_sram_arbiter #( req_t req_packed [N]; for (genvar i = 0 ; i < N ; i++) begin : gen_reqs - assign req_packed[i] = {req_write[i], req_addr[i], req_wdata[i]}; + assign req_packed[i] = {req_write_i[i], req_addr_i[i], req_wdata_i[i]}; end req_t sram_packed; - assign sram_write = sram_packed.write; - assign sram_addr = sram_packed.addr; - assign sram_wdata = sram_packed.wdata; + assign sram_write_o = sram_packed.write; + assign sram_addr_o = sram_packed.addr; + assign sram_wdata_o = sram_packed.wdata; if (ArbiterImpl == "PPC") begin : gen_arb_ppc prim_arbiter_ppc #( @@ -67,11 +67,11 @@ module prim_sram_arbiter #( ) u_reqarb ( .clk_i, .rst_ni, - .req_i ( req ), + .req_i, .data_i ( req_packed ), - .gnt_o ( gnt ), + .gnt_o, .idx_o ( ), - .valid_o ( sram_req ), + .valid_o ( sram_req_o ), .data_o ( sram_packed ), .ready_i ( 1'b1 ) ); @@ -82,11 +82,11 @@ module prim_sram_arbiter #( ) u_reqarb ( .clk_i, .rst_ni, - .req_i ( req ), + .req_i, .data_i ( req_packed ), - .gnt_o ( gnt ), + .gnt_o, .idx_o ( ), - .valid_o ( sram_req ), + .valid_o ( sram_req_o ), .data_o ( sram_packed ), .ready_i ( 1'b1 ) ); @@ -95,10 +95,10 @@ module prim_sram_arbiter #( end - logic [N-1:0] steer; // Steering sram_rvalid - logic sram_ack; // Ack for rvalid. |sram_rvalid + logic [N-1:0] steer; // Steering sram_rvalid_i + logic sram_ack; // Ack for rvalid. |sram_rvalid_i - assign sram_ack = sram_rvalid & (|steer); + assign sram_ack = sram_rvalid_i & (|steer); // Request FIFO prim_fifo_sync #( @@ -109,20 +109,20 @@ module prim_sram_arbiter #( .clk_i, .rst_ni, .clr_i (1'b0), - .wvalid (sram_req && !sram_write), // Push only for read - .wready (), // TODO: Generate Error - .wdata (gnt), - .depth (), // Not used - .rvalid (), // TODO; Generate error if sram_rvalid but rvalid==0 - .rready (sram_ack), - .rdata (steer) + .wvalid_i (sram_req_o & ~sram_write_o), // Push only for read + .wready_o (), // TODO: Generate Error + .wdata_i (gnt_o), + .depth_o (), // Not used + .rvalid_o (), // TODO; Generate error if sram_rvalid_i but rvalid==0 + .rready_i (sram_ack), + .rdata_o (steer) ); - assign rsp_rvalid = steer & {N{sram_rvalid}}; + assign rsp_rvalid_o = steer & {N{sram_rvalid_i}}; for (genvar i = 0 ; i < N ; i++) begin : gen_rsp - assign rsp_rdata[i] = sram_rdata; - assign rsp_error[i] = sram_rerror; // No SECDED yet + assign rsp_rdata_o[i] = sram_rdata_i; + assign rsp_error_o[i] = sram_rerror_i; // No SECDED yet end endmodule diff --git a/vendor/lowrisc_ip/prim/rtl/prim_subreg.sv b/vendor/lowrisc_ip/prim/rtl/prim_subreg.sv index ce2b55b8..d1fab641 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_subreg.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_subreg.sv @@ -27,50 +27,38 @@ module prim_subreg #( output logic [DW-1:0] qs ); - logic wr_en ; + logic wr_en; logic [DW-1:0] wr_data; - if ((SWACCESS == "RW") || (SWACCESS == "WO")) begin : gen_w - assign wr_en = we | de ; - assign wr_data = (we == 1'b1) ? wd : d ; // SW higher priority - end else if (SWACCESS == "RO") begin : gen_ro - // Unused we, wd - assign wr_en = de ; - assign wr_data = d ; - end else if (SWACCESS == "W1S") begin : gen_w1s - // If SWACCESS is W1S, then assume hw tries to clear. - // So, give a chance HW to clear when SW tries to set. - // If both try to set/clr at the same bit pos, SW wins. - assign wr_en = we | de ; - assign wr_data = (de ? d : q) | (we ? wd : '0); - end else if (SWACCESS == "W1C") begin : gen_w1c - // If SWACCESS is W1C, then assume hw tries to set. - // So, give a chance HW to set when SW tries to clear. - // If both try to set/clr at the same bit pos, SW wins. - assign wr_en = we | de ; - assign wr_data = (de ? d : q) & (we ? ~wd : '1); - end else if (SWACCESS == "W0C") begin : gen_w0c - assign wr_en = we | de ; - assign wr_data = (de ? d : q) & (we ? wd : '1); - end else if (SWACCESS == "RC") begin : gen_rc - // This swtype is not recommended but exists for compatibility. - // WARN: we signal is actually read signal not write enable. - assign wr_en = we | de ; - assign wr_data = (de ? d : q) & (we ? '0 : '1); - end else begin : gen_hw - assign wr_en = de ; - assign wr_data = d ; + prim_subreg_arb #( + .DW ( DW ), + .SWACCESS ( SWACCESS ) + ) wr_en_data_arb ( + .we, + .wd, + .de, + .d, + .q, + .wr_en, + .wr_data + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + qe <= 1'b0; + end else begin + qe <= we; + end end always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) qe <= 1'b0; - else qe <= we ; + if (!rst_ni) begin + q <= RESVAL; + end else if (wr_en) begin + q <= wr_data; + end end - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) q <= RESVAL ; - else if (wr_en) q <= wr_data; - end assign qs = q; endmodule diff --git a/vendor/lowrisc_ip/prim/rtl/prim_subreg_arb.sv b/vendor/lowrisc_ip/prim/rtl/prim_subreg_arb.sv new file mode 100644 index 00000000..410cf2d1 --- /dev/null +++ b/vendor/lowrisc_ip/prim/rtl/prim_subreg_arb.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Write enable and data arbitration logic for register slice conforming to Comportibility guide. + +module prim_subreg_arb #( + parameter int DW = 32 , + parameter SWACCESS = "RW" // {RW, RO, WO, W1C, W1S, W0C, RC} +) ( + // From SW: valid for RW, WO, W1C, W1S, W0C, RC. + // In case of RC, top connects read pulse to we. + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO. + input de, + input [DW-1:0] d, + + // From register: actual reg value. + input [DW-1:0] q, + + // To register: actual write enable and write data. + output logic wr_en, + output logic [DW-1:0] wr_data +); + + if ((SWACCESS == "RW") || (SWACCESS == "WO")) begin : gen_w + assign wr_en = we | de; + assign wr_data = (we == 1'b1) ? wd : d; // SW higher priority + // Unused q - Prevent lint errors. + logic [DW-1:0] unused_q; + assign unused_q = q; + end else if (SWACCESS == "RO") begin : gen_ro + assign wr_en = de; + assign wr_data = d; + // Unused we, wd, q - Prevent lint errors. + logic unused_we; + logic [DW-1:0] unused_wd; + logic [DW-1:0] unused_q; + assign unused_we = we; + assign unused_wd = wd; + assign unused_q = q; + end else if (SWACCESS == "W1S") begin : gen_w1s + // If SWACCESS is W1S, then assume hw tries to clear. + // So, give a chance HW to clear when SW tries to set. + // If both try to set/clr at the same bit pos, SW wins. + assign wr_en = we | de; + assign wr_data = (de ? d : q) | (we ? wd : '0); + end else if (SWACCESS == "W1C") begin : gen_w1c + // If SWACCESS is W1C, then assume hw tries to set. + // So, give a chance HW to set when SW tries to clear. + // If both try to set/clr at the same bit pos, SW wins. + assign wr_en = we | de; + assign wr_data = (de ? d : q) & (we ? ~wd : '1); + end else if (SWACCESS == "W0C") begin : gen_w0c + assign wr_en = we | de; + assign wr_data = (de ? d : q) & (we ? wd : '1); + end else if (SWACCESS == "RC") begin : gen_rc + // This swtype is not recommended but exists for compatibility. + // WARN: we signal is actually read signal not write enable. + assign wr_en = we | de; + assign wr_data = (de ? d : q) & (we ? '0 : '1); + // Unused wd - Prevent lint errors. + logic [DW-1:0] unused_wd; + assign unused_wd = wd; + end else begin : gen_hw + assign wr_en = de; + assign wr_data = d; + // Unused we, wd, q - Prevent lint errors. + logic unused_we; + logic [DW-1:0] unused_wd; + logic [DW-1:0] unused_q; + assign unused_we = we; + assign unused_wd = wd; + assign unused_q = q; + end + +endmodule diff --git a/vendor/lowrisc_ip/prim/rtl/prim_subreg_shadow.sv b/vendor/lowrisc_ip/prim/rtl/prim_subreg_shadow.sv new file mode 100644 index 00000000..347e57f8 --- /dev/null +++ b/vendor/lowrisc_ip/prim/rtl/prim_subreg_shadow.sv @@ -0,0 +1,157 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Shadowed register slice conforming to Comportibility guide. + +module prim_subreg_shadow #( + parameter int DW = 32 , + parameter SWACCESS = "RW", // {RW, RO, WO, W1C, W1S, W0C, RC} + parameter logic [DW-1:0] RESVAL = '0 // reset value +) ( + input clk_i, + input rst_ni, + + // From SW: valid for RW, WO, W1C, W1S, W0C, RC. + // SW reads clear phase unless SWACCESS is RO. + input re, + // In case of RC, top connects read pulse to we. + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO. + input de, + input [DW-1:0] d, + + // Output to HW and Reg Read + output logic qe, + output logic [DW-1:0] q, + output logic [DW-1:0] qs, + + // Error conditions + output logic err_update, + output logic err_storage +); + + // Subreg control signals + logic phase_clear; + logic phase_q; + logic staged_we, shadow_we, committed_we; + logic staged_de, shadow_de, committed_de; + + // Subreg status and data signals + logic staged_qe, shadow_qe, committed_qe; + logic [DW-1:0] staged_q, shadow_q, committed_q; + logic [DW-1:0] committed_qs; + + // Effective write enable and write data signals. + // These depend on we, de and wd, d, q as well as SWACCESS. + logic wr_en; + logic [DW-1:0] wr_data; + + prim_subreg_arb #( + .DW ( DW ), + .SWACCESS ( SWACCESS ) + ) wr_en_data_arb ( + .we ( we ), + .wd ( wd ), + .de ( de ), + .d ( d ), + .q ( q ), + .wr_en ( wr_en ), + .wr_data ( wr_data ) + ); + + // Phase clearing: + // - SW reads clear phase unless SWACCESS is RO. + // - In case of RO, SW should not interfere with update process. + assign phase_clear = (SWACCESS == "RO") ? 1'b0 : re; + + // Phase tracker: + // - Reads from SW clear the phase back to 0. + // - Writes have priority (can come from SW or HW). + always_ff @(posedge clk_i or negedge rst_ni) begin : phase_reg + if (!rst_ni) begin + phase_q <= 1'b0; + end else if (wr_en) begin + phase_q <= ~phase_q; + end else if (phase_clear) begin + phase_q <= 1'b0; + end + end + + // The staged register: + // - Holds the 1's complement value. + // - Written in Phase 0. + assign staged_we = we & ~phase_q; + assign staged_de = de & ~phase_q; + prim_subreg #( + .DW ( DW ), + .SWACCESS ( SWACCESS ), + .RESVAL ( ~RESVAL ) + ) staged_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we ( staged_we ), + .wd ( ~wd ), + .de ( staged_de ), + .d ( ~d ), + .qe ( staged_qe ), + .q ( staged_q ), + .qs ( ) + ); + + // The shadow register: + // - Holds the 1's complement value. + // - Written in Phase 1. + // - Writes are ignored in case of update errors. + // - Gets the value from the staged register. + assign shadow_we = we & phase_q & ~err_update; + assign shadow_de = de & phase_q & ~err_update; + prim_subreg #( + .DW ( DW ), + .SWACCESS ( SWACCESS ), + .RESVAL ( ~RESVAL ) + ) shadow_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we ( shadow_we ), + .wd ( staged_q ), + .de ( shadow_de ), + .d ( staged_q ), + .qe ( shadow_qe ), + .q ( shadow_q ), + .qs ( ) + ); + + // The committed register: + // - Written in Phase 1. + // - Writes are ignored in case of update errors. + assign committed_we = shadow_we; + assign committed_de = shadow_de; + prim_subreg #( + .DW ( DW ), + .SWACCESS ( SWACCESS ), + .RESVAL ( RESVAL ) + ) committed_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we ( committed_we ), + .wd ( wd ), + .de ( committed_de ), + .d ( d ), + .qe ( committed_qe ), + .q ( committed_q ), + .qs ( committed_qs ) + ); + + // Error detection - all bits must match. + assign err_update = (~staged_q != wr_data) ? phase_q & wr_en : 1'b0; + assign err_storage = (~shadow_q != committed_q); + + // Remaining output assignments + assign qe = staged_qe | shadow_qe | committed_qe; + assign q = committed_q; + assign qs = committed_qs; + +endmodule diff --git a/vendor/lowrisc_ip/prim/rtl/prim_sync_reqack.sv b/vendor/lowrisc_ip/prim/rtl/prim_sync_reqack.sv index 5484898b..2481c71b 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_sync_reqack.sv +++ b/vendor/lowrisc_ip/prim/rtl/prim_sync_reqack.sv @@ -53,8 +53,8 @@ module prim_sync_reqack ( ) req_sync ( .clk_i (clk_dst_i), .rst_ni (rst_dst_ni), - .d (src_req_q), - .q (dst_req) + .d_i (src_req_q), + .q_o (dst_req) ); // Move ACK over to REQ side. @@ -63,8 +63,8 @@ module prim_sync_reqack ( ) ack_sync ( .clk_i (clk_src_i), .rst_ni (rst_src_ni), - .d (dst_ack_q), - .q (src_ack) + .d_i (dst_ack_q), + .q_o (src_ack) ); // REQ-side FSM (source domain) diff --git a/vendor/lowrisc_ip/prim/util/primgen.py b/vendor/lowrisc_ip/prim/util/primgen.py index 17453191..f601d503 100755 --- a/vendor/lowrisc_ip/prim/util/primgen.py +++ b/vendor/lowrisc_ip/prim/util/primgen.py @@ -5,7 +5,6 @@ import os import re import shutil -import subprocess import sys import yaml @@ -45,6 +44,7 @@ def _prim_cores(cores, prim_name=None): if (vlnv['vendor'] == 'lowrisc' and vlnv['library'].startswith('prim_') and (prim_name is None or vlnv['name'] == prim_name)): + return core return None @@ -159,6 +159,14 @@ def _parse_module_header(generic_impl_filepath, module_name): } +def test_parse_parameter_port_list(): + assert _parse_parameter_port_list("parameter integer P") == {'P'} + assert _parse_parameter_port_list("parameter logic [W-1:0] P") == {'P'} + assert _parse_parameter_port_list("parameter logic [W-1:0] P = '0") == {'P'} + assert _parse_parameter_port_list("parameter logic [W-1:0] P = 'b0") == {'P'} + assert _parse_parameter_port_list("parameter logic [W-1:0] P = 2'd0") == {'P'} + + def _parse_parameter_port_list(parameter_port_list): """ Parse a list of ports in a module header into individual parameters """ @@ -177,9 +185,9 @@ def _parse_parameter_port_list(parameter_port_list): # XXX: Not covering the complete grammar, e.g. `parameter x, y` RE_PARAMS = ( r'parameter\s+' - r'(?:[a-zA-Z0-9\]\[:\s\$]+\s+)?' # type + r'(?:[a-zA-Z0-9\]\[:\s\$-]+\s+)?' # type r'(?P\w+)' # name - r'(?:\s*=\s*[^,;]+)' # initial value + r'(?:\s*=\s*[^,;]+)?' # initial value ) re_params = re.compile(RE_PARAMS) parameters = set() @@ -189,9 +197,8 @@ def _parse_parameter_port_list(parameter_port_list): def _check_gapi(gapi): - if not 'cores' in gapi: + if 'cores' not in gapi: print("Key 'cores' not found in GAPI structure. " - "At least FuseSoC 1.11 is needed. " "Install a compatible version with " "'pip3 install --user -r python-requirements.txt'.") return False @@ -293,7 +300,7 @@ def _generate_abstract_impl(gapi): techlibs = _techlibs(prim_cores) - if not 'generic' in techlibs: + if 'generic' not in techlibs: raise ValueError("Techlib generic is required, but not found for " "primitive %s." % prim_name) print("Implementations for primitive %s: %s" % @@ -371,7 +378,8 @@ def _generate_abstract_impl(gapi): f, encoding="utf-8", default_flow_style=False, - sort_keys=False) + sort_keys=False, + Dumper=YamlDumper) print("Core file written to %s" % (abstract_prim_core_filepath, )) diff --git a/vendor/lowrisc_ip/prim_generic/lint/prim_generic_pad_wrapper.waiver b/vendor/lowrisc_ip/prim_generic/lint/prim_generic_pad_wrapper.waiver index fb823f36..8757e586 100644 --- a/vendor/lowrisc_ip/prim_generic/lint/prim_generic_pad_wrapper.waiver +++ b/vendor/lowrisc_ip/prim_generic/lint/prim_generic_pad_wrapper.waiver @@ -13,5 +13,10 @@ waive -rules SELF_ASSIGN -regexp {LHS signal 'inout_io' encountered on the RHS o -comment "This implements a keeper termination (it's basically an explicit TRIREG)" waive -rules DRIVE_STRENGTH -regexp {Drive strength .* encountered on assignment to 'inout_io'} -location {prim_generic_pad_wrapper.sv} \ -comment "The pad simulation model uses driving strength attributes to emulate different IO terminations." -waive -rules INPUT_NOT_READ -regexp {Input port 'attr\_i\[.:6\]' is not read from} -location {prim_generic_pad_wrapper.sv}\ +waive -rules INPUT_NOT_READ -regexp {Input port 'attr\_i*' is not read from} -location {prim_generic_pad_wrapper.sv} \ -comment "Some IO attributes may not be implemented." +waive -rules Z_USE -regexp {Constant with 'Z literal value '1'bz' encountered} -location {prim_generic_pad_wrapper.sv} \ + -comment "This z assignment is correct." +waive -rules PARAM_NOT_USED -regexp {Parameter 'Variant' not used in module 'prim_generic_pad_wrapper'} -location {prim_generic_pad_wrapper.sv} \ + -comment "This parameter has been provisioned for later and is currently unused." + diff --git a/vendor/lowrisc_ip/prim_generic/prim_generic_clock_buf.core b/vendor/lowrisc_ip/prim_generic/prim_generic_clock_buf.core new file mode 100644 index 00000000..e51f32a4 --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/prim_generic_clock_buf.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_generic:clock_buf" +description: "clock buffer" +filesets: + files_rtl: + files: + - rtl/prim_generic_clock_buf.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/vendor/lowrisc_ip/prim_generic/prim_generic_clock_inv.core b/vendor/lowrisc_ip/prim_generic/prim_generic_clock_inv.core new file mode 100644 index 00000000..b606644e --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/prim_generic_clock_inv.core @@ -0,0 +1,45 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_generic:clock_inv" +description: "Clock inverter with scanmode bypass mux" +filesets: + files_rtl: + depend: + - lowrisc:prim:assert + - lowrisc:prim:clock_mux2 + files: + - rtl/prim_generic_clock_inv.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + # - lint/prim_generic_clock_inv.vlt + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + # - lint/prim_generic_clock_inv.waiver + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/vendor/lowrisc_ip/prim_generic/prim_generic_flop.core b/vendor/lowrisc_ip/prim_generic/prim_generic_flop.core new file mode 100644 index 00000000..e44b7b4c --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/prim_generic_flop.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_generic:flop" +description: "generic flop" +filesets: + files_rtl: + files: + - rtl/prim_generic_flop.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/vendor/lowrisc_ip/prim_generic/prim_generic_flop_2sync.core b/vendor/lowrisc_ip/prim_generic/prim_generic_flop_2sync.core new file mode 100644 index 00000000..d9c3b932 --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/prim_generic_flop_2sync.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_generic:flop_2sync" +description: "Generic synchronizer cell" +filesets: + files_rtl: + files: + - rtl/prim_generic_flop_2sync.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/vendor/lowrisc_ip/prim_generic/prim_generic_ram_2p.core b/vendor/lowrisc_ip/prim_generic/prim_generic_ram_2p.core index 196a9b98..0db36d51 100644 --- a/vendor/lowrisc_ip/prim_generic/prim_generic_ram_2p.core +++ b/vendor/lowrisc_ip/prim_generic/prim_generic_ram_2p.core @@ -8,6 +8,7 @@ description: "prim" filesets: files_rtl: depend: + - lowrisc:prim:assert - lowrisc:prim:util_memload files: - rtl/prim_generic_ram_2p.sv diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_buf.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_buf.sv new file mode 100644 index 00000000..dd5adf0e --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_buf.sv @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "prim_assert.sv" + +module prim_generic_clock_buf ( + input clk_i, + output logic clk_o +); + + assign clk_o = clk_i; + +endmodule // prim_generic_clock_buf diff --git a/vendor/lowrisc_ip/prim/rtl/prim_clock_inverter.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_inv.sv similarity index 70% rename from vendor/lowrisc_ip/prim/rtl/prim_clock_inverter.sv rename to vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_inv.sv index 3113c55f..ddae18ac 100644 --- a/vendor/lowrisc_ip/prim/rtl/prim_clock_inverter.sv +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_inv.sv @@ -5,7 +5,7 @@ // Clock inverter // Varies on the process -module prim_clock_inverter #( +module prim_generic_clock_inv #( parameter bit HasScanMode = 1'b1 ) ( input clk_i, @@ -15,10 +15,10 @@ module prim_clock_inverter #( if (HasScanMode) begin : gen_scan prim_clock_mux2 i_dft_tck_mux ( - .clk0_i ( ~clk_i ), - .clk1_i ( clk_i ), // bypass the inverted clock for testing - .sel_i ( scanmode_i ), - .clk_o ( clk_no ) + .clk0_i ( ~clk_i ), + .clk1_i ( clk_i ), // bypass the inverted clock for testing + .sel_i ( scanmode_i ), + .clk_o ( clk_no ) ); end else begin : gen_noscan logic unused_scanmode; @@ -26,4 +26,4 @@ module prim_clock_inverter #( assign clk_no = ~clk_i; end -endmodule +endmodule : prim_generic_clock_inv diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flash.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flash.sv index 1f0ec3c1..1bfd9a32 100644 --- a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flash.sv +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flash.sv @@ -77,20 +77,20 @@ module prim_generic_flash #( flash_ctrl_pkg::flash_part_e part_q; prim_fifo_sync #( - .Width (AddrW + $bits(flash_ctrl_pkg::flash_part_e)), - .Pass (0), - .Depth (2) + .Width (AddrW + $bits(flash_ctrl_pkg::flash_part_e)), + .Pass (0), + .Depth (2) ) i_slice ( .clk_i, .rst_ni, - .clr_i (1'b0), - .wvalid (rd_i), - .wready (), - .wdata ({part_i, addr_i}), - .depth (), - .rvalid (rd_q), - .rready (hold_cmd), //whenver command is held, pop - .rdata ({part_q, addr_q}) + .clr_i (1'b0), + .wvalid_i(rd_i), + .wready_o(), + .wdata_i ({part_i, addr_i}), + .depth_o (), + .rvalid_o(rd_q), + .rready_i(hold_cmd), //whenver command is held, pop + .rdata_o ({part_q, addr_q}) ); @@ -102,7 +102,7 @@ module prim_generic_flash #( always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin held_addr <= '0; - held_part <= flash_ctrl_pkg::DataPart; + held_part <= flash_ctrl_pkg::FlashPartData; held_wdata <= '0; end else if (hold_cmd) begin held_addr <= rd_q ? addr_q : addr_i; @@ -155,7 +155,7 @@ module prim_generic_flash #( mem_req = 'h0; mem_wr = 'h0; mem_addr = 'h0; - mem_part = flash_ctrl_pkg::DataPart; + mem_part = flash_ctrl_pkg::FlashPartData; mem_wdata = 'h0; time_cnt_inc = 1'h0; time_cnt_clr = 1'h0; @@ -291,7 +291,7 @@ module prim_generic_flash #( .DataBitsPerMask(DataWidth) ) u_mem ( .clk_i, - .req_i (mem_req & (mem_part == flash_ctrl_pkg::DataPart)), + .req_i (mem_req & (mem_part == flash_ctrl_pkg::FlashPartData)), .write_i (mem_wr), .addr_i (mem_addr), .wdata_i (mem_wdata), @@ -305,7 +305,7 @@ module prim_generic_flash #( .DataBitsPerMask(DataWidth) ) u_info_mem ( .clk_i, - .req_i (mem_req & (mem_part == flash_ctrl_pkg::InfoPart)), + .req_i (mem_req & (mem_part == flash_ctrl_pkg::FlashPartInfo)), .write_i (mem_wr), .addr_i (mem_addr[0 +: InfoAddrW]), .wdata_i (mem_wdata), @@ -313,6 +313,6 @@ module prim_generic_flash #( .rdata_o (rd_data_info) ); - assign rd_data_o = held_part == flash_ctrl_pkg::DataPart ? rd_data_main : rd_data_info; + assign rd_data_o = held_part == flash_ctrl_pkg::FlashPartData ? rd_data_main : rd_data_info; endmodule // prim_generic_flash diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop.sv new file mode 100644 index 00000000..0e620e98 --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop.sv @@ -0,0 +1,26 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "prim_assert.sv" + +module prim_generic_flop # ( + parameter int Width = 1, + localparam int WidthSubOne = Width-1, + parameter logic [WidthSubOne:0] ResetValue = 0 +) ( + input clk_i, + input rst_ni, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + q_o <= ResetValue; + end else begin + q_o <= d_i; + end + end + +endmodule // prim_generic_flop diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop_2sync.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop_2sync.sv new file mode 100644 index 00000000..76a072ca --- /dev/null +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop_2sync.sv @@ -0,0 +1,43 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic double-synchronizer flop +// This may need to be moved to prim_generic if libraries have a specific cell +// for synchronization + +module prim_generic_flop_2sync #( + parameter int Width = 16, + localparam int WidthSubOne = Width-1, // temp work around #2679 + parameter logic [WidthSubOne:0] ResetValue = '0 +) ( + input clk_i, // receive clock + input rst_ni, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + logic [Width-1:0] intq; + + prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_sync_1 ( + .clk_i, + .rst_ni, + .d_i, + .q_o(intq) + ); + + prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_sync_2 ( + .clk_i, + .rst_ni, + .d_i(intq), + .q_o + ); + + +endmodule diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_pad_wrapper.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_pad_wrapper.sv index ecf3354c..962d3b55 100644 --- a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_pad_wrapper.sv +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_pad_wrapper.sv @@ -8,46 +8,87 @@ `include "prim_assert.sv" module prim_generic_pad_wrapper #( - parameter int unsigned AttrDw = 6 + parameter int Variant = 0, // currently ignored + parameter int AttrDw = 10, + parameter bit WarlOnly = 0 // If set to 1, no pad is instantiated and only warl_o is driven ) ( inout wire inout_io, // bidirectional pad output logic in_o, // input data + input ie_i, // input enable input out_i, // output data input oe_i, // output enable - // additional attributes {drive strength, keeper, pull-up, pull-down, open-drain, invert} - input [AttrDw-1:0] attr_i + // additional attributes + input [AttrDw-1:0] attr_i, + output logic [AttrDw-1:0] warl_o ); - // get pad attributes - logic kp, pu, pd, od, inv; - typedef enum logic {STRONG_DRIVE = 1'b0, WEAK_DRIVE = 1'b1} drv_e; - drv_e drv; - assign {drv, kp, pu, pd, od, inv} = attr_i[5:0]; + // Supported attributes: + // [x] Bit 0: input/output inversion, + // [x] Bit 1: Virtual open drain enable. + // [x] Bit 2: Pull enable. + // [x] Bit 3: Pull select (0: pull down, 1: pull up). + // [x] Bit 4: Keeper enable. + // [ ] Bit 5: Schmitt trigger enable. + // [ ] Bit 6: Slew rate (0: slow, 1: fast). + // [x] Bit 7/8: Drive strength (00: weakest, 11: strongest). + // [ ] Bit 9: Reserved. + assign warl_o = AttrDw'(10'h19F); - // input inversion - assign in_o = inv ^ inout_io; + if (WarlOnly) begin : gen_warl + assign inout_io = 1'bz; + assign in_o = 1'b0; - // virtual open drain emulation - logic oe, out; - assign out = out_i ^ inv; - assign oe = oe_i & ((od & ~out) | ~od); + logic [AttrDw-1:0] unused_attr; + logic unused_ie, unused_oe, unused_out, unused_inout; + assign unused_ie = ie_i; + assign unused_oe = oe_i; + assign unused_out = out_i; + assign unused_attr = attr_i; + assign unused_inout = inout_io; + end else begin : gen_pad + // get pad attributes + logic unused_sm, kp, unused_sr, ps, pe, od, inv; + typedef enum logic [1:0] {DRIVE_00 = 2'b00, + DRIVE_01 = 2'b01, + DRIVE_10 = 2'b10, + DRIVE_11 = 2'b11} drv_e; + drv_e drv; + assign {drv, unused_sr, unused_sm, kp, ps, pe, od, inv} = attr_i[8:0]; -// driving strength attributes are not supported by verilator + if (AttrDw > 9) begin : gen_unused_attr + logic [AttrDw-9-1:0] unused_attr; + assign unused_attr = attr_i[AttrDw-1:9]; + end + + // input inversion + logic in; + assign in = inv ^ inout_io; + + // virtual open drain emulation + logic oe, out; + assign out = out_i ^ inv; + assign oe = oe_i & ((od & ~out) | ~od); + + // driving strength attributes are not supported by verilator `ifdef VERILATOR - assign inout_io = (oe) ? out : 1'bz; + assign inout_io = (oe) ? out : 1'bz; + // received data driver + assign in_o = (ie_i) ? in : 1'bz; `else - // different driver types - assign (strong0, strong1) inout_io = (oe && drv == STRONG_DRIVE) ? out : 1'bz; - assign (pull0, pull1) inout_io = (oe && drv == WEAK_DRIVE) ? out : 1'bz; - // pullup / pulldown termination - // default to high-Z in case both PU and PD are asserted (safety mechanism). - assign (highz0, weak1) inout_io = pu & ~pd; - assign (weak0, highz1) inout_io = pu | ~pd; - // fake trireg emulation - assign (weak0, weak1) inout_io = (kp) ? inout_io : 1'bz; + // different driver types + assign (strong0, strong1) inout_io = (oe && drv != DRIVE_00) ? out : 1'bz; + assign (pull0, pull1) inout_io = (oe && drv == DRIVE_00) ? out : 1'bz; + // pullup / pulldown termination + assign (highz0, weak1) inout_io = pe & ps; // enabled and select = 1 + assign (weak0, highz1) inout_io = pe & ~ps; // enabled and select = 0 + // fake trireg emulation + assign (weak0, weak1) inout_io = (kp) ? inout_io : 1'bz; + // received data driver + assign in_o = (ie_i) ? in : 1'bz; `endif + end // assertions - `ASSERT_INIT(AttrDwCheck_A, AttrDw >= 7) + `ASSERT_INIT(AttrDwCheck_A, AttrDw >= 9) endmodule : prim_generic_pad_wrapper diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_1p.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_1p.sv index c2b95c16..6c83d3b5 100644 --- a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_1p.sv +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_1p.sv @@ -34,8 +34,8 @@ module prim_generic_ram_1p #( for (genvar k = 0; k < MaskWidth; k++) begin : gen_wmask assign wmask[k] = &wmask_i[k*DataBitsPerMask +: DataBitsPerMask]; - // Ensure that all mask bits within a group have the same value - `ASSERT(MaskCheck_A, req_i |-> + // Ensure that all mask bits within a group have the same value for a write + `ASSERT(MaskCheck_A, req_i && write_i |-> wmask_i[k*DataBitsPerMask +: DataBitsPerMask] inside {{DataBitsPerMask{1'b1}}, '0}, clk_i, '0) end diff --git a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_2p.sv b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_2p.sv index de017d94..bdbd77dd 100644 --- a/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_2p.sv +++ b/vendor/lowrisc_ip/prim_generic/rtl/prim_generic_ram_2p.sv @@ -5,7 +5,7 @@ // Synchronous dual-port SRAM register model // This module is for simulation and small size SRAM. // Implementing ECC should be done inside wrapper not this model. - +`include "prim_assert.sv" module prim_generic_ram_2p #( parameter int Width = 32, // bit parameter int Depth = 128, @@ -44,11 +44,11 @@ module prim_generic_ram_2p #( assign a_wmask[k] = &a_wmask_i[k*DataBitsPerMask +: DataBitsPerMask]; assign b_wmask[k] = &b_wmask_i[k*DataBitsPerMask +: DataBitsPerMask]; - // Ensure that all mask bits within a group have the same value - `ASSERT(MaskCheckPortA_A, a_req_i |-> + // Ensure that all mask bits within a group have the same value for a write + `ASSERT(MaskCheckPortA_A, a_req_i && a_write_i |-> a_wmask_i[k*DataBitsPerMask +: DataBitsPerMask] inside {{DataBitsPerMask{1'b1}}, '0}, clk_a_i, '0) - `ASSERT(MaskCheckPortB_A, b_req_i |-> + `ASSERT(MaskCheckPortB_A, b_req_i && b_write_i |-> b_wmask_i[k*DataBitsPerMask +: DataBitsPerMask] inside {{DataBitsPerMask{1'b1}}, '0}, clk_b_i, '0) end diff --git a/vendor/lowrisc_ip/prim_xilinx/rtl/prim_xilinx_pad_wrapper.sv b/vendor/lowrisc_ip/prim_xilinx/rtl/prim_xilinx_pad_wrapper.sv index 57e9bb49..f9649ddf 100644 --- a/vendor/lowrisc_ip/prim_xilinx/rtl/prim_xilinx_pad_wrapper.sv +++ b/vendor/lowrisc_ip/prim_xilinx/rtl/prim_xilinx_pad_wrapper.sv @@ -7,37 +7,72 @@ module prim_xilinx_pad_wrapper #( - parameter int unsigned AttrDw = 2 + parameter int Variant = 0, // currently ignored + parameter int AttrDw = 10, + parameter bit WarlOnly = 0 // If set to 1, no pad is instantiated and only warl_o is driven ) ( inout wire inout_io, // bidirectional pad output logic in_o, // input data + input ie_i, // input enable input out_i, // output data input oe_i, // output enable // additional attributes - input [AttrDw-1:0] attr_i + input [AttrDw-1:0] attr_i, + output logic [AttrDw-1:0] warl_o ); - // get pad attributes - logic od, inv; - assign {od, inv} = attr_i[1:0]; + // Supported attributes: + // [x] Bit 0: input/output inversion, + // [x] Bit 1: Virtual open drain enable. + // [ ] Bit 2: Pull enable. + // [ ] Bit 3: Pull select (0: pull down, 1: pull up). + // [ ] Bit 4: Keeper enable. + // [ ] Bit 5: Schmitt trigger enable. + // [ ] Bit 6: Slew rate (0: slow, 1: fast). + // [ ] Bit 7/8: Drive strength (00: weakest, 11: strongest). + // [ ] Bit 9: Reserved. + assign warl_o = AttrDw'(2'h3); - // input inversion - logic in; - assign in_o = inv ^ in; + if (WarlOnly) begin : gen_warl + assign inout_io = 1'bz; + assign in_o = 1'b0; - // virtual open drain emulation - logic oe_n, out; - assign out = out_i ^ inv; - // oe_n = 0: enable driver - // oe_n = 1: disable driver - assign oe_n = ~oe_i | (out & od); + logic [AttrDw-1:0] unused_attr; + logic unused_ie, unused_oe, unused_out, unused_inout; + assign unused_ie = ie_i; + assign unused_oe = oe_i; + assign unused_out = out_i; + assign unused_attr = attr_i; + assign unused_inout = inout_io; + end else begin : gen_pad - // driver - IOBUF i_iobuf ( - .T(oe_n), - .I(out), - .O(in), - .IO(inout_io) - ); + // get pad attributes + logic od, inv; + assign {od, inv} = attr_i[1:0]; + + if (AttrDw > 9) begin : gen_unused_attr + logic [AttrDw-9-1:0] unused_attr; + assign unused_attr = attr_i[AttrDw-1:9]; + end + + // input inversion and buffer + logic in; + assign in_o = (ie_i) ? inv ^ in : 1'bz; + + // virtual open drain emulation + logic oe_n, out; + assign out = out_i ^ inv; + // oe_n = 0: enable driver + // oe_n = 1: disable driver + assign oe_n = ~oe_i | (out & od); + + // driver + IOBUF i_iobuf ( + .T ( oe_n ), + .I ( out ), + .O ( in ), + .IO ( inout_io ) + ); + end endmodule : prim_xilinx_pad_wrapper diff --git a/vendor/lowrisc_ip/uvmdvgen/Makefile.tpl b/vendor/lowrisc_ip/uvmdvgen/Makefile.tpl index 01c1380d..10427e5e 100644 --- a/vendor/lowrisc_ip/uvmdvgen/Makefile.tpl +++ b/vendor/lowrisc_ip/uvmdvgen/Makefile.tpl @@ -1,3 +1,6 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 ${'####################################################################################################'} ${'## Copyright lowRISC contributors. ##'} ${'## Licensed under the Apache License, Version 2.0, see LICENSE for details. ##'}