mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 21:17:59 -04:00
Update lowrisc_ip to lowRISC/opentitan@067272a2
Update code from upstream repository https://github.com/lowRISC/opentitan to revision 067272a253f4eeed4ae58a9171ee266256528117 * [dv/common] initial support for shadow register (Cindy Chen) * [rtl/prince] Small fixes for PRINCE cipher logic (Udi Jonnalagadda) * [dv doc] Fix rendered testplan table (Srikrishna Iyer) * [prim/dv] Enable coverage collection for PRESENT (Udi Jonnalagadda) * [dvsim/syn] Minor fix in message reporting (Michael Schaffner) * [prim] Make prim_clock_inverter a tech specific prim (Michael Schaffner) * [vsg] fix _i/_o for several modules (Scott Johnson) * [doc] Update Licence Headers to fit agreed style (Sam Elliott) * [vsg] fix _i/_o usage on sram_arbiter (Scott Johnson) * [vsg] fix _i/_o usage on prim_fifo (Scott Johnson) * switch to host, primary, or over-arching as appropriate (Scott Johnson) * [dvsim/lint/syn] Properly set the errors_seen value to return nonzero status (Michael Schaffner) * [dvsim] Fix open() call with Pathlib for older Python versions (Michael Schaffner) * [style-lint] Last round of minor fixes to get all targets clean (Michael Schaffner) * [prim] Add shadow register primitive (Pirmin Vogel) * [flash_ctrl] Cosmetic updates enum literals (Srikrishna Iyer) * [tool/script] delete clean section in make files (Cindy Chen) * [dvsim] Add git commit and branch info to reports (Michael Schaffner) * [dvsim/syn/lint] Add options to selectively sanitize reports (Michael Schaffner) * [lint] Update waiver file for prim_generic_pad_wrapper (Michael Schaffner) * [prim_pad_wrapper] Update pad wrapper (Michael Schaffner) * [alert_handler/rtl] priority between ping_ok and sig_int_err (Cindy Chen) * [prim] Add a few prim cells needed for clock / resets (Timothy Chen) * [dv] added default timeout message to DV_SPINWAIT (Srikrishna Iyer) * [dv] Add mechanism to configure vseq via knobs (Srikrishna Iyer) * Make the wmask assertion in prim_generic_ram_*p only apply to writes (Rupert Swarbrick) * [prim_gate_gen] Recalibrate gate generator for new std cells (Michael Schaffner) * [primgen] Use SafeDumper for YAML (Philipp Wagner) * [primgen] Fix some flake8-reported style issues (Philipp Wagner) * [prim] Improve extraction of parameter port list (Philipp Wagner) * [prim] Remove outdated comment from primgen (Philipp Wagner) * Added missing include prim_assert.sv (Dawid Zimonczyk) Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
This commit is contained in:
parent
94d5057168
commit
e37c81a1c1
65 changed files with 1497 additions and 659 deletions
2
vendor/lowrisc_ip.lock.hjson
vendored
2
vendor/lowrisc_ip.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/lowRISC/opentitan
|
||||
rev: ebf4663b42a9d81d026db5821b5c8249d54f23a7
|
||||
rev: 067272a253f4eeed4ae58a9171ee266256528117
|
||||
}
|
||||
}
|
||||
|
|
48
vendor/lowrisc_ip/csr_utils/csr_utils_pkg.sv
vendored
48
vendor/lowrisc_ip/csr_utils/csr_utils_pkg.sv
vendored
|
@ -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,
|
||||
|
|
112
vendor/lowrisc_ip/dv_base_reg/dv_base_reg.sv
vendored
112
vendor/lowrisc_ip/dv_base_reg/dv_base_reg.sv
vendored
|
@ -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
|
||||
|
|
23
vendor/lowrisc_ip/dv_lib/dv_base_vseq.sv
vendored
23
vendor/lowrisc_ip/dv_lib/dv_base_vseq.sv
vendored
|
@ -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
|
||||
|
|
2
vendor/lowrisc_ip/dv_utils/dv_macros.svh
vendored
2
vendor/lowrisc_ip/dv_utils/dv_macros.svh
vendored
|
@ -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 \
|
||||
|
|
80
vendor/lowrisc_ip/dvsim/FlowCfg.py
vendored
80
vendor/lowrisc_ip/dvsim/FlowCfg.py
vendored
|
@ -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):
|
||||
|
|
7
vendor/lowrisc_ip/dvsim/FpvCfg.py
vendored
7
vendor/lowrisc_ip/dvsim/FpvCfg.py
vendored
|
@ -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"
|
||||
|
||||
|
|
38
vendor/lowrisc_ip/dvsim/LintCfg.py
vendored
38
vendor/lowrisc_ip/dvsim/LintCfg.py
vendored
|
@ -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"
|
||||
|
|
6
vendor/lowrisc_ip/dvsim/OneShotCfg.py
vendored
6
vendor/lowrisc_ip/dvsim/OneShotCfg.py
vendored
|
@ -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
|
||||
|
|
18
vendor/lowrisc_ip/dvsim/SimCfg.py
vendored
18
vendor/lowrisc_ip/dvsim/SimCfg.py
vendored
|
@ -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",
|
||||
|
|
38
vendor/lowrisc_ip/dvsim/SynCfg.py
vendored
38
vendor/lowrisc_ip/dvsim/SynCfg.py
vendored
|
@ -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)
|
||||
|
|
4
vendor/lowrisc_ip/dvsim/dvsim.py
vendored
4
vendor/lowrisc_ip/dvsim/dvsim.py
vendored
|
@ -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')
|
||||
|
||||
|
|
7
vendor/lowrisc_ip/dvsim/style.css
vendored
7
vendor/lowrisc_ip/dvsim/style.css
vendored
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
4
vendor/lowrisc_ip/lint/data/lint.mk
vendored
4
vendor/lowrisc_ip/lint/data/lint.mk
vendored
|
@ -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 \
|
||||
|
|
2
vendor/lowrisc_ip/lint/doc/README.md
vendored
2
vendor/lowrisc_ip/lint/doc/README.md
vendored
|
@ -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
|
||||
|
|
|
@ -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 .*"),
|
||||
|
|
5
vendor/lowrisc_ip/prim/dv/prim_present/data/cover.cfg
vendored
Normal file
5
vendor/lowrisc_ip/prim/dv/prim_present/data/cover.cfg
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
+module prim_present
|
||||
begin tgl(portsonly)
|
||||
-tree prim_present_tb
|
||||
+module prim_present
|
||||
end
|
|
@ -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: []
|
|
@ -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: [
|
||||
|
|
|
@ -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
|
||||
|
|
170
vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_fpv.sv
vendored
170
vendor/lowrisc_ip/prim/fpv/tb/prim_fifo_sync_fpv.sv
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
6
vendor/lowrisc_ip/prim/prim.core
vendored
6
vendor/lowrisc_ip/prim/prim.core
vendored
|
@ -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
|
||||
|
||||
|
|
25
vendor/lowrisc_ip/prim/prim_clock_buf.core
vendored
Normal file
25
vendor/lowrisc_ip/prim/prim_clock_buf.core
vendored
Normal file
|
@ -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
|
25
vendor/lowrisc_ip/prim/prim_clock_inv.core
vendored
Normal file
25
vendor/lowrisc_ip/prim/prim_clock_inv.core
vendored
Normal file
|
@ -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
|
25
vendor/lowrisc_ip/prim/prim_flop.core
vendored
Normal file
25
vendor/lowrisc_ip/prim/prim_flop.core
vendored
Normal file
|
@ -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
|
25
vendor/lowrisc_ip/prim/prim_flop_2sync.core
vendored
Normal file
25
vendor/lowrisc_ip/prim/prim_flop_2sync.core
vendored
Normal file
|
@ -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
|
68
vendor/lowrisc_ip/prim/rtl/prim_cipher_pkg.sv
vendored
68
vendor/lowrisc_ip/prim/rtl/prim_cipher_pkg.sv
vendored
|
@ -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
|
||||
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
|
|
17
vendor/lowrisc_ip/prim/rtl/prim_esc_sender.sv
vendored
17
vendor/lowrisc_ip/prim/rtl/prim_esc_sender.sv
vendored
|
@ -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)
|
||||
|
|
48
vendor/lowrisc_ip/prim/rtl/prim_fifo_async.sv
vendored
48
vendor/lowrisc_ip/prim/rtl/prim_fifo_async.sv
vendored
|
@ -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.
|
||||
|
|
58
vendor/lowrisc_ip/prim/rtl/prim_fifo_sync.sv
vendored
58
vendor/lowrisc_ip/prim/rtl/prim_fifo_sync.sv
vendored
|
@ -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
|
||||
|
|
4
vendor/lowrisc_ip/prim/rtl/prim_filter.sv
vendored
4
vendor/lowrisc_ip/prim/rtl/prim_filter.sv
vendored
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
28
vendor/lowrisc_ip/prim/rtl/prim_flop_2sync.sv
vendored
28
vendor/lowrisc_ip/prim/rtl/prim_flop_2sync.sv
vendored
|
@ -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
|
58
vendor/lowrisc_ip/prim/rtl/prim_gate_gen.sv
vendored
58
vendor/lowrisc_ip/prim/rtl/prim_gate_gen.sv
vendored
|
@ -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;
|
||||
|
||||
|
|
2
vendor/lowrisc_ip/prim/rtl/prim_intr_hw.sv
vendored
2
vendor/lowrisc_ip/prim/rtl/prim_intr_hw.sv
vendored
|
@ -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.
|
||||
|
|
2
vendor/lowrisc_ip/prim/rtl/prim_keccak.sv
vendored
2
vendor/lowrisc_ip/prim/rtl/prim_keccak.sv
vendored
|
@ -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}
|
||||
|
||||
|
|
2
vendor/lowrisc_ip/prim/rtl/prim_present.sv
vendored
2
vendor/lowrisc_ip/prim/rtl/prim_present.sv
vendored
|
@ -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}
|
||||
|
|
2
vendor/lowrisc_ip/prim/rtl/prim_prince.sv
vendored
2
vendor/lowrisc_ip/prim/rtl/prim_prince.sv
vendored
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
||||
////////////////////////////////////////
|
||||
|
|
76
vendor/lowrisc_ip/prim/rtl/prim_sram_arbiter.sv
vendored
76
vendor/lowrisc_ip/prim/rtl/prim_sram_arbiter.sv
vendored
|
@ -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
|
||||
|
|
62
vendor/lowrisc_ip/prim/rtl/prim_subreg.sv
vendored
62
vendor/lowrisc_ip/prim/rtl/prim_subreg.sv
vendored
|
@ -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
|
||||
|
|
79
vendor/lowrisc_ip/prim/rtl/prim_subreg_arb.sv
vendored
Normal file
79
vendor/lowrisc_ip/prim/rtl/prim_subreg_arb.sv
vendored
Normal file
|
@ -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
|
157
vendor/lowrisc_ip/prim/rtl/prim_subreg_shadow.sv
vendored
Normal file
157
vendor/lowrisc_ip/prim/rtl/prim_subreg_shadow.sv
vendored
Normal file
|
@ -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
|
|
@ -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)
|
||||
|
|
22
vendor/lowrisc_ip/prim/util/primgen.py
vendored
22
vendor/lowrisc_ip/prim/util/primgen.py
vendored
|
@ -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<name>\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, ))
|
||||
|
||||
|
||||
|
|
|
@ -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."
|
||||
|
||||
|
|
40
vendor/lowrisc_ip/prim_generic/prim_generic_clock_buf.core
vendored
Normal file
40
vendor/lowrisc_ip/prim_generic/prim_generic_clock_buf.core
vendored
Normal file
|
@ -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
|
45
vendor/lowrisc_ip/prim_generic/prim_generic_clock_inv.core
vendored
Normal file
45
vendor/lowrisc_ip/prim_generic/prim_generic_clock_inv.core
vendored
Normal file
|
@ -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
|
40
vendor/lowrisc_ip/prim_generic/prim_generic_flop.core
vendored
Normal file
40
vendor/lowrisc_ip/prim_generic/prim_generic_flop.core
vendored
Normal file
|
@ -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
|
40
vendor/lowrisc_ip/prim_generic/prim_generic_flop_2sync.core
vendored
Normal file
40
vendor/lowrisc_ip/prim_generic/prim_generic_flop_2sync.core
vendored
Normal file
|
@ -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
|
|
@ -8,6 +8,7 @@ description: "prim"
|
|||
filesets:
|
||||
files_rtl:
|
||||
depend:
|
||||
- lowrisc:prim:assert
|
||||
- lowrisc:prim:util_memload
|
||||
files:
|
||||
- rtl/prim_generic_ram_2p.sv
|
||||
|
|
14
vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_buf.sv
vendored
Normal file
14
vendor/lowrisc_ip/prim_generic/rtl/prim_generic_clock_buf.sv
vendored
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
26
vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop.sv
vendored
Normal file
26
vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop.sv
vendored
Normal file
|
@ -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
|
43
vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop_2sync.sv
vendored
Normal file
43
vendor/lowrisc_ip/prim_generic/rtl/prim_generic_flop_2sync.sv
vendored
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
3
vendor/lowrisc_ip/uvmdvgen/Makefile.tpl
vendored
3
vendor/lowrisc_ip/uvmdvgen/Makefile.tpl
vendored
|
@ -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. ##'}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue