Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ vcs-elab:
script:
- make vcs-elab

sg-lint:
timeout: 30min
script:
- make sg-lint

.test-tpl:
needs:
variables:
Expand Down
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ BENDER ?= bender
VERILATOR ?= verilator
VSIM ?= vsim
VCS_SEPP ?=
SG_SHELL ?= sg_shell

# Suppress vlog-2583: always_comb/always_latch conflict checks are deferred to vopt
VLOG_FLAGS += -suppress 2583

VSIM_BUILDDIR = $(abspath build/vsim)
VCS_BUILDDIR = $(abspath build/vcs)
SG_BUILDDIR = $(abspath build/spyglass)

# All modules in src/ with a top-level module declaration, minus skipped ones
SV_MODULES = $(patsubst src/%.sv,%,$(shell grep -l "^module " src/*.sv))
VLT_ELAB_TARGETS = $(addprefix vlt-elab-,$(SV_MODULES))
SG_LINT_TARGETS = $(addprefix sg-lint-,$(SV_MODULES))

.PHONY: all vlt-elab $(VLT_ELAB_TARGETS) vsim-elab vcs-elab clean
.PHONY: all vlt-elab $(VLT_ELAB_TARGETS) vsim-elab vcs-elab sg-lint $(SG_LINT_TARGETS) clean

all: vlt-elab vsim-elab vcs-elab
all: vlt-elab vsim-elab vcs-elab sg-lint

# Re-run bender checkout only when Bender.yml changes
.bender/.checkout: Bender.yml
Expand All @@ -31,7 +34,7 @@ $(VLT_ELAB_TARGETS): vlt-elab-%: .bender/.checkout
-Wno-fatal \
-j $(shell nproc)

$(VSIM_BUILDDIR) $(VCS_BUILDDIR):
$(VSIM_BUILDDIR) $(VCS_BUILDDIR) $(SG_BUILDDIR):
mkdir -p $@

$(VSIM_BUILDDIR)/elaborate.tcl: Bender.yml | $(VSIM_BUILDDIR) .bender/.checkout
Expand All @@ -47,5 +50,13 @@ $(VCS_BUILDDIR)/elaborate.sh: Bender.yml | $(VCS_BUILDDIR) .bender/.checkout
vcs-elab: $(VCS_BUILDDIR)/elaborate.sh
cd $(VCS_BUILDDIR) && $(VCS_SEPP) $<

$(SG_BUILDDIR)/analyze.tcl: Bender.yml | $(SG_BUILDDIR) .bender/.checkout
$(BENDER) script flist-plus > $@

sg-lint: $(SG_LINT_TARGETS)

$(SG_LINT_TARGETS): sg-lint-%: $(SG_BUILDDIR)/analyze.tcl
cd $(SG_BUILDDIR) && IP=$* $(SG_SHELL) -enable_pass_exit_codes -tcl $(abspath lint/spyglass.tcl)

clean:
rm -rf build/
1 change: 1 addition & 0 deletions iis-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
export VERILATOR="oseda -2026.04 verilator"
export VSIM="questa-2023.4 vsim"
export VCS_SEPP="vcs-2024.09"
export SG_SHELL="spyglass-2024.09 sg_shell"
15 changes: 15 additions & 0 deletions lint/spyglass.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
new_project $env(IP) -force
current_methodology $env(SPYGLASS_HOME)/GuideWare/latest/block/rtl_handoff

read_file -type sourcelist analyze.tcl

set_option enableSV09 yes
set_option allow_module_override yes
set_option designread_disable_flatten no
set_option nopreserve yes

waive -rules CMD_define02 -msg "*TARGET_FLIST*"

set result [compile_design -top $env(IP)]
set code [lindex $result 0]
exit -force $code
2 changes: 1 addition & 1 deletion src/cc_addr_decode.sv
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module cc_addr_decode #(
/// Highest index which can happen in a rule.
parameter int unsigned NoIndices = 32'd0,
/// Total number of rules.
parameter int unsigned NoRules = 32'd0,
parameter int unsigned NoRules = 32'd1,
/// Address type inside the rules and to decode.
parameter type addr_t = logic,
// Whether this is a NAPOT (base and mask) or regular range decoder
Expand Down
4 changes: 2 additions & 2 deletions src/cc_addr_decode_dync.sv
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module cc_addr_decode_dync #(
/// Highest index which can happen in a rule.
parameter int unsigned NoIndices = 32'd0,
/// Total number of rules.
parameter int unsigned NoRules = 32'd0,
parameter int unsigned NoRules = 32'd1,
/// Address type inside the rules and to decode.
parameter type addr_t = logic,
/// Whether this is a NAPOT (base and mask) or regular range decoder
Expand Down Expand Up @@ -127,6 +127,7 @@ module cc_addr_decode_dync #(

// Assumptions and assertions
`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef SYNTHESIS
initial begin : proc_check_parameters
`ASSUME_I(addr_width_mismatch, $bits(addr_i) == $bits(addr_map_i[0].start_addr),
$sformatf("Input address has %d bits and address map has %d bits.",
Expand All @@ -145,7 +146,6 @@ module cc_addr_decode_dync #(
// check_start: Enforces a smaller start than end address.
// check_idx: Enforces a valid index in the rule.
// check_overlap: Warns if there are overlapping address regions.
`ifndef SYNTHESIS
always_comb begin : proc_check_addr_map
if (!$isunknown(addr_map_i) && ~config_ongoing_i) begin
for (int unsigned i = 0; i < NoRules; i++) begin
Expand Down
2 changes: 1 addition & 1 deletion src/cc_addr_decode_napot.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module cc_addr_decode_napot #(
/// Highest index which can happen in a rule.
parameter int unsigned NoIndices = 32'd0,
/// Total number of rules.
parameter int unsigned NoRules = 32'd0,
parameter int unsigned NoRules = 32'd1,
/// Address type inside the rules and to decode.
parameter type addr_t = logic,
/// Rule packed struct type.
Expand Down
2 changes: 2 additions & 0 deletions src/cc_cb_filter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,13 @@ module cc_hash_block #(
end

`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef SYNTHESIS
// assertions
initial begin
`ASSUME_I(hash_conf, InpWidth > HashWidth,
$sformatf("%m:\nA Hash Function reduces the width of the input>\nInpWidth: %s\nOUT_WIDTH: %s",
InpWidth, HashWidth))
end
`endif
`endif
endmodule
20 changes: 12 additions & 8 deletions src/cc_id_queue.sv
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
`include "common_cells/assertions.svh"

module cc_id_queue #(
parameter int ID_WIDTH = 0,
parameter int CAPACITY = 0,
parameter int ID_WIDTH = 1,
parameter int CAPACITY = 1,
parameter bit FULL_BW = 0,
parameter bit CUT_OUP_POP_INP_GNT = 0,
parameter int NUM_CMP_PORTS = 1,
Expand Down Expand Up @@ -154,12 +154,16 @@ module cc_id_queue #(
.onehot ( idx_matches_in_id ),
.bin ( match_in_idx )
);
cc_onehot_to_bin #(
.ONEHOT_WIDTH ( HtCapacity )
) i_id_ohb_out (
.onehot ( idx_matches_out_id ),
.bin ( match_out_idx )
);
if (FULL_BW) begin : gen_ohb_out
cc_onehot_to_bin #(
.ONEHOT_WIDTH ( HtCapacity )
) i_id_ohb_out (
.onehot ( idx_matches_out_id ),
.bin ( match_out_idx )
);
end else begin : gen_ohb_out_tie
assign match_out_idx = '0;
end

// Find the first free index in the head-tail table.
for (genvar i = 0; i < HtCapacity; i++) begin: gen_head_tail_free
Expand Down
6 changes: 3 additions & 3 deletions src/cc_mem_to_banks.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
/// request and valid response direction.
module cc_mem_to_banks #(
/// Input address width.
parameter int unsigned AddrWidth = 32'd0,
parameter int unsigned AddrWidth = 32'd1,
/// Input data width, must be a power of two.
parameter int unsigned DataWidth = 32'd0,
parameter int unsigned DataWidth = 32'd8,
/// Atop width.
parameter int unsigned AtopWidth = 32'd0,
parameter int unsigned AtopWidth = 32'd1,
/// Number of banks at output, must evenly divide `DataWidth`.
parameter int unsigned NumBanks = 32'd1,
/// Remove transactions that have zero strobe
Expand Down
49 changes: 25 additions & 24 deletions src/cc_mem_to_banks_detailed.sv
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
/// request and valid response direction.
module cc_mem_to_banks_detailed #(
/// Input address width.
parameter int unsigned AddrWidth = 32'd0,
parameter int unsigned AddrWidth = 32'd1,
/// Input data width, must be a power of two.
parameter int unsigned DataWidth = 32'd0,
parameter int unsigned DataWidth = 32'd8,
/// Request sideband width.
parameter int unsigned WUserWidth = 32'd0,
parameter int unsigned WUserWidth = 32'd1,
/// Response sideband width.
parameter int unsigned RUserWidth = 32'd0,
parameter int unsigned RUserWidth = 32'd1,
/// Number of banks at output, must evenly divide `DataWidth`.
parameter int unsigned NumBanks = 32'd1,
/// Remove transactions that have zero strobe
Expand Down Expand Up @@ -217,27 +217,28 @@ module cc_mem_to_banks_detailed #(
assign rvalid_o = &(resp_valid | dead_response);

// Assertions
`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef SYNTHESIS
initial begin
`ASSUME_I(datawidth_not_power_of_2, DataWidth != 0 && 2**$clog2(DataWidth) == DataWidth,
"Data width must be a power of two!")
`ASSUME_I(datawidth_not_divisible_by_banks, DataWidth % NumBanks == 0,
"Data width must be evenly divisible over banks!")
`ASSUME_I(bank_datawidth_not_divisible_by_8, (DataWidth / NumBanks) % 8 == 0,
"Data width of each bank must be divisible into 8-bit bytes!")
// With only one bank, zero-strobe writes should pass through to preserve single-bank memory
// semantics instead of being hidden and completed internally.
`ASSERT_I(num_banks_one_hide_strb, !(NumBanks == 1 && HideStrb),
"HideStrb is incompatible with NumBanks == 1.")
end

if (NumBanks == 1) begin : gen_num_banks_one_warning
initial begin
`ASSUME_I(datawidth_not_power_of_2, DataWidth != 0 && 2**$clog2(DataWidth) == DataWidth,
"Data width must be a power of two!")
`ASSUME_I(datawidth_not_divisible_by_banks, DataWidth % NumBanks == 0,
"Data width must be evenly divisible over banks!")
`ASSUME_I(bank_datawidth_not_divisible_by_8, (DataWidth / NumBanks) % 8 == 0,
"Data width of each bank must be divisible into 8-bit bytes!")
// With only one bank, zero-strobe writes should pass through to preserve single-bank memory
// semantics instead of being hidden and completed internally.
`ASSERT_I(num_banks_one_hide_strb, !(NumBanks == 1 && HideStrb),
"HideStrb is incompatible with NumBanks == 1.")
$warning("cc_mem_to_banks_detailed instantiated with NumBanks == 1. ",
"Consider bypassing this module in the instantiating module.");
end
end
`endif
`endif

`ifndef SYNTHESIS
if (NumBanks == 1) begin : gen_num_banks_one_warning
initial begin
$warning("cc_mem_to_banks_detailed instantiated with NumBanks == 1. ",
"Consider bypassing this module in the instantiating module.");
end
end
`endif
`endif
endmodule
18 changes: 11 additions & 7 deletions src/cc_multiaddr_decode.sv
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
/// doesn't fall in the address set of any rule.
module cc_multiaddr_decode #(
/// Highest index which can happen in a rule.
parameter int unsigned NoIndices = 32'd0,
parameter int unsigned NoIndices = 32'd1,
/// Total number of rules.
parameter int unsigned NoRules = 32'd0,
parameter int unsigned NoRules = 32'd1,
/// Address type inside the rules and to decode.
parameter type addr_t = logic,
/// The rule index type `idx_t` can be specified either with the width `IdxWidth`
Expand Down Expand Up @@ -128,17 +128,21 @@ module cc_multiaddr_decode #(

// Match the rules
for (int unsigned i = 0; i < NoRules; i++) begin
automatic idx_t idx = addr_map_i[i].idx;
automatic idx_t idx;
automatic addr_t dont_care;
automatic addr_t matching_bits;
automatic logic match;
idx = addr_map_i[i].idx;
// We have a match if at least one address of the input
// address set is a part of the rule's address set.
// We have this condition when all bits in the input address match
// all bits in `addr_map_i[i].addr`, with possible exception
// of those bits which are either masked in the input address
// or in the addrmap rule. In other words, any bit which is masked
// either in the input address or in the addrmap rule is treated as a don't care
automatic addr_t dont_care = mask_i | addr_map_i[i].mask;
automatic addr_t matching_bits = ~(addr_i ^ addr_map_i[i].addr);
automatic logic match = &(dont_care | matching_bits);
dont_care = mask_i | addr_map_i[i].mask;
matching_bits = ~(addr_i ^ addr_map_i[i].addr);
match = &(dont_care | matching_bits);
if (match) begin
matched_rules[i] = 1'b1;
dec_valid_o = 1'b1;
Expand Down Expand Up @@ -166,6 +170,7 @@ module cc_multiaddr_decode #(

// Assumptions and assertions
`ifndef COMMON_CELLS_ASSERTS_OFF
`ifndef SYNTHESIS
initial begin : proc_check_parameters
`ASSUME_I(norules_0, NoRules > 0, $sformatf("At least one rule needed"))
`ASSUME_I(addr_width_not_equal, $bits(addr_i) == $bits(addr_map_i[0].addr),
Expand All @@ -177,7 +182,6 @@ module cc_multiaddr_decode #(
// check_default_idx: Enforces a valid default idx.
// check_rule_idx: Enforces a valid index in the rule.
// check_rule_idx_default: Checks that no rule contains the default index.
`ifndef SYNTHESIS
always_comb begin : proc_check_addr_map
if (!$isunknown(addr_map_i)) begin

Expand Down
2 changes: 1 addition & 1 deletion src/cc_onehot.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module cc_onehot #(
logic [LVLS-2:0] carry_array;

// Extend to a power of two.
assign sum[0] = $unsigned(d_i);
assign sum[0] = d_i;

// generate half adders for each lvl
// lvl 0 is the input level
Expand Down
2 changes: 1 addition & 1 deletion src/cc_stream_arbiter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

module cc_stream_arbiter #(
parameter type DATA_T = logic, // Vivado requires a default value for type parameters.
parameter integer N_INP = 0, // Synopsys DC requires a default value for parameters.
parameter integer N_INP = 1, // Synopsys DC requires a default value for parameters.
parameter ARBITER = "rr" // "rr" or "prio"
) (
input logic clk_i,
Expand Down
2 changes: 1 addition & 1 deletion src/cc_stream_arbiter_flushable.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

module cc_stream_arbiter_flushable #(
parameter type DATA_T = logic, // Vivado requires a default value for type parameters.
parameter integer N_INP = 0, // Synopsys DC requires a default value for parameters.
parameter integer N_INP = 1, // Synopsys DC requires a default value for parameters.
parameter ARBITER = "rr" // "rr" or "prio"
) (
input logic clk_i,
Expand Down
2 changes: 1 addition & 1 deletion src/cc_stream_fork.sv
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
`include "common_cells/assertions.svh"

module cc_stream_fork #(
parameter int unsigned N_OUP = 0 // Synopsys DC requires a default value for parameters.
parameter int unsigned N_OUP = 1 // Synopsys DC requires a default value for parameters.
) (
input logic clk_i,
input logic rst_ni,
Expand Down
2 changes: 1 addition & 1 deletion src/cc_stream_fork_dynamic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/// input stream can just be applied at all output streams.
module cc_stream_fork_dynamic #(
/// Number of output streams
parameter int unsigned N_OUP = 32'd0 // Synopsys DC requires a default value for parameters.
parameter int unsigned N_OUP = 32'd1 // Synopsys DC requires a default value for parameters.
) (
/// Clock
input logic clk_i,
Expand Down
2 changes: 1 addition & 1 deletion src/cc_stream_join_dynamic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// there has been a handshake. The data channel flows outside of this module.
module cc_stream_join_dynamic #(
/// Number of input streams
parameter int unsigned N_INP = 32'd0 // Synopsys DC requires a default value for parameters.
parameter int unsigned N_INP = 32'd1 // Synopsys DC requires a default value for parameters.
) (
/// Input streams valid handshakes
input logic [N_INP-1:0] inp_valid_i,
Expand Down
4 changes: 2 additions & 2 deletions src/cc_stream_omega_net.sv
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
/// Handshaking rules as defined by the `AMBA AXI` standard on default.
module cc_stream_omega_net #(
/// Number of inputs into the network (`> 0`).
parameter int unsigned NumInp = 32'd0,
parameter int unsigned NumInp = 32'd1,
/// Number of outputs from the network (`> 0`).
parameter int unsigned NumOut = 32'd0,
parameter int unsigned NumOut = 32'd1,
/// Radix of the individual switch points of the network.
/// Currently supported are `32'd2` and `32'd4`.
parameter int unsigned Radix = 32'd2,
Expand Down
4 changes: 2 additions & 2 deletions src/cc_stream_xbar.sv
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
/// Handshaking rules as defined by the `AMBA AXI` standard on default.
module cc_stream_xbar #(
/// Number of inputs into the crossbar (`> 0`).
parameter int unsigned NumInp = 32'd0,
parameter int unsigned NumInp = 32'd1,
/// Number of outputs from the crossbar (`> 0`).
parameter int unsigned NumOut = 32'd0,
parameter int unsigned NumOut = 32'd1,
/// Data width of the stream. Can be overwritten by defining the type parameter `payload_t`.
parameter int unsigned DataWidth = 32'd1,
/// Payload type of the data ports, only usage of parameter `DataWidth`.
Expand Down
Loading