mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
Vendorize CVA6 core submodules (common_cells, FPU with related sub-modules) (#1007)
This commit is contained in:
parent
b817386ff4
commit
8a5898dce4
188 changed files with 25749 additions and 331 deletions
106
Bender.yml
106
Bender.yml
|
@ -8,7 +8,7 @@ package:
|
|||
# WT_DCACHE
|
||||
|
||||
export_include_dirs:
|
||||
- common/submodules/common_cells/include/
|
||||
- vendor/pulp-platform/common_cells/include/
|
||||
- corev_apu/axi/include/
|
||||
|
||||
sources:
|
||||
|
@ -28,8 +28,8 @@ sources:
|
|||
- corev_apu/tb/ariane_axi_soc_pkg.sv
|
||||
- core/include/ariane_axi_pkg.sv
|
||||
- core/include/std_cache_pkg.sv
|
||||
- core/fpu/src/fpnew_pkg.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
# Stand-alone source files
|
||||
- core/ariane.sv
|
||||
- core/serdiv.sv
|
||||
|
@ -68,24 +68,24 @@ sources:
|
|||
- core/issue_read_operands.sv
|
||||
- core/pmp/src/pmp_entry.sv
|
||||
- core/pmp/src/pmp.sv
|
||||
- core/fpu/src/fpnew_fma.sv
|
||||
- core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
- core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
- core/fpu/src/fpnew_fma_multi.sv
|
||||
- core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
- core/fpu/src/fpnew_classifier.sv
|
||||
- core/fpu/src/fpnew_noncomp.sv
|
||||
- core/fpu/src/fpnew_cast_multi.sv
|
||||
- core/fpu/src/fpnew_opgroup_block.sv
|
||||
- core/fpu/src/fpnew_rounding.sv
|
||||
- core/fpu/src/fpnew_top.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
- core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
- vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
|
||||
- core/frontend/frontend.sv
|
||||
- core/frontend/instr_scan.sv
|
||||
- core/frontend/instr_queue.sv
|
||||
|
@ -143,16 +143,16 @@ sources:
|
|||
- corev_apu/riscv-dbg/debug_rom/debug_rom.sv
|
||||
- corev_apu/register_interface/src/apb_to_reg.sv
|
||||
- corev_apu/axi/src/axi_multicut.sv
|
||||
- common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
- common/submodules/common_cells/src/deprecated/generic_fifo.sv
|
||||
- common/submodules/common_cells/src/deprecated/pulp_sync.sv
|
||||
- common/submodules/common_cells/src/deprecated/find_first_one.sv
|
||||
- common/submodules/common_cells/src/rstgen_bypass.sv
|
||||
- common/submodules/common_cells/src/rstgen.sv
|
||||
- common/submodules/common_cells/src/stream_mux.sv
|
||||
- common/submodules/common_cells/src/stream_demux.sv
|
||||
- common/submodules/common_cells/src/stream_arbiter.sv
|
||||
- common/submodules/common_cells/src/stream_arbiter_flushable.sv
|
||||
- vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
- vendor/pulp-platform/common_cells/src/deprecated/generic_fifo.sv
|
||||
- vendor/pulp-platform/common_cells/src/deprecated/pulp_sync.sv
|
||||
- vendor/pulp-platform/common_cells/src/deprecated/find_first_one.sv
|
||||
- vendor/pulp-platform/common_cells/src/rstgen_bypass.sv
|
||||
- vendor/pulp-platform/common_cells/src/rstgen.sv
|
||||
- vendor/pulp-platform/common_cells/src/stream_mux.sv
|
||||
- vendor/pulp-platform/common_cells/src/stream_demux.sv
|
||||
- vendor/pulp-platform/common_cells/src/stream_arbiter.sv
|
||||
- vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv
|
||||
- corev_apu/axi/src/axi_cut.sv
|
||||
- corev_apu/axi/src/axi_join.sv
|
||||
- corev_apu/axi/src/axi_delayer.sv
|
||||
|
@ -164,28 +164,28 @@ sources:
|
|||
- corev_apu/axi/src/axi_demux.sv
|
||||
- corev_apu/axi/src/axi_xbar.sv
|
||||
- common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
- common/submodules/common_cells/src/sync.sv
|
||||
- common/submodules/common_cells/src/popcount.sv
|
||||
- common/submodules/common_cells/src/unread.sv
|
||||
- common/submodules/common_cells/src/cdc_2phase.sv
|
||||
- common/submodules/common_cells/src/spill_register_flushable.sv
|
||||
- common/submodules/common_cells/src/spill_register.sv
|
||||
- common/submodules/common_cells/src/edge_detect.sv
|
||||
- common/submodules/common_cells/src/fifo_v3.sv
|
||||
- common/submodules/common_cells/src/deprecated/fifo_v2.sv
|
||||
- common/submodules/common_cells/src/deprecated/fifo_v1.sv
|
||||
- common/submodules/common_cells/src/lzc.sv
|
||||
- common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
- common/submodules/common_cells/src/deprecated/rrarbiter.sv
|
||||
- common/submodules/common_cells/src/stream_delay.sv
|
||||
- common/submodules/common_cells/src/lfsr.sv
|
||||
- common/submodules/common_cells/src/lfsr_8bit.sv
|
||||
- common/submodules/common_cells/src/lfsr_16bit.sv
|
||||
- common/submodules/common_cells/src/counter.sv
|
||||
- common/submodules/common_cells/src/shift_reg.sv
|
||||
- common/submodules/common_cells/src/exp_backoff.sv
|
||||
- common/submodules/common_cells/src/addr_decode.sv
|
||||
- common/submodules/common_cells/src/stream_register.sv
|
||||
- vendor/pulp-platform/common_cells/src/sync.sv
|
||||
- vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
- vendor/pulp-platform/common_cells/src/unread.sv
|
||||
- vendor/pulp-platform/common_cells/src/cdc_2phase.sv
|
||||
- vendor/pulp-platform/common_cells/src/spill_register_flushable.sv
|
||||
- vendor/pulp-platform/common_cells/src/spill_register.sv
|
||||
- vendor/pulp-platform/common_cells/src/edge_detect.sv
|
||||
- vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
- vendor/pulp-platform/common_cells/src/deprecated/fifo_v2.sv
|
||||
- vendor/pulp-platform/common_cells/src/deprecated/fifo_v1.sv
|
||||
- vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
- vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
- vendor/pulp-platform/common_cells/src/deprecated/rrarbiter.sv
|
||||
- vendor/pulp-platform/common_cells/src/stream_delay.sv
|
||||
- vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
- vendor/pulp-platform/common_cells/src/lfsr_8bit.sv
|
||||
- vendor/pulp-platform/common_cells/src/lfsr_16bit.sv
|
||||
- vendor/pulp-platform/common_cells/src/counter.sv
|
||||
- vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
- vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
- vendor/pulp-platform/common_cells/src/addr_decode.sv
|
||||
- vendor/pulp-platform/common_cells/src/stream_register.sv
|
||||
- corev_apu/src/tech_cells_generic/src/cluster_clock_inverter.sv
|
||||
- corev_apu/src/tech_cells_generic/src/pulp_clock_mux2.sv
|
||||
- target: not(cv32a6)
|
||||
|
|
76
Flist.ariane
76
Flist.ariane
|
@ -15,7 +15,7 @@
|
|||
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 15.08.2018
|
||||
// Description: File list for OpenPiton flow
|
||||
+incdir+common/submodules/common_cells/include/
|
||||
+incdir+vendor/pulp-platform/common_cells/include/
|
||||
+incdir+common/local/util/
|
||||
+incdir+corev_apu/register_interface/include/
|
||||
|
||||
|
@ -28,27 +28,27 @@ corev_apu/axi/src/axi_pkg.sv
|
|||
core/include/ariane_axi_pkg.sv
|
||||
core/include/wt_cache_pkg.sv
|
||||
core/include/axi_intf.sv
|
||||
core/fpu/src/fpnew_pkg.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
core/include/cvxif_pkg.sv
|
||||
common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
core/include/instr_tracer_pkg.sv
|
||||
core/cvxif_example/include/cvxif_instr_pkg.sv
|
||||
corev_apu/rv_plic/rtl/rv_plic_reg_pkg.sv
|
||||
common/local/util/sram.sv
|
||||
common/submodules/common_cells/src/deprecated/rrarbiter.sv
|
||||
common/submodules/common_cells/src/deprecated/fifo_v1.sv
|
||||
common/submodules/common_cells/src/deprecated/fifo_v2.sv
|
||||
common/submodules/common_cells/src/fifo_v3.sv
|
||||
common/submodules/common_cells/src/shift_reg.sv
|
||||
common/submodules/common_cells/src/lfsr_8bit.sv
|
||||
common/submodules/common_cells/src/lfsr.sv
|
||||
common/submodules/common_cells/src/lzc.sv
|
||||
common/submodules/common_cells/src/exp_backoff.sv
|
||||
common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
common/submodules/common_cells/src/rstgen_bypass.sv
|
||||
common/submodules/common_cells/src/cdc_2phase.sv
|
||||
common/submodules/common_cells/src/unread.sv
|
||||
common/submodules/common_cells/src/popcount.sv
|
||||
vendor/pulp-platform/common_cells/src/deprecated/rrarbiter.sv
|
||||
vendor/pulp-platform/common_cells/src/deprecated/fifo_v1.sv
|
||||
vendor/pulp-platform/common_cells/src/deprecated/fifo_v2.sv
|
||||
vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
vendor/pulp-platform/common_cells/src/lfsr_8bit.sv
|
||||
vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
vendor/pulp-platform/common_cells/src/rstgen_bypass.sv
|
||||
vendor/pulp-platform/common_cells/src/cdc_2phase.sv
|
||||
vendor/pulp-platform/common_cells/src/unread.sv
|
||||
vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
corev_apu/axi_mem_if/src/axi2mem.sv
|
||||
corev_apu/src/tech_cells_generic/src/deprecated/cluster_clk_cells.sv
|
||||
corev_apu/src/tech_cells_generic/src/deprecated/pulp_clk_cells.sv
|
||||
|
@ -132,31 +132,31 @@ corev_apu/fpga/src/axi_slice/src/axi_r_buffer.sv
|
|||
corev_apu/fpga/src/axi_slice/src/axi_aw_buffer.sv
|
||||
corev_apu/register_interface/src/apb_to_reg.sv
|
||||
corev_apu/register_interface/src/reg_intf.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
core/fpu/src/fpnew_cast_multi.sv
|
||||
core/fpu/src/fpnew_classifier.sv
|
||||
core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
core/fpu/src/fpnew_fma_multi.sv
|
||||
core/fpu/src/fpnew_fma.sv
|
||||
core/fpu/src/fpnew_noncomp.sv
|
||||
core/fpu/src/fpnew_opgroup_block.sv
|
||||
core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
core/fpu/src/fpnew_rounding.sv
|
||||
core/fpu/src/fpnew_top.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
core/pmp/src/pmp.sv
|
||||
core/pmp/src/pmp_entry.sv
|
||||
common/local/util/instr_tracer.sv
|
||||
common/local/util/instr_tracer_if.sv
|
||||
core/cvxif_example/cvxif_example_coprocessor.sv
|
||||
core/cvxif_example/instr_decoder.sv
|
||||
common/submodules/common_cells/src/counter.sv
|
||||
common/submodules/common_cells/src/delta_counter.sv
|
||||
vendor/pulp-platform/common_cells/src/counter.sv
|
||||
vendor/pulp-platform/common_cells/src/delta_counter.sv
|
||||
core/cvxif_fu.sv
|
||||
|
|
36
Makefile
36
Makefile
|
@ -169,13 +169,13 @@ src := core/axi_adapter.sv
|
|||
corev_apu/riscv-dbg/debug_rom/debug_rom.sv \
|
||||
corev_apu/register_interface/src/apb_to_reg.sv \
|
||||
corev_apu/axi/src/axi_multicut.sv \
|
||||
common/submodules/common_cells/src/rstgen_bypass.sv \
|
||||
common/submodules/common_cells/src/rstgen.sv \
|
||||
common/submodules/common_cells/src/stream_mux.sv \
|
||||
common/submodules/common_cells/src/stream_demux.sv \
|
||||
common/submodules/common_cells/src/exp_backoff.sv \
|
||||
common/submodules/common_cells/src/addr_decode.sv \
|
||||
common/submodules/common_cells/src/stream_register.sv \
|
||||
vendor/pulp-platform/common_cells/src/rstgen_bypass.sv \
|
||||
vendor/pulp-platform/common_cells/src/rstgen.sv \
|
||||
vendor/pulp-platform/common_cells/src/stream_mux.sv \
|
||||
vendor/pulp-platform/common_cells/src/stream_demux.sv \
|
||||
vendor/pulp-platform/common_cells/src/exp_backoff.sv \
|
||||
vendor/pulp-platform/common_cells/src/addr_decode.sv \
|
||||
vendor/pulp-platform/common_cells/src/stream_register.sv \
|
||||
corev_apu/axi/src/axi_cut.sv \
|
||||
corev_apu/axi/src/axi_join.sv \
|
||||
corev_apu/axi/src/axi_delayer.sv \
|
||||
|
@ -186,15 +186,15 @@ src := core/axi_adapter.sv
|
|||
corev_apu/axi/src/axi_mux.sv \
|
||||
corev_apu/axi/src/axi_demux.sv \
|
||||
corev_apu/axi/src/axi_xbar.sv \
|
||||
common/submodules/common_cells/src/cdc_2phase.sv \
|
||||
common/submodules/common_cells/src/spill_register_flushable.sv \
|
||||
common/submodules/common_cells/src/spill_register.sv \
|
||||
common/submodules/common_cells/src/stream_arbiter.sv \
|
||||
common/submodules/common_cells/src/stream_arbiter_flushable.sv \
|
||||
common/submodules/common_cells/src/deprecated/fifo_v1.sv \
|
||||
common/submodules/common_cells/src/deprecated/fifo_v2.sv \
|
||||
common/submodules/common_cells/src/stream_delay.sv \
|
||||
common/submodules/common_cells/src/lfsr_16bit.sv \
|
||||
vendor/pulp-platform/common_cells/src/cdc_2phase.sv \
|
||||
vendor/pulp-platform/common_cells/src/spill_register_flushable.sv \
|
||||
vendor/pulp-platform/common_cells/src/spill_register.sv \
|
||||
vendor/pulp-platform/common_cells/src/stream_arbiter.sv \
|
||||
vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv \
|
||||
vendor/pulp-platform/common_cells/src/deprecated/fifo_v1.sv \
|
||||
vendor/pulp-platform/common_cells/src/deprecated/fifo_v2.sv \
|
||||
vendor/pulp-platform/common_cells/src/stream_delay.sv \
|
||||
vendor/pulp-platform/common_cells/src/lfsr_16bit.sv \
|
||||
corev_apu/src/tech_cells_generic/src/deprecated/cluster_clk_cells.sv \
|
||||
corev_apu/src/tech_cells_generic/src/deprecated/pulp_clk_cells.sv \
|
||||
corev_apu/src/tech_cells_generic/src/rtl/tc_clk.sv \
|
||||
|
@ -244,7 +244,7 @@ riscv-fp-tests := $(shell xargs printf '\n%s' < $(riscv-fp-tests-list
|
|||
riscv-benchmarks := $(shell xargs printf '\n%s' < $(riscv-benchmarks-list) | cut -b 1-)
|
||||
|
||||
# Search here for include files (e.g.: non-standalone components)
|
||||
incdir := common/submodules/common_cells/include/ corev_apu/axi/include/ corev_apu/register_interface/include/
|
||||
incdir := vendor/pulp-platform/common_cells/include/ corev_apu/axi/include/ corev_apu/register_interface/include/
|
||||
|
||||
# Compile and sim flags
|
||||
compile_flag += +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive +define+$(defines)
|
||||
|
@ -293,7 +293,7 @@ vcs_build: $(dpi-library)/ariane_dpi.so
|
|||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) -f ../core/Flist.$(target) &&\
|
||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) $(filter %.sv,$(ariane_pkg)) +incdir+core/include/+$(VCS_HOME)/etc/uvm-1.2/dpi &&\
|
||||
vhdlan $(if $(VERDI), -kdb,) -full64 -nc $(filter %.vhd,$(uart_src)) &&\
|
||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -assert svaext +define+$(defines) $(filter %.sv,$(src)) +incdir+../common/submodules/common_cells/include/+../corev_apu/axi/include/+../corev_apu/register_interface/include/ &&\
|
||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -assert svaext +define+$(defines) $(filter %.sv,$(src)) +incdir+../vendor/pulp-platform/common_cells/include/+../corev_apu/axi/include/+../corev_apu/register_interface/include/ &&\
|
||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 &&\
|
||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 $(tbs) +define+$(defines) +incdir+../corev_apu/axi/include/ &&\
|
||||
vcs $(if $(VERDI), -kdb -debug_access+all -lca,) -full64 -timescale=1ns/1ns -ntb_opts uvm-1.2 work.ariane_tb
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
+define+WT_DCACHE
|
||||
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/common/local/util/
|
||||
|
||||
${CVA6_REPO_DIR}/core/include/cv32a60x_config_pkg.sv
|
||||
|
@ -58,40 +58,40 @@ ${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv
|
|||
${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv
|
||||
|
||||
// Common Cells
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
|
||||
// Common Cells for example coprocessor
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/counter.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/delta_counter.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/counter.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/delta_counter.sv
|
||||
|
||||
// Floating point unit
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// Top-level source files (not necessarily instantiated at the top of the cva6).
|
||||
${CVA6_REPO_DIR}/core/ariane.sv
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
+define+WT_DCACHE
|
||||
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/common/local/util/
|
||||
|
||||
${CVA6_REPO_DIR}/core/include/cv32a6_imac_sv0_config_pkg.sv
|
||||
|
@ -55,36 +55,36 @@ ${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
|
|||
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
||||
|
||||
// Common Cells
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
|
||||
// Floating point unit
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// Top-level source files (not necessarily instantiated at the top of the cva6).
|
||||
${CVA6_REPO_DIR}/core/ariane.sv
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
+define+WT_DCACHE
|
||||
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/common/local/util/
|
||||
|
||||
${CVA6_REPO_DIR}/core/include/cv32a6_imac_sv0_config_pkg.sv
|
||||
|
@ -55,36 +55,36 @@ ${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
|
|||
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
||||
|
||||
// Common Cells
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
|
||||
// Floating point unit
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// Top-level source files (not necessarily instantiated at the top of the cva6).
|
||||
${CVA6_REPO_DIR}/core/ariane.sv
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
+define+WT_DCACHE
|
||||
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/common/local/util/
|
||||
|
||||
${CVA6_REPO_DIR}/core/include/cv32a6_imac_sv0_config_pkg.sv
|
||||
|
@ -55,36 +55,36 @@ ${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
|
|||
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
||||
|
||||
// Common Cells
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
|
||||
// Floating point unit
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// Top-level source files (not necessarily instantiated at the top of the cva6).
|
||||
${CVA6_REPO_DIR}/core/ariane.sv
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
+define+WT_DCACHE
|
||||
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/common/local/util/
|
||||
|
||||
${CVA6_REPO_DIR}/core/include/cv32a6_imac_sv0_config_pkg.sv
|
||||
|
@ -55,36 +55,36 @@ ${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
|
|||
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
||||
|
||||
// Common Cells
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
|
||||
// Floating point unit
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// Top-level source files (not necessarily instantiated at the top of the cva6).
|
||||
${CVA6_REPO_DIR}/core/ariane.sv
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
+define+WT_DCACHE
|
||||
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/
|
||||
+incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/
|
||||
+incdir+${CVA6_REPO_DIR}/common/local/util/
|
||||
|
||||
${CVA6_REPO_DIR}/core/include/cv64a6_imafdc_sv39_config_pkg.sv
|
||||
|
@ -58,40 +58,40 @@ ${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv
|
|||
${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv
|
||||
|
||||
// Common Cells
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
|
||||
// Common Cells for example coprocessor
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/counter.sv
|
||||
${CVA6_REPO_DIR}/common/submodules/common_cells/src/delta_counter.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/counter.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/delta_counter.sv
|
||||
|
||||
// Floating point unit
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_cast_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_classifier.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_divsqrt_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma_multi.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_fma.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_noncomp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_block.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_fmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_rounding.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpnew_top.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${CVA6_REPO_DIR}/vendor/pulp-platform/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// Top-level source files (not necessarily instantiated at the top of the cva6).
|
||||
${CVA6_REPO_DIR}/core/ariane.sv
|
||||
|
|
|
@ -38,24 +38,24 @@ read_ip { \
|
|||
}
|
||||
# read_ip xilinx/xlnx_protocol_checker/ip/xlnx_protocol_checker.xci
|
||||
|
||||
set_property include_dirs { "src/axi_sd_bridge/include" "../../common/submodules/common_cells/include" "../axi/include" "../register_interface/include"} [current_fileset]
|
||||
set_property include_dirs { "src/axi_sd_bridge/include" "../../vendor/pulp-platform/common_cells/include" "../axi/include" "../register_interface/include"} [current_fileset]
|
||||
|
||||
source scripts/add_sources.tcl
|
||||
|
||||
set_property top ${project}_xilinx [current_fileset]
|
||||
|
||||
if {$::env(BOARD) eq "genesys2"} {
|
||||
read_verilog -sv {src/genesysii.svh ../../common/submodules/common_cells/include/common_cells/registers.svh}
|
||||
read_verilog -sv {src/genesysii.svh ../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh}
|
||||
set file "src/genesysii.svh"
|
||||
set registers "../../common/submodules/common_cells/include/common_cells/registers.svh"
|
||||
set registers "../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh"
|
||||
} elseif {$::env(BOARD) eq "kc705"} {
|
||||
read_verilog -sv {src/kc705.svh ../../common/submodules/common_cells/include/common_cells/registers.svh}
|
||||
read_verilog -sv {src/kc705.svh ../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh}
|
||||
set file "src/kc705.svh"
|
||||
set registers "../../common/submodules/common_cells/include/common_cells/registers.svh"
|
||||
set registers "../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh"
|
||||
} elseif {$::env(BOARD) eq "vc707"} {
|
||||
read_verilog -sv {src/vc707.svh ../../common/submodules/common_cells/include/common_cells/registers.svh}
|
||||
read_verilog -sv {src/vc707.svh ../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh}
|
||||
set file "src/vc707.svh"
|
||||
set registers "../../common/submodules/common_cells/include/common_cells/registers.svh"
|
||||
set registers "../../vendor/pulp-platform/common_cells/include/common_cells/registers.svh"
|
||||
} else {
|
||||
exit 1
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
../../riscv-dbg/src/dm_pkg.sv
|
||||
../../../core/include/ariane_pkg.sv
|
||||
../../../core/include/wt_cache_pkg.sv
|
||||
../../../common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
../../../common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/cva6_icache.sv
|
||||
../../../common/submodules/common_cells/src/lfsr.sv
|
||||
../../../common/submodules/common_cells/src/fifo_v3.sv
|
||||
../../../common/submodules/common_cells/src/lzc.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
../../../common/local/util/sram.sv
|
||||
hdl/mem_emul.sv
|
||||
hdl/tlb_emul.sv
|
||||
|
|
|
@ -23,16 +23,16 @@
|
|||
../../../core/cache_subsystem/std_nbdcache.sv
|
||||
../../../core/cache_subsystem/amo_alu.sv
|
||||
../../../core/cache_subsystem/tag_cmp.sv
|
||||
../../../common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
../../../common/submodules/common_cells/src/lfsr_8bit.sv
|
||||
../../../common/submodules/common_cells/src/fifo_v3.sv
|
||||
../../../common/submodules/common_cells/src/lzc.sv
|
||||
../../../common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
../../../common/submodules/common_cells/src/exp_backoff.sv
|
||||
../../../common/submodules/common_cells/src/stream_arbiter.sv
|
||||
../../../common/submodules/common_cells/src/stream_arbiter_flushable.sv
|
||||
../../../common/submodules/common_cells/src/stream_mux.sv
|
||||
../../../common/submodules/common_cells/src/stream_demux.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lfsr_8bit.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_arbiter.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_mux.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_demux.sv
|
||||
../../../core/axi_adapter.sv
|
||||
../../../common/local/util/sram.sv
|
||||
../../src/axi_riscv_atomics/src/axi_res_tbl.sv
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
../../axi/src/axi_pkg.sv
|
||||
../../axi/src/axi_intf.sv
|
||||
../../axi/src/axi_test.sv
|
||||
../../../core/fpu/src/fpnew_pkg.sv
|
||||
../../../vendor/pulp-platform/fpnew/src/fpnew_pkg.sv
|
||||
../../../core/include/ariane_pkg.sv
|
||||
../ariane_soc_pkg.sv
|
||||
../ariane_axi_soc_pkg.sv
|
||||
|
@ -28,15 +28,15 @@
|
|||
../../../core/axi_shim.sv
|
||||
../../../core/cache_subsystem/wt_axi_adapter.sv
|
||||
../../../core/cache_subsystem/wt_cache_subsystem.sv
|
||||
../../../common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
../../../common/submodules/common_cells/src/lfsr.sv
|
||||
../../../common/submodules/common_cells/src/fifo_v3.sv
|
||||
../../../common/submodules/common_cells/src/lzc.sv
|
||||
../../../common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
../../../common/submodules/common_cells/src/exp_backoff.sv
|
||||
../../../common/submodules/common_cells/src/stream_arbiter.sv
|
||||
../../../common/submodules/common_cells/src/stream_arbiter_flushable.sv
|
||||
../../../common/submodules/common_cells/src/stream_mux.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_arbiter.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/stream_mux.sv
|
||||
../../src/tech_cells_generic/src/rtl/tc_sram.sv
|
||||
../../../common/local/util/tc_sram_wrapper.sv
|
||||
../../../common/local/util/sram.sv
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
../../../core/cache_subsystem/wt_dcache_missunit.sv
|
||||
../../../core/cache_subsystem/wt_dcache_wbuffer.sv
|
||||
../../../core/cache_subsystem/wt_dcache.sv
|
||||
../../../common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
../../../common/submodules/common_cells/src/lfsr.sv
|
||||
../../../common/submodules/common_cells/src/fifo_v3.sv
|
||||
../../../common/submodules/common_cells/src/lzc.sv
|
||||
../../../common/submodules/common_cells/src/rr_arb_tree.sv
|
||||
../../../common/submodules/common_cells/src/exp_backoff.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lfsr.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/fifo_v3.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/lzc.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
|
||||
../../../vendor/pulp-platform/common_cells/src/exp_backoff.sv
|
||||
../../src/tech_cells_generic/src/rtl/tc_sram.sv
|
||||
../../../common/local/util/tc_sram_wrapper.sv
|
||||
../../../common/local/util/sram.sv
|
||||
|
|
|
@ -17,7 +17,7 @@ set clk_period $PERIOD
|
|||
set input_delay $INPUT_DELAY
|
||||
set output_delay $OUTPUT_DELAY
|
||||
|
||||
set_app_var search_path "../../core/fpu/src/common_cells/include/ $search_path"
|
||||
set_app_var search_path "../../vendor/pulp-platform/fpnew/src/common_cells/include/ $search_path"
|
||||
|
||||
sh rm -rf work
|
||||
sh mkdir work
|
||||
|
|
5
util/README.md
Normal file
5
util/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
Content:
|
||||
|
||||
* vendor.py
|
||||
- vendorization script
|
||||
- copied from https://github.com/openhwgroup/cv32e40p/blob/master/util/vendor.py, commit 69e839e
|
782
util/vendor.py
Normal file
782
util/vendor.py
Normal file
|
@ -0,0 +1,782 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'''A tool to copy source code from upstream into this repository.
|
||||
|
||||
For an introduction to using this tool, see doc/ug/vendor_hw.md in this
|
||||
repository (on the internet at https://docs.opentitan.org/doc/ug/vendor_hw/).
|
||||
|
||||
For full documentation, see doc/rm/vendor_in_tool.md (on the internet at
|
||||
https://docs.opentitan.org/doc/rm/vendor_in_tool).
|
||||
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import fnmatch
|
||||
import logging as log
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
import hjson
|
||||
|
||||
EXCLUDE_ALWAYS = ['.git']
|
||||
|
||||
LOCK_FILE_HEADER = """// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// This file is generated by the util/vendor script. Please do not modify it
|
||||
// manually.
|
||||
|
||||
"""
|
||||
|
||||
# Keys in the description (configuration) file which can be overridden through
|
||||
# the command line.
|
||||
OVERRIDABLE_DESC_KEYS = [
|
||||
'patch_repo.url',
|
||||
'patch_repo.rev_base',
|
||||
'patch_repo.rev_patched',
|
||||
'upstream.url',
|
||||
'upstream.ref',
|
||||
]
|
||||
|
||||
verbose = False
|
||||
|
||||
|
||||
def git_is_clean_workdir(git_workdir):
|
||||
"""Check if the git working directory is clean (no unstaged or staged changes)"""
|
||||
cmd = ['git', 'status', '--untracked-files=no', '--porcelain']
|
||||
modified_files = subprocess.run(cmd,
|
||||
cwd=str(git_workdir),
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE).stdout.strip()
|
||||
return not modified_files
|
||||
|
||||
|
||||
def github_qualify_references(log, repo_userorg, repo_name):
|
||||
""" Replace "unqualified" GitHub references with "fully qualified" one
|
||||
|
||||
GitHub automatically links issues and pull requests if they have a specific
|
||||
format. Links can be qualified with the user/org name and the repository
|
||||
name, or unqualified, if they only contain the issue or pull request number.
|
||||
|
||||
This function converts all unqualified references to qualified ones.
|
||||
|
||||
See https://help.github.com/en/articles/autolinked-references-and-urls#issues-and-pull-requests
|
||||
for a documentation of all supported formats.
|
||||
"""
|
||||
|
||||
r = re.compile(r"(^|[^\w])(?:#|[gG][hH]-)(\d+)\b")
|
||||
repl_str = r'\1%s/%s#\2' % (repo_userorg, repo_name)
|
||||
return [r.sub(repl_str, l) for l in log]
|
||||
|
||||
|
||||
def test_github_qualify_references():
|
||||
repo_userorg = 'lowRISC'
|
||||
repo_name = 'ibex'
|
||||
|
||||
# Unqualified references, should be replaced
|
||||
items_unqualified = [
|
||||
'#28',
|
||||
'GH-27',
|
||||
'klaus #27',
|
||||
'Fixes #27',
|
||||
'Fixes #27 and #28',
|
||||
'(#27)',
|
||||
'something (#27) done',
|
||||
'#27 and (GH-38)',
|
||||
]
|
||||
exp_items_unqualified = [
|
||||
'lowRISC/ibex#28',
|
||||
'lowRISC/ibex#27',
|
||||
'klaus lowRISC/ibex#27',
|
||||
'Fixes lowRISC/ibex#27',
|
||||
'Fixes lowRISC/ibex#27 and lowRISC/ibex#28',
|
||||
'(lowRISC/ibex#27)',
|
||||
'something (lowRISC/ibex#27) done',
|
||||
'lowRISC/ibex#27 and (lowRISC/ibex#38)',
|
||||
]
|
||||
assert github_qualify_references(items_unqualified, repo_userorg,
|
||||
repo_name) == exp_items_unqualified
|
||||
|
||||
# Qualified references, should stay as they are
|
||||
items_qualified = [
|
||||
'Fixes lowrisc/ibex#27',
|
||||
'lowrisc/ibex#2',
|
||||
]
|
||||
assert github_qualify_references(items_qualified, repo_userorg,
|
||||
repo_name) == items_qualified
|
||||
|
||||
# Invalid references, should stay as they are
|
||||
items_invalid = [
|
||||
'something#27',
|
||||
'lowrisc/ibex#',
|
||||
]
|
||||
assert github_qualify_references(items_invalid, repo_userorg,
|
||||
repo_name) == items_invalid
|
||||
|
||||
|
||||
def test_github_parse_url():
|
||||
assert github_parse_url('https://example.com/something/asdf.git') is None
|
||||
assert github_parse_url('https://github.com/lowRISC/ibex.git') == (
|
||||
'lowRISC', 'ibex')
|
||||
assert github_parse_url('https://github.com/lowRISC/ibex') == ('lowRISC',
|
||||
'ibex')
|
||||
assert github_parse_url('git@github.com:lowRISC/ibex.git') == ('lowRISC',
|
||||
'ibex')
|
||||
|
||||
|
||||
def github_parse_url(github_repo_url):
|
||||
"""Parse a GitHub repository URL into its parts.
|
||||
|
||||
Return a tuple (userorg, name), or None if the parsing failed.
|
||||
"""
|
||||
|
||||
regex = r"(?:@github\.com\:|\/github\.com\/)([a-zA-Z\d-]+)\/([a-zA-Z\d-]+)(?:\.git)?$"
|
||||
m = re.search(regex, github_repo_url)
|
||||
if m is None:
|
||||
return None
|
||||
return (m.group(1), m.group(2))
|
||||
|
||||
|
||||
def produce_shortlog(clone_dir, mapping, old_rev, new_rev):
|
||||
""" Produce a list of changes between two revisions, one revision per line
|
||||
|
||||
Merges are excluded"""
|
||||
|
||||
# If mapping is None, we want to list all changes below clone_dir.
|
||||
# Otherwise, we want to list changes in each 'source' in the mapping. Since
|
||||
# these strings are paths relative to clone_dir, we can just pass them all
|
||||
# to git and let it figure out what to do.
|
||||
subdirs = (['.'] if mapping is None
|
||||
else [m.from_path for m in mapping.items])
|
||||
|
||||
cmd = (['git', '-C', str(clone_dir), 'log',
|
||||
'--pretty=format:%s (%aN)', '--no-merges',
|
||||
old_rev + '..' + new_rev] +
|
||||
subdirs)
|
||||
try:
|
||||
proc = subprocess.run(cmd,
|
||||
cwd=str(clone_dir),
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
return proc.stdout.splitlines()
|
||||
except subprocess.CalledProcessError as e:
|
||||
log.error("Unable to capture shortlog: %s", e.stderr)
|
||||
return ""
|
||||
|
||||
|
||||
def format_list_to_str(list, width=70):
|
||||
""" Create Markdown-style formatted string from a list of strings """
|
||||
wrapper = textwrap.TextWrapper(initial_indent="* ",
|
||||
subsequent_indent=" ",
|
||||
width=width)
|
||||
return '\n'.join([wrapper.fill(s) for s in list])
|
||||
|
||||
|
||||
class JsonError(Exception):
|
||||
'''An error class for when data in the source HJSON is bad'''
|
||||
def __init__(self, path, msg):
|
||||
self.path = path
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return 'In hjson at {}, {}'.format(self.path, self.msg)
|
||||
|
||||
|
||||
def get_field(path, where, data, name, expected_type=dict, optional=False, constructor=None):
|
||||
value = data.get(name)
|
||||
if value is None:
|
||||
if not optional:
|
||||
raise JsonError(path, '{}, missing {!r} field.'.format(where, name))
|
||||
return None
|
||||
|
||||
if not isinstance(value, expected_type):
|
||||
raise JsonError(path,
|
||||
'{}, the {!r} field is {!r}, but should be of type {!r}.'
|
||||
.format(where, name, value, expected_type.__name__))
|
||||
|
||||
return value if constructor is None else constructor(value)
|
||||
|
||||
|
||||
class Upstream:
|
||||
'''A class representing the 'upstream' field in a config or lock file'''
|
||||
def __init__(self, path, data):
|
||||
# Fields: 'url', 'rev', 'only_subdir' (optional). All should be strings.
|
||||
where = 'in upstream dict'
|
||||
self.url = get_field(path, where, data, 'url', str)
|
||||
self.rev = get_field(path, where, data, 'rev', str)
|
||||
self.only_subdir = get_field(path, where, data,
|
||||
'only_subdir', str, optional=True)
|
||||
|
||||
def as_dict(self):
|
||||
data = {'url': self.url, 'rev': self.rev}
|
||||
if self.only_subdir is not None:
|
||||
data['only_subdir'] = self.only_subdir
|
||||
return data
|
||||
|
||||
|
||||
class PatchRepo:
|
||||
'''A class representing the 'patch_repo' field in a config file'''
|
||||
def __init__(self, path, data):
|
||||
# Fields: 'url', 'rev_base', 'rev_patched'. All should be strings.
|
||||
where = 'in patch_repo dict'
|
||||
self.url = get_field(path, where, data, 'url', str)
|
||||
self.rev_base = get_field(path, where, data, 'rev_base', str)
|
||||
self.rev_patched = get_field(path, where, data, 'rev_patched', str)
|
||||
|
||||
|
||||
class Mapping1:
|
||||
'''A class to represent a single item in the 'mapping' field in a config file'''
|
||||
def __init__(self, from_path, to_path, patch_dir):
|
||||
self.from_path = from_path
|
||||
self.to_path = to_path
|
||||
self.patch_dir = patch_dir
|
||||
|
||||
@staticmethod
|
||||
def make(path, idx, data):
|
||||
assert isinstance(data, dict)
|
||||
|
||||
def get_path(name, optional=False):
|
||||
val = get_field(path, 'in mapping entry {}'.format(idx + 1),
|
||||
data, name, expected_type=str, optional=optional)
|
||||
if val is None:
|
||||
return None
|
||||
|
||||
# Check that the paths aren't evil ('../../../foo' or '/etc/passwd'
|
||||
# are *not* ok!)
|
||||
val = os.path.normpath(val)
|
||||
if val.startswith('/') or val.startswith('..'):
|
||||
raise JsonError(path,
|
||||
'Mapping entry {} has a bad path for {!r} '
|
||||
'(must be a relative path that doesn\'t '
|
||||
'escape the directory)'
|
||||
.format(idx + 1, name))
|
||||
|
||||
return Path(val)
|
||||
|
||||
from_path = get_path('from')
|
||||
to_path = get_path('to')
|
||||
patch_dir = get_path('patch_dir', optional=True)
|
||||
|
||||
return Mapping1(from_path, to_path, patch_dir)
|
||||
|
||||
@staticmethod
|
||||
def make_default(have_patch_dir):
|
||||
'''Make a default mapping1, which copies everything straight through'''
|
||||
return Mapping1(Path('.'), Path('.'),
|
||||
Path('.') if have_patch_dir else None)
|
||||
|
||||
@staticmethod
|
||||
def apply_patch(basedir, patchfile):
|
||||
cmd = ['git', 'apply', '--directory', str(basedir), '-p1',
|
||||
str(patchfile)]
|
||||
if verbose:
|
||||
cmd += ['--verbose']
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
def import_from_upstream(self, upstream_path,
|
||||
target_path, exclude_files, patch_dir):
|
||||
'''Copy from the upstream checkout to target_path'''
|
||||
from_path = upstream_path / self.from_path
|
||||
to_path = target_path / self.to_path
|
||||
|
||||
# Make sure the target directory actually exists
|
||||
to_path.parent.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
# Copy src to dst recursively. For directories, we can use
|
||||
# shutil.copytree. This doesn't support files, though, so we have to
|
||||
# check for them first.
|
||||
if from_path.is_file():
|
||||
shutil.copy(str(from_path), str(to_path))
|
||||
else:
|
||||
ignore = ignore_patterns(str(upstream_path), *exclude_files)
|
||||
shutil.copytree(str(from_path), str(to_path), ignore=ignore)
|
||||
|
||||
# Apply any patches to the copied files. If self.patch_dir is None,
|
||||
# there are none to apply. Otherwise, resolve it relative to patch_dir.
|
||||
if self.patch_dir is not None:
|
||||
patches = (patch_dir / self.patch_dir).glob('*.patch')
|
||||
for patch in sorted(patches):
|
||||
log.info("Applying patch {} at {}".format(patch, to_path))
|
||||
Mapping1.apply_patch(to_path, patch)
|
||||
|
||||
|
||||
class Mapping:
|
||||
'''A class representing the 'mapping' field in a config file
|
||||
|
||||
This should be a list of dicts.
|
||||
'''
|
||||
def __init__(self, items):
|
||||
self.items = items
|
||||
|
||||
@staticmethod
|
||||
def make(path, data):
|
||||
items = []
|
||||
assert isinstance(data, list)
|
||||
for idx, elt in enumerate(data):
|
||||
if not isinstance(elt, dict):
|
||||
raise JsonError(path, 'Mapping element {!r} is not a dict.'.format(elt))
|
||||
items.append(Mapping1.make(path, idx, elt))
|
||||
|
||||
return Mapping(items)
|
||||
|
||||
def has_patch_dir(self):
|
||||
'''Check whether at least one item defines a patch dir'''
|
||||
for item in self.items:
|
||||
if item.patch_dir is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class LockDesc:
|
||||
'''A class representing the contents of a lock file'''
|
||||
def __init__(self, handle):
|
||||
data = hjson.loads(handle.read(), use_decimal=True)
|
||||
self.upstream = get_field(handle.name, 'at top-level', data, 'upstream',
|
||||
constructor=lambda data: Upstream(handle.name, data))
|
||||
|
||||
|
||||
class Desc:
|
||||
'''A class representing the configuration file'''
|
||||
|
||||
def __init__(self, handle, desc_overrides):
|
||||
|
||||
# Ensure description file matches our naming rules (otherwise we don't
|
||||
# know the name for the lockfile). This regex checks that we have the
|
||||
# right suffix and a nonempty name.
|
||||
if not re.match(r'.+\.vendor\.hjson', handle.name):
|
||||
raise ValueError("Description file names must have a .vendor.hjson suffix.")
|
||||
|
||||
data = hjson.loads(handle.read(), use_decimal=True)
|
||||
where = 'at top-level'
|
||||
|
||||
self.apply_overrides(data, desc_overrides)
|
||||
|
||||
path = Path(handle.name)
|
||||
|
||||
def take_path(p):
|
||||
return path.parent / p
|
||||
|
||||
self.path = path
|
||||
self.name = get_field(path, where, data, 'name', expected_type=str)
|
||||
self.target_dir = get_field(path, where, data, 'target_dir',
|
||||
expected_type=str, constructor=take_path)
|
||||
self.upstream = get_field(path, where, data, 'upstream',
|
||||
constructor=lambda data: Upstream(path, data))
|
||||
self.patch_dir = get_field(path, where, data, 'patch_dir',
|
||||
optional=True, expected_type=str, constructor=take_path)
|
||||
self.patch_repo = get_field(path, where, data, 'patch_repo',
|
||||
optional=True,
|
||||
constructor=lambda data: PatchRepo(path, data))
|
||||
self.exclude_from_upstream = (get_field(path, where, data, 'exclude_from_upstream',
|
||||
optional=True, expected_type=list) or
|
||||
[])
|
||||
self.mapping = get_field(path, where, data, 'mapping', optional=True,
|
||||
expected_type=list,
|
||||
constructor=lambda data: Mapping.make(path, data))
|
||||
|
||||
# Add default exclusions
|
||||
self.exclude_from_upstream += EXCLUDE_ALWAYS
|
||||
|
||||
# It doesn't make sense to define a patch_repo, but not a patch_dir
|
||||
# (where should we put the patches that we get?)
|
||||
if self.patch_repo is not None and self.patch_dir is None:
|
||||
raise JsonError(path, 'Has patch_repo but not patch_dir.')
|
||||
|
||||
# We don't currently support a patch_repo and a mapping (just because
|
||||
# we haven't written the code to generate the patches across subdirs
|
||||
# yet). Tracked in issue #2317.
|
||||
if self.patch_repo is not None and self.mapping is not None:
|
||||
raise JsonError(path,
|
||||
"vendor.py doesn't currently support patch_repo "
|
||||
"and mapping at the same time (see issue #2317).")
|
||||
|
||||
# If a patch_dir is defined and there is no mapping, we will look in
|
||||
# that directory for patches and apply them in (the only) directory
|
||||
# that we copy stuff into.
|
||||
#
|
||||
# If there is a mapping check that there is a patch_dir if and only if
|
||||
# least one mapping entry uses it.
|
||||
if self.mapping is not None:
|
||||
if self.patch_dir is not None:
|
||||
if not self.mapping.has_patch_dir():
|
||||
raise JsonError(path, 'Has patch_dir, but no mapping item uses it.')
|
||||
else:
|
||||
if self.mapping.has_patch_dir():
|
||||
raise JsonError(path,
|
||||
'Has a mapping item with a patch directory, '
|
||||
'but there is no global patch_dir key.')
|
||||
|
||||
# Check that exclude_from_upstream really is a list of strings. Most of
|
||||
# this type-checking is in the constructors for field types, but we
|
||||
# don't have a "ExcludeList" class, so have to do it explicitly here.
|
||||
for efu in self.exclude_from_upstream:
|
||||
if not isinstance(efu, str):
|
||||
raise JsonError(path,
|
||||
'exclude_from_upstream has entry {}, which is not a string.'
|
||||
.format(efu))
|
||||
|
||||
def apply_overrides(self, desc_data, desc_overrides):
|
||||
""" Apply overrides from command line to configuration file data
|
||||
|
||||
Updates are applied to the desc_data reference."""
|
||||
|
||||
for key, value in desc_overrides:
|
||||
log.info("Overriding description key {!r} with value {!r}".format(
|
||||
key, value))
|
||||
ref = desc_data
|
||||
split_keys = key.split('.')
|
||||
for key_part in split_keys[:-1]:
|
||||
if key_part not in ref:
|
||||
ref[key_part] = {}
|
||||
ref = ref[key_part]
|
||||
ref[split_keys[-1]] = value
|
||||
|
||||
def lock_file_path(self):
|
||||
desc_file_stem = self.path.name.rsplit('.', 2)[0]
|
||||
return self.path.with_name(desc_file_stem + '.lock.hjson')
|
||||
|
||||
def import_from_upstream(self, upstream_path):
|
||||
log.info('Copying upstream sources to {}'.format(self.target_dir))
|
||||
|
||||
# Remove existing directories before importing them again
|
||||
shutil.rmtree(str(self.target_dir), ignore_errors=True)
|
||||
|
||||
items = (self.mapping.items if self.mapping is not None
|
||||
else [Mapping1.make_default(self.patch_dir is not None)])
|
||||
for map1 in items:
|
||||
map1.import_from_upstream(upstream_path,
|
||||
self.target_dir,
|
||||
self.exclude_from_upstream,
|
||||
self.patch_dir)
|
||||
|
||||
|
||||
def refresh_patches(desc):
|
||||
if desc.patch_repo is None:
|
||||
log.fatal('Unable to refresh patches, patch_repo not set in config.')
|
||||
sys.exit(1)
|
||||
|
||||
log.info('Refreshing patches in {}'.format(desc.patch_dir))
|
||||
|
||||
# remove existing patches
|
||||
for patch in desc.patch_dir.glob('*.patch'):
|
||||
os.unlink(str(patch))
|
||||
|
||||
# get current patches
|
||||
_export_patches(desc.patch_repo.url, desc.patch_dir,
|
||||
desc.patch_repo.rev_base,
|
||||
desc.patch_repo.rev_patched)
|
||||
|
||||
|
||||
def _export_patches(patchrepo_clone_url, target_patch_dir, upstream_rev,
|
||||
patched_rev):
|
||||
with tempfile.TemporaryDirectory() as clone_dir:
|
||||
clone_git_repo(patchrepo_clone_url, clone_dir, patched_rev)
|
||||
rev_range = 'origin/' + upstream_rev + '..' + 'origin/' + patched_rev
|
||||
cmd = [
|
||||
'git',
|
||||
'format-patch',
|
||||
'--no-signature',
|
||||
'--no-stat',
|
||||
'-o',
|
||||
str(target_patch_dir.resolve()),
|
||||
rev_range
|
||||
]
|
||||
if not verbose:
|
||||
cmd += ['-q']
|
||||
subprocess.run(cmd, cwd=str(clone_dir), check=True)
|
||||
|
||||
|
||||
def ignore_patterns(base_dir, *patterns):
|
||||
"""Similar to shutil.ignore_patterns, but with support for directory excludes."""
|
||||
def _rel_to_base(path, name):
|
||||
return os.path.relpath(os.path.join(path, name), base_dir)
|
||||
|
||||
def _ignore_patterns(path, names):
|
||||
ignored_names = []
|
||||
for pattern in patterns:
|
||||
pattern_matches = [
|
||||
n for n in names
|
||||
if fnmatch.fnmatch(_rel_to_base(path, n), pattern)
|
||||
]
|
||||
ignored_names.extend(pattern_matches)
|
||||
return set(ignored_names)
|
||||
|
||||
return _ignore_patterns
|
||||
|
||||
|
||||
def clone_git_repo(repo_url, clone_dir, rev='master'):
|
||||
log.info('Cloning upstream repository %s @ %s', repo_url, rev)
|
||||
|
||||
# Clone the whole repository
|
||||
cmd = ['git', 'clone', '--no-single-branch']
|
||||
if not verbose:
|
||||
cmd += ['-q']
|
||||
cmd += [repo_url, str(clone_dir)]
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# Check out exactly the revision requested
|
||||
cmd = ['git', '-C', str(clone_dir), 'checkout', '--force', rev]
|
||||
if not verbose:
|
||||
cmd += ['-q']
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# Get revision information
|
||||
cmd = ['git', '-C', str(clone_dir), 'rev-parse', 'HEAD']
|
||||
rev = subprocess.run(cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
check=True,
|
||||
universal_newlines=True).stdout.strip()
|
||||
log.info('Cloned at revision %s', rev)
|
||||
return rev
|
||||
|
||||
|
||||
def git_get_short_rev(clone_dir, rev):
|
||||
""" Get the shortened SHA-1 hash for a revision """
|
||||
cmd = ['git', '-C', str(clone_dir), 'rev-parse', '--short', rev]
|
||||
short_rev = subprocess.run(cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
check=True,
|
||||
universal_newlines=True).stdout.strip()
|
||||
return short_rev
|
||||
|
||||
|
||||
def git_add_commit(paths, commit_msg):
|
||||
""" Stage and commit all changes in paths"""
|
||||
|
||||
assert paths
|
||||
base_dir = paths[0].parent
|
||||
|
||||
# Stage all changes
|
||||
#
|
||||
# Rather than figuring out GIT_DIR properly, we cheat and use "git -C" to
|
||||
# pretend that we're running in base_dir. Of course, the elements of paths
|
||||
# are relative to our actual working directory. Rather than do anything
|
||||
# clever, we just resolve them to absolute paths as we go.
|
||||
abs_paths = [p.resolve() for p in paths]
|
||||
subprocess.run(['git', '-C', base_dir, 'add'] + abs_paths, check=True)
|
||||
|
||||
cmd_commit = ['git', '-C', base_dir, 'commit', '-s', '-F', '-']
|
||||
try:
|
||||
subprocess.run(cmd_commit,
|
||||
check=True,
|
||||
universal_newlines=True,
|
||||
input=commit_msg)
|
||||
except subprocess.CalledProcessError:
|
||||
log.warning("Unable to create commit. Are there no changes?")
|
||||
|
||||
|
||||
def define_arg_type(arg):
|
||||
"""Sanity-check and return a config file override argument"""
|
||||
try:
|
||||
(key, value) = [v.strip() for v in arg.split('=', 2)]
|
||||
except Exception:
|
||||
raise argparse.ArgumentTypeError(
|
||||
'unable to parse {!r}: configuration overrides must be in the form key=value'
|
||||
.format(arg))
|
||||
|
||||
if key not in OVERRIDABLE_DESC_KEYS:
|
||||
raise argparse.ArgumentTypeError(
|
||||
'invalid configuration override: key {!r} cannot be overwritten'
|
||||
.format(key))
|
||||
return (key, value)
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser(prog="vendor", description=__doc__)
|
||||
parser.add_argument(
|
||||
'--update',
|
||||
'-U',
|
||||
dest='update',
|
||||
action='store_true',
|
||||
help='Update locked version of repository with upstream changes')
|
||||
parser.add_argument('--refresh-patches',
|
||||
action='store_true',
|
||||
help='Refresh the patches from the patch repository')
|
||||
parser.add_argument('--commit',
|
||||
'-c',
|
||||
action='store_true',
|
||||
help='Commit the changes')
|
||||
parser.add_argument('--desc-override',
|
||||
'-D',
|
||||
dest="desc_overrides",
|
||||
action="append",
|
||||
type=define_arg_type,
|
||||
default=[],
|
||||
help='Override a setting in the description file. '
|
||||
'Format: -Dsome.key=value. '
|
||||
'Can be used multiple times.')
|
||||
parser.add_argument('desc_file',
|
||||
metavar='file',
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
help='vendoring description file (*.vendor.hjson)')
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help='Verbose')
|
||||
args = parser.parse_args()
|
||||
|
||||
global verbose
|
||||
verbose = args.verbose
|
||||
if (verbose):
|
||||
log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG)
|
||||
else:
|
||||
log.basicConfig(format="%(levelname)s: %(message)s")
|
||||
|
||||
# Load input files (desc file; lock file) and check syntax etc.
|
||||
try:
|
||||
# Load description file
|
||||
desc = Desc(args.desc_file, args.desc_overrides)
|
||||
lock_file_path = desc.lock_file_path()
|
||||
|
||||
# Try to load lock file (which might not exist)
|
||||
try:
|
||||
with open(str(lock_file_path), 'r') as lock_file:
|
||||
lock = LockDesc(lock_file)
|
||||
except FileNotFoundError:
|
||||
lock = None
|
||||
except (JsonError, ValueError) as err:
|
||||
log.fatal(str(err))
|
||||
raise SystemExit(1)
|
||||
|
||||
# Check for a clean working directory when commit is requested
|
||||
if args.commit:
|
||||
if not git_is_clean_workdir(desc.path.parent):
|
||||
log.fatal("A clean git working directory is required for "
|
||||
"--commit/-c. git stash your changes and try again.")
|
||||
raise SystemExit(1)
|
||||
|
||||
if lock is None and not args.update:
|
||||
log.warning("No lock file at {}, so will update upstream repo."
|
||||
.format(str(desc.lock_file_path())))
|
||||
args.update = True
|
||||
|
||||
# If we have a lock file and we're not in update mode, override desc's
|
||||
# upstream field with the one from the lock file. Keep track of whether the
|
||||
# URL differs (in which case, we can't get a shortlog)
|
||||
changed_url = False
|
||||
if lock is not None:
|
||||
changed_url = desc.upstream.url != lock.upstream.url
|
||||
if not args.update:
|
||||
desc.upstream = lock.upstream
|
||||
|
||||
if args.refresh_patches:
|
||||
refresh_patches(desc)
|
||||
|
||||
with tempfile.TemporaryDirectory() as clone_dir:
|
||||
# clone upstream repository
|
||||
upstream_new_rev = clone_git_repo(desc.upstream.url, clone_dir, rev=desc.upstream.rev)
|
||||
|
||||
if not args.update:
|
||||
if upstream_new_rev != lock.upstream.rev:
|
||||
log.fatal(
|
||||
"Revision mismatch. Unable to re-clone locked version of repository."
|
||||
)
|
||||
log.fatal("Attempted revision: %s", desc.upstream.rev)
|
||||
log.fatal("Re-cloned revision: %s", upstream_new_rev)
|
||||
raise SystemExit(1)
|
||||
|
||||
clone_subdir = Path(clone_dir)
|
||||
if desc.upstream.only_subdir is not None:
|
||||
clone_subdir = clone_subdir / desc.upstream.only_subdir
|
||||
if not clone_subdir.is_dir():
|
||||
log.fatal("subdir '{}' does not exist in repo"
|
||||
.format(desc.upstream.only_subdir))
|
||||
raise SystemExit(1)
|
||||
|
||||
# copy selected files from upstream repo and apply patches as necessary
|
||||
desc.import_from_upstream(clone_subdir)
|
||||
|
||||
# get shortlog
|
||||
get_shortlog = args.update
|
||||
if args.update:
|
||||
if lock is None:
|
||||
get_shortlog = False
|
||||
log.warning("No lock file %s: unable to summarize changes.", str(lock_file_path))
|
||||
elif changed_url:
|
||||
get_shortlog = False
|
||||
log.warning("The repository URL changed since the last run. "
|
||||
"Unable to get log of changes.")
|
||||
|
||||
shortlog = None
|
||||
if get_shortlog:
|
||||
shortlog = produce_shortlog(clone_subdir, desc.mapping,
|
||||
lock.upstream.rev, upstream_new_rev)
|
||||
|
||||
# Ensure fully-qualified issue/PR references for GitHub repos
|
||||
gh_repo_info = github_parse_url(desc.upstream.url)
|
||||
if gh_repo_info:
|
||||
shortlog = github_qualify_references(shortlog, gh_repo_info[0],
|
||||
gh_repo_info[1])
|
||||
|
||||
log.info("Changes since the last import:\n" +
|
||||
format_list_to_str(shortlog))
|
||||
|
||||
# write lock file
|
||||
if args.update:
|
||||
lock_data = {}
|
||||
lock_data['upstream'] = desc.upstream.as_dict()
|
||||
lock_data['upstream']['rev'] = upstream_new_rev
|
||||
with open(str(lock_file_path), 'w', encoding='UTF-8') as f:
|
||||
f.write(LOCK_FILE_HEADER)
|
||||
hjson.dump(lock_data, f)
|
||||
f.write("\n")
|
||||
log.info("Wrote lock file %s", str(lock_file_path))
|
||||
|
||||
# Commit changes
|
||||
if args.commit:
|
||||
sha_short = git_get_short_rev(clone_subdir, upstream_new_rev)
|
||||
|
||||
repo_info = github_parse_url(desc.upstream.url)
|
||||
if repo_info is not None:
|
||||
sha_short = "%s/%s@%s" % (repo_info[0], repo_info[1],
|
||||
sha_short)
|
||||
|
||||
commit_msg_subject = 'Update %s to %s' % (desc.name, sha_short)
|
||||
intro = ('Update code from {}upstream repository {} to revision {}'
|
||||
.format(('' if desc.upstream.only_subdir is None else
|
||||
'subdir {} in '.format(desc.upstream.only_subdir)),
|
||||
desc.upstream.url,
|
||||
upstream_new_rev))
|
||||
commit_msg_body = textwrap.fill(intro, width=70)
|
||||
|
||||
if shortlog:
|
||||
commit_msg_body += "\n\n"
|
||||
commit_msg_body += format_list_to_str(shortlog, width=70)
|
||||
|
||||
commit_msg = commit_msg_subject + "\n\n" + commit_msg_body
|
||||
|
||||
commit_paths = []
|
||||
commit_paths.append(desc.target_dir)
|
||||
if args.refresh_patches:
|
||||
commit_paths.append(desc.patch_dir)
|
||||
commit_paths.append(lock_file_path)
|
||||
|
||||
git_add_commit(commit_paths, commit_msg)
|
||||
|
||||
log.info('Import finished')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main(sys.argv)
|
||||
except subprocess.CalledProcessError as e:
|
||||
log.fatal("Called program '%s' returned with %d.\n"
|
||||
"STDOUT:\n%s\n"
|
||||
"STDERR:\n%s\n" %
|
||||
(" ".join(e.cmd), e.returncode, e.stdout, e.stderr))
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
log.info("Aborting operation on user request.")
|
||||
sys.exit(1)
|
14
vendor/pulp-platform/common_cells/.gitignore
vendored
Normal file
14
vendor/pulp-platform/common_cells/.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
.*
|
||||
!.travis.yml
|
||||
!.git*
|
||||
*.out
|
||||
*~
|
||||
/Bender.lock
|
||||
/Bender.local
|
||||
build
|
||||
formal/fifo_v3
|
||||
formal/counter
|
||||
formal/fall_through_register
|
||||
*.check
|
||||
*.vcd
|
||||
obj_dir/
|
342
vendor/pulp-platform/common_cells/CHANGELOG.md
vendored
Normal file
342
vendor/pulp-platform/common_cells/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,342 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 1.23.0 - 2021-09-05
|
||||
### Added
|
||||
- Add `cc_onehot`
|
||||
- `isochronous_4phase_handshake`: Isochronous clock domain crossing cutting all paths using a 4-phase handshake.
|
||||
- Changed `isochronous_spill_register_tb` to `isochronous_crossing_tb` also covering the `isochronous_4phase_handshake`
|
||||
module.
|
||||
- Make reset value of `sync` module parameterizable.
|
||||
|
||||
### Changed
|
||||
- `id_queue`: Allow simultaneous input and output requests in `FULL_BW` mode
|
||||
|
||||
## 1.22.1 - 2021-06-14
|
||||
### Fixed
|
||||
- Remove breaking change of `spill_register`
|
||||
|
||||
## 1.22.0 - 2021-06-09
|
||||
### Added
|
||||
- Add `spill_register_flushable`
|
||||
|
||||
### Changed
|
||||
- `registers.svh`: Merge explicit and implicit register variants into `` `FF `` and `` `FFL `` macros
|
||||
- `rr_arb_tree`: Allow flushing locked decision
|
||||
- Improved `verific` compatibility
|
||||
|
||||
## 1.21.0 - 2021-01-28
|
||||
### Changed
|
||||
- Remove `timeprecision/timeunit` arguments
|
||||
- Update `common_verification` to `0.2.0`
|
||||
- Update `tech_cells_generic` to `0.2.3`
|
||||
|
||||
## 1.20.1 - 2021-01-21
|
||||
### Changed
|
||||
- `id_queue`: Replace default or reset value of signals that were assigned `'x` with `'0`.
|
||||
- `id_queue`: Use `cf_math_pkg::idx_width()` for computation of localparams.
|
||||
|
||||
### Fixed
|
||||
- Add `XSIM` define guard for statements incompatible with `xsim`.
|
||||
|
||||
## 1.20.0 - 2020-11-04
|
||||
### Added
|
||||
- assertions: Assertion include header with macros (from lowrisc)
|
||||
|
||||
### Changed
|
||||
- `sram.sv`: Deprecated as it has been moved to `tech_cells_generic`
|
||||
|
||||
### Fixed
|
||||
- `stream_register`: Fix `DATA_WIDTH` of instantiated FIFO.
|
||||
- `stream_xbar`: Add missing argument in assertion error string.
|
||||
- Lint style fixes
|
||||
- `stream_omega`: Fix parse issue with verible.
|
||||
- `src_files.yml`: Fix compile order and missing modules.
|
||||
|
||||
## 1.19.0 - 2020-05-25
|
||||
### Added
|
||||
- stream_to_mem: Allows to use memories with flow control (req/gnt) for requests but
|
||||
without flow control for output data to be used in streams.
|
||||
- isochronous_spill_register: Isochronous clock domain crossing cutting all paths.
|
||||
- `rr_arb_tree_tb`: Systemverilog testbench for `rr_arb_tree`, which checks for fair throughput.
|
||||
- `cf_math_pkg::idx_width`: Constant function for defining the binary representation width
|
||||
of an index signal.
|
||||
|
||||
### Changed
|
||||
- `addr_decode`: Use `cf_math_pkg::idx_width` for computing the index width, inline documentation.
|
||||
- `lzc`: Use `cf_math_pkg::idx_width` for computing the index width, inline documentation.
|
||||
- `Bender`: Change levels of modules affected by depending on `cf_math_pkg::idx_width()`.
|
||||
- `stream_xbar`: Fully connected stream bassed interconnect with variable number of inputs and outputs.
|
||||
- `stream_xbar`: Fully connected stream-bassed interconnect with a variable number of inputs and outputs.
|
||||
- `stream_omega_net`: Stream-based network implementing an omega topology. Variable number of inputs,
|
||||
outputs and radix. Topology is isomorphic to a butterfly network.
|
||||
|
||||
### Fixed
|
||||
- Improve tool compatibility.
|
||||
- `rr_arb_tree`: Properly degenerate `rr_i` and `idx_o` signals.
|
||||
- `rr_arb_tree`: Add parameter `FairArb` to distribute throughput of input requests evenly when
|
||||
not all inputs have requests active.
|
||||
- `stream_demux`: Properly degenerate `inp_sel_i` signal.
|
||||
|
||||
## 1.18.0 - 2020-04-15
|
||||
### Added
|
||||
- stream_fork_dynamic: Wrapper around `stream_fork` for partial forking.
|
||||
- stream_join: Join multiple Ready/Valid handshakes to one common handshake.
|
||||
- SECDED (Single Error Correction, Double Error Detection) encoder and decoder
|
||||
- SECDED Verilator-based testbench
|
||||
- Travis build for SECDED module
|
||||
|
||||
## 1.17.0 - 2020-04-09
|
||||
### Added
|
||||
- stream_fifo: Ready/Valid handshake wrapper around `fifo_v3`
|
||||
|
||||
## 1.16.4 - 2020-03-02
|
||||
### Fixed
|
||||
- id_queue: Fix generation of `head_tail_q` registers
|
||||
|
||||
## 1.16.3 - 2020-02-11
|
||||
### Fixed
|
||||
- Handle degenerated `addr_decode` with `NoIndices == 1`, change default parameters to `32'd0`
|
||||
|
||||
## 1.16.2 - 2020-02-04
|
||||
### Fixed
|
||||
- Fix author section in Bender.yml
|
||||
|
||||
## 1.16.1 - 2020-02-03
|
||||
### Fixed
|
||||
- `rr_arb_tree`: Add guard SVA statement for Verilator
|
||||
- Added missing sources in `Bender.yml` and `src_files.yml`
|
||||
|
||||
## 1.16.0 - 2020-01-13
|
||||
### Fixed
|
||||
- Handle degenerated `onehot_to_bin` with `ONEHOT_WIDTH == 1`
|
||||
- Handle degenerated `id_queue` with `CAPACITY == 1` or `HT_CAPACITY == 1`
|
||||
- Fix `cdc_fifo_gray` to be a safe clock domain crossing (CDC)
|
||||
|
||||
## 1.15.0 - 2019-12-09
|
||||
### Added
|
||||
- Added address map decoder module
|
||||
|
||||
### Fixed
|
||||
- Handle degenerated `lzc` with `WIDTH == 1`
|
||||
|
||||
## 1.14.0 - 2019-10-08
|
||||
|
||||
### Added
|
||||
- Added spubstitution-permutation hash function module
|
||||
- Added couning-bloom-filter module
|
||||
- `spill_register`: Added Bypass parameter
|
||||
- `counter`: Added sticky overflow
|
||||
- Added counter with variable delta
|
||||
- Added counter that tracks its maximum value
|
||||
|
||||
### Changed
|
||||
- Added formal testbench for `fifo` and `fall_through_regsiter`
|
||||
|
||||
## 1.13.1 - 2019-06-01
|
||||
|
||||
### Changed
|
||||
|
||||
- Fix path in `src_files.yml` for `stream_arbiter` and `stream_arbiter_flushable`
|
||||
|
||||
## 1.13.0 - 2019-05-29
|
||||
|
||||
### Added
|
||||
|
||||
- Added exponential backoff window module
|
||||
- Added parametric Galois LFSR module with optional whitening feature
|
||||
- Added `cf_math_pkg`: Constant Function implementations of mathematical functions for HDL elaboration
|
||||
|
||||
### Changed
|
||||
- Parametric payload data type for `rr_arb_tree`
|
||||
|
||||
### Deprecated
|
||||
- The following arbiter implementations are deprecated and superseded by `rr_arb_tree`:
|
||||
- Priority arbiter `prioarbiter`
|
||||
- Round-robin arbiter `rrarbiter`
|
||||
|
||||
### Fixed
|
||||
|
||||
## 1.12.0 - 2019-04-09
|
||||
|
||||
### Added
|
||||
- Add priority arbiter
|
||||
- Add Pseudo Least Recently Used tree
|
||||
- Add round robin arbiter mux tree
|
||||
|
||||
### Changed
|
||||
- Add selectable arbiter implementation for `stream_arbiter` and `stream_arbiter_flushable`. One can choose between priority (`prio`) and round-robin arbitration (`rr`).
|
||||
- Add `$onehot0` assertion in one-hot to bin
|
||||
- Rework `rrarbiter` unit (uses `rr_arb_tree` implementation underneath)
|
||||
|
||||
## 1.11.0 - 2019-03-20
|
||||
|
||||
### Added
|
||||
- Add stream fork
|
||||
- Add fall-through register
|
||||
- Add stream filter
|
||||
- Add ID queue
|
||||
|
||||
### Changed
|
||||
- `sync_wedge` use existing synchronizer. This defines a single place where a tech-specific synchronizer can be defined.
|
||||
|
||||
### Fixed
|
||||
- Fix FIFO push and pop signals in `stream_register` to observe interface prerequisites.
|
||||
- In `fifo_v3`, fix data output when pushing into empty fall-through FIFO. Previously, the data
|
||||
output of an empty fall-through FIFO with data at its input (and `push_i=1`) depended on
|
||||
`pop_i`: When `pop_i=0`, old, invalid data were visible at the output (even though `empty_o=0`,
|
||||
indicating that the data output is valid). Only when `pop_i=1`, the data from the input fell
|
||||
through. One consequence of this bug was that `data_o` of the `fall_through_register` could change
|
||||
while `valid_o=1`, violating the basic stream specification.
|
||||
|
||||
## 1.10.0 - 2018-12-18
|
||||
|
||||
### Added
|
||||
- Add `fifo_v3` with generic fill count
|
||||
- Add 16 bit LFSR
|
||||
- Add stream delayer
|
||||
- Add stream arbiter
|
||||
- Add register macros for RTL
|
||||
- Add shift register
|
||||
|
||||
### Changed
|
||||
- Make number of registers of `rstgen_bypass` a parameter.
|
||||
|
||||
### Fixed
|
||||
- Fix `valid_i` and `grant_i` guarantees in `generic_fifo` for backward compatibility.
|
||||
- LZC: Synthesis of streaming operators in ternary operators
|
||||
- Add missing entry for `popcount` to `Bender.yml`.
|
||||
- Add default values for parameters to improve compatibility with Synopsys DC and Vivado.
|
||||
|
||||
## 1.9.0 - 2018-11-02
|
||||
|
||||
### Added
|
||||
- Add popcount circuit `popcount`
|
||||
|
||||
## 1.8.0 - 2018-10-15
|
||||
|
||||
### Added
|
||||
- Add lock feature to the rrarbiter. This prevents the arbiter to change the decision when we have pending requests that remain unaknowledged for several cycles.
|
||||
- Add deglitching circuit
|
||||
- Add generic clock divider
|
||||
- Add edge detecter as alias to sync_wedge (name is more expressive)
|
||||
- Add generic counter
|
||||
- Add moving deglitcher
|
||||
|
||||
## 1.7.6 - 2018-09-27
|
||||
|
||||
### Added
|
||||
- Add reset synchronizer with explicit reset bypass in testmode
|
||||
|
||||
## 1.7.5 - 2018-09-06
|
||||
### Fixed
|
||||
- Fix incompatibility with verilator
|
||||
- Fix dependency to open-source repo
|
||||
|
||||
## 1.7.4 - 2018-09-06
|
||||
- Fix assertions in `fifo_v2` (write on full / read on empty did not trigger properly)
|
||||
|
||||
## 1.7.3 - 2018-08-27
|
||||
### Fixed
|
||||
- Use proper `fifo_v2` in `generic_fifo` module.
|
||||
|
||||
## 1.7.2 - 2018-08-27
|
||||
### Added
|
||||
- Almost full/empty flags to FIFO, as `fifo_v2`.
|
||||
|
||||
### Changed
|
||||
- FIFO moved to `fifo_v1` and instantiates `fifo_v2`.
|
||||
|
||||
## 1.7.1 - 2018-08-27
|
||||
### Fixed
|
||||
- Revert breaking changes to `fifo`.
|
||||
|
||||
## 1.7.0 - 2018-08-24
|
||||
### Added
|
||||
- Add stream register (`stream_register`).
|
||||
- Add stream multiplexer and demultiplexer (`stream_mux`, `stream_demux`).
|
||||
- Add round robin arbiter (`rrarbiter`).
|
||||
- Add leading zero counter (`lzc`).
|
||||
|
||||
### Changed
|
||||
- Deprecate `find_first_one` in favor of `lzc`.
|
||||
|
||||
## 1.6.0 - 2018-04-03
|
||||
### Added
|
||||
- Add binary to Gray code converter.
|
||||
- Add Gray code to binary converter.
|
||||
- Add Gray code testbench.
|
||||
- Add CDC FIFO based on Gray counters. This is a faster alternative to the 2-phase FIFO which also works if a domain's clock has stopped.
|
||||
|
||||
### Changed
|
||||
- Rename `cdc_fifo` to `cdc_fifo_2phase`.
|
||||
- Adjust CDC FIFO testbench to cover both implementations.
|
||||
|
||||
## 1.5.4 - 2018-03-31
|
||||
### Changed
|
||||
- Replace explicit clock gate in `fifo` with implicit one.
|
||||
|
||||
## 1.5.3 - 2018-03-16
|
||||
### Changed
|
||||
- Remove duplicate deprecated modules.
|
||||
|
||||
## 1.5.2 - 2018-03-16
|
||||
### Changed
|
||||
- Remove deprecated `rstgen` and fix interface.
|
||||
|
||||
## 1.5.1 - 2018-03-16
|
||||
### Changed
|
||||
- Remove deprecated `onehot_to_bin`.
|
||||
|
||||
## 1.5.0 - 2018-03-14
|
||||
### Added
|
||||
- Add behavioural SRAM model
|
||||
|
||||
## 1.4.0 - 2018-03-14
|
||||
### Added
|
||||
- Clock domain crossing FIFO
|
||||
|
||||
### Changed
|
||||
- Re-name new sync modules to resolve namespace collisions
|
||||
|
||||
## 1.3.0 - 2018-03-12
|
||||
### Added
|
||||
- 2-phase clock domain crossing
|
||||
- Add old common cells as deprecated legacy modules
|
||||
|
||||
## 1.2.3 - 2018-03-09
|
||||
### Added
|
||||
- Backwards compatibility wrapper for `generic_LFSR_8bit`
|
||||
|
||||
## 1.2.2 - 2018-03-09
|
||||
### Added
|
||||
- Backwards compatibility wrapper for `generic_fifo`
|
||||
|
||||
## 1.2.1 - 2018-03-09
|
||||
### Fixed
|
||||
- Fix an issue in the spill register which causes transactions to be lost
|
||||
|
||||
## 1.2.0 - 2018-03-09
|
||||
### Added
|
||||
- Add spill register
|
||||
|
||||
## 1.1.0 - 2018-03-06
|
||||
### Added
|
||||
- Find first zero
|
||||
|
||||
## 1.0.0 - 2018-03-02
|
||||
### Added
|
||||
- Re-implementation of the generic FIFO supporting all kinds of use-cases
|
||||
- Testbench for FIFO
|
||||
|
||||
### Changed
|
||||
- Re-formatting and artistic code clean-up
|
||||
|
||||
## 0.1.0 - 2018-02-23
|
||||
### Added
|
||||
- Fork of PULP common cells repository
|
176
vendor/pulp-platform/common_cells/LICENSE
vendored
Normal file
176
vendor/pulp-platform/common_cells/LICENSE
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
SOLDERPAD HARDWARE LICENSE version 0.51
|
||||
|
||||
This license is based closely on the Apache License Version 2.0, but is not
|
||||
approved or endorsed by the Apache Foundation. A copy of the non-modified
|
||||
Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
As this license is not currently OSI or FSF approved, the Licensor permits any
|
||||
Work licensed under this License, at the option of the Licensee, to be treated
|
||||
as licensed under the Apache License Version 2.0 (which is so approved).
|
||||
|
||||
This License is licensed under the terms of this License and in particular
|
||||
clause 7 below (Disclaimer of Warranties) applies in relation to its use.
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the Rights owner or entity authorized by the Rights owner
|
||||
that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Rights" means copyright and any similar right including design right (whether
|
||||
registered or unregistered), semiconductor topography (mask) rights and
|
||||
database rights (but excluding Patents and Trademarks).
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to source code, net lists, board layouts, CAD files,
|
||||
documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object
|
||||
code, generated documentation, the instantiation of a hardware design and
|
||||
conversions to other media types, including intermediate forms such as
|
||||
bytecodes, FPGA bitstreams, artwork and semiconductor topographies (mask
|
||||
works).
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source form or other
|
||||
Object form, made available under the License, as indicated by a Rights notice
|
||||
that is included in or attached to the work (an example is provided in the
|
||||
Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) or physically connect to or interoperate with the interfaces of, the Work
|
||||
and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any design or work of authorship, including the
|
||||
original version of the Work and any modifications or additions to that Work or
|
||||
Derivative Works thereof, that is intentionally submitted to Licensor for
|
||||
inclusion in the Work by the Rights owner or by an individual or Legal Entity
|
||||
authorized to submit on behalf of the Rights owner. For the purposes of this
|
||||
definition, "submitted" means any form of electronic, verbal, or written
|
||||
communication sent to the Licensor or its representatives, including but not
|
||||
limited to communication on electronic mailing lists, source code control
|
||||
systems, and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but excluding
|
||||
communication that is conspicuously marked or otherwise designated in writing
|
||||
by the Rights owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of License. Subject to the terms and conditions of this License, each
|
||||
Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable license under the Rights to reproduce,
|
||||
prepare Derivative Works of, publicly display, publicly perform, sublicense,
|
||||
and distribute the Work and such Derivative Works in Source or Object form and
|
||||
do anything in relation to the Work as if the Rights did not exist.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this
|
||||
License, each Contributor hereby grants to You a perpetual, worldwide,
|
||||
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
|
||||
section) patent license to make, have made, use, offer to sell, sell, import,
|
||||
and otherwise transfer the Work, where such license applies only to those
|
||||
patent claims licensable by such Contributor that are necessarily infringed by
|
||||
their Contribution(s) alone or by combination of their Contribution(s) with the
|
||||
Work to which such Contribution(s) was submitted. If You institute patent
|
||||
litigation against any entity (including a cross-claim or counterclaim in a
|
||||
lawsuit) alleging that the Work or a Contribution incorporated within the Work
|
||||
constitutes direct or contributory patent infringement, then any patent
|
||||
licenses granted to You under this License for that Work shall terminate as of
|
||||
the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||
Derivative Works thereof in any medium, with or without modifications, and in
|
||||
Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy
|
||||
of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that
|
||||
You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You
|
||||
distribute, all copyright, patent, trademark, and attribution notices from
|
||||
the Source form of the Work, excluding those notices that do not pertain to
|
||||
any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then
|
||||
any Derivative Works that You distribute must include a readable copy of
|
||||
the attribution notices contained within such NOTICE file, excluding those
|
||||
notices that do not pertain to any part of the Derivative Works, in at
|
||||
least one of the following places: within a NOTICE text file distributed as
|
||||
part of the Derivative Works; within the Source form or documentation, if
|
||||
provided along with the Derivative Works; or, within a display generated by
|
||||
the Derivative Works, if and wherever such third-party notices normally
|
||||
appear. The contents of the NOTICE file are for informational purposes only
|
||||
and do not modify the License. You may add Your own attribution notices
|
||||
within Derivative Works that You distribute, alongside or as an addendum to
|
||||
the NOTICE text from the Work, provided that such additional attribution
|
||||
notices cannot be construed as modifying the License. You may add Your own
|
||||
copyright statement to Your modifications and may provide additional or
|
||||
different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a
|
||||
whole, provided Your use, reproduction, and distribution of the Work
|
||||
otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||
Licensor shall be under the terms and conditions of this License, without any
|
||||
additional terms or conditions. Notwithstanding the above, nothing herein shall
|
||||
supersede or modify the terms of any separate license agreement you may have
|
||||
executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names,
|
||||
trademarks, service marks, or product names of the Licensor, except as required
|
||||
for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
|
||||
writing, Licensor provides the Work (and each Contributor provides its
|
||||
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied, including, without limitation, any warranties
|
||||
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any risks
|
||||
associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in
|
||||
tort (including negligence), contract, or otherwise, unless required by
|
||||
applicable law (such as deliberate and grossly negligent acts) or agreed to in
|
||||
writing, shall any Contributor be liable to You for damages, including any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character arising as a result of this License or out of the use or inability to
|
||||
use the Work (including but not limited to damages for loss of goodwill, work
|
||||
stoppage, computer failure or malfunction, or any and all other commercial
|
||||
damages or losses), even if such Contributor has been advised of the
|
||||
possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or
|
||||
Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||
acceptance of support, warranty, indemnity, or other liability obligations
|
||||
and/or rights consistent with this License. However, in accepting such
|
||||
obligations, You may act only on Your own behalf and on Your sole
|
||||
responsibility, not on behalf of any other Contributor, and only if You agree
|
||||
to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
181
vendor/pulp-platform/common_cells/README.md
vendored
Normal file
181
vendor/pulp-platform/common_cells/README.md
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
[](https://travis-ci.com/pulp-platform/common_cells)
|
||||
[](CHANGELOG.md)
|
||||
[](LICENSE)
|
||||
|
||||
# Common Cells Repository
|
||||
|
||||
Maintainer: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
This repository contains commonly used cells and headers for use in various projects.
|
||||
|
||||
## Cell Contents
|
||||
|
||||
This repository currently contains the following cells, ordered by categories.
|
||||
Please note that cells with status *deprecated* are not to be used for new designs and only serve to provide compatibility with old code.
|
||||
|
||||
### Clocks and Resets
|
||||
|
||||
| Name | Description | Status | Superseded By |
|
||||
| ----------------------- | --------------------------------------------------- | ------------ | ------------- |
|
||||
| `clk_div` | Clock divider with integer divisor | active | |
|
||||
| `clock_divider` | Clock divider with configuration registers | *deprecated* | `clk_div` |
|
||||
| `clock_divider_counter` | Clock divider using a counter | *deprecated* | `clk_div` |
|
||||
| `rstgen` | Reset synchronizer | active | |
|
||||
| `rstgen_bypass` | Reset synchronizer with dedicated test reset bypass | active | |
|
||||
|
||||
### Clock Domains and Asynchronous Crossings
|
||||
|
||||
| Name | Description | Status | Superseded By |
|
||||
|--------------------------------|----------------------------------------------------------------------------------|--------------|---------------|
|
||||
| `cdc_2phase` | Clock domain crossing using two-phase handshake, with ready/valid interface | active | |
|
||||
| `cdc_fifo_2phase` | Clock domain crossing FIFO using two-phase handshake, with ready/valid interface | active | |
|
||||
| `cdc_fifo_gray` | Clock domain crossing FIFO using a gray-counter, with ready/valid interface | active | |
|
||||
| `edge_detect` | Rising/falling edge detector | active | |
|
||||
| `edge_propagator` | **ANTONIO ADD DESCRIPTION** | active | |
|
||||
| `edge_propagator_rx` | **ANTONIO ADD DESCRIPTION** | active | |
|
||||
| `edge_propagator_tx` | **ANTONIO ADD DESCRIPTION** | active | |
|
||||
| `isochronous_spill_register` | Isochronous clock domain crossing and full handshake (like `spill_register`) | active | |
|
||||
| `isochronous_4phase_handshake` | Isochronous four-phase handshake. | active | |
|
||||
| `pulp_sync` | Serial line synchronizer | *deprecated* | `sync` |
|
||||
| `pulp_sync_wedge` | Serial line synchronizer with edge detector | *deprecated* | `sync_wedge` |
|
||||
| `serial_deglitch` | Serial line deglitcher | active | |
|
||||
| `sync` | Serial line synchronizer | active | |
|
||||
| `sync_wedge` | Serial line synchronizer with edge detector | active | |
|
||||
|
||||
### Counters and Shift Registers
|
||||
|
||||
| Name | Description | Status | Superseded By |
|
||||
| ------------------- | ----------------------------------------------------------------- | ------------ | ------------- |
|
||||
| `counter` | Generic up/down counter with overflow detection | active | |
|
||||
| `delta_counter` | Up/down counter with variable delta and overflow detection | active | |
|
||||
| `generic_LFSR_8bit` | 8-bit linear feedback shift register (LFSR) | *deprecated* | `lfsr_8bit` |
|
||||
| `lfsr_8bit` | 8-bit linear feedback shift register (LFSR) | active | |
|
||||
| `lfsr_16bit` | 16-bit linear feedback shift register (LFSR) | active | |
|
||||
| `lfsr` | 4...64-bit parametric Galois LFSR with optional whitening feature | active | |
|
||||
| `max_counter` | Up/down counter with variable delta that tracks its maximum value | active | |
|
||||
| `mv_filter` | **ZARUBAF ADD DESCRIPTION** | active | |
|
||||
|
||||
### Data Path Elements
|
||||
|
||||
| Name | Description | Status | Superseded By |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------- | ------------ | ------------- |
|
||||
| `addr_decode ` | Address map decoder | active | |
|
||||
| `ecc_decode` | SECDED Decoder (Single Error Correction, Double Error Detection) | active | |
|
||||
| `ecc_encode` | SECDED Encoder (Single Error Correction, Double Error Detection) | active | |
|
||||
| `binary_to_gray` | Binary to gray code converter | active | |
|
||||
| `find_first_one` | Leading-one finder / leading-zero counter | *deprecated* | `lzc` |
|
||||
| `gray_to_binary` | Gray code to binary converter | active | |
|
||||
| `lzc` | Leading/trailing-zero counter | active | |
|
||||
| `onehot_to_bin` | One-hot to binary converter | active | |
|
||||
| `shift_reg` | Shift register for arbitrary types | active | |
|
||||
| `rr_arb_tree` | Round-robin arbiter for req/gnt and vld/rdy interfaces with optional priority | active | |
|
||||
| `rrarbiter` | Round-robin arbiter for req/ack interface with look-ahead | *deprecated* | `rr_arb_tree` |
|
||||
| `prioarbiter` | Priority arbiter arbiter for req/ack interface with look-ahead | *deprecated* | `rr_arb_tree` |
|
||||
| `fall_through_register` | Fall-through register with ready/valid interface | active | |
|
||||
| `spill_register_flushable` | Register with ready/valid interface to cut all combinational interface paths and additional flush signal. | active | |
|
||||
| `spill_register` | Register with ready/valid interface to cut all combinational interface paths | active | |
|
||||
| `stream_arbiter` | Round-robin arbiter for ready/valid stream interface | active | |
|
||||
| `stream_arbiter_flushable` | Round-robin arbiter for ready/valid stream interface and flush functionality | active | |
|
||||
| `stream_demux` | Ready/valid interface demultiplexer | active | |
|
||||
| `stream_join` | Ready/valid handshake join multiple to one common | active | |
|
||||
| `stream_mux` | Ready/valid interface multiplexer | active | |
|
||||
| `stream_register` | Register with ready/valid interface | active | |
|
||||
| `stream_fork` | Ready/valid fork | active | |
|
||||
| `stream_fork_dynamic` | Ready/valid fork, with selection mask for partial forking | active | |
|
||||
| `stream_filter` | Ready/valid filter | active | |
|
||||
| `stream_delay` | Randomize or delay ready/valid interface | active | |
|
||||
| `stream_to_mem` | Use memories without flow control for output data in streams. | active | |
|
||||
| `stream_xbar` | Fully connected crossbar with ready/valid interface. | active | |
|
||||
| `stream_omega_net` | One-way stream omega-net with ready/valid interface. Isomorphic to a butterfly. | active | |
|
||||
| `sub_per_hash` | Substitution-permutation hash function | active | |
|
||||
| `popcount` | Combinatorial popcount (hamming weight) | active | |
|
||||
|
||||
### Data Structures
|
||||
|
||||
| Name | Description | Status | Superseded By |
|
||||
| ------------------ | ----------------------------------------------- | ------------ | ------------- |
|
||||
| `cb_filter` | Counting-Bloom-Filter with combinational lookup | active | |
|
||||
| `fifo` | FIFO register with upper threshold | *deprecated* | `fifo_v3` |
|
||||
| `fifo_v2` | FIFO register with upper and lower threshold | *deprecated* | `fifo_v3` |
|
||||
| `fifo_v3` | FIFO register with generic fill counts | active | |
|
||||
| `stream_fifo` | FIFO register with ready/valid interface | active | |
|
||||
| `generic_fifo` | FIFO register without thresholds | *deprecated* | `fifo_v3` |
|
||||
| `generic_fifo_adv` | FIFO register without thresholds | *deprecated* | `fifo_v3` |
|
||||
| `sram` | SRAM behavioral model | active | |
|
||||
| `plru_tree` | Pseudo least recently used tree | active | |
|
||||
| `unread` | Empty module to sink unconnected outputs into | active | |
|
||||
|
||||
|
||||
## Header Contents
|
||||
|
||||
This repository currently contains the following header files.
|
||||
|
||||
### RTL Register Macros
|
||||
|
||||
The header file `registers.svh` contains macros that expand to descriptions of registers.
|
||||
To avoid misuse of `always_ff` blocks, only the following macros shall be used to describe sequential behavior.
|
||||
The use of linter rules that flag explicit uses of `always_ff` in source code is encouraged.
|
||||
|
||||
| Macro | Arguments | Description |
|
||||
| ------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| `` `FF`` | `q_sig`, `d_sig`, `rst_val`, (`clk_sig`, `arstn_sig`) | Flip-flop with asynchronous active-low reset |
|
||||
| `` `FFAR`` | `q_sig`, `d_sig`, `rst_val`, `clk_sig`, `arst_sig` | Flip-flop with asynchronous active-high reset |
|
||||
| `` `FFARN`` | `q_sig`, `d_sig`, `rst_val`, `clk_sig`, `arstn_sig` | *deprecated* Flip-flop with asynchronous active-low reset |
|
||||
| `` `FFSR`` | `q_sig`, `d_sig`, `rst_val`, `clk_sig`, `rst_sig` | Flip-flop with synchronous active-high reset |
|
||||
| `` `FFSRN`` | `q_sig`, `d_sig`, `rst_val`, `clk_sig`, `rstn_sig` | Flip-flop with synchronous active-low reset |
|
||||
| `` `FFNR`` | `q_sig`, `d_sig`, `clk_sig` | Flip-flop without reset |
|
||||
| | | |
|
||||
| `` `FFL`` | `q_sig`, `d_sig`, `load_ena`, `rst_val`, (`clk_sig`, `arstn_sig`) | Flip-flop with load-enable and asynchronous active-low reset |
|
||||
| `` `FFLAR`` | `q_sig`, `d_sig`, `load_ena`, `rst_val`, `clk_sig`, `arst_sig` | Flip-flop with load-enable and asynchronous active-high reset |
|
||||
| `` `FFLARN`` | `q_sig`, `d_sig`, `load_ena`, `rst_val`, `clk_sig`, `arstn_sig` | *deprecated* Flip-flop with load-enable and asynchronous active-low reset |
|
||||
| `` `FFLSR`` | `q_sig`, `d_sig`, `load_ena`, `rst_val`, `clk_sig`, `rst_sig` | Flip-flop with load-enable and synchronous active-high reset |
|
||||
| `` `FFLSRN`` | `q_sig`, `d_sig`, `load_ena`, `rst_val`, `clk_sig`, `rstn_sig` | Flip-flop with load-enable and synchronous active-low reset |
|
||||
| `` `FFLNR`` | `q_sig`, `d_sig`, `load_ena`, `clk_sig` | Flip-flop with load-enable without reset |
|
||||
- *The name of the clock and reset signals for implicit variants is `clk_i` and `rst_ni`, respectively.*
|
||||
- *Argument suffix `_sig` indicates signal names for present and next state as well as clocks and resets.*
|
||||
- *Argument `rst_val` specifies the value literal to be assigned upon reset.*
|
||||
- *Argument `load_ena` specifies the boolean expression that forms the load enable of the register.*
|
||||
|
||||
### SystemVerilog Assertion Macros
|
||||
|
||||
The header file `assertions.svh` contains macros that expand to assertion blocks.
|
||||
These macros should recduce the effort in writing many assertions and make it
|
||||
easier to use them. They are identical with the macros used by [lowrisc](https://github.com/lowRISC/opentitan/blob/master/hw/ip/prim/rtl/prim_assert.sv)
|
||||
and just re-implemented here for the sake of easier use in PULP projects (the same include guard is used so they should not clash).
|
||||
|
||||
#### Simple Assertion and Cover Macros
|
||||
| Macro | Arguments | Description |
|
||||
| ----------------------------------------------------------- | -------------------------------------------------------------------------- | ----------- |
|
||||
| `` `ASSERT_I`` | `__name`, `__prop` | Immediate assertion |
|
||||
| `` `ASSERT_INIT`` | `__name`, `__prop` | Assertion in initial block. Can be used for things like parameter checking |
|
||||
| `` `ASSERT_FINAL`` | `__name`, `__prop` | Assertion in final block |
|
||||
| `` `ASSERT`` | `__name`, `__prop`, (`__clk`, `__rst`) | Assert a concurrent property directly |
|
||||
| `` `ASSERT_NEVER`` | `__name`, `__prop`, (`__clk`, `__rst`) | Assert a concurrent property NEVER happens |
|
||||
| `` `ASSERT_KNOWN`` | `__name`, `__sig`, (`__clk`, `__rst`) | Concurrent clocked assertion with custom error message |
|
||||
| `` `COVER`` | `__name`, `__prop`, (`__clk`, `__rst`) | Cover a concurrent property |
|
||||
- *The name of the clock and reset signals for implicit variants is `clk_i` and `rst_ni`, respectively.*
|
||||
|
||||
#### Complex Assertion Macros
|
||||
| Macro | Arguments | Description |
|
||||
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
|
||||
| `` `ASSERT_PULSE`` | `__name`, `__sig`, (`__clk`, `__rst`) | Assert that signal is an active-high pulse with pulse length of 1 clock cycle |
|
||||
| `` `ASSERT_IF`` | `__name`, `__prop`, `__enable`, (`__clk`, `__rst`) | Assert that a property is true only when an enable signal is set |
|
||||
| `` `ASSERT_KNOWN_IF`` | `__name`, `__sig`, `__enable`, (`__clk`, `__rst`) | Assert that signal has a known value (each bit is either '0' or '1') after reset if enable is set |
|
||||
- *The name of the clock and reset signals for implicit variants is `clk_i` and `rst_ni`, respectively.*
|
||||
|
||||
#### Assumption Macros
|
||||
|
||||
| Macro | Arguments | Description |
|
||||
| ------------------------------------------------------- | ---------------------------- | ----------- |
|
||||
| `` `ASSUME`` | `__name`, `__prop`, (`__clk`, `__rst`) | Assume a concurrent property |
|
||||
| `` `ASSUME_I`` | `__name`, `__prop` | Assume an immediate property |
|
||||
- *The name of the clock and reset signals for implicit variants is `clk_i` and `rst_ni`, respectively.*
|
||||
|
||||
#### Formal Verification Macros
|
||||
|
||||
| Macro | Arguments | Description |
|
||||
| ----------------------------------------------------------- | ------------------------------------------------------------ | ----------- |
|
||||
| `` `ASSUME_FPV`` | `__name`, `__prop`, (`__clk`, `__rst`) | Assume a concurrent property during formal verification only |
|
||||
| `` `ASSUME_I_FPV`` | `__name`, `__prop` | Assume a concurrent property during formal verification only |
|
||||
| `` `COVER_FPV`` | `__name`, `__prop`, (`__clk`, `__rst`) | Cover a concurrent property during formal verification |
|
||||
- *The name of the clock and reset signals for implicit variants is `clk_i` and `rst_ni`, respectively.*
|
201
vendor/pulp-platform/common_cells/include/common_cells/assertions.svh
vendored
Normal file
201
vendor/pulp-platform/common_cells/include/common_cells/assertions.svh
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Macros and helper code for using assertions.
|
||||
// - Provides default clk and rst options to simplify code
|
||||
// - Provides boiler plate template for common assertions
|
||||
|
||||
`ifndef PRIM_ASSERT_SV
|
||||
`define PRIM_ASSERT_SV
|
||||
|
||||
`ifdef UVM
|
||||
// report assertion error with UVM if compiled
|
||||
package assert_rpt_pkg;
|
||||
import uvm_pkg::*;
|
||||
`include "uvm_macros.svh"
|
||||
function void assert_rpt(string msg);
|
||||
`uvm_error("ASSERT FAILED", msg)
|
||||
endfunction
|
||||
endpackage
|
||||
`endif
|
||||
|
||||
///////////////////
|
||||
// Helper macros //
|
||||
///////////////////
|
||||
|
||||
// local helper macro to reduce code clutter. undefined at the end of this file
|
||||
`ifndef VERILATOR
|
||||
`ifndef SYNTHESIS
|
||||
`ifndef XSIM
|
||||
`define INC_ASSERT
|
||||
`endif
|
||||
`endif
|
||||
`endif
|
||||
|
||||
// Converts an arbitrary block of code into a Verilog string
|
||||
`define PRIM_STRINGIFY(__x) `"__x`"
|
||||
|
||||
// ASSERT_RPT is available to change the reporting mechanism when an assert fails
|
||||
`define ASSERT_RPT(__name) \
|
||||
`ifdef UVM \
|
||||
assert_rpt_pkg::assert_rpt($sformatf("[%m] %s (%s:%0d)", \
|
||||
__name, `__FILE__, `__LINE__)); \
|
||||
`else \
|
||||
$error("[ASSERT FAILED] [%m] %s (%s:%0d)", __name, `__FILE__, `__LINE__); \
|
||||
`endif
|
||||
|
||||
///////////////////////////////////////
|
||||
// Simple assertion and cover macros //
|
||||
///////////////////////////////////////
|
||||
|
||||
// Default clk and reset signals used by assertion macros below.
|
||||
`define ASSERT_DEFAULT_CLK clk_i
|
||||
`define ASSERT_DEFAULT_RST !rst_ni
|
||||
|
||||
// Immediate assertion
|
||||
// Note that immediate assertions are sensitive to simulation glitches.
|
||||
`define ASSERT_I(__name, __prop) \
|
||||
`ifdef INC_ASSERT \
|
||||
__name: assert (__prop) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
`endif
|
||||
|
||||
// Assertion in initial block. Can be used for things like parameter checking.
|
||||
`define ASSERT_INIT(__name, __prop) \
|
||||
`ifdef INC_ASSERT \
|
||||
initial begin \
|
||||
__name: assert (__prop) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
end \
|
||||
`endif
|
||||
|
||||
// Assertion in final block. Can be used for things like queues being empty
|
||||
// at end of sim, all credits returned at end of sim, state machines in idle
|
||||
// at end of sim.
|
||||
`define ASSERT_FINAL(__name, __prop) \
|
||||
`ifdef INC_ASSERT \
|
||||
final begin \
|
||||
__name: assert (__prop || $test$plusargs("disable_assert_final_checks")) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
end \
|
||||
`endif
|
||||
|
||||
// Assert a concurrent property directly.
|
||||
// It can be called as a module (or interface) body item.
|
||||
`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
__name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
`endif
|
||||
// Note: Above we use (__rst !== '0) in the disable iff statements instead of
|
||||
// (__rst == '1). This properly disables the assertion in cases when reset is X at
|
||||
// the beginning of a simulation. For that case, (reset == '1) does not disable the
|
||||
// assertion.
|
||||
|
||||
// Assert a concurrent property NEVER happens
|
||||
`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
__name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) not (__prop)) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
`endif
|
||||
|
||||
// Assert that signal has a known value (each bit is either '0' or '1') after reset.
|
||||
// It can be called as a module (or interface) body item.
|
||||
`define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
`ASSERT(__name, !$isunknown(__sig), __clk, __rst) \
|
||||
`endif
|
||||
|
||||
// Cover a concurrent property
|
||||
`define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
__name: cover property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)); \
|
||||
`endif
|
||||
|
||||
//////////////////////////////
|
||||
// Complex assertion macros //
|
||||
//////////////////////////////
|
||||
|
||||
// Assert that signal is an active-high pulse with pulse length of 1 clock cycle
|
||||
`define ASSERT_PULSE(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
`ASSERT(__name, $rose(__sig) |=> !(__sig), __clk, __rst) \
|
||||
`endif
|
||||
|
||||
// Assert that a property is true only when an enable signal is set. It can be called as a module
|
||||
// (or interface) body item.
|
||||
`define ASSERT_IF(__name, __prop, __enable, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
`ASSERT(__name, (__enable) |-> (__prop), __clk, __rst) \
|
||||
`endif
|
||||
|
||||
// Assert that signal has a known value (each bit is either '0' or '1') after reset if enable is
|
||||
// set. It can be called as a module (or interface) body item.
|
||||
`define ASSERT_KNOWN_IF(__name, __sig, __enable, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
`ASSERT_KNOWN(__name``KnownEnable, __enable, __clk, __rst) \
|
||||
`ASSERT_IF(__name, !$isunknown(__sig), __enable, __clk, __rst) \
|
||||
`endif
|
||||
|
||||
///////////////////////
|
||||
// Assumption macros //
|
||||
///////////////////////
|
||||
|
||||
// Assume a concurrent property
|
||||
`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef INC_ASSERT \
|
||||
__name: assume property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
`endif
|
||||
|
||||
// Assume an immediate property
|
||||
`define ASSUME_I(__name, __prop) \
|
||||
`ifdef INC_ASSERT \
|
||||
__name: assume (__prop) \
|
||||
else begin \
|
||||
`ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
|
||||
end \
|
||||
`endif
|
||||
|
||||
//////////////////////////////////
|
||||
// For formal verification only //
|
||||
//////////////////////////////////
|
||||
|
||||
// Note that the existing set of ASSERT macros specified above shall be used for FPV,
|
||||
// thereby ensuring that the assertions are evaluated during DV simulations as well.
|
||||
|
||||
// ASSUME_FPV
|
||||
// Assume a concurrent property during formal verification only.
|
||||
`define ASSUME_FPV(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef FPV_ON \
|
||||
`ASSUME(__name, __prop, __clk, __rst) \
|
||||
`endif
|
||||
|
||||
// ASSUME_I_FPV
|
||||
// Assume a concurrent property during formal verification only.
|
||||
`define ASSUME_I_FPV(__name, __prop) \
|
||||
`ifdef FPV_ON \
|
||||
`ASSUME_I(__name, __prop) \
|
||||
`endif
|
||||
|
||||
// COVER_FPV
|
||||
// Cover a concurrent property during formal verification
|
||||
`define COVER_FPV(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
|
||||
`ifdef FPV_ON \
|
||||
`COVER(__name, __prop, __clk, __rst) \
|
||||
`endif
|
||||
|
||||
`endif // PRIM_ASSERT_SV
|
221
vendor/pulp-platform/common_cells/include/common_cells/registers.svh
vendored
Normal file
221
vendor/pulp-platform/common_cells/include/common_cells/registers.svh
vendored
Normal file
|
@ -0,0 +1,221 @@
|
|||
// Copyright 2018, 2021 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
// SPDX-License-Identifier: SHL-0.51
|
||||
//
|
||||
// Author: Stefan Mach <smach@iis.ee.ethz.ch>
|
||||
// Description: Common register defines for RTL designs
|
||||
|
||||
`ifndef COMMON_CELLS_REGISTERS_SVH_
|
||||
`define COMMON_CELLS_REGISTERS_SVH_
|
||||
|
||||
// Abridged Summary of available FF macros:
|
||||
// `FF: asynchronous active-low reset
|
||||
// `FFAR: asynchronous active-high reset
|
||||
// `FFARN: [deprecated] asynchronous active-low reset
|
||||
// `FFSR: synchronous active-high reset
|
||||
// `FFSRN: synchronous active-low reset
|
||||
// `FFNR: without reset
|
||||
// `FFL: load-enable and asynchronous active-low reset
|
||||
// `FFLAR: load-enable and asynchronous active-high reset
|
||||
// `FFLARN: [deprecated] load-enable and asynchronous active-low reset
|
||||
// `FFLARNC: load-enable and asynchronous active-low reset and synchronous active-high clear
|
||||
// `FFLSR: load-enable and synchronous active-high reset
|
||||
// `FFLSRN: load-enable and synchronous active-low reset
|
||||
// `FFLNR: load-enable without reset
|
||||
|
||||
`ifdef VERILATOR
|
||||
`define NO_SYNOPSYS_FF 1
|
||||
`endif
|
||||
|
||||
`define REG_DFLT_CLK clk_i
|
||||
`define REG_DFLT_RST rst_ni
|
||||
|
||||
// Flip-Flop with asynchronous active-low reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// (__clk: clock input)
|
||||
// (__arst_n: asynchronous reset, active-low)
|
||||
`define FF(__q, __d, __reset_value, __clk = `REG_DFLT_CLK, __arst_n = `REG_DFLT_RST) \
|
||||
always_ff @(posedge (__clk) or negedge (__arst_n)) begin \
|
||||
if (!__arst_n) begin \
|
||||
__q <= (__reset_value); \
|
||||
end else begin \
|
||||
__q <= (__d); \
|
||||
end \
|
||||
end
|
||||
|
||||
// Flip-Flop with asynchronous active-high reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __arst: asynchronous reset, active-high
|
||||
`define FFAR(__q, __d, __reset_value, __clk, __arst) \
|
||||
always_ff @(posedge (__clk) or posedge (__arst)) begin \
|
||||
if (__arst) begin \
|
||||
__q <= (__reset_value); \
|
||||
end else begin \
|
||||
__q <= (__d); \
|
||||
end \
|
||||
end
|
||||
|
||||
// DEPRECATED - use `FF instead
|
||||
// Flip-Flop with asynchronous active-low reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __arst_n: asynchronous reset, active-low
|
||||
`define FFARN(__q, __d, __reset_value, __clk, __arst_n) \
|
||||
`FF(__q, __d, __reset_value, __clk, __arst_n)
|
||||
|
||||
// Flip-Flop with synchronous active-high reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __reset_clk: reset input, active-high
|
||||
`define FFSR(__q, __d, __reset_value, __clk, __reset_clk) \
|
||||
`ifndef NO_SYNOPSYS_FF \
|
||||
/``* synopsys sync_set_reset `"__reset_clk`" *``/ \
|
||||
`endif \
|
||||
always_ff @(posedge (__clk)) begin \
|
||||
__q <= (__reset_clk) ? (__reset_value) : (__d); \
|
||||
end
|
||||
|
||||
// Flip-Flop with synchronous active-low reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __reset_n_clk: reset input, active-low
|
||||
`define FFSRN(__q, __d, __reset_value, __clk, __reset_n_clk) \
|
||||
`ifndef NO_SYNOPSYS_FF \
|
||||
/``* synopsys sync_set_reset `"__reset_n_clk`" *``/ \
|
||||
`endif \
|
||||
always_ff @(posedge (__clk)) begin \
|
||||
__q <= (!__reset_n_clk) ? (__reset_value) : (__d); \
|
||||
end
|
||||
|
||||
// Always-enable Flip-Flop without reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __clk: clock input
|
||||
`define FFNR(__q, __d, __clk) \
|
||||
always_ff @(posedge (__clk)) begin \
|
||||
__q <= (__d); \
|
||||
end
|
||||
|
||||
// Flip-Flop with load-enable and asynchronous active-low reset (implicit clock and reset)
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// (__clk: clock input)
|
||||
// (__arst_n: asynchronous reset, active-low)
|
||||
`define FFL(__q, __d, __load, __reset_value, __clk = `REG_DFLT_CLK, __arst_n = `REG_DFLT_RST) \
|
||||
always_ff @(posedge (__clk) or negedge (__arst_n)) begin \
|
||||
if (!__arst_n) begin \
|
||||
__q <= (__reset_value); \
|
||||
end else begin \
|
||||
__q <= (__load) ? (__d) : (__q); \
|
||||
end \
|
||||
end
|
||||
|
||||
// Flip-Flop with load-enable and asynchronous active-high reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __arst: asynchronous reset, active-high
|
||||
`define FFLAR(__q, __d, __load, __reset_value, __clk, __arst) \
|
||||
always_ff @(posedge (__clk) or posedge (__arst)) begin \
|
||||
if (__arst) begin \
|
||||
__q <= (__reset_value); \
|
||||
end else begin \
|
||||
__q <= (__load) ? (__d) : (__q); \
|
||||
end \
|
||||
end
|
||||
|
||||
// DEPRECATED - use `FFL instead
|
||||
// Flip-Flop with load-enable and asynchronous active-low reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __arst_n: asynchronous reset, active-low
|
||||
`define FFLARN(__q, __d, __load, __reset_value, __clk, __arst_n) \
|
||||
`FFL(__q, __d, __load, __reset_value, __clk, __arst_n)
|
||||
|
||||
// Flip-Flop with load-enable and synchronous active-high reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __reset_clk: reset input, active-high
|
||||
`define FFLSR(__q, __d, __load, __reset_value, __clk, __reset_clk) \
|
||||
`ifndef NO_SYNOPSYS_FF \
|
||||
/``* synopsys sync_set_reset `"__reset_clk`" *``/ \
|
||||
`endif \
|
||||
always_ff @(posedge (__clk)) begin \
|
||||
__q <= (__reset_clk) ? (__reset_value) : ((__load) ? (__d) : (__q)); \
|
||||
end
|
||||
|
||||
// Flip-Flop with load-enable and synchronous active-low reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __reset_n_clk: reset input, active-low
|
||||
`define FFLSRN(__q, __d, __load, __reset_value, __clk, __reset_n_clk) \
|
||||
`ifndef NO_SYNOPSYS_FF \
|
||||
/``* synopsys sync_set_reset `"__reset_n_clk`" *``/ \
|
||||
`endif \
|
||||
always_ff @(posedge (__clk)) begin \
|
||||
__q <= (!__reset_n_clk) ? (__reset_value) : ((__load) ? (__d) : (__q)); \
|
||||
end
|
||||
|
||||
// Flip-Flop with load-enable and asynchronous active-low reset and synchronous clear
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __clear: assign reset value into FF
|
||||
// __reset_value: value assigned upon reset
|
||||
// __clk: clock input
|
||||
// __arst_n: asynchronous reset, active-low
|
||||
`define FFLARNC(__q, __d, __load, __clear, __reset_value, __clk, __arst_n) \
|
||||
`ifndef NO_SYNOPSYS_FF \
|
||||
/``* synopsys sync_set_reset `"__clear`" *``/ \
|
||||
`endif \
|
||||
always_ff @(posedge (__clk) or negedge (__arst_n)) begin \
|
||||
if (!__arst_n) begin \
|
||||
__q <= (__reset_value); \
|
||||
end else begin \
|
||||
__q <= (__clear) ? (__reset_value) : (__load) ? (__d) : (__q); \
|
||||
end \
|
||||
end
|
||||
|
||||
// Load-enable Flip-Flop without reset
|
||||
// __q: Q output of FF
|
||||
// __d: D input of FF
|
||||
// __load: load d value into FF
|
||||
// __clk: clock input
|
||||
`define FFLNR(__q, __d, __load, __clk) \
|
||||
always_ff @(posedge (__clk)) begin \
|
||||
__q <= (__load) ? (__d) : (__q); \
|
||||
end
|
||||
|
||||
`endif
|
161
vendor/pulp-platform/common_cells/src/addr_decode.sv
vendored
Normal file
161
vendor/pulp-platform/common_cells/src/addr_decode.sv
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
// Copyright 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Wolfgang Roenninger <wroennin@ethz.ch>
|
||||
|
||||
/// Address Decoder: Maps the input address combinatorially to an index.
|
||||
/// The address map `addr_map_i` is a packed array of rule_t structs.
|
||||
/// The ranges of any two rules may overlap. If so, the rule at the higher (more significant)
|
||||
/// position in `addr_map_i` prevails.
|
||||
///
|
||||
/// There can be an arbitrary number of address rules. There can be multiple
|
||||
/// ranges defined for the same index. The start address has to be less than the end address.
|
||||
///
|
||||
/// There is the possibility to add a default mapping:
|
||||
/// `en_default_idx_i`: Driving this port to `1'b1` maps all input addresses
|
||||
/// for which no rule in `addr_map_i` exists to the default index specified by
|
||||
/// `default_idx_i`. In this case, `dec_error_o` is always `1'b0`.
|
||||
///
|
||||
/// Assertions: The module checks every time there is a change in the address mapping
|
||||
/// if the resulting map is valid. It fatals if `start_addr` is higher than `end_addr`
|
||||
/// or if a mapping targets an index that is outside the number of allowed indices.
|
||||
/// It issues warnings if the address regions of any two mappings overlap.
|
||||
module 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,
|
||||
/// Address type inside the rules and to decode.
|
||||
parameter type addr_t = logic,
|
||||
/// Rule packed struct type.
|
||||
/// The address decoder expects three fields in `rule_t`:
|
||||
///
|
||||
/// typedef struct packed {
|
||||
/// int unsigned idx;
|
||||
/// addr_t start_addr;
|
||||
/// addr_t end_addr;
|
||||
/// } rule_t;
|
||||
///
|
||||
/// - `idx`: index of the rule, has to be < `NoIndices`
|
||||
/// - `start_addr`: start address of the range the rule describes, value is included in range
|
||||
/// - `end_addr`: end address of the range the rule describes, value is NOT included in range
|
||||
parameter type rule_t = logic,
|
||||
/// Dependent parameter, do **not** overwite!
|
||||
///
|
||||
/// Width of the `idx_o` output port.
|
||||
parameter int unsigned IdxWidth = cf_math_pkg::idx_width(NoIndices),
|
||||
/// Dependent parameter, do **not** overwite!
|
||||
///
|
||||
/// Type of the `idx_o` output port.
|
||||
parameter type idx_t = logic [IdxWidth-1:0]
|
||||
) (
|
||||
/// Address to decode.
|
||||
input addr_t addr_i,
|
||||
/// Address map: rule with the highest array position wins on collision
|
||||
input rule_t [NoRules-1:0] addr_map_i,
|
||||
/// Decoded index.
|
||||
output idx_t idx_o,
|
||||
/// Decode is valid.
|
||||
output logic dec_valid_o,
|
||||
/// Decode is not valid, no matching rule found.
|
||||
output logic dec_error_o,
|
||||
/// Enable default port mapping.
|
||||
///
|
||||
/// When not used, tie to `0`.
|
||||
input logic en_default_idx_i,
|
||||
/// Default port index.
|
||||
///
|
||||
/// When `en_default_idx_i` is `1`, this will be the index when no rule matches.
|
||||
///
|
||||
/// When not used, tie to `0`.
|
||||
input idx_t default_idx_i
|
||||
);
|
||||
|
||||
logic [NoRules-1:0] matched_rules; // purely for address map debugging
|
||||
|
||||
always_comb begin
|
||||
// default assignments
|
||||
matched_rules = '0;
|
||||
dec_valid_o = 1'b0;
|
||||
dec_error_o = (en_default_idx_i) ? 1'b0 : 1'b1;
|
||||
idx_o = (en_default_idx_i) ? default_idx_i : '0;
|
||||
|
||||
// match the rules
|
||||
for (int unsigned i = 0; i < NoRules; i++) begin
|
||||
if ((addr_i >= addr_map_i[i].start_addr) && (addr_i < addr_map_i[i].end_addr)) begin
|
||||
matched_rules[i] = 1'b1;
|
||||
dec_valid_o = 1'b1;
|
||||
dec_error_o = 1'b0;
|
||||
idx_o = idx_t'(addr_map_i[i].idx);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Assumptions and assertions
|
||||
`ifndef VERILATOR
|
||||
`ifndef XSIM
|
||||
// pragma translate_off
|
||||
initial begin : proc_check_parameters
|
||||
assume ($bits(addr_i) == $bits(addr_map_i[0].start_addr)) else
|
||||
$warning($sformatf("Input address has %d bits and address map has %d bits.",
|
||||
$bits(addr_i), $bits(addr_map_i[0].start_addr)));
|
||||
assume (NoRules > 0) else
|
||||
$fatal(1, $sformatf("At least one rule needed"));
|
||||
assume (NoIndices > 0) else
|
||||
$fatal(1, $sformatf("At least one index needed"));
|
||||
end
|
||||
|
||||
assert final ($onehot0(matched_rules)) else
|
||||
$warning("More than one bit set in the one-hot signal, matched_rules");
|
||||
|
||||
// These following assumptions check the validity of the address map.
|
||||
// The assumptions gets generated for each distinct pair of rules.
|
||||
// Each assumption is present two times, as they rely on one rules being
|
||||
// effectively ordered. Only one of the rules with the same function is
|
||||
// active at a time for a given pair.
|
||||
// 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.
|
||||
always @(addr_map_i) #0 begin : proc_check_addr_map
|
||||
if (!$isunknown(addr_map_i)) begin
|
||||
for (int unsigned i = 0; i < NoRules; i++) begin
|
||||
check_start : assume (addr_map_i[i].start_addr < addr_map_i[i].end_addr) else
|
||||
$fatal(1, $sformatf("This rule has a higher start than end address!!!\n\
|
||||
Violating rule %d.\n\
|
||||
Rule> IDX: %h START: %h END: %h\n\
|
||||
#####################################################",
|
||||
i ,addr_map_i[i].idx, addr_map_i[i].start_addr, addr_map_i[i].end_addr));
|
||||
// check the SLV ids
|
||||
check_idx : assume (addr_map_i[i].idx < NoIndices) else
|
||||
$fatal(1, $sformatf("This rule has a IDX that is not allowed!!!\n\
|
||||
Violating rule %d.\n\
|
||||
Rule> IDX: %h START: %h END: %h\n\
|
||||
Rule> MAX_IDX: %h\n\
|
||||
#####################################################",
|
||||
i, addr_map_i[i].idx, addr_map_i[i].start_addr, addr_map_i[i].end_addr,
|
||||
(NoIndices-1)));
|
||||
for (int unsigned j = i + 1; j < NoRules; j++) begin
|
||||
// overlap check
|
||||
check_overlap : assume (!((addr_map_i[j].start_addr < addr_map_i[i].end_addr) &&
|
||||
(addr_map_i[j].end_addr > addr_map_i[i].start_addr))) else
|
||||
$warning($sformatf("Overlapping address region found!!!\n\
|
||||
Rule %d: IDX: %h START: %h END: %h\n\
|
||||
Rule %d: IDX: %h START: %h END: %h\n\
|
||||
#####################################################",
|
||||
i, addr_map_i[i].idx, addr_map_i[i].start_addr, addr_map_i[i].end_addr,
|
||||
j, addr_map_i[j].idx, addr_map_i[j].start_addr, addr_map_i[j].end_addr));
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
// pragma translate_on
|
||||
`endif
|
||||
`endif
|
||||
endmodule
|
22
vendor/pulp-platform/common_cells/src/binary_to_gray.sv
vendored
Normal file
22
vendor/pulp-platform/common_cells/src/binary_to_gray.sv
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
|
||||
/// A binary to gray code converter.
|
||||
module binary_to_gray #(
|
||||
parameter int N = -1
|
||||
)(
|
||||
input logic [N-1:0] A,
|
||||
output logic [N-1:0] Z
|
||||
);
|
||||
assign Z = A ^ (A >> 1);
|
||||
endmodule
|
246
vendor/pulp-platform/common_cells/src/cb_filter.sv
vendored
Normal file
246
vendor/pulp-platform/common_cells/src/cb_filter.sv
vendored
Normal file
|
@ -0,0 +1,246 @@
|
|||
// Copyright (c) 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Wolfgang Roenninger <wroennin@ethz.ch>
|
||||
|
||||
// `cb_filter`: This module implements a counting bloom filter with parameterizable hash functions.
|
||||
//
|
||||
// Functionality: A counting bloom filter is a data structure to efficiently implement
|
||||
// set lookups. It does so by hashing its data inputs onto multiple pointers
|
||||
// which serve as indicators for an array of buckets. For lookups can be
|
||||
// false positives, but no false negatives.
|
||||
// - Seeding: The pseudo random generators need seeds at elaboration time to generate
|
||||
// different hashes. In principle any combination of seeds can be used.
|
||||
// But one should look that the hash outputs give sufficient different patterns,
|
||||
// such that the resulting collision rate is low. The package `cb_filter_pkg`
|
||||
// contains the struct for seeding the PRG's in the hash functions.
|
||||
// - Lookup:
|
||||
// - Ports: `look_data_i`, `look_valid_o`
|
||||
// - Description: Lookup combinational, `look_valid_o` is high, when `look_data_i` was
|
||||
// previously put into the filter.
|
||||
// - Increment:
|
||||
// - Ports: `incr_data_i`, `incr_valid_i`
|
||||
// - Description: Put data into the counting bloom filter, when valid is high.
|
||||
// - Decrement:
|
||||
// - Ports: `decr_data_i`, `decr_valid_i`
|
||||
// - Description: Remove data from the counting bloom filter. Only remove data that was
|
||||
// previously put in, otherwise will go in a wrong state.
|
||||
// - Status:
|
||||
// - `filter_clear_i`: Clears the filter and sets all counters to 0.
|
||||
// - `filter_ussage_o`: How many data items are currently in the filter.
|
||||
// - `filter_full_o`: Filter is full, can no longer hold more items.
|
||||
// - `filter_empty_o`: Filter is empty.
|
||||
// - `filter_error_o`: One of the internal counters or buckets overflowed.
|
||||
|
||||
/// This is a counting bloom filter
|
||||
module cb_filter #(
|
||||
parameter int unsigned KHashes = 32'd3, // Number of hash functions
|
||||
parameter int unsigned HashWidth = 32'd4, // Number of counters is 2**HashWidth
|
||||
parameter int unsigned HashRounds = 32'd1, // Number of permutation substitution rounds
|
||||
parameter int unsigned InpWidth = 32'd32, // Input data width
|
||||
parameter int unsigned BucketWidth = 32'd4, // Width of Bucket counters
|
||||
// the seeds used for seeding the PRG's inside each hash, one `cb_seed_t` per hash function.
|
||||
parameter cb_filter_pkg::cb_seed_t [KHashes-1:0] Seeds = cb_filter_pkg::EgSeeds
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Active low reset
|
||||
// data lookup
|
||||
input logic [InpWidth-1:0] look_data_i,
|
||||
output logic look_valid_o,
|
||||
// data increment
|
||||
input logic [InpWidth-1:0] incr_data_i,
|
||||
input logic incr_valid_i,
|
||||
// data decrement
|
||||
input logic [InpWidth-1:0] decr_data_i,
|
||||
input logic decr_valid_i,
|
||||
// status signals
|
||||
input logic filter_clear_i,
|
||||
output logic [HashWidth-1:0] filter_usage_o,
|
||||
output logic filter_full_o,
|
||||
output logic filter_empty_o,
|
||||
output logic filter_error_o
|
||||
);
|
||||
|
||||
localparam int unsigned NoCounters = 2**HashWidth;
|
||||
|
||||
// signal declarations
|
||||
logic [NoCounters-1:0] look_ind; // hash function pointers
|
||||
logic [NoCounters-1:0] incr_ind; // hash function pointers
|
||||
logic [NoCounters-1:0] decr_ind; // hash function pointers
|
||||
// bucket (counter signals)
|
||||
logic [NoCounters-1:0] bucket_en;
|
||||
logic [NoCounters-1:0] bucket_down;
|
||||
logic [NoCounters-1:0] bucket_occupied;
|
||||
logic [NoCounters-1:0] bucket_overflow;
|
||||
logic [NoCounters-1:0] bucket_full;
|
||||
logic [NoCounters-1:0] bucket_empty;
|
||||
// membership lookup signals
|
||||
logic [NoCounters-1:0] data_in_bucket;
|
||||
// tot count signals (filter usage)
|
||||
logic cnt_en;
|
||||
logic cnt_down;
|
||||
logic cnt_overflow;
|
||||
|
||||
// -----------------------------------------
|
||||
// Lookup Hash - Membership Detection
|
||||
// -----------------------------------------
|
||||
hash_block #(
|
||||
.NoHashes ( KHashes ),
|
||||
.InpWidth ( InpWidth ),
|
||||
.HashWidth ( HashWidth ),
|
||||
.NoRounds ( HashRounds ),
|
||||
.Seeds ( Seeds )
|
||||
) i_look_hashes (
|
||||
.data_i ( look_data_i ),
|
||||
.indicator_o ( look_ind )
|
||||
);
|
||||
assign data_in_bucket = look_ind & bucket_occupied;
|
||||
assign look_valid_o = (data_in_bucket == look_ind) ? 1'b1 : 1'b0;
|
||||
|
||||
// -----------------------------------------
|
||||
// Increment Hash - Add Member to Set
|
||||
// -----------------------------------------
|
||||
hash_block #(
|
||||
.NoHashes ( KHashes ),
|
||||
.InpWidth ( InpWidth ),
|
||||
.HashWidth ( HashWidth ),
|
||||
.NoRounds ( HashRounds ),
|
||||
.Seeds ( Seeds )
|
||||
) i_incr_hashes (
|
||||
.data_i ( incr_data_i ),
|
||||
.indicator_o ( incr_ind )
|
||||
);
|
||||
|
||||
// -----------------------------------------
|
||||
// Decrement Hash - Remove Member from Set
|
||||
// -----------------------------------------
|
||||
hash_block #(
|
||||
.NoHashes ( KHashes ),
|
||||
.InpWidth ( InpWidth ),
|
||||
.HashWidth ( HashWidth ),
|
||||
.NoRounds ( HashRounds ),
|
||||
.Seeds ( Seeds )
|
||||
) i_decr_hashes (
|
||||
.data_i ( decr_data_i ),
|
||||
.indicator_o ( decr_ind )
|
||||
);
|
||||
|
||||
// -----------------------------------------
|
||||
// Control the incr/decr of buckets
|
||||
// -----------------------------------------
|
||||
assign bucket_down = decr_valid_i ? decr_ind : '0;
|
||||
|
||||
always_comb begin : proc_bucket_control
|
||||
case ({incr_valid_i, decr_valid_i})
|
||||
2'b00 : bucket_en = '0;
|
||||
2'b10 : bucket_en = incr_ind;
|
||||
2'b01 : bucket_en = decr_ind;
|
||||
2'b11 : bucket_en = incr_ind ^ decr_ind;
|
||||
default: bucket_en = '0; // unreachable
|
||||
endcase
|
||||
end
|
||||
|
||||
// -----------------------------------------
|
||||
// Counters
|
||||
// -----------------------------------------
|
||||
for (genvar i = 0; i < NoCounters; i++) begin : gen_buckets
|
||||
logic [BucketWidth-1:0] bucket_content;
|
||||
counter #(
|
||||
.WIDTH( BucketWidth )
|
||||
) i_bucket (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.clear_i ( filter_clear_i ),
|
||||
.en_i ( bucket_en[i] ),
|
||||
.load_i ( '0 ),
|
||||
.down_i ( bucket_down[i] ),
|
||||
.d_i ( '0 ),
|
||||
.q_o ( bucket_content ),
|
||||
.overflow_o ( bucket_overflow[i])
|
||||
);
|
||||
assign bucket_full[i] = bucket_overflow[i] | (&bucket_content);
|
||||
assign bucket_occupied[i] = |bucket_content;
|
||||
assign bucket_empty[i] = ~bucket_occupied[i];
|
||||
end
|
||||
|
||||
// -----------------------------------------
|
||||
// Filter tot item counter
|
||||
// -----------------------------------------
|
||||
assign cnt_en = incr_valid_i ^ decr_valid_i;
|
||||
assign cnt_down = decr_valid_i;
|
||||
counter #(
|
||||
.WIDTH ( HashWidth )
|
||||
) i_tot_count (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.clear_i ( filter_clear_i ),
|
||||
.en_i ( cnt_en ),
|
||||
.load_i ( '0 ),
|
||||
.down_i ( cnt_down ),
|
||||
.d_i ( '0 ),
|
||||
.q_o ( filter_usage_o ),
|
||||
.overflow_o( cnt_overflow )
|
||||
);
|
||||
|
||||
// -----------------------------------------
|
||||
// Filter Output Flags
|
||||
// -----------------------------------------
|
||||
assign filter_full_o = |bucket_full;
|
||||
assign filter_empty_o = &bucket_empty;
|
||||
assign filter_error_o = |bucket_overflow | cnt_overflow;
|
||||
endmodule
|
||||
|
||||
// gives out the or 'onehots' of all hash functions
|
||||
module hash_block #(
|
||||
parameter int unsigned NoHashes = 32'd3,
|
||||
parameter int unsigned InpWidth = 32'd11,
|
||||
parameter int unsigned HashWidth = 32'd5,
|
||||
parameter int unsigned NoRounds = 32'd1,
|
||||
parameter cb_filter_pkg::cb_seed_t [NoHashes-1:0] Seeds = cb_filter_pkg::EgSeeds
|
||||
) (
|
||||
input logic [InpWidth-1:0] data_i,
|
||||
output logic [2**HashWidth-1:0] indicator_o
|
||||
);
|
||||
|
||||
logic [NoHashes-1:0][2**HashWidth-1:0] hashes;
|
||||
|
||||
for (genvar i = 0; i < NoHashes; i++) begin : gen_hashes
|
||||
sub_per_hash #(
|
||||
.InpWidth ( InpWidth ),
|
||||
.HashWidth ( HashWidth ),
|
||||
.NoRounds ( NoRounds ),
|
||||
.PermuteKey ( Seeds[i].PermuteSeed ),
|
||||
.XorKey ( Seeds[i].XorSeed )
|
||||
) i_hash (
|
||||
.data_i ( data_i ),
|
||||
.hash_o ( ), // not used, because we want the onehot
|
||||
.hash_onehot_o ( hashes[i] )
|
||||
);
|
||||
end
|
||||
|
||||
// output assignment
|
||||
always_comb begin : proc_hash_or
|
||||
indicator_o = '0;
|
||||
for (int unsigned i = 0; i < (2**HashWidth); i++) begin
|
||||
for (int unsigned j = 0; j < NoHashes; j++) begin
|
||||
indicator_o[i] = indicator_o[i] | hashes[j][i];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// assertions
|
||||
// pragma translate_off
|
||||
initial begin
|
||||
hash_conf: assume (InpWidth > HashWidth) else
|
||||
$fatal(1, "%m:\nA Hash Function reduces the width of the input>\nInpWidth: %s\nOUT_WIDTH: %s",
|
||||
InpWidth, HashWidth);
|
||||
end
|
||||
// pragma translate_on
|
||||
endmodule
|
26
vendor/pulp-platform/common_cells/src/cb_filter_pkg.sv
vendored
Normal file
26
vendor/pulp-platform/common_cells/src/cb_filter_pkg.sv
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Wolfgang Roenninger <wroennin@ethz.ch>
|
||||
|
||||
/// Package with the struct definition for the seeds and an example.
|
||||
package cb_filter_pkg;
|
||||
typedef struct packed {
|
||||
int unsigned PermuteSeed;
|
||||
int unsigned XorSeed;
|
||||
} cb_seed_t;
|
||||
|
||||
// example seeding struct
|
||||
localparam cb_seed_t [2:0] EgSeeds = '{
|
||||
'{PermuteSeed: 32'd299034753, XorSeed: 32'd4094834 },
|
||||
'{PermuteSeed: 32'd19921030, XorSeed: 32'd995713 },
|
||||
'{PermuteSeed: 32'd294388, XorSeed: 32'd65146511 }
|
||||
};
|
||||
endpackage
|
50
vendor/pulp-platform/common_cells/src/cc_onehot.sv
vendored
Normal file
50
vendor/pulp-platform/common_cells/src/cc_onehot.sv
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2021 ETH Zurich.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/// Hardware implementation of SystemVerilog's `$onehot()` function.
|
||||
/// It uses a tree of half adders and a separate
|
||||
/// or reduction tree for the carry.
|
||||
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
// Author: Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
// Author: Stefan Mach <smach@iis.ee.ethz.ch>
|
||||
module cc_onehot #(
|
||||
parameter int unsigned Width = 4
|
||||
) (
|
||||
input logic [Width-1:0] d_i,
|
||||
output logic is_onehot_o
|
||||
);
|
||||
// trivial base case
|
||||
if (Width == 1) begin : gen_degenerated_onehot
|
||||
assign is_onehot_o = d_i;
|
||||
end else begin : gen_onehot
|
||||
localparam int LVLS = $clog2(Width) + 1;
|
||||
|
||||
logic [LVLS-1:0][2**(LVLS-1)-1:0] sum, carry;
|
||||
logic [LVLS-2:0] carry_array;
|
||||
|
||||
// Extend to a power of two.
|
||||
assign sum[0] = $unsigned(d_i);
|
||||
|
||||
// generate half adders for each lvl
|
||||
// lvl 0 is the input level
|
||||
for (genvar i = 1; i < LVLS; i++) begin : gen_lvl
|
||||
localparam int unsigned LVLWidth = 2**LVLS / 2**i;
|
||||
for (genvar j = 0; j < LVLWidth; j+=2) begin : gen_width
|
||||
assign sum[i][j/2] = sum[i-1][j] ^ sum[i-1][j+1];
|
||||
assign carry[i][j/2] = sum[i-1][j] & sum[i-1][j+1];
|
||||
end
|
||||
// generate carry tree
|
||||
assign carry_array[i-1] = |carry[i][LVLWidth/2-1:0];
|
||||
end
|
||||
assign is_onehot_o = sum[LVLS-1][0] & ~|carry_array;
|
||||
end
|
||||
|
||||
endmodule
|
175
vendor/pulp-platform/common_cells/src/cdc_2phase.sv
vendored
Normal file
175
vendor/pulp-platform/common_cells/src/cdc_2phase.sv
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
|
||||
/// A two-phase clock domain crossing.
|
||||
///
|
||||
/// CONSTRAINT: Requires max_delay of min_period(src_clk_i, dst_clk_i) through
|
||||
/// the paths async_req, async_ack, async_data.
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
module cdc_2phase #(
|
||||
parameter type T = logic
|
||||
)(
|
||||
input logic src_rst_ni,
|
||||
input logic src_clk_i,
|
||||
input T src_data_i,
|
||||
input logic src_valid_i,
|
||||
output logic src_ready_o,
|
||||
|
||||
input logic dst_rst_ni,
|
||||
input logic dst_clk_i,
|
||||
output T dst_data_o,
|
||||
output logic dst_valid_o,
|
||||
input logic dst_ready_i
|
||||
);
|
||||
|
||||
// Asynchronous handshake signals.
|
||||
(* dont_touch = "true" *) logic async_req;
|
||||
(* dont_touch = "true" *) logic async_ack;
|
||||
(* dont_touch = "true" *) T async_data;
|
||||
|
||||
// The sender in the source domain.
|
||||
cdc_2phase_src #(.T(T)) i_src (
|
||||
.rst_ni ( src_rst_ni ),
|
||||
.clk_i ( src_clk_i ),
|
||||
.data_i ( src_data_i ),
|
||||
.valid_i ( src_valid_i ),
|
||||
.ready_o ( src_ready_o ),
|
||||
.async_req_o ( async_req ),
|
||||
.async_ack_i ( async_ack ),
|
||||
.async_data_o ( async_data )
|
||||
);
|
||||
|
||||
// The receiver in the destination domain.
|
||||
cdc_2phase_dst #(.T(T)) i_dst (
|
||||
.rst_ni ( dst_rst_ni ),
|
||||
.clk_i ( dst_clk_i ),
|
||||
.data_o ( dst_data_o ),
|
||||
.valid_o ( dst_valid_o ),
|
||||
.ready_i ( dst_ready_i ),
|
||||
.async_req_i ( async_req ),
|
||||
.async_ack_o ( async_ack ),
|
||||
.async_data_i ( async_data )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
/// Half of the two-phase clock domain crossing located in the source domain.
|
||||
module cdc_2phase_src #(
|
||||
parameter type T = logic
|
||||
)(
|
||||
input logic rst_ni,
|
||||
input logic clk_i,
|
||||
input T data_i,
|
||||
input logic valid_i,
|
||||
output logic ready_o,
|
||||
output logic async_req_o,
|
||||
input logic async_ack_i,
|
||||
output T async_data_o
|
||||
);
|
||||
|
||||
(* dont_touch = "true" *)
|
||||
logic req_src_q, ack_src_q, ack_q;
|
||||
(* dont_touch = "true" *)
|
||||
T data_src_q;
|
||||
|
||||
// The req_src and data_src registers change when a new data item is accepted.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
req_src_q <= 0;
|
||||
data_src_q <= '0;
|
||||
end else if (valid_i && ready_o) begin
|
||||
req_src_q <= ~req_src_q;
|
||||
data_src_q <= data_i;
|
||||
end
|
||||
end
|
||||
|
||||
// The ack_src and ack registers act as synchronization stages.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
ack_src_q <= 0;
|
||||
ack_q <= 0;
|
||||
end else begin
|
||||
ack_src_q <= async_ack_i;
|
||||
ack_q <= ack_src_q;
|
||||
end
|
||||
end
|
||||
|
||||
// Output assignments.
|
||||
assign ready_o = (req_src_q == ack_q);
|
||||
assign async_req_o = req_src_q;
|
||||
assign async_data_o = data_src_q;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
/// Half of the two-phase clock domain crossing located in the destination
|
||||
/// domain.
|
||||
module cdc_2phase_dst #(
|
||||
parameter type T = logic
|
||||
)(
|
||||
input logic rst_ni,
|
||||
input logic clk_i,
|
||||
output T data_o,
|
||||
output logic valid_o,
|
||||
input logic ready_i,
|
||||
input logic async_req_i,
|
||||
output logic async_ack_o,
|
||||
input T async_data_i
|
||||
);
|
||||
|
||||
(* dont_touch = "true" *)
|
||||
(* async_reg = "true" *)
|
||||
logic req_dst_q, req_q0, req_q1, ack_dst_q;
|
||||
(* dont_touch = "true" *)
|
||||
T data_dst_q;
|
||||
|
||||
// The ack_dst register changes when a new data item is accepted.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
ack_dst_q <= 0;
|
||||
end else if (valid_o && ready_i) begin
|
||||
ack_dst_q <= ~ack_dst_q;
|
||||
end
|
||||
end
|
||||
|
||||
// The data_dst register changes when a new data item is presented. This is
|
||||
// indicated by the async_req line changing levels.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
data_dst_q <= '0;
|
||||
end else if (req_q0 != req_q1 && !valid_o) begin
|
||||
data_dst_q <= async_data_i;
|
||||
end
|
||||
end
|
||||
|
||||
// The req_dst and req registers act as synchronization stages.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
req_dst_q <= 0;
|
||||
req_q0 <= 0;
|
||||
req_q1 <= 0;
|
||||
end else begin
|
||||
req_dst_q <= async_req_i;
|
||||
req_q0 <= req_dst_q;
|
||||
req_q1 <= req_q0;
|
||||
end
|
||||
end
|
||||
|
||||
// Output assignments.
|
||||
assign valid_o = (ack_dst_q != req_q1);
|
||||
assign data_o = data_dst_q;
|
||||
assign async_ack_o = ack_dst_q;
|
||||
|
||||
endmodule
|
||||
/* verilator lint_on DECLFILENAME */
|
134
vendor/pulp-platform/common_cells/src/cdc_fifo_2phase.sv
vendored
Normal file
134
vendor/pulp-platform/common_cells/src/cdc_fifo_2phase.sv
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
|
||||
/// A clock domain crossing FIFO, using 2-phase hand shakes.
|
||||
///
|
||||
/// This FIFO has its push and pop ports in two separate clock domains. Its size
|
||||
/// can only be powers of two, which is why its depth is given as 2**LOG_DEPTH.
|
||||
/// LOG_DEPTH must be at least 1.
|
||||
///
|
||||
/// CONSTRAINT: See the constraints for `cdc_2phase`. An additional maximum
|
||||
/// delay path needs to be specified from fifo_data_q to dst_data_o.
|
||||
module cdc_fifo_2phase #(
|
||||
/// The data type of the payload transported by the FIFO.
|
||||
parameter type T = logic,
|
||||
/// The FIFO's depth given as 2**LOG_DEPTH.
|
||||
parameter int LOG_DEPTH = 3
|
||||
)(
|
||||
input logic src_rst_ni,
|
||||
input logic src_clk_i,
|
||||
input T src_data_i,
|
||||
input logic src_valid_i,
|
||||
output logic src_ready_o,
|
||||
|
||||
input logic dst_rst_ni,
|
||||
input logic dst_clk_i,
|
||||
output T dst_data_o,
|
||||
output logic dst_valid_o,
|
||||
input logic dst_ready_i
|
||||
);
|
||||
|
||||
// Check the invariants.
|
||||
//pragma translate_off
|
||||
initial begin
|
||||
assert(LOG_DEPTH > 0);
|
||||
end
|
||||
//pragma translate_on
|
||||
|
||||
localparam int PtrWidth = LOG_DEPTH+1;
|
||||
typedef logic [PtrWidth-1:0] pointer_t;
|
||||
typedef logic [LOG_DEPTH-1:0] index_t;
|
||||
|
||||
localparam pointer_t PtrFull = (1 << LOG_DEPTH);
|
||||
localparam pointer_t PtrEmpty = '0;
|
||||
|
||||
// Allocate the registers for the FIFO memory with its separate write and read
|
||||
// ports. The FIFO has the following ports:
|
||||
//
|
||||
// - write: fifo_widx, fifo_wdata, fifo_write, src_clk_i
|
||||
// - read: fifo_ridx, fifo_rdata
|
||||
index_t fifo_widx, fifo_ridx;
|
||||
logic fifo_write;
|
||||
T fifo_wdata, fifo_rdata;
|
||||
T fifo_data_q [2**LOG_DEPTH];
|
||||
|
||||
assign fifo_rdata = fifo_data_q[fifo_ridx];
|
||||
|
||||
for (genvar i = 0; i < 2**LOG_DEPTH; i++) begin : g_word
|
||||
always_ff @(posedge src_clk_i, negedge src_rst_ni) begin
|
||||
if (!src_rst_ni)
|
||||
fifo_data_q[i] <= '0;
|
||||
else if (fifo_write && fifo_widx == i)
|
||||
fifo_data_q[i] <= fifo_wdata;
|
||||
end
|
||||
end
|
||||
|
||||
// Allocate the read and write pointers in the source and destination domain.
|
||||
pointer_t src_wptr_q, dst_wptr, src_rptr, dst_rptr_q;
|
||||
|
||||
always_ff @(posedge src_clk_i, negedge src_rst_ni) begin
|
||||
if (!src_rst_ni)
|
||||
src_wptr_q <= 0;
|
||||
else if (src_valid_i && src_ready_o)
|
||||
src_wptr_q <= src_wptr_q + 1;
|
||||
end
|
||||
|
||||
always_ff @(posedge dst_clk_i, negedge dst_rst_ni) begin
|
||||
if (!dst_rst_ni)
|
||||
dst_rptr_q <= 0;
|
||||
else if (dst_valid_o && dst_ready_i)
|
||||
dst_rptr_q <= dst_rptr_q + 1;
|
||||
end
|
||||
|
||||
// The pointers into the FIFO are one bit wider than the actual address into
|
||||
// the FIFO. This makes detecting critical states very simple: if all but the
|
||||
// topmost bit of rptr and wptr agree, the FIFO is in a critical state. If the
|
||||
// topmost bit is equal, the FIFO is empty, otherwise it is full.
|
||||
assign src_ready_o = ((src_wptr_q ^ src_rptr) != PtrFull);
|
||||
assign dst_valid_o = ((dst_rptr_q ^ dst_wptr) != PtrEmpty);
|
||||
|
||||
// Transport the read and write pointers across the clock domain boundary.
|
||||
cdc_2phase #( .T(pointer_t) ) i_cdc_wptr (
|
||||
.src_rst_ni ( src_rst_ni ),
|
||||
.src_clk_i ( src_clk_i ),
|
||||
.src_data_i ( src_wptr_q ),
|
||||
.src_valid_i ( 1'b1 ),
|
||||
.src_ready_o ( ),
|
||||
.dst_rst_ni ( dst_rst_ni ),
|
||||
.dst_clk_i ( dst_clk_i ),
|
||||
.dst_data_o ( dst_wptr ),
|
||||
.dst_valid_o ( ),
|
||||
.dst_ready_i ( 1'b1 )
|
||||
);
|
||||
|
||||
cdc_2phase #( .T(pointer_t) ) i_cdc_rptr (
|
||||
.src_rst_ni ( dst_rst_ni ),
|
||||
.src_clk_i ( dst_clk_i ),
|
||||
.src_data_i ( dst_rptr_q ),
|
||||
.src_valid_i ( 1'b1 ),
|
||||
.src_ready_o ( ),
|
||||
.dst_rst_ni ( src_rst_ni ),
|
||||
.dst_clk_i ( src_clk_i ),
|
||||
.dst_data_o ( src_rptr ),
|
||||
.dst_valid_o ( ),
|
||||
.dst_ready_i ( 1'b1 )
|
||||
);
|
||||
|
||||
// Drive the FIFO write and read ports.
|
||||
assign fifo_widx = src_wptr_q;
|
||||
assign fifo_wdata = src_data_i;
|
||||
assign fifo_write = src_valid_i && src_ready_o;
|
||||
assign fifo_ridx = dst_rptr_q;
|
||||
assign dst_data_o = fifo_rdata;
|
||||
|
||||
endmodule
|
269
vendor/pulp-platform/common_cells/src/cdc_fifo_gray.sv
vendored
Normal file
269
vendor/pulp-platform/common_cells/src/cdc_fifo_gray.sv
vendored
Normal file
|
@ -0,0 +1,269 @@
|
|||
// Copyright 2018-2019 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
// Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
/// A clock domain crossing FIFO, using gray counters.
|
||||
///
|
||||
/// # Architecture
|
||||
///
|
||||
/// The design is split into two parts, each one being clocked and reset
|
||||
/// separately.
|
||||
/// 1. The data to be transferred over the clock domain boundary is
|
||||
/// is stored in a FIFO. The corresponding write pointer is managed
|
||||
/// (incremented) in the source clock domain.
|
||||
/// 2. The entire FIFO content is exposed over the `async_data` port.
|
||||
/// The destination clock domain increments its read pointer
|
||||
/// in its destination clock domain.
|
||||
///
|
||||
/// Read and write pointers are then gray coded, communicated
|
||||
/// and synchronized using a classic multi-stage FF synchronizer
|
||||
/// in the other clock domain. The gray coding ensures that only
|
||||
/// one bit changes at each pointer increment, preventing the
|
||||
/// synchronizer to accidentally latch an inconsistent state
|
||||
/// on a multi-bit bus.
|
||||
///
|
||||
/// The not full signal e.g. `src_ready_o` (on the sending side)
|
||||
/// is generated using the local write pointer and the pessimistic
|
||||
/// read pointer from the destination clock domain (pessimistic
|
||||
/// because it is delayed at least two cycles because of the synchronizer
|
||||
/// stages). This prevents the FIFO from overflowing.
|
||||
///
|
||||
/// The not empty signal e.g. `dst_valid_o` is generated using
|
||||
/// the pessimistic write pointer and the local read pointer in
|
||||
/// the destination clock domain. This means the FIFO content
|
||||
/// does not need to be synchronized as we are sure we are reading
|
||||
/// data which has been written at least two cycles earlier.
|
||||
/// Furthermore, the read select logic into the FIFO is completely
|
||||
/// clocked by the destination clock domain which avoids
|
||||
/// inefficient data synchronization.
|
||||
///
|
||||
/// The FIFO size must be powers of two, which is why its depth is
|
||||
/// given as 2**LOG_DEPTH. LOG_DEPTH must be at least 1.
|
||||
///
|
||||
/// # Constraints
|
||||
///
|
||||
/// We need to make sure that the propagation delay of the
|
||||
/// data, read and write pointer is bound to the minimum of
|
||||
/// either the sending or receiving clock period to prevent
|
||||
/// an inconsistent state to be latched (if for example the one
|
||||
/// bit of the read/write pointer have an excessive delay).
|
||||
/// Furthermore, we should deactivate setup and hold checks on
|
||||
/// the asynchronous signals.
|
||||
///
|
||||
/// ```
|
||||
/// set_ungroup [get_designs cdc_fifo_gray*] false
|
||||
/// set_boundary_optimization [get_designs cdc_fifo_gray*] false
|
||||
/// set_max_delay min(T_src, T_dst) \
|
||||
/// -through [get_pins -hierarchical -filter async] \
|
||||
/// -through [get_pins -hierarchical -filter async]
|
||||
/// set_false_path -hold \
|
||||
/// -through [get_pins -hierarchical -filter async] \
|
||||
/// -through [get_pins -hierarchical -filter async]
|
||||
/// ```
|
||||
|
||||
`include "common_cells/registers.svh"
|
||||
|
||||
(* no_ungroup *)
|
||||
(* no_boundary_optimization *)
|
||||
module cdc_fifo_gray #(
|
||||
/// The width of the default logic type.
|
||||
parameter int unsigned WIDTH = 1,
|
||||
/// The data type of the payload transported by the FIFO.
|
||||
parameter type T = logic [WIDTH-1:0],
|
||||
/// The FIFO's depth given as 2**LOG_DEPTH.
|
||||
parameter int LOG_DEPTH = 3,
|
||||
/// The number of synchronization registers to insert on the async pointers.
|
||||
parameter int SYNC_STAGES = 2
|
||||
) (
|
||||
input logic src_rst_ni,
|
||||
input logic src_clk_i,
|
||||
input T src_data_i,
|
||||
input logic src_valid_i,
|
||||
output logic src_ready_o,
|
||||
|
||||
input logic dst_rst_ni,
|
||||
input logic dst_clk_i,
|
||||
output T dst_data_o,
|
||||
output logic dst_valid_o,
|
||||
input logic dst_ready_i
|
||||
);
|
||||
|
||||
T [2**LOG_DEPTH-1:0] async_data;
|
||||
logic [LOG_DEPTH:0] async_wptr;
|
||||
logic [LOG_DEPTH:0] async_rptr;
|
||||
|
||||
cdc_fifo_gray_src #(
|
||||
.T ( T ),
|
||||
.LOG_DEPTH ( LOG_DEPTH )
|
||||
) i_src (
|
||||
.src_rst_ni,
|
||||
.src_clk_i,
|
||||
.src_data_i,
|
||||
.src_valid_i,
|
||||
.src_ready_o,
|
||||
|
||||
(* async *) .async_data_o ( async_data ),
|
||||
(* async *) .async_wptr_o ( async_wptr ),
|
||||
(* async *) .async_rptr_i ( async_rptr )
|
||||
);
|
||||
|
||||
cdc_fifo_gray_dst #(
|
||||
.T ( T ),
|
||||
.LOG_DEPTH ( LOG_DEPTH )
|
||||
) i_dst (
|
||||
.dst_rst_ni,
|
||||
.dst_clk_i,
|
||||
.dst_data_o,
|
||||
.dst_valid_o,
|
||||
.dst_ready_i,
|
||||
|
||||
(* async *) .async_data_i ( async_data ),
|
||||
(* async *) .async_wptr_i ( async_wptr ),
|
||||
(* async *) .async_rptr_o ( async_rptr )
|
||||
);
|
||||
|
||||
// Check the invariants.
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial assert(LOG_DEPTH > 0);
|
||||
initial assert(SYNC_STAGES >= 2);
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
(* no_ungroup *)
|
||||
(* no_boundary_optimization *)
|
||||
module cdc_fifo_gray_src #(
|
||||
parameter type T = logic,
|
||||
parameter int LOG_DEPTH = 3,
|
||||
parameter int SYNC_STAGES = 2
|
||||
)(
|
||||
input logic src_rst_ni,
|
||||
input logic src_clk_i,
|
||||
input T src_data_i,
|
||||
input logic src_valid_i,
|
||||
output logic src_ready_o,
|
||||
|
||||
output T [2**LOG_DEPTH-1:0] async_data_o,
|
||||
output logic [LOG_DEPTH:0] async_wptr_o,
|
||||
input logic [LOG_DEPTH:0] async_rptr_i
|
||||
);
|
||||
|
||||
localparam int PtrWidth = LOG_DEPTH+1;
|
||||
localparam logic [PtrWidth-1:0] PtrFull = (1 << LOG_DEPTH);
|
||||
|
||||
T [2**LOG_DEPTH-1:0] data_q;
|
||||
logic [PtrWidth-1:0] wptr_q, wptr_d, wptr_bin, wptr_next, rptr, rptr_bin;
|
||||
|
||||
// Data FIFO.
|
||||
assign async_data_o = data_q;
|
||||
for (genvar i = 0; i < 2**LOG_DEPTH; i++) begin : gen_word
|
||||
`FFLNR(data_q[i], src_data_i,
|
||||
src_valid_i & src_ready_o & (wptr_bin[LOG_DEPTH-1:0] == i), src_clk_i)
|
||||
end
|
||||
|
||||
// Read pointer.
|
||||
for (genvar i = 0; i < PtrWidth; i++) begin : gen_sync
|
||||
sync #(.STAGES(SYNC_STAGES)) i_sync (
|
||||
.clk_i ( src_clk_i ),
|
||||
.rst_ni ( src_rst_ni ),
|
||||
.serial_i ( async_rptr_i[i] ),
|
||||
.serial_o ( rptr[i] )
|
||||
);
|
||||
end
|
||||
gray_to_binary #(PtrWidth) i_rptr_g2b (.A(rptr), .Z(rptr_bin));
|
||||
|
||||
// Write pointer.
|
||||
assign wptr_next = wptr_bin+1;
|
||||
gray_to_binary #(PtrWidth) i_wptr_g2b (.A(wptr_q), .Z(wptr_bin));
|
||||
binary_to_gray #(PtrWidth) i_wptr_b2g (.A(wptr_next), .Z(wptr_d));
|
||||
`FFLARN(wptr_q, wptr_d, src_valid_i & src_ready_o, '0, src_clk_i, src_rst_ni)
|
||||
assign async_wptr_o = wptr_q;
|
||||
|
||||
// The pointers into the FIFO are one bit wider than the actual address into
|
||||
// the FIFO. This makes detecting critical states very simple: if all but the
|
||||
// topmost bit of rptr and wptr agree, the FIFO is in a critical state. If the
|
||||
// topmost bit is equal, the FIFO is empty, otherwise it is full.
|
||||
assign src_ready_o = ((wptr_bin ^ rptr_bin) != PtrFull);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
(* no_ungroup *)
|
||||
(* no_boundary_optimization *)
|
||||
module cdc_fifo_gray_dst #(
|
||||
parameter type T = logic,
|
||||
parameter int LOG_DEPTH = 3,
|
||||
parameter int SYNC_STAGES = 2
|
||||
)(
|
||||
input logic dst_rst_ni,
|
||||
input logic dst_clk_i,
|
||||
output T dst_data_o,
|
||||
output logic dst_valid_o,
|
||||
input logic dst_ready_i,
|
||||
|
||||
input T [2**LOG_DEPTH-1:0] async_data_i,
|
||||
input logic [LOG_DEPTH:0] async_wptr_i,
|
||||
output logic [LOG_DEPTH:0] async_rptr_o
|
||||
);
|
||||
|
||||
localparam int PtrWidth = LOG_DEPTH+1;
|
||||
localparam logic [PtrWidth-1:0] PtrEmpty = '0;
|
||||
|
||||
T dst_data;
|
||||
logic [PtrWidth-1:0] rptr_q, rptr_d, rptr_bin, rptr_bin_d, rptr_next, wptr, wptr_bin;
|
||||
logic dst_valid, dst_ready;
|
||||
// Data selector and register.
|
||||
assign dst_data = async_data_i[rptr_bin[LOG_DEPTH-1:0]];
|
||||
|
||||
// Read pointer.
|
||||
assign rptr_next = rptr_bin+1;
|
||||
gray_to_binary #(PtrWidth) i_rptr_g2b (.A(rptr_q), .Z(rptr_bin));
|
||||
binary_to_gray #(PtrWidth) i_rptr_b2g (.A(rptr_next), .Z(rptr_d));
|
||||
`FFLARN(rptr_q, rptr_d, dst_valid & dst_ready, '0, dst_clk_i, dst_rst_ni)
|
||||
assign async_rptr_o = rptr_q;
|
||||
|
||||
// Write pointer.
|
||||
for (genvar i = 0; i < PtrWidth; i++) begin : gen_sync
|
||||
sync #(.STAGES(SYNC_STAGES)) i_sync (
|
||||
.clk_i ( dst_clk_i ),
|
||||
.rst_ni ( dst_rst_ni ),
|
||||
.serial_i ( async_wptr_i[i] ),
|
||||
.serial_o ( wptr[i] )
|
||||
);
|
||||
end
|
||||
gray_to_binary #(PtrWidth) i_wptr_g2b (.A(wptr), .Z(wptr_bin));
|
||||
|
||||
// The pointers into the FIFO are one bit wider than the actual address into
|
||||
// the FIFO. This makes detecting critical states very simple: if all but the
|
||||
// topmost bit of rptr and wptr agree, the FIFO is in a critical state. If the
|
||||
// topmost bit is equal, the FIFO is empty, otherwise it is full.
|
||||
assign dst_valid = ((wptr_bin ^ rptr_bin) != PtrEmpty);
|
||||
|
||||
// Cut the combinatorial path with a spill register.
|
||||
spill_register #(
|
||||
.T ( T )
|
||||
) i_spill_register (
|
||||
.clk_i ( dst_clk_i ),
|
||||
.rst_ni ( dst_rst_ni ),
|
||||
.valid_i ( dst_valid ),
|
||||
.ready_o ( dst_ready ),
|
||||
.data_i ( dst_data ),
|
||||
.valid_o ( dst_valid_o ),
|
||||
.ready_i ( dst_ready_i ),
|
||||
.data_o ( dst_data_o )
|
||||
);
|
||||
|
||||
endmodule
|
61
vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
vendored
Normal file
61
vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2016 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/// cf_math_pkg: Constant Function Implementations of Mathematical Functions for HDL Elaboration
|
||||
///
|
||||
/// This package contains a collection of mathematical functions that are commonly used when defining
|
||||
/// the value of constants in HDL code. These functions are implemented as Verilog constants
|
||||
/// functions. Introduced in Verilog 2001 (IEEE Std 1364-2001), a constant function (§ 10.3.5) is a
|
||||
/// function whose value can be evaluated at compile time or during elaboration. A constant function
|
||||
/// must be called with arguments that are constants.
|
||||
package cf_math_pkg;
|
||||
|
||||
/// Ceiled Division of Two Natural Numbers
|
||||
///
|
||||
/// Returns the quotient of two natural numbers, rounded towards plus infinity.
|
||||
function automatic integer ceil_div (input longint dividend, input longint divisor);
|
||||
automatic longint remainder;
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
if (dividend < 0) begin
|
||||
$fatal(1, "Dividend %0d is not a natural number!", dividend);
|
||||
end
|
||||
|
||||
if (divisor < 0) begin
|
||||
$fatal(1, "Divisor %0d is not a natural number!", divisor);
|
||||
end
|
||||
|
||||
if (divisor == 0) begin
|
||||
$fatal(1, "Division by zero!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
remainder = dividend;
|
||||
for (ceil_div = 0; remainder > 0; ceil_div++) begin
|
||||
remainder = remainder - divisor;
|
||||
end
|
||||
endfunction
|
||||
|
||||
/// Index width required to be able to represent up to `num_idx` indices as a binary
|
||||
/// encoded signal.
|
||||
/// Ensures that the minimum width if an index signal is `1`, regardless of parametrization.
|
||||
///
|
||||
/// Sample usage in type definition:
|
||||
/// As parameter:
|
||||
/// `parameter type idx_t = logic[cf_math_pkg::idx_width(NumIdx)-1:0]`
|
||||
/// As typedef:
|
||||
/// `typedef logic [cf_math_pkg::idx_width(NumIdx)-1:0] idx_t`
|
||||
function automatic integer unsigned idx_width (input integer unsigned num_idx);
|
||||
return (num_idx > 32'd1) ? unsigned'($clog2(num_idx)) : 32'd1;
|
||||
endfunction
|
||||
|
||||
endpackage
|
42
vendor/pulp-platform/common_cells/src/clk_div.sv
vendored
Normal file
42
vendor/pulp-platform/common_cells/src/clk_div.sv
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba
|
||||
// Description: Divides the clock by an integer factor
|
||||
module clk_div #(
|
||||
parameter int unsigned RATIO = 4
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic testmode_i, // testmode
|
||||
input logic en_i, // enable clock divider
|
||||
output logic clk_o // divided clock out
|
||||
);
|
||||
logic [RATIO-1:0] counter_q;
|
||||
logic clk_q;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
clk_q <= 1'b0;
|
||||
counter_q <= '0;
|
||||
end else begin
|
||||
clk_q <= 1'b0;
|
||||
if (en_i) begin
|
||||
if (counter_q == (RATIO[RATIO-1:0] - 1)) begin
|
||||
clk_q <= 1'b1;
|
||||
end else begin
|
||||
counter_q <= counter_q + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
// output assignment - bypass in testmode
|
||||
assign clk_o = testmode_i ? clk_i : clk_q;
|
||||
endmodule
|
43
vendor/pulp-platform/common_cells/src/counter.sv
vendored
Normal file
43
vendor/pulp-platform/common_cells/src/counter.sv
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba
|
||||
// Description: Generic up/down counter
|
||||
|
||||
module counter #(
|
||||
parameter int unsigned WIDTH = 4,
|
||||
parameter bit STICKY_OVERFLOW = 1'b0
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic clear_i, // synchronous clear
|
||||
input logic en_i, // enable the counter
|
||||
input logic load_i, // load a new value
|
||||
input logic down_i, // downcount, default is up
|
||||
input logic [WIDTH-1:0] d_i,
|
||||
output logic [WIDTH-1:0] q_o,
|
||||
output logic overflow_o
|
||||
);
|
||||
delta_counter #(
|
||||
.WIDTH (WIDTH),
|
||||
.STICKY_OVERFLOW (STICKY_OVERFLOW)
|
||||
) i_counter (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.clear_i,
|
||||
.en_i,
|
||||
.load_i,
|
||||
.down_i,
|
||||
.delta_i({{WIDTH-1{1'b0}}, 1'b1}),
|
||||
.d_i,
|
||||
.q_o,
|
||||
.overflow_o
|
||||
);
|
||||
endmodule
|
74
vendor/pulp-platform/common_cells/src/delta_counter.sv
vendored
Normal file
74
vendor/pulp-platform/common_cells/src/delta_counter.sv
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Up/down counter with variable delta
|
||||
|
||||
module delta_counter #(
|
||||
parameter int unsigned WIDTH = 4,
|
||||
parameter bit STICKY_OVERFLOW = 1'b0
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic clear_i, // synchronous clear
|
||||
input logic en_i, // enable the counter
|
||||
input logic load_i, // load a new value
|
||||
input logic down_i, // downcount, default is up
|
||||
input logic [WIDTH-1:0] delta_i,
|
||||
input logic [WIDTH-1:0] d_i,
|
||||
output logic [WIDTH-1:0] q_o,
|
||||
output logic overflow_o
|
||||
);
|
||||
logic [WIDTH:0] counter_q, counter_d;
|
||||
if (STICKY_OVERFLOW) begin : gen_sticky_overflow
|
||||
logic overflow_d, overflow_q;
|
||||
always_ff @(posedge clk_i or negedge rst_ni) overflow_q <= ~rst_ni ? 1'b0 : overflow_d;
|
||||
always_comb begin
|
||||
overflow_d = overflow_q;
|
||||
if (clear_i || load_i) begin
|
||||
overflow_d = 1'b0;
|
||||
end else if (!overflow_q && en_i) begin
|
||||
if (down_i) begin
|
||||
overflow_d = delta_i > counter_q[WIDTH-1:0];
|
||||
end else begin
|
||||
overflow_d = counter_q[WIDTH-1:0] > ({WIDTH{1'b1}} - delta_i);
|
||||
end
|
||||
end
|
||||
end
|
||||
assign overflow_o = overflow_q;
|
||||
end else begin : gen_transient_overflow
|
||||
// counter overflowed if the MSB is set
|
||||
assign overflow_o = counter_q[WIDTH];
|
||||
end
|
||||
assign q_o = counter_q[WIDTH-1:0];
|
||||
|
||||
always_comb begin
|
||||
counter_d = counter_q;
|
||||
|
||||
if (clear_i) begin
|
||||
counter_d = '0;
|
||||
end else if (load_i) begin
|
||||
counter_d = {1'b0, d_i};
|
||||
end else if (en_i) begin
|
||||
if (down_i) begin
|
||||
counter_d = counter_q - delta_i;
|
||||
end else begin
|
||||
counter_d = counter_q + delta_i;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
counter_q <= '0;
|
||||
end else begin
|
||||
counter_q <= counter_d;
|
||||
end
|
||||
end
|
||||
endmodule
|
191
vendor/pulp-platform/common_cells/src/deprecated/clock_divider.sv
vendored
Normal file
191
vendor/pulp-platform/common_cells/src/deprecated/clock_divider.sv
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Company: Multitherman Laboratory @ DEIS - University of Bologna //
|
||||
// Viale Risorgimento 2 40136 //
|
||||
// Bologna - fax 0512093785 - //
|
||||
// //
|
||||
// Engineer: Antonio Pullini - pullinia@iis.ee.ethz.ch //
|
||||
// //
|
||||
// Additional contributions by: //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// Create Date: 13/02/2013 //
|
||||
// Design Name: ULPSoC //
|
||||
// Module Name: clock_divider //
|
||||
// Project Name: ULPSoC //
|
||||
// Language: SystemVerilog //
|
||||
// //
|
||||
// Description: Clock Divider //
|
||||
// //
|
||||
// //
|
||||
// Revision: //
|
||||
// Revision v0.1 - File Created //
|
||||
// Revision v0.2 - (19/03/2015) clock_gating swapped in pulp_clock_gating //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module clock_divider
|
||||
#(
|
||||
parameter DIV_INIT = 0,
|
||||
parameter BYPASS_INIT = 1
|
||||
)
|
||||
(
|
||||
input logic clk_i,
|
||||
input logic rstn_i,
|
||||
input logic test_mode_i,
|
||||
input logic clk_gate_async_i,
|
||||
input logic [7:0] clk_div_data_i,
|
||||
input logic clk_div_valid_i,
|
||||
output logic clk_div_ack_o,
|
||||
output logic clk_o
|
||||
);
|
||||
|
||||
enum logic [1:0] {IDLE, STOP, WAIT, RELEASE} state, state_next;
|
||||
|
||||
logic s_clk_out;
|
||||
logic s_clock_enable;
|
||||
logic s_clock_enable_gate;
|
||||
logic s_clk_div_valid;
|
||||
|
||||
logic [7:0] reg_clk_div;
|
||||
logic s_clk_div_valid_sync;
|
||||
|
||||
logic s_rstn_sync;
|
||||
|
||||
logic [1:0] reg_ext_gate_sync;
|
||||
|
||||
assign s_clock_enable_gate = s_clock_enable & reg_ext_gate_sync;
|
||||
|
||||
`ifndef PULP_FPGA_EMUL
|
||||
rstgen i_rst_gen
|
||||
(
|
||||
// PAD FRAME SIGNALS
|
||||
.clk_i(clk_i),
|
||||
.rst_ni(rstn_i), //async signal coming from pads
|
||||
|
||||
// TEST MODE
|
||||
.test_mode_i(test_mode_i),
|
||||
|
||||
// OUTPUT RESET
|
||||
.rst_no(s_rstn_sync),
|
||||
.init_no() //not used
|
||||
);
|
||||
`else
|
||||
assign s_rstn_sync = rstn_i;
|
||||
`endif
|
||||
|
||||
|
||||
//handle the handshake with the soc_ctrl. Interface is now async
|
||||
pulp_sync_wedge i_edge_prop
|
||||
(
|
||||
.clk_i(clk_i),
|
||||
.rstn_i(s_rstn_sync),
|
||||
.en_i(1'b1),
|
||||
.serial_i(clk_div_valid_i),
|
||||
.serial_o(clk_div_ack_o),
|
||||
.r_edge_o(s_clk_div_valid_sync),
|
||||
.f_edge_o()
|
||||
);
|
||||
|
||||
clock_divider_counter
|
||||
#(
|
||||
.BYPASS_INIT(BYPASS_INIT),
|
||||
.DIV_INIT(DIV_INIT)
|
||||
)
|
||||
i_clkdiv_cnt
|
||||
(
|
||||
.clk(clk_i),
|
||||
.rstn(s_rstn_sync),
|
||||
.test_mode(test_mode_i),
|
||||
.clk_div(reg_clk_div),
|
||||
.clk_div_valid(s_clk_div_valid),
|
||||
.clk_out(s_clk_out)
|
||||
);
|
||||
|
||||
pulp_clock_gating i_clk_gate
|
||||
(
|
||||
.clk_i(s_clk_out),
|
||||
.en_i(s_clock_enable_gate),
|
||||
.test_en_i(test_mode_i),
|
||||
.clk_o(clk_o)
|
||||
);
|
||||
|
||||
always_comb
|
||||
begin
|
||||
case(state)
|
||||
IDLE:
|
||||
begin
|
||||
s_clock_enable = 1'b1;
|
||||
s_clk_div_valid = 1'b0;
|
||||
if (s_clk_div_valid_sync)
|
||||
state_next = STOP;
|
||||
else
|
||||
state_next = IDLE;
|
||||
end
|
||||
|
||||
STOP:
|
||||
begin
|
||||
s_clock_enable = 1'b0;
|
||||
s_clk_div_valid = 1'b1;
|
||||
state_next = WAIT;
|
||||
end
|
||||
|
||||
WAIT:
|
||||
begin
|
||||
s_clock_enable = 1'b0;
|
||||
s_clk_div_valid = 1'b0;
|
||||
state_next = RELEASE;
|
||||
end
|
||||
|
||||
RELEASE:
|
||||
begin
|
||||
s_clock_enable = 1'b0;
|
||||
s_clk_div_valid = 1'b0;
|
||||
state_next = IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge s_rstn_sync)
|
||||
begin
|
||||
if (!s_rstn_sync)
|
||||
state <= IDLE;
|
||||
else
|
||||
state <= state_next;
|
||||
end
|
||||
|
||||
//sample the data when valid has been sync and there is a rise edge
|
||||
always_ff @(posedge clk_i or negedge s_rstn_sync)
|
||||
begin
|
||||
if (!s_rstn_sync)
|
||||
reg_clk_div <= '0;
|
||||
else if (s_clk_div_valid_sync)
|
||||
reg_clk_div <= clk_div_data_i;
|
||||
end
|
||||
|
||||
//sample the data when valid has been sync and there is a rise edge
|
||||
always_ff @(posedge clk_i or negedge s_rstn_sync)
|
||||
begin
|
||||
if (!s_rstn_sync)
|
||||
reg_ext_gate_sync <= 2'b00;
|
||||
else
|
||||
reg_ext_gate_sync <= {clk_gate_async_i, reg_ext_gate_sync[1]};
|
||||
end
|
||||
|
||||
endmodule
|
211
vendor/pulp-platform/common_cells/src/deprecated/clock_divider_counter.sv
vendored
Normal file
211
vendor/pulp-platform/common_cells/src/deprecated/clock_divider_counter.sv
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Company: Multitherman Laboratory @ DEIS - University of Bologna //
|
||||
// Viale Risorgimento 2 40136 //
|
||||
// Bologna - fax 0512093785 - //
|
||||
// //
|
||||
// Engineer: Antonio Pullini - pullinia@iis.ee.ethz.ch //
|
||||
// //
|
||||
// Additional contributions by: //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// Create Date: 13/02/2013 //
|
||||
// Design Name: ULPSoC //
|
||||
// Module Name: clock_divider_counter //
|
||||
// Project Name: ULPSoC //
|
||||
// Language: SystemVerilog //
|
||||
// //
|
||||
// Description: clock_divider_counter //
|
||||
// //
|
||||
// //
|
||||
// Revision: //
|
||||
// Revision v0.1 - File Created //
|
||||
// Revision v0.2 - (19/03/2015) clock_gating swapped in pulp_clock_gating //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module clock_divider_counter
|
||||
#(
|
||||
parameter BYPASS_INIT = 1,
|
||||
parameter DIV_INIT = 'hFF
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rstn,
|
||||
input logic test_mode,
|
||||
input logic [7:0] clk_div,
|
||||
input logic clk_div_valid,
|
||||
output logic clk_out
|
||||
);
|
||||
|
||||
logic [7:0] counter;
|
||||
logic [7:0] counter_next;
|
||||
logic [7:0] clk_cnt;
|
||||
logic en1;
|
||||
logic en2;
|
||||
|
||||
logic is_odd;
|
||||
|
||||
logic div1;
|
||||
logic div2;
|
||||
logic div2_neg_sync;
|
||||
|
||||
logic [7:0] clk_cnt_odd;
|
||||
logic [7:0] clk_cnt_odd_incr;
|
||||
logic [7:0] clk_cnt_even;
|
||||
logic [7:0] clk_cnt_en2;
|
||||
|
||||
logic bypass;
|
||||
|
||||
logic clk_out_gen;
|
||||
logic clk_div_valid_reg;
|
||||
|
||||
logic clk_inv_test;
|
||||
logic clk_inv;
|
||||
|
||||
// assign clk_cnt_odd_incr = clk_div + 1;
|
||||
// assign clk_cnt_odd = {1'b0,clk_cnt_odd_incr[7:1]}; //if odd divider than clk_cnt = (clk_div+1)/2
|
||||
assign clk_cnt_odd = clk_div - 8'h1; //if odd divider than clk_cnt = clk_div - 1
|
||||
assign clk_cnt_even = (clk_div == 8'h2) ? 8'h0 : ({1'b0,clk_div[7:1]} - 8'h1); //if even divider than clk_cnt = clk_div/2
|
||||
assign clk_cnt_en2 = {1'b0,clk_cnt[7:1]} + 8'h1;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
if (counter == 'h0)
|
||||
en1 = 1'b1;
|
||||
else
|
||||
en1 = 1'b0;
|
||||
|
||||
if (clk_div_valid)
|
||||
counter_next = 'h0;
|
||||
else if (counter == clk_cnt)
|
||||
counter_next = 'h0;
|
||||
else
|
||||
counter_next = counter + 1;
|
||||
|
||||
if (clk_div_valid)
|
||||
en2 = 1'b0;
|
||||
else if (counter == clk_cnt_en2)
|
||||
en2 = 1'b1;
|
||||
else
|
||||
en2 = 1'b0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk, negedge rstn)
|
||||
begin
|
||||
if (~rstn)
|
||||
begin
|
||||
counter <= 'h0;
|
||||
div1 <= 1'b0;
|
||||
bypass <= BYPASS_INIT;
|
||||
clk_cnt <= DIV_INIT;
|
||||
is_odd <= 1'b0;
|
||||
clk_div_valid_reg <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (!bypass)
|
||||
counter <= counter_next;
|
||||
|
||||
clk_div_valid_reg <= clk_div_valid;
|
||||
if (clk_div_valid)
|
||||
begin
|
||||
if ((clk_div == 8'h0) || (clk_div == 8'h1))
|
||||
begin
|
||||
bypass <= 1'b1;
|
||||
clk_cnt <= 'h0;
|
||||
is_odd <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
bypass <= 1'b0;
|
||||
if (clk_div[0])
|
||||
begin
|
||||
is_odd <= 1'b1;
|
||||
clk_cnt <= clk_cnt_odd;
|
||||
end
|
||||
else
|
||||
begin
|
||||
is_odd <= 1'b0;
|
||||
clk_cnt <= clk_cnt_even;
|
||||
end
|
||||
end
|
||||
div1 <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (en1 && !bypass)
|
||||
div1 <= ~div1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pulp_clock_inverter clk_inv_i
|
||||
(
|
||||
.clk_i(clk),
|
||||
.clk_o(clk_inv)
|
||||
);
|
||||
|
||||
`ifndef PULP_FPGA_EMUL
|
||||
`ifdef PULP_DFT
|
||||
pulp_clock_mux2 clk_muxinv_i
|
||||
(
|
||||
.clk0_i(clk_inv),
|
||||
.clk1_i(clk),
|
||||
.clk_sel_i(test_mode),
|
||||
.clk_o(clk_inv_test)
|
||||
);
|
||||
`else
|
||||
assign clk_inv_test = clk_inv;
|
||||
`endif
|
||||
`else
|
||||
assign clk_inv_test = clk_inv;
|
||||
`endif
|
||||
|
||||
always_ff @(posedge clk_inv_test or negedge rstn)
|
||||
begin
|
||||
if (!rstn)
|
||||
begin
|
||||
div2 <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (clk_div_valid_reg)
|
||||
div2 <= 1'b0;
|
||||
else if (en2 && is_odd && !bypass)
|
||||
div2 <= ~div2;
|
||||
end
|
||||
end // always_ff @ (posedge clk_inv_test or negedge rstn)
|
||||
|
||||
pulp_clock_xor2 clock_xor_i
|
||||
(
|
||||
.clk_o(clk_out_gen),
|
||||
.clk0_i(div1),
|
||||
.clk1_i(div2)
|
||||
);
|
||||
|
||||
pulp_clock_mux2 clk_mux_i
|
||||
(
|
||||
.clk0_i(clk_out_gen),
|
||||
.clk1_i(clk),
|
||||
.clk_sel_i(bypass || test_mode),
|
||||
.clk_o(clk_out)
|
||||
);
|
||||
|
||||
endmodule
|
57
vendor/pulp-platform/common_cells/src/deprecated/fifo_v1.sv
vendored
Normal file
57
vendor/pulp-platform/common_cells/src/deprecated/fifo_v1.sv
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
module fifo #(
|
||||
parameter bit FALL_THROUGH = 1'b0, // fifo is in fall-through mode
|
||||
parameter int unsigned DATA_WIDTH = 32, // default data width if the fifo is of type logic
|
||||
parameter int unsigned DEPTH = 8, // depth can be arbitrary from 0 to 2**32
|
||||
parameter int unsigned THRESHOLD = 1, // fill count until when to assert threshold_o
|
||||
parameter type dtype = logic [DATA_WIDTH-1:0]
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // flush the queue
|
||||
input logic testmode_i, // test_mode to bypass clock gating
|
||||
// status flags
|
||||
output logic full_o, // queue is full
|
||||
output logic empty_o, // queue is empty
|
||||
output logic threshold_o, // the FIFO is above the specified threshold
|
||||
// as long as the queue is not full we can push new data
|
||||
input dtype data_i, // data to push into the queue
|
||||
input logic push_i, // data is valid and can be pushed to the queue
|
||||
// as long as the queue is not empty we can pop new elements
|
||||
output dtype data_o, // output data
|
||||
input logic pop_i // pop head from queue
|
||||
);
|
||||
fifo_v2 #(
|
||||
.FALL_THROUGH ( FALL_THROUGH ),
|
||||
.DATA_WIDTH ( DATA_WIDTH ),
|
||||
.DEPTH ( DEPTH ),
|
||||
.ALM_FULL_TH ( THRESHOLD ),
|
||||
.dtype ( dtype )
|
||||
) impl (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.flush_i ( flush_i ),
|
||||
.testmode_i ( testmode_i ),
|
||||
.full_o ( full_o ),
|
||||
.empty_o ( empty_o ),
|
||||
.alm_full_o ( threshold_o ),
|
||||
.alm_empty_o ( ),
|
||||
.data_i ( data_i ),
|
||||
.push_i ( push_i ),
|
||||
.data_o ( data_o ),
|
||||
.pop_i ( pop_i )
|
||||
);
|
||||
endmodule
|
||||
/* verilator lint_on DECLFILENAME */
|
79
vendor/pulp-platform/common_cells/src/deprecated/fifo_v2.sv
vendored
Normal file
79
vendor/pulp-platform/common_cells/src/deprecated/fifo_v2.sv
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module fifo_v2 #(
|
||||
parameter bit FALL_THROUGH = 1'b0, // fifo is in fall-through mode
|
||||
parameter int unsigned DATA_WIDTH = 32, // default data width if the fifo is of type logic
|
||||
parameter int unsigned DEPTH = 8, // depth can be arbitrary from 0 to 2**32
|
||||
parameter int unsigned ALM_EMPTY_TH = 1, // almost empty threshold (when to assert alm_empty_o)
|
||||
parameter int unsigned ALM_FULL_TH = 1, // almost full threshold (when to assert alm_full_o)
|
||||
parameter type dtype = logic [DATA_WIDTH-1:0],
|
||||
// DO NOT OVERWRITE THIS PARAMETER
|
||||
parameter int unsigned ADDR_DEPTH = (DEPTH > 1) ? $clog2(DEPTH) : 1
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // flush the queue
|
||||
input logic testmode_i, // test_mode to bypass clock gating
|
||||
// status flags
|
||||
output logic full_o, // queue is full
|
||||
output logic empty_o, // queue is empty
|
||||
output logic alm_full_o, // FIFO fillstate >= the specified threshold
|
||||
output logic alm_empty_o, // FIFO fillstate <= the specified threshold
|
||||
// as long as the queue is not full we can push new data
|
||||
input dtype data_i, // data to push into the queue
|
||||
input logic push_i, // data is valid and can be pushed to the queue
|
||||
// as long as the queue is not empty we can pop new elements
|
||||
output dtype data_o, // output data
|
||||
input logic pop_i // pop head from queue
|
||||
);
|
||||
|
||||
logic [ADDR_DEPTH-1:0] usage;
|
||||
|
||||
// generate threshold parameters
|
||||
if (DEPTH == 0) begin
|
||||
assign alm_full_o = 1'b0; // that signal does not make any sense in a FIFO of depth 0
|
||||
assign alm_empty_o = 1'b0; // that signal does not make any sense in a FIFO of depth 0
|
||||
end else begin
|
||||
assign alm_full_o = (usage >= ALM_FULL_TH[ADDR_DEPTH-1:0]);
|
||||
assign alm_empty_o = (usage <= ALM_EMPTY_TH[ADDR_DEPTH-1:0]);
|
||||
end
|
||||
|
||||
fifo_v3 #(
|
||||
.FALL_THROUGH ( FALL_THROUGH ),
|
||||
.DATA_WIDTH ( DATA_WIDTH ),
|
||||
.DEPTH ( DEPTH ),
|
||||
.dtype ( dtype )
|
||||
) i_fifo_v3 (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.testmode_i,
|
||||
.full_o,
|
||||
.empty_o,
|
||||
.usage_o (usage),
|
||||
.data_i,
|
||||
.push_i,
|
||||
.data_o,
|
||||
.pop_i
|
||||
);
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin
|
||||
assert (ALM_FULL_TH <= DEPTH) else $error("ALM_FULL_TH can't be larger than the DEPTH.");
|
||||
assert (ALM_EMPTY_TH <= DEPTH) else $error("ALM_EMPTY_TH can't be larger than the DEPTH.");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule // fifo_v2
|
83
vendor/pulp-platform/common_cells/src/deprecated/find_first_one.sv
vendored
Normal file
83
vendor/pulp-platform/common_cells/src/deprecated/find_first_one.sv
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Deprecated, use lzc unit instead.
|
||||
|
||||
/// A leading-one finder / leading zero counter.
|
||||
/// Set FLIP to 0 for find_first_one => first_one_o is the index of the first one (from the LSB)
|
||||
/// Set FLIP to 1 for leading zero counter => first_one_o is the number of leading zeroes (from the MSB)
|
||||
module find_first_one #(
|
||||
/// The width of the input vector.
|
||||
parameter int WIDTH = -1,
|
||||
parameter int FLIP = 0
|
||||
)(
|
||||
input logic [WIDTH-1:0] in_i,
|
||||
output logic [$clog2(WIDTH)-1:0] first_one_o,
|
||||
output logic no_ones_o
|
||||
);
|
||||
|
||||
localparam int NUM_LEVELS = $clog2(WIDTH);
|
||||
|
||||
// pragma translate_off
|
||||
initial begin
|
||||
assert(WIDTH >= 0);
|
||||
end
|
||||
// pragma translate_on
|
||||
|
||||
logic [WIDTH-1:0][NUM_LEVELS-1:0] index_lut;
|
||||
logic [2**NUM_LEVELS-1:0] sel_nodes;
|
||||
logic [2**NUM_LEVELS-1:0][NUM_LEVELS-1:0] index_nodes;
|
||||
|
||||
logic [WIDTH-1:0] in_tmp;
|
||||
|
||||
for (genvar i = 0; i < WIDTH; i++) begin
|
||||
assign in_tmp[i] = FLIP ? in_i[WIDTH-1-i] : in_i[i];
|
||||
end
|
||||
|
||||
for (genvar j = 0; j < WIDTH; j++) begin
|
||||
assign index_lut[j] = j;
|
||||
end
|
||||
|
||||
for (genvar level = 0; level < NUM_LEVELS; level++) begin
|
||||
|
||||
if (level < NUM_LEVELS-1) begin
|
||||
for (genvar l = 0; l < 2**level; l++) begin
|
||||
assign sel_nodes[2**level-1+l] = sel_nodes[2**(level+1)-1+l*2] | sel_nodes[2**(level+1)-1+l*2+1];
|
||||
assign index_nodes[2**level-1+l] = (sel_nodes[2**(level+1)-1+l*2] == 1'b1) ?
|
||||
index_nodes[2**(level+1)-1+l*2] : index_nodes[2**(level+1)-1+l*2+1];
|
||||
end
|
||||
end
|
||||
|
||||
if (level == NUM_LEVELS-1) begin
|
||||
for (genvar k = 0; k < 2**level; k++) begin
|
||||
// if two successive indices are still in the vector...
|
||||
if (k * 2 < WIDTH-1) begin
|
||||
assign sel_nodes[2**level-1+k] = in_tmp[k*2] | in_tmp[k*2+1];
|
||||
assign index_nodes[2**level-1+k] = (in_tmp[k*2] == 1'b1) ? index_lut[k*2] : index_lut[k*2+1];
|
||||
end
|
||||
// if only the first index is still in the vector...
|
||||
if (k * 2 == WIDTH-1) begin
|
||||
assign sel_nodes[2**level-1+k] = in_tmp[k*2];
|
||||
assign index_nodes[2**level-1+k] = index_lut[k*2];
|
||||
end
|
||||
// if index is out of range
|
||||
if (k * 2 > WIDTH-1) begin
|
||||
assign sel_nodes[2**level-1+k] = 1'b0;
|
||||
assign index_nodes[2**level-1+k] = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign first_one_o = NUM_LEVELS > 0 ? index_nodes[0] : '0;
|
||||
assign no_ones_o = NUM_LEVELS > 0 ? ~sel_nodes[0] : '1;
|
||||
|
||||
endmodule
|
64
vendor/pulp-platform/common_cells/src/deprecated/generic_LFSR_8bit.sv
vendored
Normal file
64
vendor/pulp-platform/common_cells/src/deprecated/generic_LFSR_8bit.sv
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Igor Loi <igor.loi@unibo.it>
|
||||
|
||||
module generic_LFSR_8bit
|
||||
#(
|
||||
parameter OH_WIDTH = 4,
|
||||
parameter BIN_WIDTH = $clog2(OH_WIDTH),
|
||||
parameter SEED = 8'b00000000
|
||||
)
|
||||
(
|
||||
output logic [OH_WIDTH-1:0] data_OH_o, // One hot encoding
|
||||
output logic [BIN_WIDTH-1:0] data_BIN_o, // Binary encoding
|
||||
input logic enable_i, //
|
||||
input logic clk, //
|
||||
input logic rst_n //
|
||||
);
|
||||
|
||||
logic [7:0] out;
|
||||
logic linear_feedback;
|
||||
logic [BIN_WIDTH-1:0] temp_ref_way;
|
||||
|
||||
|
||||
//-------------Code Starts Here-------
|
||||
assign linear_feedback = !(out[7] ^ out[3] ^ out[2] ^ out[1]); // TAPS for XOR feedback
|
||||
|
||||
assign data_BIN_o = temp_ref_way;
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
out <= SEED ;
|
||||
end
|
||||
else if (enable_i)
|
||||
begin
|
||||
out <= {out[6],out[5],out[4],out[3],out[2],out[1],out[0], linear_feedback};
|
||||
end
|
||||
end
|
||||
|
||||
generate
|
||||
|
||||
if(OH_WIDTH == 2)
|
||||
assign temp_ref_way = out[1];
|
||||
else
|
||||
assign temp_ref_way = out[BIN_WIDTH:1];
|
||||
endgenerate
|
||||
|
||||
// Bin to One Hot Encoder
|
||||
always_comb
|
||||
begin
|
||||
data_OH_o = '0;
|
||||
data_OH_o[temp_ref_way] = 1'b1;
|
||||
end
|
||||
|
||||
endmodule
|
274
vendor/pulp-platform/common_cells/src/deprecated/generic_fifo.sv
vendored
Normal file
274
vendor/pulp-platform/common_cells/src/deprecated/generic_fifo.sv
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// ============================================================================= //
|
||||
// Company: Multitherman Laboratory @ DEIS - University of Bologna //
|
||||
// Viale Risorgimento 2 40136 //
|
||||
// Bologna - fax 0512093785 - //
|
||||
// //
|
||||
// Engineer: Igor Loi - igor.loi@unibo.it //
|
||||
// //
|
||||
// //
|
||||
// Additional contributions by: //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// Create Date: 01/02/2014 //
|
||||
// Design Name: MISC //
|
||||
// Module Name: generic_fifo //
|
||||
// Project Name: PULP //
|
||||
// Language: SystemVerilog //
|
||||
// //
|
||||
// Description: A simple FIFO used in the D_address_decoder, and D_allocator //
|
||||
// to store the destinations ports //
|
||||
// //
|
||||
// Revision: //
|
||||
// Revision v0.1 - 01/02/2014 : File Created //
|
||||
// Revision v0.2 - 02/09/2015 : Updated with a global CG cell //
|
||||
// //
|
||||
// ============================================================================= //
|
||||
|
||||
module generic_fifo
|
||||
#(
|
||||
parameter int unsigned DATA_WIDTH = 32,
|
||||
parameter int unsigned DATA_DEPTH = 8
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
//PUSH SIDE
|
||||
input logic [DATA_WIDTH-1:0] data_i,
|
||||
input logic valid_i,
|
||||
output logic grant_o,
|
||||
//POP SIDE
|
||||
output logic [DATA_WIDTH-1:0] data_o,
|
||||
output logic valid_o,
|
||||
input logic grant_i,
|
||||
|
||||
input logic test_mode_i
|
||||
);
|
||||
|
||||
|
||||
// Local Parameter
|
||||
localparam int unsigned ADDR_DEPTH = $clog2(DATA_DEPTH);
|
||||
enum logic [1:0] { EMPTY, FULL, MIDDLE } CS, NS;
|
||||
// Internal Signals
|
||||
|
||||
logic gate_clock;
|
||||
logic clk_gated;
|
||||
|
||||
logic [ADDR_DEPTH-1:0] Pop_Pointer_CS, Pop_Pointer_NS;
|
||||
logic [ADDR_DEPTH-1:0] Push_Pointer_CS, Push_Pointer_NS;
|
||||
logic [DATA_WIDTH-1:0] FIFO_REGISTERS[DATA_DEPTH-1:0];
|
||||
int unsigned i;
|
||||
|
||||
// Parameter Check
|
||||
// synopsys translate_off
|
||||
initial begin : parameter_check
|
||||
integer param_err_flg;
|
||||
param_err_flg = 0;
|
||||
|
||||
if (DATA_WIDTH < 1) begin
|
||||
param_err_flg = 1;
|
||||
$display("ERROR: %m :\n Invalid value (%d) for parameter DATA_WIDTH (legal range: greater than 1)", DATA_WIDTH );
|
||||
end
|
||||
|
||||
if (DATA_DEPTH < 1) begin
|
||||
param_err_flg = 1;
|
||||
$display("ERROR: %m :\n Invalid value (%d) for parameter DATA_DEPTH (legal range: greater than 1)", DATA_DEPTH );
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
`ifndef PULP_FPGA_EMUL
|
||||
cluster_clock_gating cg_cell
|
||||
(
|
||||
.clk_i ( clk ),
|
||||
.en_i (~gate_clock ),
|
||||
.test_en_i ( test_mode_i ),
|
||||
.clk_o ( clk_gated )
|
||||
);
|
||||
`else
|
||||
assign clk_gated = clk;
|
||||
`endif
|
||||
|
||||
// UPDATE THE STATE
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin
|
||||
if(rst_n == 1'b0)
|
||||
begin
|
||||
CS <= EMPTY;
|
||||
Pop_Pointer_CS <= {ADDR_DEPTH {1'b0}};
|
||||
Push_Pointer_CS <= {ADDR_DEPTH {1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
CS <= NS;
|
||||
Pop_Pointer_CS <= Pop_Pointer_NS;
|
||||
Push_Pointer_CS <= Push_Pointer_NS;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Compute Next State
|
||||
always_comb
|
||||
begin
|
||||
gate_clock = 1'b0;
|
||||
|
||||
case(CS)
|
||||
|
||||
EMPTY:
|
||||
begin
|
||||
grant_o = 1'b1;
|
||||
valid_o = 1'b0;
|
||||
|
||||
case(valid_i)
|
||||
1'b0 :
|
||||
begin
|
||||
NS = EMPTY;
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
gate_clock = 1'b1;
|
||||
end
|
||||
|
||||
1'b1:
|
||||
begin
|
||||
NS = MIDDLE;
|
||||
Push_Pointer_NS = Push_Pointer_CS + 1'b1;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
|
||||
endcase
|
||||
end//~EMPTY
|
||||
|
||||
MIDDLE:
|
||||
begin
|
||||
grant_o = 1'b1;
|
||||
valid_o = 1'b1;
|
||||
|
||||
case({valid_i,grant_i})
|
||||
|
||||
2'b01:
|
||||
begin
|
||||
gate_clock = 1'b1;
|
||||
|
||||
if((Pop_Pointer_CS == Push_Pointer_CS -1 ) || ((Pop_Pointer_CS == DATA_DEPTH-1) && (Push_Pointer_CS == 0) ))
|
||||
NS = EMPTY;
|
||||
else
|
||||
NS = MIDDLE;
|
||||
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
|
||||
if(Pop_Pointer_CS == DATA_DEPTH-1)
|
||||
Pop_Pointer_NS = 0;
|
||||
else
|
||||
Pop_Pointer_NS = Pop_Pointer_CS + 1'b1;
|
||||
end
|
||||
|
||||
2'b00 :
|
||||
begin
|
||||
gate_clock = 1'b1;
|
||||
NS = MIDDLE;
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
|
||||
2'b11:
|
||||
begin
|
||||
NS = MIDDLE;
|
||||
|
||||
if(Push_Pointer_CS == DATA_DEPTH-1)
|
||||
Push_Pointer_NS = 0;
|
||||
else
|
||||
Push_Pointer_NS = Push_Pointer_CS + 1'b1;
|
||||
|
||||
if(Pop_Pointer_CS == DATA_DEPTH-1)
|
||||
Pop_Pointer_NS = 0;
|
||||
else
|
||||
Pop_Pointer_NS = Pop_Pointer_CS + 1'b1;
|
||||
end
|
||||
|
||||
2'b10:
|
||||
begin
|
||||
if(( Push_Pointer_CS == Pop_Pointer_CS - 1) || ( (Push_Pointer_CS == DATA_DEPTH-1) && (Pop_Pointer_CS == 0) ))
|
||||
NS = FULL;
|
||||
else
|
||||
NS = MIDDLE;
|
||||
|
||||
if(Push_Pointer_CS == DATA_DEPTH - 1)
|
||||
Push_Pointer_NS = 0;
|
||||
else
|
||||
Push_Pointer_NS = Push_Pointer_CS + 1'b1;
|
||||
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
FULL:
|
||||
begin
|
||||
grant_o = 1'b0;
|
||||
valid_o = 1'b1;
|
||||
gate_clock = 1'b1;
|
||||
|
||||
case(grant_i)
|
||||
1'b1:
|
||||
begin
|
||||
NS = MIDDLE;
|
||||
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
|
||||
if(Pop_Pointer_CS == DATA_DEPTH-1)
|
||||
Pop_Pointer_NS = 0;
|
||||
else
|
||||
Pop_Pointer_NS = Pop_Pointer_CS + 1'b1;
|
||||
end
|
||||
|
||||
1'b0:
|
||||
begin
|
||||
NS = FULL;
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
endcase
|
||||
|
||||
end // end of FULL
|
||||
|
||||
default :
|
||||
begin
|
||||
gate_clock = 1'b1;
|
||||
grant_o = 1'b0;
|
||||
valid_o = 1'b0;
|
||||
NS = EMPTY;
|
||||
Pop_Pointer_NS = 0;
|
||||
Push_Pointer_NS = 0;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_gated, negedge rst_n)
|
||||
begin
|
||||
if(rst_n == 1'b0)
|
||||
begin
|
||||
for (i=0; i< DATA_DEPTH; i++)
|
||||
FIFO_REGISTERS[i] <= {DATA_WIDTH {1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
if((grant_o == 1'b1) && (valid_i == 1'b1))
|
||||
FIFO_REGISTERS[Push_Pointer_CS] <= data_i;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_o = FIFO_REGISTERS[Pop_Pointer_CS];
|
||||
|
||||
endmodule // generic_fifo
|
264
vendor/pulp-platform/common_cells/src/deprecated/generic_fifo_adv.sv
vendored
Normal file
264
vendor/pulp-platform/common_cells/src/deprecated/generic_fifo_adv.sv
vendored
Normal file
|
@ -0,0 +1,264 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Igor Loi <igor.loi@unibo.it>
|
||||
|
||||
module generic_fifo_adv
|
||||
#(
|
||||
parameter int unsigned DATA_WIDTH = 32,
|
||||
parameter int unsigned DATA_DEPTH = 8
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic clear_i,
|
||||
|
||||
//PUSH SIDE
|
||||
input logic [DATA_WIDTH-1:0] data_i,
|
||||
input logic valid_i,
|
||||
output logic grant_o,
|
||||
|
||||
//POP SIDE
|
||||
output logic [DATA_WIDTH-1:0] data_o,
|
||||
output logic valid_o,
|
||||
input logic grant_i,
|
||||
|
||||
input logic test_mode_i
|
||||
);
|
||||
|
||||
|
||||
// Local Parameter
|
||||
localparam int unsigned ADDR_DEPTH = $clog2(DATA_DEPTH);
|
||||
enum logic [1:0] { EMPTY, FULL, MIDDLE } CS, NS;
|
||||
// Internal Signals
|
||||
|
||||
logic gate_clock;
|
||||
logic clk_gated;
|
||||
|
||||
logic [ADDR_DEPTH-1:0] Pop_Pointer_CS, Pop_Pointer_NS;
|
||||
logic [ADDR_DEPTH-1:0] Push_Pointer_CS, Push_Pointer_NS;
|
||||
logic [DATA_WIDTH-1:0] FIFO_REGISTERS[DATA_DEPTH-1:0];
|
||||
int unsigned i;
|
||||
|
||||
// Parameter Check
|
||||
// synopsys translate_off
|
||||
initial
|
||||
begin : parameter_check
|
||||
integer param_err_flg;
|
||||
param_err_flg = 0;
|
||||
|
||||
if (DATA_WIDTH < 1)
|
||||
begin
|
||||
param_err_flg = 1;
|
||||
$display("ERROR: %m :\n Invalid value (%d) for parameter DATA_WIDTH (legal range: greater than 1)", DATA_WIDTH );
|
||||
end
|
||||
|
||||
if (DATA_DEPTH < 1)
|
||||
begin
|
||||
param_err_flg = 1;
|
||||
$display("ERROR: %m :\n Invalid value (%d) for parameter DATA_DEPTH (legal range: greater than 1)", DATA_DEPTH );
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
`ifndef PULP_FPGA_EMUL
|
||||
cluster_clock_gating cg_cell
|
||||
(
|
||||
.clk_i ( clk ),
|
||||
.en_i (~gate_clock ),
|
||||
.test_en_i ( test_mode_i ),
|
||||
.clk_o ( clk_gated )
|
||||
);
|
||||
`else
|
||||
assign clk_gated = clk;
|
||||
`endif
|
||||
|
||||
// UPDATE THE STATE
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin
|
||||
if(rst_n == 1'b0)
|
||||
begin
|
||||
CS <= EMPTY;
|
||||
Pop_Pointer_CS <= {ADDR_DEPTH {1'b0}};
|
||||
Push_Pointer_CS <= {ADDR_DEPTH {1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(clear_i)
|
||||
begin
|
||||
CS <= EMPTY;
|
||||
Pop_Pointer_CS <= {ADDR_DEPTH {1'b0}};
|
||||
Push_Pointer_CS <= {ADDR_DEPTH {1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
CS <= NS;
|
||||
Pop_Pointer_CS <= Pop_Pointer_NS;
|
||||
Push_Pointer_CS <= Push_Pointer_NS;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Compute Next State
|
||||
always_comb
|
||||
begin
|
||||
gate_clock = 1'b0;
|
||||
|
||||
case(CS)
|
||||
|
||||
EMPTY:
|
||||
begin
|
||||
grant_o = 1'b1;
|
||||
valid_o = 1'b0;
|
||||
|
||||
case(valid_i)
|
||||
1'b0 :
|
||||
begin
|
||||
NS = EMPTY;
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
gate_clock = 1'b1;
|
||||
end
|
||||
|
||||
1'b1:
|
||||
begin
|
||||
NS = MIDDLE;
|
||||
Push_Pointer_NS = Push_Pointer_CS + 1'b1;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
|
||||
endcase
|
||||
end//~EMPTY
|
||||
|
||||
MIDDLE:
|
||||
begin
|
||||
grant_o = 1'b1;
|
||||
valid_o = 1'b1;
|
||||
|
||||
case({valid_i,grant_i})
|
||||
|
||||
2'b01:
|
||||
begin
|
||||
gate_clock = 1'b1;
|
||||
|
||||
if((Pop_Pointer_CS == Push_Pointer_CS -1 ) || ((Pop_Pointer_CS == DATA_DEPTH-1) && (Push_Pointer_CS == 0) ))
|
||||
NS = EMPTY;
|
||||
else
|
||||
NS = MIDDLE;
|
||||
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
|
||||
if(Pop_Pointer_CS == DATA_DEPTH-1)
|
||||
Pop_Pointer_NS = 0;
|
||||
else
|
||||
Pop_Pointer_NS = Pop_Pointer_CS + 1'b1;
|
||||
end
|
||||
|
||||
2'b00 :
|
||||
begin
|
||||
gate_clock = 1'b1;
|
||||
NS = MIDDLE;
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
|
||||
2'b11:
|
||||
begin
|
||||
NS = MIDDLE;
|
||||
|
||||
if(Push_Pointer_CS == DATA_DEPTH-1)
|
||||
Push_Pointer_NS = 0;
|
||||
else
|
||||
Push_Pointer_NS = Push_Pointer_CS + 1'b1;
|
||||
|
||||
if(Pop_Pointer_CS == DATA_DEPTH-1)
|
||||
Pop_Pointer_NS = 0;
|
||||
else
|
||||
Pop_Pointer_NS = Pop_Pointer_CS + 1'b1;
|
||||
end
|
||||
|
||||
2'b10:
|
||||
begin
|
||||
if(( Push_Pointer_CS == Pop_Pointer_CS - 1) || ( (Push_Pointer_CS == DATA_DEPTH-1) && (Pop_Pointer_CS == 0) ))
|
||||
NS = FULL;
|
||||
else
|
||||
NS = MIDDLE;
|
||||
|
||||
if(Push_Pointer_CS == DATA_DEPTH - 1)
|
||||
Push_Pointer_NS = 0;
|
||||
else
|
||||
Push_Pointer_NS = Push_Pointer_CS + 1'b1;
|
||||
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
FULL:
|
||||
begin
|
||||
grant_o = 1'b0;
|
||||
valid_o = 1'b1;
|
||||
gate_clock = 1'b1;
|
||||
|
||||
case(grant_i)
|
||||
1'b1:
|
||||
begin
|
||||
NS = MIDDLE;
|
||||
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
|
||||
if(Pop_Pointer_CS == DATA_DEPTH-1)
|
||||
Pop_Pointer_NS = 0;
|
||||
else
|
||||
Pop_Pointer_NS = Pop_Pointer_CS + 1'b1;
|
||||
end
|
||||
|
||||
1'b0:
|
||||
begin
|
||||
NS = FULL;
|
||||
Push_Pointer_NS = Push_Pointer_CS;
|
||||
Pop_Pointer_NS = Pop_Pointer_CS;
|
||||
end
|
||||
endcase
|
||||
|
||||
end // end of FULL
|
||||
|
||||
default :
|
||||
begin
|
||||
gate_clock = 1'b1;
|
||||
grant_o = 1'b0;
|
||||
valid_o = 1'b0;
|
||||
NS = EMPTY;
|
||||
Pop_Pointer_NS = 0;
|
||||
Push_Pointer_NS = 0;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_gated, negedge rst_n)
|
||||
begin
|
||||
if(rst_n == 1'b0)
|
||||
begin
|
||||
for (i=0; i< DATA_DEPTH; i++)
|
||||
FIFO_REGISTERS[i] <= {DATA_WIDTH {1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
if((grant_o == 1'b1) && (valid_i == 1'b1))
|
||||
FIFO_REGISTERS[Push_Pointer_CS] <= data_i;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_o = FIFO_REGISTERS[Pop_Pointer_CS];
|
||||
|
||||
endmodule // generic_fifo
|
89
vendor/pulp-platform/common_cells/src/deprecated/prioarbiter.sv
vendored
Normal file
89
vendor/pulp-platform/common_cells/src/deprecated/prioarbiter.sv
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 16.03.2019
|
||||
// Description: Priority arbiter with Lock in. Port 0 has priority over port 1, port 1 over port2
|
||||
// and so on. If the `LOCK_IN` feature is activated the arbitration decision is kept
|
||||
// when the `en_i` is low.
|
||||
|
||||
// Dependencies: relies on fast leading zero counter tree "onehot_to_bin" in common_cells
|
||||
module prioarbiter #(
|
||||
parameter int unsigned NUM_REQ = 13,
|
||||
parameter int unsigned LOCK_IN = 0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input logic flush_i, // clears the fsm and control signal registers
|
||||
input logic en_i, // arbiter enable
|
||||
input logic [NUM_REQ-1:0] req_i, // request signals
|
||||
|
||||
output logic [NUM_REQ-1:0] ack_o, // acknowledge signals
|
||||
output logic vld_o, // request ack'ed
|
||||
output logic [$clog2(NUM_REQ)-1:0] idx_o // idx output
|
||||
);
|
||||
|
||||
localparam SEL_WIDTH = $clog2(NUM_REQ);
|
||||
|
||||
logic [SEL_WIDTH-1:0] arb_sel_lock_d, arb_sel_lock_q;
|
||||
logic lock_d, lock_q;
|
||||
|
||||
logic [$clog2(NUM_REQ)-1:0] idx;
|
||||
|
||||
// shared
|
||||
assign vld_o = (|req_i) & en_i;
|
||||
assign idx_o = (lock_q) ? arb_sel_lock_q : idx;
|
||||
|
||||
// Arbiter
|
||||
// Port 0 has priority over all other ports
|
||||
assign ack_o[0] = (req_i[0]) ? en_i : 1'b0;
|
||||
// check that the priorities
|
||||
for (genvar i = 1; i < NUM_REQ; i++) begin : gen_arb_req_ports
|
||||
// for every subsequent port check the priorities of the previous port
|
||||
assign ack_o[i] = (req_i[i] & ~(|ack_o[i-1:0])) ? en_i : 1'b0;
|
||||
end
|
||||
|
||||
onehot_to_bin #(
|
||||
.ONEHOT_WIDTH ( NUM_REQ )
|
||||
) i_onehot_to_bin (
|
||||
.onehot ( ack_o ),
|
||||
.bin ( idx )
|
||||
);
|
||||
|
||||
if (LOCK_IN) begin : gen_lock_in
|
||||
// latch decision in case we got at least one req and no acknowledge
|
||||
assign lock_d = (|req_i) & ~en_i;
|
||||
assign arb_sel_lock_d = idx_o;
|
||||
end else begin
|
||||
// disable
|
||||
assign lock_d = '0;
|
||||
assign arb_sel_lock_d = '0;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
|
||||
if (!rst_ni) begin
|
||||
lock_q <= 1'b0;
|
||||
arb_sel_lock_q <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
lock_q <= 1'b0;
|
||||
arb_sel_lock_q <= '0;
|
||||
end else begin
|
||||
lock_q <= lock_d;
|
||||
arb_sel_lock_q <= arb_sel_lock_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule : prioarbiter
|
||||
|
||||
|
||||
|
36
vendor/pulp-platform/common_cells/src/deprecated/pulp_sync.sv
vendored
Normal file
36
vendor/pulp-platform/common_cells/src/deprecated/pulp_sync.sv
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module pulp_sync
|
||||
#(
|
||||
parameter STAGES = 2
|
||||
)
|
||||
(
|
||||
input logic clk_i,
|
||||
input logic rstn_i,
|
||||
input logic serial_i,
|
||||
output logic serial_o
|
||||
);
|
||||
|
||||
logic [STAGES-1:0] r_reg;
|
||||
|
||||
always_ff @(posedge clk_i, negedge rstn_i)
|
||||
begin
|
||||
if(!rstn_i)
|
||||
r_reg <= 'h0;
|
||||
else
|
||||
r_reg <= {r_reg[STAGES-2:0], serial_i};
|
||||
end
|
||||
|
||||
assign serial_o = r_reg[STAGES-1];
|
||||
|
||||
endmodule
|
55
vendor/pulp-platform/common_cells/src/deprecated/pulp_sync_wedge.sv
vendored
Normal file
55
vendor/pulp-platform/common_cells/src/deprecated/pulp_sync_wedge.sv
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module pulp_sync_wedge #(
|
||||
parameter int unsigned STAGES = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rstn_i,
|
||||
input logic en_i,
|
||||
input logic serial_i,
|
||||
output logic r_edge_o,
|
||||
output logic f_edge_o,
|
||||
output logic serial_o
|
||||
);
|
||||
logic clk;
|
||||
logic serial, serial_q;
|
||||
|
||||
assign serial_o = serial_q;
|
||||
assign f_edge_o = ~serial & serial_q;
|
||||
assign r_edge_o = serial & ~serial_q;
|
||||
|
||||
pulp_sync #(
|
||||
.STAGES(STAGES)
|
||||
) i_pulp_sync (
|
||||
.clk_i,
|
||||
.rstn_i,
|
||||
.serial_i,
|
||||
.serial_o ( serial )
|
||||
);
|
||||
|
||||
pulp_clock_gating i_pulp_clock_gating (
|
||||
.clk_i,
|
||||
.en_i,
|
||||
.test_en_i ( 1'b0 ),
|
||||
.clk_o ( clk )
|
||||
);
|
||||
|
||||
always_ff @(posedge clk, negedge rstn_i) begin
|
||||
if (!rstn_i) begin
|
||||
serial_q <= 1'b0;
|
||||
end else begin
|
||||
serial_q <= serial;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
61
vendor/pulp-platform/common_cells/src/deprecated/rrarbiter.sv
vendored
Normal file
61
vendor/pulp-platform/common_cells/src/deprecated/rrarbiter.sv
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 16.08.2018
|
||||
// Description: Fair round robin arbiter with lock feature.
|
||||
//
|
||||
// The rrarbiter employs fair round robin arbitration - i.e. the priorities
|
||||
// rotate each cycle.
|
||||
//
|
||||
// The lock-in feature prevents the arbiter from changing the arbitration
|
||||
// decision when the arbiter is disabled. I.e., the index of the first request
|
||||
// that wins the arbitration will be locked until en_i is asserted again.
|
||||
//
|
||||
// Dependencies: relies on rr_arb_tree from common_cells.
|
||||
|
||||
module rrarbiter #(
|
||||
parameter int unsigned NUM_REQ = 64,
|
||||
parameter bit LOCK_IN = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input logic flush_i, // clears arbiter state
|
||||
input logic en_i, // arbiter enable
|
||||
input logic [NUM_REQ-1:0] req_i, // request signals
|
||||
|
||||
output logic [NUM_REQ-1:0] ack_o, // acknowledge signals
|
||||
output logic vld_o, // request ack'ed
|
||||
output logic [$clog2(NUM_REQ)-1:0] idx_o // idx output
|
||||
);
|
||||
|
||||
logic req;
|
||||
assign vld_o = (|req_i) & en_i;
|
||||
|
||||
rr_arb_tree #(
|
||||
.NumIn ( NUM_REQ ),
|
||||
.DataWidth ( 1 ),
|
||||
.LockIn ( LOCK_IN ))
|
||||
i_rr_arb_tree (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.flush_i ( flush_i ),
|
||||
.rr_i ( '0 ),
|
||||
.req_i ( req_i ),
|
||||
.gnt_o ( ack_o ),
|
||||
.data_i ( '0 ),
|
||||
.gnt_i ( en_i & req ),
|
||||
.req_o ( req ),
|
||||
.data_o ( ),
|
||||
.idx_o ( idx_o )
|
||||
);
|
||||
|
||||
endmodule : rrarbiter
|
46
vendor/pulp-platform/common_cells/src/deprecated/sram.sv
vendored
Normal file
46
vendor/pulp-platform/common_cells/src/deprecated/sram.sv
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2017, 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Date: 13.10.2017
|
||||
// Description: SRAM Behavioral Model
|
||||
|
||||
module sram #(
|
||||
int unsigned DATA_WIDTH = 64,
|
||||
int unsigned NUM_WORDS = 1024
|
||||
)(
|
||||
input logic clk_i,
|
||||
|
||||
input logic req_i,
|
||||
input logic we_i,
|
||||
input logic [$clog2(NUM_WORDS)-1:0] addr_i,
|
||||
input logic [DATA_WIDTH-1:0] wdata_i,
|
||||
input logic [DATA_WIDTH-1:0] be_i,
|
||||
output logic [DATA_WIDTH-1:0] rdata_o
|
||||
);
|
||||
localparam ADDR_WIDTH = $clog2(NUM_WORDS);
|
||||
|
||||
logic [DATA_WIDTH-1:0] ram [NUM_WORDS-1:0];
|
||||
logic [ADDR_WIDTH-1:0] raddr_q;
|
||||
|
||||
// 1. randomize array
|
||||
// 2. randomize output when no request is active
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (req_i) begin
|
||||
if (!we_i)
|
||||
raddr_q <= addr_i;
|
||||
else
|
||||
for (int i = 0; i < DATA_WIDTH; i++)
|
||||
if (be_i[i]) ram[addr_i][i] <= wdata_i[i];
|
||||
end
|
||||
end
|
||||
|
||||
assign rdata_o = ram[raddr_q];
|
||||
|
||||
endmodule
|
128
vendor/pulp-platform/common_cells/src/ecc_decode.sv
vendored
Normal file
128
vendor/pulp-platform/common_cells/src/ecc_decode.sv
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
//
|
||||
/// # ECC Decoder
|
||||
///
|
||||
/// Implements SECDED (Single Error Correction, Double Error Detection) Hamming Code
|
||||
/// with extended parity bit [1].
|
||||
/// The module receives a data word including parity bit and decodes it according to the
|
||||
/// number of data and parity bit.
|
||||
///
|
||||
/// 1. If no error has been detected, the syndrome will be zero and all flags will be zero.
|
||||
/// 2. If a single error has been detected, the syndrome is non-zero, and `single_error_o` will be
|
||||
/// asserted. The output word contains the corrected data.
|
||||
/// 3. If the parity bit contained an error, the module will assert `parity_error_o`.
|
||||
/// 4. In case of a double fault the syndrome is non-zero, `double_error_o` will be asserted.
|
||||
/// All other status flags will be de-asserted.
|
||||
///
|
||||
/// [1] https://en.wikipedia.org/wiki/Hamming_code
|
||||
|
||||
module ecc_decode import ecc_pkg::*; #(
|
||||
/// Data width of unencoded word.
|
||||
parameter int unsigned DataWidth = 64,
|
||||
// Do not change
|
||||
parameter type data_t = logic [DataWidth-1:0],
|
||||
parameter type parity_t = logic [get_parity_width(DataWidth)-1:0],
|
||||
parameter type code_word_t = logic [get_cw_width(DataWidth)-1:0],
|
||||
parameter type encoded_data_t = struct packed {
|
||||
logic parity;
|
||||
code_word_t code_word;
|
||||
}
|
||||
) (
|
||||
/// Encoded data in
|
||||
input encoded_data_t data_i,
|
||||
/// Corrected data out
|
||||
output data_t data_o,
|
||||
/// Error syndrome indicates the erroneous bit position
|
||||
output parity_t syndrome_o,
|
||||
/// A single error occurred
|
||||
output logic single_error_o,
|
||||
/// Error received in parity bit (MSB)
|
||||
output logic parity_error_o,
|
||||
/// A double error occurred
|
||||
output logic double_error_o
|
||||
);
|
||||
|
||||
logic parity;
|
||||
data_t data_wo_parity;
|
||||
parity_t syndrome;
|
||||
logic syndrome_not_zero;
|
||||
code_word_t correct_data;
|
||||
|
||||
// Check parity bit. 0 = parity equal, 1 = different parity
|
||||
assign parity = data_i.parity ^ (^data_i.code_word);
|
||||
|
||||
///! | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
///! |p1 p2 d1 p4 d2 d3 d4 p8 d5 d6 d7 d8 d9 d10 d11
|
||||
///! ---|----------------------------------------------
|
||||
///! p1 | x x x x x x x x
|
||||
///! p2 | x x x x x x x x
|
||||
///! p4 | x x x x x x x x
|
||||
///! p8 | x x x x x x x x
|
||||
|
||||
///! 1. Parity bit 1 covers all bit positions which have the least significant bit
|
||||
///! set: bit 1 (the parity bit itself), 3, 5, 7, 9, etc.
|
||||
///! 2. Parity bit 2 covers all bit positions which have the second least
|
||||
///! significant bit set: bit 2 (the parity bit itself), 3, 6, 7, 10, 11, etc.
|
||||
///! 3. Parity bit 4 covers all bit positions which have the third least
|
||||
///! significant bit set: bits 4–7, 12–15, 20–23, etc.
|
||||
///! 4. Parity bit 8 covers all bit positions which have the fourth least
|
||||
///! significant bit set: bits 8–15, 24–31, 40–47, etc.
|
||||
///! 5. In general each parity bit covers all bits where the bitwise AND of the
|
||||
///! parity position and the bit position is non-zero.
|
||||
always_comb begin : calculate_syndrome
|
||||
syndrome = 0;
|
||||
for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
|
||||
for (int unsigned j = 0; j < unsigned'($bits(code_word_t)); j++) begin
|
||||
if (|(unsigned'(2**i) & (j + 1))) syndrome[i] = syndrome[i] ^ data_i.code_word[j];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign syndrome_not_zero = |syndrome;
|
||||
|
||||
// correct the data word if the syndrome is non-zero
|
||||
always_comb begin
|
||||
correct_data = data_i.code_word;
|
||||
if (syndrome_not_zero) begin
|
||||
correct_data[syndrome - 1] = ~data_i.code_word[syndrome - 1];
|
||||
end
|
||||
end
|
||||
|
||||
///! Syndrome | Overall Parity (MSB) | Error Type | Notes
|
||||
///! --------------------------------------------------------
|
||||
///! 0 | 0 | No Error |
|
||||
///! /=0 | 1 | Single Error | Correctable. Syndrome holds incorrect bit position.
|
||||
///! 0 | 1 | Parity Error | Overall parity, MSB is in error and can be corrected.
|
||||
///! /=0 | 0 | Double Error | Not correctable.
|
||||
assign single_error_o = parity & syndrome_not_zero;
|
||||
assign parity_error_o = parity & ~syndrome_not_zero;
|
||||
assign double_error_o = ~parity & syndrome_not_zero;
|
||||
|
||||
// Extract data vector
|
||||
always_comb begin
|
||||
automatic int unsigned idx; // bit index
|
||||
data_wo_parity = '0;
|
||||
idx = 0;
|
||||
|
||||
for (int unsigned i = 1; i < unsigned'($bits(code_word_t)) + 1; i++) begin
|
||||
// if i is a power of two we are indexing a parity bit
|
||||
if (unsigned'(2**$clog2(i)) != i) begin
|
||||
data_wo_parity[idx] = correct_data[i - 1];
|
||||
idx++;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign data_o = data_wo_parity;
|
||||
|
||||
endmodule
|
78
vendor/pulp-platform/common_cells/src/ecc_encode.sv
vendored
Normal file
78
vendor/pulp-platform/common_cells/src/ecc_encode.sv
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
/// # ECC Encoder
|
||||
///
|
||||
/// Implements SECDED (Single Error Correction, Double Error Detection) Hamming Code
|
||||
/// with extended parity bit [1].
|
||||
/// The module receives a data word and encodes it using above mentioned error
|
||||
/// detection and correction code. The corresponding decode module
|
||||
/// can be found in `ecc_decode.sv`
|
||||
///
|
||||
/// [1] https://en.wikipedia.org/wiki/Hamming_code
|
||||
|
||||
module ecc_encode import ecc_pkg::*; #(
|
||||
/// Data width of unencoded word.
|
||||
parameter int unsigned DataWidth = 64,
|
||||
// Do not change
|
||||
parameter type data_t = logic [DataWidth-1:0],
|
||||
parameter type parity_t = logic [get_parity_width(DataWidth)-1:0],
|
||||
parameter type code_word_t = logic [get_cw_width(DataWidth)-1:0],
|
||||
parameter type encoded_data_t = struct packed {
|
||||
logic parity;
|
||||
code_word_t code_word;
|
||||
}
|
||||
) (
|
||||
/// Unencoded data in
|
||||
input data_t data_i,
|
||||
/// Encoded data out
|
||||
output encoded_data_t data_o
|
||||
);
|
||||
|
||||
parity_t parity_code_word;
|
||||
code_word_t data, codeword;
|
||||
|
||||
// Expand incoming data to codeword width
|
||||
always_comb begin : expand_data
|
||||
automatic int unsigned idx;
|
||||
data = '0;
|
||||
idx = 0;
|
||||
for (int unsigned i = 1; i < unsigned'($bits(code_word_t)) + 1; i++) begin
|
||||
// if it is not a power of two word it is a normal data index
|
||||
if (unsigned'(2**$clog2(i)) != i) begin
|
||||
data[i - 1] = data_i[idx];
|
||||
idx++;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// calculate code word
|
||||
always_comb begin : calculate_syndrome
|
||||
parity_code_word = 0;
|
||||
for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
|
||||
for (int unsigned j = 1; j < unsigned'($bits(code_word_t)) + 1; j++) begin
|
||||
if (|(unsigned'(2**i) & j)) parity_code_word[i] = parity_code_word[i] ^ data[j - 1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// fuse the final codeword
|
||||
always_comb begin : generate_codeword
|
||||
codeword = data;
|
||||
for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
|
||||
codeword[2**i-1] = parity_code_word[i];
|
||||
end
|
||||
end
|
||||
|
||||
assign data_o.code_word = codeword;
|
||||
assign data_o.parity = ^codeword;
|
||||
|
||||
endmodule
|
31
vendor/pulp-platform/common_cells/src/ecc_pkg.sv
vendored
Normal file
31
vendor/pulp-platform/common_cells/src/ecc_pkg.sv
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
//
|
||||
/// Contains common ECC definitions and helper functions.
|
||||
|
||||
package ecc_pkg;
|
||||
|
||||
// Calculate required ECC parity width:
|
||||
function automatic int unsigned get_parity_width (input int unsigned data_width);
|
||||
// data_width + cw_width + 1 <= 2**cw_width
|
||||
int unsigned cw_width = 2;
|
||||
while (unsigned'(2**cw_width) < cw_width + data_width + 1) cw_width++;
|
||||
return cw_width;
|
||||
endfunction
|
||||
|
||||
// Calculate required ECC codeword width:
|
||||
function automatic int unsigned get_cw_width (input int unsigned data_width);
|
||||
// data width + parity width + one additional parity bit (for double error detection)
|
||||
return data_width + get_parity_width(data_width);
|
||||
endfunction
|
||||
|
||||
endpackage
|
32
vendor/pulp-platform/common_cells/src/edge_detect.sv
vendored
Normal file
32
vendor/pulp-platform/common_cells/src/edge_detect.sv
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba
|
||||
// Description: Edge detector, clock needs to oversample for proper edge detection
|
||||
|
||||
module edge_detect (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic d_i, // data stream in
|
||||
output logic re_o, // rising edge detected
|
||||
output logic fe_o // falling edge detected
|
||||
);
|
||||
|
||||
sync_wedge i_sync_wedge (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.en_i ( 1'b1 ),
|
||||
.serial_i ( d_i ),
|
||||
.r_edge_o ( re_o ),
|
||||
.f_edge_o ( fe_o ),
|
||||
.serial_o ( )
|
||||
);
|
||||
|
||||
endmodule
|
50
vendor/pulp-platform/common_cells/src/edge_propagator.sv
vendored
Normal file
50
vendor/pulp-platform/common_cells/src/edge_propagator.sv
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module edge_propagator (
|
||||
input logic clk_tx_i,
|
||||
input logic rstn_tx_i,
|
||||
input logic edge_i,
|
||||
input logic clk_rx_i,
|
||||
input logic rstn_rx_i,
|
||||
output logic edge_o
|
||||
);
|
||||
|
||||
logic [1:0] sync_a;
|
||||
logic sync_b;
|
||||
|
||||
logic r_input_reg;
|
||||
logic s_input_reg_next;
|
||||
|
||||
assign s_input_reg_next = edge_i | (r_input_reg & (~sync_a[0]));
|
||||
|
||||
always @(negedge rstn_tx_i or posedge clk_tx_i) begin
|
||||
if (~rstn_tx_i) begin
|
||||
r_input_reg <= 1'b0;
|
||||
sync_a <= 2'b00;
|
||||
end else begin
|
||||
r_input_reg <= s_input_reg_next;
|
||||
sync_a <= {sync_b,sync_a[1]};
|
||||
end
|
||||
end
|
||||
|
||||
pulp_sync_wedge i_sync_clkb (
|
||||
.clk_i ( clk_rx_i ),
|
||||
.rstn_i ( rstn_rx_i ),
|
||||
.en_i ( 1'b1 ),
|
||||
.serial_i ( r_input_reg ),
|
||||
.r_edge_o ( edge_o ),
|
||||
.f_edge_o ( ),
|
||||
.serial_o ( sync_b )
|
||||
);
|
||||
|
||||
endmodule
|
31
vendor/pulp-platform/common_cells/src/edge_propagator_rx.sv
vendored
Normal file
31
vendor/pulp-platform/common_cells/src/edge_propagator_rx.sv
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module edge_propagator_rx (
|
||||
input logic clk_i,
|
||||
input logic rstn_i,
|
||||
input logic valid_i,
|
||||
output logic ack_o,
|
||||
output logic valid_o
|
||||
);
|
||||
|
||||
pulp_sync_wedge i_sync_clkb (
|
||||
.clk_i ( clk_i ),
|
||||
.rstn_i ( rstn_i ),
|
||||
.en_i ( 1'b1 ),
|
||||
.serial_i ( valid_i ),
|
||||
.r_edge_o ( valid_o ),
|
||||
.f_edge_o ( ),
|
||||
.serial_o ( ack_o )
|
||||
);
|
||||
|
||||
endmodule
|
40
vendor/pulp-platform/common_cells/src/edge_propagator_tx.sv
vendored
Normal file
40
vendor/pulp-platform/common_cells/src/edge_propagator_tx.sv
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module edge_propagator_tx (
|
||||
input logic clk_i,
|
||||
input logic rstn_i,
|
||||
input logic valid_i,
|
||||
input logic ack_i,
|
||||
output logic valid_o
|
||||
);
|
||||
|
||||
logic [1:0] sync_a;
|
||||
|
||||
logic r_input_reg;
|
||||
logic s_input_reg_next;
|
||||
|
||||
assign s_input_reg_next = valid_i | (r_input_reg & ~sync_a[0]);
|
||||
|
||||
always @(negedge rstn_i or posedge clk_i) begin
|
||||
if (~rstn_i) begin
|
||||
r_input_reg <= 1'b0;
|
||||
sync_a <= 2'b00;
|
||||
end else begin
|
||||
r_input_reg <= s_input_reg_next;
|
||||
sync_a <= {ack_i,sync_a[1]};
|
||||
end
|
||||
end
|
||||
|
||||
assign valid_o = r_input_reg;
|
||||
|
||||
endmodule
|
98
vendor/pulp-platform/common_cells/src/exp_backoff.sv
vendored
Normal file
98
vendor/pulp-platform/common_cells/src/exp_backoff.sv
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 10.04.2019
|
||||
// Description: exponential backoff counter with randomization.
|
||||
//
|
||||
// For each failed trial (set_i pulsed), this unit exponentially increases the
|
||||
// (average) backoff time by masking an LFSR with a shifted mask in order to
|
||||
// create the backoff counter initial value.
|
||||
//
|
||||
// The shift register mask and the counter value are both reset to '0 in case of
|
||||
// a successful trial (clr_i).
|
||||
//
|
||||
|
||||
module exp_backoff #(
|
||||
/// Seed for 16bit LFSR
|
||||
parameter int unsigned Seed = 'hffff,
|
||||
/// 2**MaxExp-1 determines the maximum range from which random wait counts are drawn
|
||||
parameter int unsigned MaxExp = 16
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
/// Sets the backoff counter (pulse) -> use when trial did not succeed
|
||||
input logic set_i,
|
||||
/// Clears the backoff counter (pulse) -> use when trial succeeded
|
||||
input logic clr_i,
|
||||
/// Indicates whether the backoff counter is equal to zero and a new trial can be launched
|
||||
output logic is_zero_o
|
||||
);
|
||||
|
||||
// leave this constant
|
||||
localparam int unsigned WIDTH = 16;
|
||||
|
||||
logic [WIDTH-1:0] lfsr_d, lfsr_q, cnt_d, cnt_q, mask_d, mask_q;
|
||||
logic lfsr;
|
||||
|
||||
// generate random wait counts
|
||||
// note: we use a flipped lfsr here to
|
||||
// avoid strange correlation effects between
|
||||
// the (left-shifted) mask and the lfsr
|
||||
assign lfsr = lfsr_q[15-15] ^
|
||||
lfsr_q[15-13] ^
|
||||
lfsr_q[15-12] ^
|
||||
lfsr_q[15-10];
|
||||
|
||||
assign lfsr_d = (set_i) ? {lfsr, lfsr_q[$high(lfsr_q):1]} :
|
||||
lfsr_q;
|
||||
|
||||
// mask the wait counts with exponentially increasing mask (shift reg)
|
||||
assign mask_d = (clr_i) ? '0 :
|
||||
(set_i) ? {{(WIDTH-MaxExp){1'b0}},mask_q[MaxExp-2:0], 1'b1} :
|
||||
mask_q;
|
||||
|
||||
assign cnt_d = (clr_i) ? '0 :
|
||||
(set_i) ? (mask_q & lfsr_q) :
|
||||
(!is_zero_o) ? cnt_q - 1'b1 : '0;
|
||||
|
||||
assign is_zero_o = (cnt_q=='0);
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
|
||||
if (!rst_ni) begin
|
||||
lfsr_q <= WIDTH'(Seed);
|
||||
mask_q <= '0;
|
||||
cnt_q <= '0;
|
||||
end else begin
|
||||
lfsr_q <= lfsr_d;
|
||||
mask_q <= mask_d;
|
||||
cnt_q <= cnt_d;
|
||||
end
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// assertions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
//pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin
|
||||
// assert wrong parameterizations
|
||||
assert (MaxExp>0)
|
||||
else $fatal(1,"MaxExp must be greater than 0");
|
||||
assert (MaxExp<=16)
|
||||
else $fatal(1,"MaxExp cannot be greater than 16");
|
||||
assert (Seed>0)
|
||||
else $fatal(1,"Zero seed is not allowed for LFSR");
|
||||
end
|
||||
`endif
|
||||
//pragma translate_on
|
||||
|
||||
endmodule // exp_backoff
|
58
vendor/pulp-platform/common_cells/src/fall_through_register.sv
vendored
Normal file
58
vendor/pulp-platform/common_cells/src/fall_through_register.sv
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Fall-through register with a simple stream-like ready/valid handshake.
|
||||
// This register does not cut combinatorial paths on any signals: in case the module at its output
|
||||
// is ready to accept data within the same clock cycle, they are forwarded. Use this module to get a
|
||||
// 'default ready' behavior towards the input.
|
||||
module fall_through_register #(
|
||||
parameter type T = logic // Vivado requires a default value for type parameters.
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous active-low reset
|
||||
input logic clr_i, // Synchronous clear
|
||||
input logic testmode_i, // Test mode to bypass clock gating
|
||||
// Input port
|
||||
input logic valid_i,
|
||||
output logic ready_o,
|
||||
input T data_i,
|
||||
// Output port
|
||||
output logic valid_o,
|
||||
input logic ready_i,
|
||||
output T data_o
|
||||
);
|
||||
|
||||
logic fifo_empty,
|
||||
fifo_full;
|
||||
|
||||
fifo_v2 #(
|
||||
.FALL_THROUGH (1'b1),
|
||||
.DATA_WIDTH ($size(T)),
|
||||
.DEPTH (1),
|
||||
.dtype (T)
|
||||
) i_fifo (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.flush_i (clr_i),
|
||||
.testmode_i (testmode_i),
|
||||
.full_o (fifo_full),
|
||||
.empty_o (fifo_empty),
|
||||
.alm_full_o ( ),
|
||||
.alm_empty_o ( ),
|
||||
.data_i (data_i),
|
||||
.push_i (valid_i & ~fifo_full),
|
||||
.data_o (data_o),
|
||||
.pop_i (ready_i & ~fifo_empty)
|
||||
);
|
||||
|
||||
assign ready_o = ~fifo_full;
|
||||
assign valid_o = ~fifo_empty;
|
||||
|
||||
endmodule
|
154
vendor/pulp-platform/common_cells/src/fifo_v3.sv
vendored
Normal file
154
vendor/pulp-platform/common_cells/src/fifo_v3.sv
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module fifo_v3 #(
|
||||
parameter bit FALL_THROUGH = 1'b0, // fifo is in fall-through mode
|
||||
parameter int unsigned DATA_WIDTH = 32, // default data width if the fifo is of type logic
|
||||
parameter int unsigned DEPTH = 8, // depth can be arbitrary from 0 to 2**32
|
||||
parameter type dtype = logic [DATA_WIDTH-1:0],
|
||||
// DO NOT OVERWRITE THIS PARAMETER
|
||||
parameter int unsigned ADDR_DEPTH = (DEPTH > 1) ? $clog2(DEPTH) : 1
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // flush the queue
|
||||
input logic testmode_i, // test_mode to bypass clock gating
|
||||
// status flags
|
||||
output logic full_o, // queue is full
|
||||
output logic empty_o, // queue is empty
|
||||
output logic [ADDR_DEPTH-1:0] usage_o, // fill pointer
|
||||
// as long as the queue is not full we can push new data
|
||||
input dtype data_i, // data to push into the queue
|
||||
input logic push_i, // data is valid and can be pushed to the queue
|
||||
// as long as the queue is not empty we can pop new elements
|
||||
output dtype data_o, // output data
|
||||
input logic pop_i // pop head from queue
|
||||
);
|
||||
// local parameter
|
||||
// FIFO depth - handle the case of pass-through, synthesizer will do constant propagation
|
||||
localparam int unsigned FifoDepth = (DEPTH > 0) ? DEPTH : 1;
|
||||
// clock gating control
|
||||
logic gate_clock;
|
||||
// pointer to the read and write section of the queue
|
||||
logic [ADDR_DEPTH - 1:0] read_pointer_n, read_pointer_q, write_pointer_n, write_pointer_q;
|
||||
// keep a counter to keep track of the current queue status
|
||||
// this integer will be truncated by the synthesis tool
|
||||
logic [ADDR_DEPTH:0] status_cnt_n, status_cnt_q;
|
||||
// actual memory
|
||||
dtype [FifoDepth - 1:0] mem_n, mem_q;
|
||||
|
||||
assign usage_o = status_cnt_q[ADDR_DEPTH-1:0];
|
||||
|
||||
if (DEPTH == 0) begin : gen_pass_through
|
||||
assign empty_o = ~push_i;
|
||||
assign full_o = ~pop_i;
|
||||
end else begin : gen_fifo
|
||||
assign full_o = (status_cnt_q == FifoDepth[ADDR_DEPTH:0]);
|
||||
assign empty_o = (status_cnt_q == 0) & ~(FALL_THROUGH & push_i);
|
||||
end
|
||||
// status flags
|
||||
|
||||
// read and write queue logic
|
||||
always_comb begin : read_write_comb
|
||||
// default assignment
|
||||
read_pointer_n = read_pointer_q;
|
||||
write_pointer_n = write_pointer_q;
|
||||
status_cnt_n = status_cnt_q;
|
||||
data_o = (DEPTH == 0) ? data_i : mem_q[read_pointer_q];
|
||||
mem_n = mem_q;
|
||||
gate_clock = 1'b1;
|
||||
|
||||
// push a new element to the queue
|
||||
if (push_i && ~full_o) begin
|
||||
// push the data onto the queue
|
||||
mem_n[write_pointer_q] = data_i;
|
||||
// un-gate the clock, we want to write something
|
||||
gate_clock = 1'b0;
|
||||
// increment the write counter
|
||||
if (write_pointer_q == FifoDepth[ADDR_DEPTH-1:0] - 1)
|
||||
write_pointer_n = '0;
|
||||
else
|
||||
write_pointer_n = write_pointer_q + 1;
|
||||
// increment the overall counter
|
||||
status_cnt_n = status_cnt_q + 1;
|
||||
end
|
||||
|
||||
if (pop_i && ~empty_o) begin
|
||||
// read from the queue is a default assignment
|
||||
// but increment the read pointer...
|
||||
if (read_pointer_n == FifoDepth[ADDR_DEPTH-1:0] - 1)
|
||||
read_pointer_n = '0;
|
||||
else
|
||||
read_pointer_n = read_pointer_q + 1;
|
||||
// ... and decrement the overall count
|
||||
status_cnt_n = status_cnt_q - 1;
|
||||
end
|
||||
|
||||
// keep the count pointer stable if we push and pop at the same time
|
||||
if (push_i && pop_i && ~full_o && ~empty_o)
|
||||
status_cnt_n = status_cnt_q;
|
||||
|
||||
// FIFO is in pass through mode -> do not change the pointers
|
||||
if (FALL_THROUGH && (status_cnt_q == 0) && push_i) begin
|
||||
data_o = data_i;
|
||||
if (pop_i) begin
|
||||
status_cnt_n = status_cnt_q;
|
||||
read_pointer_n = read_pointer_q;
|
||||
write_pointer_n = write_pointer_q;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// sequential process
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if(~rst_ni) begin
|
||||
read_pointer_q <= '0;
|
||||
write_pointer_q <= '0;
|
||||
status_cnt_q <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
read_pointer_q <= '0;
|
||||
write_pointer_q <= '0;
|
||||
status_cnt_q <= '0;
|
||||
end else begin
|
||||
read_pointer_q <= read_pointer_n;
|
||||
write_pointer_q <= write_pointer_n;
|
||||
status_cnt_q <= status_cnt_n;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if(~rst_ni) begin
|
||||
mem_q <= '0;
|
||||
end else if (!gate_clock) begin
|
||||
mem_q <= mem_n;
|
||||
end
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin
|
||||
assert (DEPTH > 0) else $error("DEPTH must be greater than 0.");
|
||||
end
|
||||
|
||||
full_write : assert property(
|
||||
@(posedge clk_i) disable iff (~rst_ni) (full_o |-> ~push_i))
|
||||
else $fatal (1, "Trying to push new data although the FIFO is full.");
|
||||
|
||||
empty_read : assert property(
|
||||
@(posedge clk_i) disable iff (~rst_ni) (empty_o |-> ~pop_i))
|
||||
else $fatal (1, "Trying to pop data although the FIFO is empty.");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule // fifo_v3
|
23
vendor/pulp-platform/common_cells/src/gray_to_binary.sv
vendored
Normal file
23
vendor/pulp-platform/common_cells/src/gray_to_binary.sv
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
|
||||
/// A gray code to binary converter.
|
||||
module gray_to_binary #(
|
||||
parameter int N = -1
|
||||
)(
|
||||
input logic [N-1:0] A,
|
||||
output logic [N-1:0] Z
|
||||
);
|
||||
for (genvar i = 0; i < N; i++)
|
||||
assign Z[i] = ^A[N-1:i];
|
||||
endmodule
|
419
vendor/pulp-platform/common_cells/src/id_queue.sv
vendored
Normal file
419
vendor/pulp-platform/common_cells/src/id_queue.sv
vendored
Normal file
|
@ -0,0 +1,419 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// ID Queue
|
||||
//
|
||||
// In an ID queue, every element has a numeric ID. Among all elements that have the same ID, the ID
|
||||
// queue preserves FIFO order.
|
||||
//
|
||||
// This ID queue implementation allows to either push (through the `inp_*` signals) or pop (through
|
||||
// the `oup_*` signals) one element per clock cycle (depending on the _FULL_BW_ operating mode
|
||||
// descibed below). The `inp_` port has priority and grants a request iff the queue is not full. The
|
||||
// `oup_` port dequeues an element iff `oup_pop_i` is asserted during an `oup_` handshake;
|
||||
// otherwise, it performs a non-destructive read. `oup_data_o` is valid iff `oup_data_valid_o` is
|
||||
// asserted during an `oup_` handshake. If `oup_data_valid_o` is not asserted, the queue did not
|
||||
// contain an element with the provided ID.
|
||||
//
|
||||
// The queue can work in two bandwidth modes:
|
||||
// * !FULL_BW: Input and output cannot be performed simultaneously (max bandwidth: 50%).
|
||||
// * FULL_BW: Input and output can be performed simultaneously and a popped cell can be reused
|
||||
// immediately in the same clock cycle. Area increase typically 5-10%.
|
||||
//
|
||||
// This ID queue additionally provides the `exists_` port, which searches for an element anywhere in
|
||||
// the queue. The comparison performed during the search can be masked: for every bit that is
|
||||
// asserted in `exists_mask_i`, the corresponding bit in the queue element and in `exists_data_i`
|
||||
// must be equal for a match; the other bits are not compared. If masking is not required, tie
|
||||
// `exists_mask_i_ to `'1` and the synthesizer should simplify the comparisons to unmasked ones. The
|
||||
// `exists_` port operates independently of the `inp_` and `oup_` ports. If the `exists_` port is
|
||||
// unused, tie `exists_req_i` to `1'b0` and the synthesizer should remove the internal comparators.
|
||||
//
|
||||
// This ID queue can store at most `CAPACITY` elements, independent of their ID. Let
|
||||
// - C = `CAPACITY`
|
||||
// - B = $bits(data_t)
|
||||
// - I = 2**`ID_WIDTH`
|
||||
// Then
|
||||
// - the queue element storage requires O(C * (B + log2(C))) bit
|
||||
// - the ID table requires O(H * log2(C)) bit, where H = min(C, I)
|
||||
//
|
||||
// Maintainers:
|
||||
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
|
||||
|
||||
module id_queue #(
|
||||
parameter int ID_WIDTH = 0,
|
||||
parameter int CAPACITY = 0,
|
||||
parameter bit FULL_BW = 0,
|
||||
parameter type data_t = logic,
|
||||
// Dependent parameters, DO NOT OVERRIDE!
|
||||
localparam type id_t = logic[ID_WIDTH-1:0],
|
||||
localparam type mask_t = logic[$bits(data_t)-1:0]
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input id_t inp_id_i,
|
||||
input data_t inp_data_i,
|
||||
input logic inp_req_i,
|
||||
output logic inp_gnt_o,
|
||||
|
||||
input data_t exists_data_i,
|
||||
input mask_t exists_mask_i,
|
||||
input logic exists_req_i,
|
||||
output logic exists_o,
|
||||
output logic exists_gnt_o,
|
||||
|
||||
input id_t oup_id_i,
|
||||
input logic oup_pop_i,
|
||||
input logic oup_req_i,
|
||||
output data_t oup_data_o,
|
||||
output logic oup_data_valid_o,
|
||||
output logic oup_gnt_o
|
||||
);
|
||||
|
||||
// Capacity of the head-tail table, which associates an ID with corresponding head and tail
|
||||
// indices.
|
||||
localparam int NIds = 2**ID_WIDTH;
|
||||
localparam int HtCapacity = (NIds <= CAPACITY) ? NIds : CAPACITY;
|
||||
localparam int unsigned HtIdxWidth = cf_math_pkg::idx_width(HtCapacity);
|
||||
localparam int unsigned LdIdxWidth = cf_math_pkg::idx_width(CAPACITY);
|
||||
|
||||
// Type for indexing the head-tail table.
|
||||
typedef logic [HtIdxWidth-1:0] ht_idx_t;
|
||||
|
||||
// Type for indexing the lined data table.
|
||||
typedef logic [LdIdxWidth-1:0] ld_idx_t;
|
||||
|
||||
// Type of an entry in the head-tail table.
|
||||
typedef struct packed {
|
||||
id_t id;
|
||||
ld_idx_t head,
|
||||
tail;
|
||||
logic free;
|
||||
} head_tail_t;
|
||||
|
||||
// Type of an entry in the linked data table.
|
||||
typedef struct packed {
|
||||
data_t data;
|
||||
ld_idx_t next;
|
||||
logic free;
|
||||
} linked_data_t;
|
||||
|
||||
head_tail_t [HtCapacity-1:0] head_tail_d, head_tail_q;
|
||||
|
||||
linked_data_t [CAPACITY-1:0] linked_data_d, linked_data_q;
|
||||
|
||||
logic full,
|
||||
match_in_id_valid,
|
||||
match_out_id_valid,
|
||||
no_in_id_match,
|
||||
no_out_id_match;
|
||||
|
||||
logic [HtCapacity-1:0] head_tail_free,
|
||||
idx_matches_in_id,
|
||||
idx_matches_out_id;
|
||||
|
||||
logic [CAPACITY-1:0] exists_match,
|
||||
linked_data_free;
|
||||
|
||||
id_t match_in_id, match_out_id;
|
||||
|
||||
ht_idx_t head_tail_free_idx,
|
||||
match_in_idx,
|
||||
match_out_idx;
|
||||
|
||||
ld_idx_t linked_data_free_idx,
|
||||
oup_data_free_idx;
|
||||
|
||||
logic oup_data_popped,
|
||||
oup_ht_popped;
|
||||
|
||||
// Find the index in the head-tail table that matches a given ID.
|
||||
for (genvar i = 0; i < HtCapacity; i++) begin: gen_idx_match
|
||||
assign idx_matches_in_id[i] = match_in_id_valid && (head_tail_q[i].id == match_in_id) &&
|
||||
!head_tail_q[i].free;
|
||||
assign idx_matches_out_id[i] = match_out_id_valid && (head_tail_q[i].id == match_out_id) &&
|
||||
!head_tail_q[i].free;
|
||||
end
|
||||
assign no_in_id_match = !(|idx_matches_in_id);
|
||||
assign no_out_id_match = !(|idx_matches_out_id);
|
||||
onehot_to_bin #(
|
||||
.ONEHOT_WIDTH ( HtCapacity )
|
||||
) i_id_ohb_in (
|
||||
.onehot ( idx_matches_in_id ),
|
||||
.bin ( match_in_idx )
|
||||
);
|
||||
onehot_to_bin #(
|
||||
.ONEHOT_WIDTH ( HtCapacity )
|
||||
) i_id_ohb_out (
|
||||
.onehot ( idx_matches_out_id ),
|
||||
.bin ( match_out_idx )
|
||||
);
|
||||
|
||||
// Find the first free index in the head-tail table.
|
||||
for (genvar i = 0; i < HtCapacity; i++) begin: gen_head_tail_free
|
||||
assign head_tail_free[i] = head_tail_q[i].free;
|
||||
end
|
||||
lzc #(
|
||||
.WIDTH ( HtCapacity ),
|
||||
.MODE ( 0 ) // Start at index 0.
|
||||
) i_ht_free_lzc (
|
||||
.in_i ( head_tail_free ),
|
||||
.cnt_o ( head_tail_free_idx ),
|
||||
.empty_o ( )
|
||||
);
|
||||
|
||||
// Find the first free index in the linked data table.
|
||||
for (genvar i = 0; i < CAPACITY; i++) begin: gen_linked_data_free
|
||||
assign linked_data_free[i] = linked_data_q[i].free;
|
||||
end
|
||||
lzc #(
|
||||
.WIDTH ( CAPACITY ),
|
||||
.MODE ( 0 ) // Start at index 0.
|
||||
) i_ld_free_lzc (
|
||||
.in_i ( linked_data_free ),
|
||||
.cnt_o ( linked_data_free_idx ),
|
||||
.empty_o ( )
|
||||
);
|
||||
|
||||
// The queue is full if and only if there are no free items in the linked data structure.
|
||||
assign full = !(|linked_data_free);
|
||||
// Data potentially freed by the output.
|
||||
assign oup_data_free_idx = head_tail_q[match_out_idx].head;
|
||||
|
||||
// Data can be accepted if the linked list pool is not full, or some data is simultaneously.
|
||||
assign inp_gnt_o = ~full || (oup_data_popped && FULL_BW);
|
||||
always_comb begin
|
||||
match_in_id = '0;
|
||||
match_out_id = '0;
|
||||
match_in_id_valid = 1'b0;
|
||||
match_out_id_valid = 1'b0;
|
||||
head_tail_d = head_tail_q;
|
||||
linked_data_d = linked_data_q;
|
||||
oup_gnt_o = 1'b0;
|
||||
oup_data_o = data_t'('0);
|
||||
oup_data_valid_o = 1'b0;
|
||||
oup_data_popped = 1'b0;
|
||||
oup_ht_popped = 1'b0;
|
||||
|
||||
if (!FULL_BW) begin
|
||||
if (inp_req_i && !full) begin
|
||||
match_in_id = inp_id_i;
|
||||
match_in_id_valid = 1'b1;
|
||||
// If the ID does not yet exist in the queue, add a new ID entry.
|
||||
if (no_in_id_match) begin
|
||||
head_tail_d[head_tail_free_idx] = '{
|
||||
id: inp_id_i,
|
||||
head: linked_data_free_idx,
|
||||
tail: linked_data_free_idx,
|
||||
free: 1'b0
|
||||
};
|
||||
// Otherwise append it to the existing ID subqueue.
|
||||
end else begin
|
||||
linked_data_d[head_tail_q[match_in_idx].tail].next = linked_data_free_idx;
|
||||
head_tail_d[match_in_idx].tail = linked_data_free_idx;
|
||||
end
|
||||
linked_data_d[linked_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end else if (oup_req_i) begin
|
||||
match_in_id = oup_id_i;
|
||||
match_in_id_valid = 1'b1;
|
||||
if (!no_in_id_match) begin
|
||||
oup_data_o = data_t'(linked_data_q[head_tail_q[match_in_idx].head].data);
|
||||
oup_data_valid_o = 1'b1;
|
||||
if (oup_pop_i) begin
|
||||
// Set free bit of linked data entry, all other bits are don't care.
|
||||
linked_data_d[head_tail_q[match_in_idx].head] = '0;
|
||||
linked_data_d[head_tail_q[match_in_idx].head][0] = 1'b1;
|
||||
if (head_tail_q[match_in_idx].head == head_tail_q[match_in_idx].tail) begin
|
||||
head_tail_d[match_in_idx] = '{free: 1'b1, default: '0};
|
||||
end else begin
|
||||
head_tail_d[match_in_idx].head =
|
||||
linked_data_q[head_tail_q[match_in_idx].head].next;
|
||||
end
|
||||
end
|
||||
end
|
||||
// Always grant the output request. If there was no match, the default, invalid entry
|
||||
// will be returned.
|
||||
oup_gnt_o = 1'b1;
|
||||
end
|
||||
end else begin
|
||||
// FULL_BW
|
||||
if (oup_req_i) begin
|
||||
match_out_id = oup_id_i;
|
||||
match_out_id_valid = 1'b1;
|
||||
if (!no_out_id_match) begin
|
||||
oup_data_o = data_t'(linked_data_q[head_tail_q[match_out_idx].head].data);
|
||||
oup_data_valid_o = 1'b1;
|
||||
if (oup_pop_i) begin
|
||||
oup_data_popped = 1'b1;
|
||||
// Set free bit of linked data entry, all other bits are don't care.
|
||||
linked_data_d[head_tail_q[match_out_idx].head] = '0;
|
||||
linked_data_d[head_tail_q[match_out_idx].head][0] = 1'b1;
|
||||
if (head_tail_q[match_out_idx].head
|
||||
== head_tail_q[match_out_idx].tail) begin
|
||||
oup_ht_popped = 1'b1;
|
||||
head_tail_d[match_out_idx] = '{free: 1'b1, default: '0};
|
||||
end else begin
|
||||
head_tail_d[match_out_idx].head =
|
||||
linked_data_q[head_tail_q[match_out_idx].head].next;
|
||||
end
|
||||
end
|
||||
end
|
||||
// Always grant the output request. If there was no match, the default, invalid entry
|
||||
// will be returned.
|
||||
oup_gnt_o = 1'b1;
|
||||
end
|
||||
if (inp_req_i && inp_gnt_o) begin
|
||||
match_in_id = inp_id_i;
|
||||
match_in_id_valid = 1'b1;
|
||||
// If the ID does not yet exist in the queue or was just popped, add a new ID entry.
|
||||
if (oup_ht_popped && (oup_id_i==inp_id_i)) begin
|
||||
// If output data was popped for this ID, which lead the head_tail to be popped,
|
||||
// then repopulate this head_tail immediately.
|
||||
head_tail_d[match_out_idx] = '{
|
||||
id: inp_id_i,
|
||||
head: oup_data_free_idx,
|
||||
tail: oup_data_free_idx,
|
||||
free: 1'b0
|
||||
};
|
||||
linked_data_d[oup_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end else if (no_in_id_match) begin
|
||||
// Else, if no head_tail corresponds to the input id.
|
||||
if (oup_ht_popped) begin
|
||||
head_tail_d[match_out_idx] = '{
|
||||
id: inp_id_i,
|
||||
head: oup_data_free_idx,
|
||||
tail: oup_data_free_idx,
|
||||
free: 1'b0
|
||||
};
|
||||
linked_data_d[oup_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end else begin
|
||||
if (oup_data_popped) begin
|
||||
head_tail_d[head_tail_free_idx] = '{
|
||||
id: inp_id_i,
|
||||
head: oup_data_free_idx,
|
||||
tail: oup_data_free_idx,
|
||||
free: 1'b0
|
||||
};
|
||||
linked_data_d[oup_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end else begin
|
||||
head_tail_d[head_tail_free_idx] = '{
|
||||
id: inp_id_i,
|
||||
head: linked_data_free_idx,
|
||||
tail: linked_data_free_idx,
|
||||
free: 1'b0
|
||||
};
|
||||
linked_data_d[linked_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
// Otherwise append it to the existing ID subqueue.
|
||||
if (oup_data_popped) begin
|
||||
linked_data_d[head_tail_q[match_in_idx].tail].next = oup_data_free_idx;
|
||||
head_tail_d[match_in_idx].tail = oup_data_free_idx;
|
||||
linked_data_d[oup_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end else begin
|
||||
linked_data_d[head_tail_q[match_in_idx].tail].next = linked_data_free_idx;
|
||||
head_tail_d[match_in_idx].tail = linked_data_free_idx;
|
||||
linked_data_d[linked_data_free_idx] = '{
|
||||
data: inp_data_i,
|
||||
next: '0,
|
||||
free: 1'b0
|
||||
};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Exists Lookup
|
||||
for (genvar i = 0; i < CAPACITY; i++) begin: gen_lookup
|
||||
mask_t exists_match_bits;
|
||||
for (genvar j = 0; j < $bits(data_t); j++) begin: gen_mask
|
||||
always_comb begin
|
||||
if (linked_data_q[i].free) begin
|
||||
exists_match_bits[j] = 1'b0;
|
||||
end else begin
|
||||
if (!exists_mask_i[j]) begin
|
||||
exists_match_bits[j] = 1'b1;
|
||||
end else begin
|
||||
exists_match_bits[j] = (linked_data_q[i].data[j] == exists_data_i[j]);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
assign exists_match[i] = (&exists_match_bits);
|
||||
end
|
||||
always_comb begin
|
||||
exists_gnt_o = 1'b0;
|
||||
exists_o = '0;
|
||||
if (exists_req_i) begin
|
||||
exists_gnt_o = 1'b1;
|
||||
exists_o = (|exists_match);
|
||||
end
|
||||
end
|
||||
|
||||
// Registers
|
||||
for (genvar i = 0; i < HtCapacity; i++) begin: gen_ht_ffs
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
head_tail_q[i] <= '{free: 1'b1, default: '0};
|
||||
end else begin
|
||||
head_tail_q[i] <= head_tail_d[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
for (genvar i = 0; i < CAPACITY; i++) begin: gen_data_ffs
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
// Set free bit of linked data entries, all other bits are don't care.
|
||||
linked_data_q[i] <= '0;
|
||||
linked_data_q[i][0] <= 1'b1;
|
||||
end else begin
|
||||
linked_data_q[i] <= linked_data_d[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Validate parameters.
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin: validate_params
|
||||
assert (ID_WIDTH >= 1)
|
||||
else $fatal(1, "The ID must at least be one bit wide!");
|
||||
assert (CAPACITY >= 1)
|
||||
else $fatal(1, "The queue must have capacity of at least one entry!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule
|
81
vendor/pulp-platform/common_cells/src/isochronous_4phase_handshake.sv
vendored
Normal file
81
vendor/pulp-platform/common_cells/src/isochronous_4phase_handshake.sv
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
/// 4-phase handshake between isochronous clock domains
|
||||
/// (i.e., clock domains which operate on an integer multiple of each other).
|
||||
///
|
||||
/// The internals of this modules are similar to a clock-domain crossing except that
|
||||
/// they do not synchronize the handshake signals as signals can not become metastable (covered by STA).
|
||||
/// The upstream circuit will only handshake iff the downstream circuit handshaked.
|
||||
///
|
||||
/// ## Optionally Passing of Data
|
||||
///
|
||||
/// If the passing of data is necessary this should be done out side the module, for example:
|
||||
/// ```
|
||||
/// `FFLNR(dst_data_o, src_data_i, (src_valid_i && src_ready_o), src_clk_i)
|
||||
/// ```
|
||||
///
|
||||
/// This module differs to `isochronous_spill_register` that it doesn't buffer any data
|
||||
/// and only toggles the source handshake once the destination handshake has been toggled.
|
||||
///
|
||||
/// # Restrictions
|
||||
///
|
||||
/// Source and destination clock domains must be an integer multiple of each other and
|
||||
/// all timing-paths need to be covered by STA. For example a recommended SDC would be:
|
||||
///
|
||||
/// `create_generated_clock dst_clk_i -name dst_clk -source src_clk_i -divide_by 2
|
||||
///
|
||||
/// There are _no_ restrictions on which clock domain should be the faster, any integer
|
||||
/// ratio will work.
|
||||
|
||||
`include "common_cells/registers.svh"
|
||||
|
||||
module isochronous_4phase_handshake (
|
||||
input logic src_clk_i,
|
||||
input logic src_rst_ni,
|
||||
input logic src_valid_i,
|
||||
output logic src_ready_o,
|
||||
input logic dst_clk_i,
|
||||
input logic dst_rst_ni,
|
||||
output logic dst_valid_o,
|
||||
input logic dst_ready_i
|
||||
);
|
||||
|
||||
logic src_req_q, src_ack_q;
|
||||
logic dst_req_q, dst_ack_q;
|
||||
|
||||
// source is making a request
|
||||
`FFLARN(src_req_q, ~src_req_q, (src_valid_i && src_ready_o), 1'b0, src_clk_i, src_rst_ni)
|
||||
// "synchronize" the acknowledge into the sending clock-domain
|
||||
`FFARN(src_ack_q, dst_ack_q, 1'b0, src_clk_i, src_rst_ni)
|
||||
// source is ready if the request wasn't yet acknowledged
|
||||
assign src_ready_o = (src_req_q == src_ack_q);
|
||||
|
||||
// down-stream circuit is acknowledging the handshake
|
||||
`FFLARN(dst_ack_q, ~dst_ack_q, (dst_valid_o && dst_ready_i), 1'b0, dst_clk_i, dst_rst_ni)
|
||||
// "synchronize" the request into the receiving clock domain
|
||||
`FFARN(dst_req_q, src_req_q, 1'b0, dst_clk_i, dst_rst_ni)
|
||||
// destination is valid if we didn't yet get acknowledge
|
||||
assign dst_valid_o = (dst_req_q != dst_ack_q);
|
||||
|
||||
// pragma translate_off
|
||||
// stability guarantees
|
||||
`ifndef VERILATOR
|
||||
assert property (@(posedge src_clk_i) disable iff (src_rst_ni)
|
||||
(src_valid_i && !src_ready_o |=> $stable(src_valid_i))) else $error("src_valid_i is unstable");
|
||||
assert property (@(posedge dst_clk_i) disable iff (dst_rst_ni)
|
||||
(dst_valid_o && !dst_ready_i |=> $stable(dst_valid_o))) else $error("dst_valid_o is unstable");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule
|
111
vendor/pulp-platform/common_cells/src/isochronous_spill_register.sv
vendored
Normal file
111
vendor/pulp-platform/common_cells/src/isochronous_spill_register.sv
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
`include "common_cells/registers.svh"
|
||||
|
||||
/// A register with handshakes that completely cuts any combinatorial paths
|
||||
/// between the input and output in isochronous clock domains.
|
||||
///
|
||||
/// > Definition of isochronous: In telecommunication, an isochronous signal is a signal
|
||||
/// > in which the time interval separating any two significant instants is equal to the
|
||||
/// > unit interval or a multiple of the unit interval.
|
||||
///
|
||||
/// The source and destination clock domains must be derived from the same clock
|
||||
/// but can vary in frequency by a constant factor (e.g., double the frequency).
|
||||
///
|
||||
/// The module is basically a two deep dual-clock fifo with read and write pointers
|
||||
/// in different clock domains. As we know the static timing relationship between the
|
||||
/// clock domains we can rely on static timing analysis (STA) to get the sampling windows
|
||||
/// right and therefore don't need any synchronization.
|
||||
///
|
||||
/// # Restrictions
|
||||
///
|
||||
/// Source and destination clock domains must be an integer multiple of each other and
|
||||
/// all timing-paths need to be covered by STA. For example a recommended SDC would be:
|
||||
///
|
||||
/// `create_generated_clock dst_clk_i -name dst_clk -source src_clk_i -divide_by 2
|
||||
///
|
||||
/// There are _no_ restrictions on which clock domain should be the faster, any integer
|
||||
/// ratio will work.
|
||||
module isochronous_spill_register #(
|
||||
/// Data type of spill register.
|
||||
parameter type T = logic,
|
||||
/// Make this spill register transparent.
|
||||
parameter bit Bypass = 1'b0
|
||||
) (
|
||||
/// Clock of source clock domain.
|
||||
input logic src_clk_i,
|
||||
/// Active low async reset in source domain.
|
||||
input logic src_rst_ni,
|
||||
/// Source input data is valid.
|
||||
input logic src_valid_i,
|
||||
/// Source is ready to accept.
|
||||
output logic src_ready_o,
|
||||
/// Source input data.
|
||||
input T src_data_i,
|
||||
/// Clock of destination clock domain.
|
||||
input logic dst_clk_i,
|
||||
/// Active low async reset in destination domain.
|
||||
input logic dst_rst_ni,
|
||||
/// Destination output data is valid.
|
||||
output logic dst_valid_o,
|
||||
/// Destination is ready to accept.
|
||||
input logic dst_ready_i,
|
||||
/// Destination output data.
|
||||
output T dst_data_o
|
||||
);
|
||||
// Don't generate the spill register.
|
||||
if (Bypass) begin : gen_bypass
|
||||
assign dst_valid_o = src_valid_i;
|
||||
assign src_ready_o = dst_ready_i;
|
||||
assign dst_data_o = src_data_i;
|
||||
// Generate the spill register
|
||||
end else begin : gen_isochronous_spill_register
|
||||
/// Read/write pointer are one bit wider than necessary.
|
||||
/// We implicitly capture the full and empty state with the second bit:
|
||||
/// If all but the topmost bit of `rd_pointer_q` and `wr_pointer_q` agree, the
|
||||
/// FIFO is in a critical state. If the topmost bit is equal, the FIFO is
|
||||
/// empty, otherwise it is full.
|
||||
logic [1:0] rd_pointer_q, wr_pointer_q;
|
||||
// Advance write pointer if we pushed a new item into the FIFO. (Source clock domain)
|
||||
`FFLARN(wr_pointer_q, wr_pointer_q+1, (src_valid_i && src_ready_o), '0, src_clk_i, src_rst_ni)
|
||||
// Advance read pointer if downstream consumed an item. (Destination clock domain)
|
||||
`FFLARN(rd_pointer_q, rd_pointer_q+1, (dst_valid_o && dst_ready_i), '0, dst_clk_i, dst_rst_ni)
|
||||
|
||||
T [1:0] mem_d, mem_q;
|
||||
`FFLNR(mem_q, mem_d, (src_valid_i && src_ready_o), src_clk_i)
|
||||
always_comb begin
|
||||
mem_d = mem_q;
|
||||
mem_d[wr_pointer_q[0]] = src_data_i;
|
||||
end
|
||||
|
||||
assign src_ready_o = (rd_pointer_q ^ wr_pointer_q) != 2'b10;
|
||||
|
||||
assign dst_valid_o = (rd_pointer_q ^ wr_pointer_q) != '0;
|
||||
assign dst_data_o = mem_q[rd_pointer_q[0]];
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
// stability guarantees
|
||||
`ifndef VERILATOR
|
||||
assert property (@(posedge src_clk_i) disable iff (src_rst_ni)
|
||||
(src_valid_i && !src_ready_o |=> $stable(src_valid_i))) else $error("src_valid_i is unstable");
|
||||
assert property (@(posedge src_clk_i) disable iff (src_rst_ni)
|
||||
(src_valid_i && !src_ready_o |=> $stable(src_data_i))) else $error("src_data_i is unstable");
|
||||
assert property (@(posedge dst_clk_i) disable iff (dst_rst_ni)
|
||||
(dst_valid_o && !dst_ready_i |=> $stable(dst_valid_o))) else $error("dst_valid_o is unstable");
|
||||
assert property (@(posedge dst_clk_i) disable iff (dst_rst_ni)
|
||||
(dst_valid_o && !dst_ready_i |=> $stable(dst_data_o))) else $error("dst_data_o is unstable");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
315
vendor/pulp-platform/common_cells/src/lfsr.sv
vendored
Normal file
315
vendor/pulp-platform/common_cells/src/lfsr.sv
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
// Copyright 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 26.04.2019
|
||||
//
|
||||
// Description: This is a parametric LFSR with precomputed coefficients for
|
||||
// LFSR lengths from 4 to 64bit.
|
||||
|
||||
// Additional block cipher layers can be instantiated to non-linearly transform
|
||||
// the pseudo-random LFSR sequence at the output, and hence break the shifting
|
||||
// patterns. The additional cipher layers can only be used for an LFSR width
|
||||
// of 64bit, since the block cipher has been designed for that block length.
|
||||
|
||||
module lfsr #(
|
||||
parameter int unsigned LfsrWidth = 64, // [4,64]
|
||||
parameter int unsigned OutWidth = 8, // [1,LfsrWidth]
|
||||
parameter logic [LfsrWidth-1:0] RstVal = '1, // [1,2^LfsrWidth-1]
|
||||
// 0: disabled, the present cipher uses 31, but just a few layers (1-3) are enough
|
||||
// to break linear shifting patterns
|
||||
parameter int unsigned CipherLayers = 0,
|
||||
parameter bit CipherReg = 1'b1 // additional output reg after cipher
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic en_i,
|
||||
output logic [OutWidth-1:0] out_o
|
||||
);
|
||||
|
||||
// Galois LFSR feedback masks
|
||||
// Automatically generated with get_lfsr_masks.py
|
||||
// Masks are from https://users.ece.cmu.edu/~koopman/lfsr/
|
||||
localparam logic [63:0] Masks [4:64] = '{64'hC,
|
||||
64'h1E,
|
||||
64'h39,
|
||||
64'h7E,
|
||||
64'hFA,
|
||||
64'h1FD,
|
||||
64'h3FC,
|
||||
64'h64B,
|
||||
64'hD8F,
|
||||
64'h1296,
|
||||
64'h2496,
|
||||
64'h4357,
|
||||
64'h8679,
|
||||
64'h1030E,
|
||||
64'h206CD,
|
||||
64'h403FE,
|
||||
64'h807B8,
|
||||
64'h1004B2,
|
||||
64'h2006A8,
|
||||
64'h4004B2,
|
||||
64'h800B87,
|
||||
64'h10004F3,
|
||||
64'h200072D,
|
||||
64'h40006AE,
|
||||
64'h80009E3,
|
||||
64'h10000583,
|
||||
64'h20000C92,
|
||||
64'h400005B6,
|
||||
64'h80000EA6,
|
||||
64'h1000007A3,
|
||||
64'h200000ABF,
|
||||
64'h400000842,
|
||||
64'h80000123E,
|
||||
64'h100000074E,
|
||||
64'h2000000AE9,
|
||||
64'h400000086A,
|
||||
64'h8000001213,
|
||||
64'h1000000077E,
|
||||
64'h2000000123B,
|
||||
64'h40000000877,
|
||||
64'h8000000108D,
|
||||
64'h100000000AE9,
|
||||
64'h200000000E9F,
|
||||
64'h4000000008A6,
|
||||
64'h80000000191E,
|
||||
64'h100000000090E,
|
||||
64'h2000000000FB3,
|
||||
64'h4000000000D7D,
|
||||
64'h80000000016A5,
|
||||
64'h10000000000B4B,
|
||||
64'h200000000010AF,
|
||||
64'h40000000000DDE,
|
||||
64'h8000000000181A,
|
||||
64'h100000000000B65,
|
||||
64'h20000000000102D,
|
||||
64'h400000000000CD5,
|
||||
64'h8000000000024C1,
|
||||
64'h1000000000000EF6,
|
||||
64'h2000000000001363,
|
||||
64'h4000000000000FCD,
|
||||
64'h80000000000019E2};
|
||||
|
||||
// this S-box and permutation P has been taken from the Present Cipher,
|
||||
// a super lightweight block cipher. use the cipher layers to add additional
|
||||
// non-linearity to the LFSR output. note one layer does not fully correspond
|
||||
// to the present cipher round, since the key and rekeying function is not applied here.
|
||||
//
|
||||
// See also:
|
||||
// "PRESENT: An Ultra-Lightweight Block Cipher", A. Bogdanov et al., Ches 2007
|
||||
// http://www.lightweightcrypto.org/present/present_ches2007.pdf
|
||||
|
||||
// this is the sbox from the present cipher
|
||||
localparam logic[15:0][3:0] Sbox4 = {4'h2, 4'h1, 4'h7, 4'h4,
|
||||
4'h8, 4'hF, 4'hE, 4'h3,
|
||||
4'hD, 4'hA, 4'h0, 4'h9,
|
||||
4'hB, 4'h6, 4'h5, 4'hC };
|
||||
|
||||
// these are the permutation indices of the present cipher
|
||||
localparam logic[63:0][5:0] Perm = {6'd63, 6'd47, 6'd31, 6'd15, 6'd62, 6'd46, 6'd30, 6'd14,
|
||||
6'd61, 6'd45, 6'd29, 6'd13, 6'd60, 6'd44, 6'd28, 6'd12,
|
||||
6'd59, 6'd43, 6'd27, 6'd11, 6'd58, 6'd42, 6'd26, 6'd10,
|
||||
6'd57, 6'd41, 6'd25, 6'd09, 6'd56, 6'd40, 6'd24, 6'd08,
|
||||
6'd55, 6'd39, 6'd23, 6'd07, 6'd54, 6'd38, 6'd22, 6'd06,
|
||||
6'd53, 6'd37, 6'd21, 6'd05, 6'd52, 6'd36, 6'd20, 6'd04,
|
||||
6'd51, 6'd35, 6'd19, 6'd03, 6'd50, 6'd34, 6'd18, 6'd02,
|
||||
6'd49, 6'd33, 6'd17, 6'd01, 6'd48, 6'd32, 6'd16, 6'd00};
|
||||
|
||||
|
||||
function automatic logic [63:0] sbox4_layer(logic [63:0] in);
|
||||
logic [63:0] out;
|
||||
//for (logic [4:0] j = '0; j<16; j++) out[j*4 +: 4] = sbox4[in[j*4 +: 4]];
|
||||
// this simulates much faster than the loop
|
||||
out[0*4 +: 4] = Sbox4[in[0*4 +: 4]];
|
||||
out[1*4 +: 4] = Sbox4[in[1*4 +: 4]];
|
||||
out[2*4 +: 4] = Sbox4[in[2*4 +: 4]];
|
||||
out[3*4 +: 4] = Sbox4[in[3*4 +: 4]];
|
||||
|
||||
out[4*4 +: 4] = Sbox4[in[4*4 +: 4]];
|
||||
out[5*4 +: 4] = Sbox4[in[5*4 +: 4]];
|
||||
out[6*4 +: 4] = Sbox4[in[6*4 +: 4]];
|
||||
out[7*4 +: 4] = Sbox4[in[7*4 +: 4]];
|
||||
|
||||
out[8*4 +: 4] = Sbox4[in[8*4 +: 4]];
|
||||
out[9*4 +: 4] = Sbox4[in[9*4 +: 4]];
|
||||
out[10*4 +: 4] = Sbox4[in[10*4 +: 4]];
|
||||
out[11*4 +: 4] = Sbox4[in[11*4 +: 4]];
|
||||
|
||||
out[12*4 +: 4] = Sbox4[in[12*4 +: 4]];
|
||||
out[13*4 +: 4] = Sbox4[in[13*4 +: 4]];
|
||||
out[14*4 +: 4] = Sbox4[in[14*4 +: 4]];
|
||||
out[15*4 +: 4] = Sbox4[in[15*4 +: 4]];
|
||||
return out;
|
||||
endfunction : sbox4_layer
|
||||
|
||||
function automatic logic [63:0] perm_layer(logic [63:0] in);
|
||||
logic [63:0] out;
|
||||
// for (logic [7:0] j = '0; j<64; j++) out[perm[j]] = in[j];
|
||||
// this simulates much faster than the loop
|
||||
out[Perm[0]] = in[0];
|
||||
out[Perm[1]] = in[1];
|
||||
out[Perm[2]] = in[2];
|
||||
out[Perm[3]] = in[3];
|
||||
out[Perm[4]] = in[4];
|
||||
out[Perm[5]] = in[5];
|
||||
out[Perm[6]] = in[6];
|
||||
out[Perm[7]] = in[7];
|
||||
out[Perm[8]] = in[8];
|
||||
out[Perm[9]] = in[9];
|
||||
|
||||
out[Perm[10]] = in[10];
|
||||
out[Perm[11]] = in[11];
|
||||
out[Perm[12]] = in[12];
|
||||
out[Perm[13]] = in[13];
|
||||
out[Perm[14]] = in[14];
|
||||
out[Perm[15]] = in[15];
|
||||
out[Perm[16]] = in[16];
|
||||
out[Perm[17]] = in[17];
|
||||
out[Perm[18]] = in[18];
|
||||
out[Perm[19]] = in[19];
|
||||
|
||||
out[Perm[20]] = in[20];
|
||||
out[Perm[21]] = in[21];
|
||||
out[Perm[22]] = in[22];
|
||||
out[Perm[23]] = in[23];
|
||||
out[Perm[24]] = in[24];
|
||||
out[Perm[25]] = in[25];
|
||||
out[Perm[26]] = in[26];
|
||||
out[Perm[27]] = in[27];
|
||||
out[Perm[28]] = in[28];
|
||||
out[Perm[29]] = in[29];
|
||||
|
||||
out[Perm[30]] = in[30];
|
||||
out[Perm[31]] = in[31];
|
||||
out[Perm[32]] = in[32];
|
||||
out[Perm[33]] = in[33];
|
||||
out[Perm[34]] = in[34];
|
||||
out[Perm[35]] = in[35];
|
||||
out[Perm[36]] = in[36];
|
||||
out[Perm[37]] = in[37];
|
||||
out[Perm[38]] = in[38];
|
||||
out[Perm[39]] = in[39];
|
||||
|
||||
out[Perm[40]] = in[40];
|
||||
out[Perm[41]] = in[41];
|
||||
out[Perm[42]] = in[42];
|
||||
out[Perm[43]] = in[43];
|
||||
out[Perm[44]] = in[44];
|
||||
out[Perm[45]] = in[45];
|
||||
out[Perm[46]] = in[46];
|
||||
out[Perm[47]] = in[47];
|
||||
out[Perm[48]] = in[48];
|
||||
out[Perm[49]] = in[49];
|
||||
|
||||
out[Perm[50]] = in[50];
|
||||
out[Perm[51]] = in[51];
|
||||
out[Perm[52]] = in[52];
|
||||
out[Perm[53]] = in[53];
|
||||
out[Perm[54]] = in[54];
|
||||
out[Perm[55]] = in[55];
|
||||
out[Perm[56]] = in[56];
|
||||
out[Perm[57]] = in[57];
|
||||
out[Perm[58]] = in[58];
|
||||
out[Perm[59]] = in[59];
|
||||
|
||||
out[Perm[60]] = in[60];
|
||||
out[Perm[61]] = in[61];
|
||||
out[Perm[62]] = in[62];
|
||||
out[Perm[63]] = in[63];
|
||||
return out;
|
||||
endfunction : perm_layer
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// lfsr
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
logic [LfsrWidth-1:0] lfsr_d, lfsr_q;
|
||||
assign lfsr_d =
|
||||
(en_i) ? (lfsr_q>>1) ^ ({LfsrWidth{lfsr_q[0]}} & Masks[LfsrWidth][LfsrWidth-1:0]) : lfsr_q;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
|
||||
//$display("%b %h", en_i, lfsr_d);
|
||||
if (!rst_ni) begin
|
||||
lfsr_q <= LfsrWidth'(RstVal);
|
||||
end else begin
|
||||
lfsr_q <= lfsr_d;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// block cipher layers
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (CipherLayers > unsigned'(0)) begin : g_cipher_layers
|
||||
logic [63:0] ciph_layer;
|
||||
localparam int unsigned NumRepl = ((64+LfsrWidth)/LfsrWidth);
|
||||
|
||||
always_comb begin : p_ciph_layer
|
||||
automatic logic [63:0] tmp;
|
||||
tmp = 64'({NumRepl{lfsr_q}});
|
||||
for(int unsigned k = 0; k < CipherLayers; k++) begin
|
||||
tmp = perm_layer(sbox4_layer(tmp));
|
||||
end
|
||||
ciph_layer = tmp;
|
||||
end
|
||||
|
||||
// additiona output reg after cipher
|
||||
if (CipherReg) begin : g_cipher_reg
|
||||
logic [OutWidth-1:0] out_d, out_q;
|
||||
|
||||
assign out_d = (en_i) ? ciph_layer[OutWidth-1:0] : out_q;
|
||||
assign out_o = out_q[OutWidth-1:0];
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
|
||||
if (!rst_ni) begin
|
||||
out_q <= '0;
|
||||
end else begin
|
||||
out_q <= out_d;
|
||||
end
|
||||
end
|
||||
// no outreg
|
||||
end else begin : g_no_out_reg
|
||||
assign out_o = ciph_layer[OutWidth-1:0];
|
||||
end
|
||||
|
||||
// no block cipher
|
||||
end else begin : g_no_cipher_layers
|
||||
assign out_o = lfsr_q[OutWidth-1:0];
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// assertions
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// pragma translate_off
|
||||
initial begin
|
||||
// these are the LUT limits
|
||||
assert(OutWidth <= LfsrWidth) else
|
||||
$fatal(1,"OutWidth must be smaller equal the LfsrWidth.");
|
||||
assert(RstVal > unsigned'(0)) else
|
||||
$fatal(1,"RstVal must be nonzero.");
|
||||
assert((LfsrWidth >= $low(Masks)) && (LfsrWidth <= $high(Masks))) else
|
||||
$fatal(1,"Unsupported LfsrWidth.");
|
||||
assert(Masks[LfsrWidth][LfsrWidth-1]) else
|
||||
$fatal(1, "LFSR mask is not correct. The MSB must be 1." );
|
||||
assert((CipherLayers > 0) && (LfsrWidth == 64) || (CipherLayers == 0)) else
|
||||
$fatal(1, "Use additional cipher layers only in conjunction with an LFSR width of 64 bit." );
|
||||
end
|
||||
|
||||
`ifndef VERILATOR
|
||||
all_zero: assert property (
|
||||
@(posedge clk_i) disable iff (!rst_ni) en_i |-> lfsr_d)
|
||||
else $fatal(1,"Lfsr must not be all-zero.");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule // lfsr
|
68
vendor/pulp-platform/common_cells/src/lfsr_16bit.sv
vendored
Normal file
68
vendor/pulp-platform/common_cells/src/lfsr_16bit.sv
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 5.11.2018
|
||||
// Description: 16-bit LFSR
|
||||
|
||||
// --------------
|
||||
// 16-bit LFSR
|
||||
// --------------
|
||||
//
|
||||
// Description: Shift register
|
||||
//
|
||||
module lfsr_16bit #(
|
||||
parameter logic [15:0] SEED = 8'b0,
|
||||
parameter int unsigned WIDTH = 16
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic en_i,
|
||||
output logic [WIDTH-1:0] refill_way_oh,
|
||||
output logic [$clog2(WIDTH)-1:0] refill_way_bin
|
||||
);
|
||||
|
||||
localparam int unsigned LogWidth = $clog2(WIDTH);
|
||||
|
||||
logic [15:0] shift_d, shift_q;
|
||||
|
||||
|
||||
always_comb begin
|
||||
|
||||
automatic logic shift_in;
|
||||
shift_in = !(shift_q[15] ^ shift_q[12] ^ shift_q[5] ^ shift_q[1]);
|
||||
|
||||
shift_d = shift_q;
|
||||
|
||||
if (en_i)
|
||||
shift_d = {shift_q[14:0], shift_in};
|
||||
|
||||
// output assignment
|
||||
refill_way_oh = 'b0;
|
||||
refill_way_oh[shift_q[LogWidth-1:0]] = 1'b1;
|
||||
refill_way_bin = shift_q;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_
|
||||
if(~rst_ni) begin
|
||||
shift_q <= SEED;
|
||||
end else begin
|
||||
shift_q <= shift_d;
|
||||
end
|
||||
end
|
||||
|
||||
//pragma translate_off
|
||||
initial begin
|
||||
assert (WIDTH <= 16)
|
||||
else $fatal(1, "WIDTH needs to be less than 16 because of the 16-bit LFSR");
|
||||
end
|
||||
//pragma translate_on
|
||||
|
||||
endmodule
|
61
vendor/pulp-platform/common_cells/src/lfsr_8bit.sv
vendored
Normal file
61
vendor/pulp-platform/common_cells/src/lfsr_8bit.sv
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Igor Loi - University of Bologna
|
||||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 12.11.2017
|
||||
// Description: 8-bit LFSR
|
||||
|
||||
/// 8 bit Linear Feedback Shift register
|
||||
module lfsr_8bit #(
|
||||
parameter logic [7:0] SEED = 8'b0,
|
||||
parameter int unsigned WIDTH = 8
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic en_i,
|
||||
output logic [ WIDTH-1:0] refill_way_oh,
|
||||
output logic [$clog2(WIDTH)-1:0] refill_way_bin
|
||||
);
|
||||
|
||||
localparam int unsigned LogWidth = $clog2(WIDTH);
|
||||
|
||||
logic [7:0] shift_d, shift_q;
|
||||
|
||||
always_comb begin
|
||||
|
||||
automatic logic shift_in;
|
||||
shift_in = !(shift_q[7] ^ shift_q[3] ^ shift_q[2] ^ shift_q[1]);
|
||||
|
||||
shift_d = shift_q;
|
||||
|
||||
if (en_i) shift_d = {shift_q[6:0], shift_in};
|
||||
|
||||
// output assignment
|
||||
refill_way_oh = 'b0;
|
||||
refill_way_oh[shift_q[LogWidth - 1:0]] = 1'b1;
|
||||
refill_way_bin = shift_q;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_
|
||||
if (~rst_ni) begin
|
||||
shift_q <= SEED;
|
||||
end else begin
|
||||
shift_q <= shift_d;
|
||||
end
|
||||
end
|
||||
|
||||
//pragma translate_off
|
||||
initial begin
|
||||
assert (WIDTH <= 8) else $fatal(1, "WIDTH needs to be less than 8 because of the 8-bit LFSR");
|
||||
end
|
||||
//pragma translate_on
|
||||
|
||||
endmodule
|
112
vendor/pulp-platform/common_cells/src/lzc.sv
vendored
Normal file
112
vendor/pulp-platform/common_cells/src/lzc.sv
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) 2018 - 2019 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
|
||||
/// A trailing zero counter / leading zero counter.
|
||||
/// Set MODE to 0 for trailing zero counter => cnt_o is the number of trailing zeros (from the LSB)
|
||||
/// Set MODE to 1 for leading zero counter => cnt_o is the number of leading zeros (from the MSB)
|
||||
/// If the input does not contain a zero, `empty_o` is asserted. Additionally `cnt_o` contains
|
||||
/// the maximum number of zeros - 1. For example:
|
||||
/// in_i = 000_0000, empty_o = 1, cnt_o = 6 (mode = 0)
|
||||
/// in_i = 000_0001, empty_o = 0, cnt_o = 0 (mode = 0)
|
||||
/// in_i = 000_1000, empty_o = 0, cnt_o = 3 (mode = 0)
|
||||
/// Furthermore, this unit contains a more efficient implementation for Verilator (simulation only).
|
||||
/// This speeds up simulation significantly.
|
||||
module lzc #(
|
||||
/// The width of the input vector.
|
||||
parameter int unsigned WIDTH = 2,
|
||||
/// Mode selection: 0 -> trailing zero, 1 -> leading zero
|
||||
parameter bit MODE = 1'b0,
|
||||
/// Dependent parameter. Do **not** change!
|
||||
///
|
||||
/// Width of the output signal with the zero count.
|
||||
parameter int unsigned CNT_WIDTH = cf_math_pkg::idx_width(WIDTH)
|
||||
) (
|
||||
/// Input vector to be counted.
|
||||
input logic [WIDTH-1:0] in_i,
|
||||
/// Count of the leading / trailing zeros.
|
||||
output logic [CNT_WIDTH-1:0] cnt_o,
|
||||
/// Counter is empty: Asserted if all bits in in_i are zero.
|
||||
output logic empty_o
|
||||
);
|
||||
|
||||
if (WIDTH == 1) begin : gen_degenerate_lzc
|
||||
|
||||
assign cnt_o[0] = !in_i[0];
|
||||
assign empty_o = !in_i[0];
|
||||
|
||||
end else begin : gen_lzc
|
||||
|
||||
localparam int unsigned NumLevels = $clog2(WIDTH);
|
||||
|
||||
// pragma translate_off
|
||||
initial begin
|
||||
assert(WIDTH > 0) else $fatal(1, "input must be at least one bit wide");
|
||||
end
|
||||
// pragma translate_on
|
||||
|
||||
logic [WIDTH-1:0][NumLevels-1:0] index_lut;
|
||||
logic [2**NumLevels-1:0] sel_nodes;
|
||||
logic [2**NumLevels-1:0][NumLevels-1:0] index_nodes;
|
||||
|
||||
logic [WIDTH-1:0] in_tmp;
|
||||
|
||||
// reverse vector if required
|
||||
always_comb begin : flip_vector
|
||||
for (int unsigned i = 0; i < WIDTH; i++) begin
|
||||
in_tmp[i] = (MODE) ? in_i[WIDTH-1-i] : in_i[i];
|
||||
end
|
||||
end
|
||||
|
||||
for (genvar j = 0; unsigned'(j) < WIDTH; j++) begin : g_index_lut
|
||||
assign index_lut[j] = (NumLevels)'(unsigned'(j));
|
||||
end
|
||||
|
||||
for (genvar level = 0; unsigned'(level) < NumLevels; level++) begin : g_levels
|
||||
if (unsigned'(level) == NumLevels - 1) begin : g_last_level
|
||||
for (genvar k = 0; k < 2 ** level; k++) begin : g_level
|
||||
// if two successive indices are still in the vector...
|
||||
if (unsigned'(k) * 2 < WIDTH - 1) begin : g_reduce
|
||||
assign sel_nodes[2 ** level - 1 + k] = in_tmp[k * 2] | in_tmp[k * 2 + 1];
|
||||
assign index_nodes[2 ** level - 1 + k] = (in_tmp[k * 2] == 1'b1)
|
||||
? index_lut[k * 2] :
|
||||
index_lut[k * 2 + 1];
|
||||
end
|
||||
// if only the first index is still in the vector...
|
||||
if (unsigned'(k) * 2 == WIDTH - 1) begin : g_base
|
||||
assign sel_nodes[2 ** level - 1 + k] = in_tmp[k * 2];
|
||||
assign index_nodes[2 ** level - 1 + k] = index_lut[k * 2];
|
||||
end
|
||||
// if index is out of range
|
||||
if (unsigned'(k) * 2 > WIDTH - 1) begin : g_out_of_range
|
||||
assign sel_nodes[2 ** level - 1 + k] = 1'b0;
|
||||
assign index_nodes[2 ** level - 1 + k] = '0;
|
||||
end
|
||||
end
|
||||
end else begin : g_not_last_level
|
||||
for (genvar l = 0; l < 2 ** level; l++) begin : g_level
|
||||
assign sel_nodes[2 ** level - 1 + l] =
|
||||
sel_nodes[2 ** (level + 1) - 1 + l * 2] | sel_nodes[2 ** (level + 1) - 1 + l * 2 + 1];
|
||||
assign index_nodes[2 ** level - 1 + l] = (sel_nodes[2 ** (level + 1) - 1 + l * 2] == 1'b1)
|
||||
? index_nodes[2 ** (level + 1) - 1 + l * 2] :
|
||||
index_nodes[2 ** (level + 1) - 1 + l * 2 + 1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign cnt_o = NumLevels > unsigned'(0) ? index_nodes[0] : {($clog2(WIDTH)) {1'b0}};
|
||||
assign empty_o = NumLevels > unsigned'(0) ? ~sel_nodes[0] : ~(|in_i);
|
||||
|
||||
end : gen_lzc
|
||||
|
||||
endmodule : lzc
|
77
vendor/pulp-platform/common_cells/src/max_counter.sv
vendored
Normal file
77
vendor/pulp-platform/common_cells/src/max_counter.sv
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Up/down counter that tracks its maximum value
|
||||
|
||||
module max_counter #(
|
||||
parameter int unsigned WIDTH = 4
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic clear_i, // synchronous clear for counter
|
||||
input logic clear_max_i, // synchronous clear for maximum value
|
||||
input logic en_i, // enable the counter
|
||||
input logic load_i, // load a new value
|
||||
input logic down_i, // downcount, default is up
|
||||
input logic [WIDTH-1:0] delta_i, // counter delta
|
||||
input logic [WIDTH-1:0] d_i,
|
||||
output logic [WIDTH-1:0] q_o,
|
||||
output logic [WIDTH-1:0] max_o,
|
||||
output logic overflow_o,
|
||||
output logic overflow_max_o
|
||||
);
|
||||
logic [WIDTH-1:0] max_d, max_q;
|
||||
logic overflow_max_d, overflow_max_q;
|
||||
|
||||
delta_counter #(
|
||||
.WIDTH (WIDTH),
|
||||
.STICKY_OVERFLOW (1'b1)
|
||||
) i_counter (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.clear_i,
|
||||
.en_i,
|
||||
.load_i,
|
||||
.down_i,
|
||||
.delta_i,
|
||||
.d_i,
|
||||
.q_o,
|
||||
.overflow_o
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
max_d = max_q;
|
||||
max_o = max_q;
|
||||
overflow_max_d = overflow_max_q;
|
||||
if (clear_max_i) begin
|
||||
max_d = '0;
|
||||
overflow_max_d = 1'b0;
|
||||
end else if (q_o > max_q) begin
|
||||
max_d = q_o;
|
||||
max_o = q_o;
|
||||
if (overflow_o) begin
|
||||
overflow_max_d = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign overflow_max_o = overflow_max_q;
|
||||
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
max_q <= '0;
|
||||
overflow_max_q <= 1'b0;
|
||||
end else begin
|
||||
max_q <= max_d;
|
||||
overflow_max_q <= overflow_max_d;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
55
vendor/pulp-platform/common_cells/src/mv_filter.sv
vendored
Normal file
55
vendor/pulp-platform/common_cells/src/mv_filter.sv
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module mv_filter #(
|
||||
parameter int unsigned WIDTH = 4,
|
||||
parameter int unsigned THRESHOLD = 10
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic sample_i,
|
||||
input logic clear_i,
|
||||
input logic d_i,
|
||||
output logic q_o
|
||||
);
|
||||
logic [WIDTH-1:0] counter_q, counter_d;
|
||||
logic d, q;
|
||||
|
||||
assign q_o = q;
|
||||
|
||||
always_comb begin
|
||||
counter_d = counter_q;
|
||||
d = q;
|
||||
|
||||
if (counter_q >= THRESHOLD[WIDTH-1:0]) begin
|
||||
d = 1'b1;
|
||||
end else if (sample_i && d_i) begin
|
||||
counter_d = counter_q + 1;
|
||||
end
|
||||
|
||||
// sync reset
|
||||
if (clear_i) begin
|
||||
counter_d = '0;
|
||||
d = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
counter_q <= '0;
|
||||
q <= 1'b0;
|
||||
end else begin
|
||||
counter_q <= counter_d;
|
||||
q <= d;
|
||||
end
|
||||
end
|
||||
endmodule
|
38
vendor/pulp-platform/common_cells/src/onehot_to_bin.sv
vendored
Normal file
38
vendor/pulp-platform/common_cells/src/onehot_to_bin.sv
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Franceco Conti <fconti@iis.ee.ethz.ch>
|
||||
|
||||
module onehot_to_bin #(
|
||||
parameter int unsigned ONEHOT_WIDTH = 16,
|
||||
// Do Not Change
|
||||
parameter int unsigned BIN_WIDTH = ONEHOT_WIDTH == 1 ? 1 : $clog2(ONEHOT_WIDTH)
|
||||
) (
|
||||
input logic [ONEHOT_WIDTH-1:0] onehot,
|
||||
output logic [BIN_WIDTH-1:0] bin
|
||||
);
|
||||
|
||||
for (genvar j = 0; j < BIN_WIDTH; j++) begin : jl
|
||||
logic [ONEHOT_WIDTH-1:0] tmp_mask;
|
||||
for (genvar i = 0; i < ONEHOT_WIDTH; i++) begin : il
|
||||
logic [BIN_WIDTH-1:0] tmp_i;
|
||||
assign tmp_i = i;
|
||||
assign tmp_mask[i] = tmp_i[j];
|
||||
end
|
||||
assign bin[j] = |(tmp_mask & onehot);
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
assert final ($onehot0(onehot)) else
|
||||
$fatal(1, "[onehot_to_bin] More than two bit set in the one-hot signal");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
120
vendor/pulp-platform/common_cells/src/plru_tree.sv
vendored
Normal file
120
vendor/pulp-platform/common_cells/src/plru_tree.sv
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: David Schaffenrath, TU Graz
|
||||
// Author: Florian Zaruba, ETH Zurich
|
||||
//
|
||||
// Description: Pseudo Least Recently Used Tree (PLRU)
|
||||
// See: https://en.wikipedia.org/wiki/Pseudo-LRU
|
||||
|
||||
module plru_tree #(
|
||||
parameter int unsigned ENTRIES = 16
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic [ENTRIES-1:0] used_i, // element i was used (one hot)
|
||||
output logic [ENTRIES-1:0] plru_o // element i is the least recently used (one hot)
|
||||
);
|
||||
|
||||
localparam int unsigned LogEntries = $clog2(ENTRIES);
|
||||
|
||||
logic [2*(ENTRIES-1)-1:0] plru_tree_q, plru_tree_d;
|
||||
|
||||
always_comb begin : plru_replacement
|
||||
plru_tree_d = plru_tree_q;
|
||||
// The PLRU-tree indexing:
|
||||
// lvl0 0
|
||||
// / \
|
||||
// / \
|
||||
// lvl1 1 2
|
||||
// / \ / \
|
||||
// lvl2 3 4 5 6
|
||||
// / \ /\/\ /\
|
||||
// ... ... ... ...
|
||||
// Just predefine which nodes will be set/cleared
|
||||
// E.g. for a TLB with 8 entries, the for-loop is semantically
|
||||
// equivalent to the following pseudo-code:
|
||||
// unique case (1'b1)
|
||||
// used_i[7]: plru_tree_d[0, 2, 6] = {1, 1, 1};
|
||||
// used_i[6]: plru_tree_d[0, 2, 6] = {1, 1, 0};
|
||||
// used_i[5]: plru_tree_d[0, 2, 5] = {1, 0, 1};
|
||||
// used_i[4]: plru_tree_d[0, 2, 5] = {1, 0, 0};
|
||||
// used_i[3]: plru_tree_d[0, 1, 4] = {0, 1, 1};
|
||||
// used_i[2]: plru_tree_d[0, 1, 4] = {0, 1, 0};
|
||||
// used_i[1]: plru_tree_d[0, 1, 3] = {0, 0, 1};
|
||||
// used_i[0]: plru_tree_d[0, 1, 3] = {0, 0, 0};
|
||||
// default: begin /* No hit */ end
|
||||
// endcase
|
||||
for (int unsigned i = 0; i < ENTRIES; i++) begin
|
||||
automatic int unsigned idx_base, shift, new_index;
|
||||
// we got a hit so update the pointer as it was least recently used
|
||||
if (used_i[i]) begin
|
||||
// Set the nodes to the values we would expect
|
||||
for (int unsigned lvl = 0; lvl < LogEntries; lvl++) begin
|
||||
idx_base = $unsigned((2**lvl)-1);
|
||||
// lvl0 <=> MSB, lvl1 <=> MSB-1, ...
|
||||
shift = LogEntries - lvl;
|
||||
// to circumvent the 32 bit integer arithmetic assignment
|
||||
new_index = ~((i >> (shift-1)) & 1);
|
||||
plru_tree_d[idx_base + (i >> shift)] = new_index[0];
|
||||
end
|
||||
end
|
||||
end
|
||||
// Decode tree to write enable signals
|
||||
// Next for-loop basically creates the following logic for e.g. an 8 entry
|
||||
// TLB (note: pseudo-code obviously):
|
||||
// plru_o[7] = &plru_tree_q[ 6, 2, 0]; //plru_tree_q[0,2,6]=={1,1,1}
|
||||
// plru_o[6] = &plru_tree_q[~6, 2, 0]; //plru_tree_q[0,2,6]=={1,1,0}
|
||||
// plru_o[5] = &plru_tree_q[ 5,~2, 0]; //plru_tree_q[0,2,5]=={1,0,1}
|
||||
// plru_o[4] = &plru_tree_q[~5,~2, 0]; //plru_tree_q[0,2,5]=={1,0,0}
|
||||
// plru_o[3] = &plru_tree_q[ 4, 1,~0]; //plru_tree_q[0,1,4]=={0,1,1}
|
||||
// plru_o[2] = &plru_tree_q[~4, 1,~0]; //plru_tree_q[0,1,4]=={0,1,0}
|
||||
// plru_o[1] = &plru_tree_q[ 3,~1,~0]; //plru_tree_q[0,1,3]=={0,0,1}
|
||||
// plru_o[0] = &plru_tree_q[~3,~1,~0]; //plru_tree_q[0,1,3]=={0,0,0}
|
||||
// For each entry traverse the tree. If every tree-node matches,
|
||||
// the corresponding bit of the entry's index, this is
|
||||
// the next entry to replace.
|
||||
for (int unsigned i = 0; i < ENTRIES; i += 1) begin
|
||||
automatic logic en;
|
||||
automatic int unsigned idx_base, shift, new_index;
|
||||
en = 1'b1;
|
||||
for (int unsigned lvl = 0; lvl < LogEntries; lvl++) begin
|
||||
idx_base = $unsigned((2**lvl)-1);
|
||||
// lvl0 <=> MSB, lvl1 <=> MSB-1, ...
|
||||
shift = LogEntries - lvl;
|
||||
// en &= plru_tree_q[idx_base + (i>>shift)] == ((i >> (shift-1)) & 1'b1);
|
||||
new_index = (i >> (shift-1)) & 1;
|
||||
if (new_index[0]) begin
|
||||
en &= plru_tree_q[idx_base + (i>>shift)];
|
||||
end else begin
|
||||
en &= ~plru_tree_q[idx_base + (i>>shift)];
|
||||
end
|
||||
end
|
||||
plru_o[i] = en;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
plru_tree_q <= '0;
|
||||
end else begin
|
||||
plru_tree_q <= plru_tree_d;
|
||||
end
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin
|
||||
assert (ENTRIES == 2**LogEntries) else $error("Entries must be a power of two");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule
|
60
vendor/pulp-platform/common_cells/src/popcount.sv
vendored
Normal file
60
vendor/pulp-platform/common_cells/src/popcount.sv
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright (C) 2013-2018 ETH Zurich, University of Bologna
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Manuel Eggimann <meggimann@iis.ee.ethz.ch>
|
||||
|
||||
// Description: This module calculates the hamming weight (number of ones) in
|
||||
// its input vector using a balanced binary adder tree. Recursive instantiation
|
||||
// is used to build the tree. Any unsigned INPUT_WIDTH larger or equal 2 is
|
||||
// legal. The module pads the signal internally to the next power of two. The
|
||||
// output result width is ceil(log2(INPUT_WIDTH))+1.
|
||||
|
||||
module popcount #(
|
||||
parameter int unsigned INPUT_WIDTH = 256,
|
||||
localparam int unsigned PopcountWidth = $clog2(INPUT_WIDTH)+1
|
||||
) (
|
||||
input logic [INPUT_WIDTH-1:0] data_i,
|
||||
output logic [PopcountWidth-1:0] popcount_o
|
||||
);
|
||||
|
||||
localparam int unsigned PaddedWidth = 1 << $clog2(INPUT_WIDTH);
|
||||
|
||||
logic [PaddedWidth-1:0] padded_input;
|
||||
logic [PopcountWidth-2:0] left_child_result, right_child_result;
|
||||
|
||||
//Zero pad the input to next power of two
|
||||
always_comb begin
|
||||
padded_input = '0;
|
||||
padded_input[INPUT_WIDTH-1:0] = data_i;
|
||||
end
|
||||
|
||||
//Recursive instantiation to build binary adder tree
|
||||
if (INPUT_WIDTH == 1) begin : single_node
|
||||
assign left_child_result = 1'b0;
|
||||
assign right_child_result = padded_input[0];
|
||||
end else if (INPUT_WIDTH == 2) begin : leaf_node
|
||||
assign left_child_result = padded_input[1];
|
||||
assign right_child_result = padded_input[0];
|
||||
end else begin : non_leaf_node
|
||||
popcount #(.INPUT_WIDTH(PaddedWidth / 2))
|
||||
left_child(
|
||||
.data_i(padded_input[PaddedWidth-1:PaddedWidth/2]),
|
||||
.popcount_o(left_child_result));
|
||||
|
||||
popcount #(.INPUT_WIDTH(PaddedWidth / 2))
|
||||
right_child(
|
||||
.data_i(padded_input[PaddedWidth/2-1:0]),
|
||||
.popcount_o(right_child_result));
|
||||
end
|
||||
|
||||
//Output assignment
|
||||
assign popcount_o = left_child_result + right_child_result;
|
||||
|
||||
endmodule : popcount
|
348
vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
vendored
Normal file
348
vendor/pulp-platform/common_cells/src/rr_arb_tree.sv
vendored
Normal file
|
@ -0,0 +1,348 @@
|
|||
// Copyright 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Wolfgang Roenninger <wroennin@iis.ee.ethz.ch>, ETH Zurich
|
||||
// Date: 02.04.2019
|
||||
// Description: logarithmic arbitration tree with round robin arbitration scheme.
|
||||
|
||||
/// The rr_arb_tree employs non-starving round robin-arbitration - i.e., the priorities
|
||||
/// rotate each cycle.
|
||||
///
|
||||
/// ## Fair vs. unfair Arbitration
|
||||
///
|
||||
/// This refers to fair throughput distribution when not all inputs have active requests.
|
||||
/// This module has an internal state `rr_q` which defines the highest priority input. (When
|
||||
/// `ExtPrio` is `1'b1` this state is provided from the outside.) The arbitration tree will
|
||||
/// choose the input with the same index as currently defined by the state if it has an active
|
||||
/// request. Otherwise a *random* other active input is selected. The parameter `FairArb` is used
|
||||
/// to distinguish between two methods of calculating the next state.
|
||||
/// * `1'b0`: The next state is calculated by advancing the current state by one. This leads to the
|
||||
/// state being calculated without the context of the active request. Leading to an
|
||||
/// unfair throughput distribution if not all inputs have active requests.
|
||||
/// * `1'b1`: The next state jumps to the next unserved request with higher index.
|
||||
/// This is achieved by using two trailing-zero-counters (`lzc`). The upper has the masked
|
||||
/// `req_i` signal with all indices which will have a higher priority in the next state.
|
||||
/// The trailing zero count defines the input index with the next highest priority after
|
||||
/// the current one is served. When the upper is empty the lower `lzc` provides the
|
||||
/// wrapped index if there are outstanding requests with lower or same priority.
|
||||
/// The implication of throughput fairness on the module timing are:
|
||||
/// * The trailing zero counter (`lzc`) has a loglog relation of input to output timing. This means
|
||||
/// that in this module the input to register path scales with Log(Log(`NumIn`)).
|
||||
/// * The `rr_arb_tree` data multiplexing scales with Log(`NumIn`). This means that the input to output
|
||||
/// timing path of this module also scales scales with Log(`NumIn`).
|
||||
/// This implies that in this module the input to output path is always longer than the input to
|
||||
/// register path. As the output data usually also terminates in a register the parameter `FairArb`
|
||||
/// only has implications on the area. When it is `1'b0` a static plus one adder is instantiated.
|
||||
/// If it is `1'b1` two `lzc`, a masking logic stage and a two input multiplexer are instantiated.
|
||||
/// However these are small in respect of the data multiplexers needed, as the width of the `req_i`
|
||||
/// signal is usually less as than `DataWidth`.
|
||||
module rr_arb_tree #(
|
||||
/// Number of inputs to be arbitrated.
|
||||
parameter int unsigned NumIn = 64,
|
||||
/// Data width of the payload in bits. Not needed if `DataType` is overwritten.
|
||||
parameter int unsigned DataWidth = 32,
|
||||
/// Data type of the payload, can be overwritten with custom type. Only use of `DataWidth`.
|
||||
parameter type DataType = logic [DataWidth-1:0],
|
||||
/// The `ExtPrio` option allows to override the internal round robin counter via the
|
||||
/// `rr_i` signal. This can be useful in case multiple arbiters need to have
|
||||
/// rotating priorities that are operating in lock-step. If static priority arbitration
|
||||
/// is needed, just connect `rr_i` to '0.
|
||||
///
|
||||
/// Set to 1'b1 to enable.
|
||||
parameter bit ExtPrio = 1'b0,
|
||||
/// If `AxiVldRdy` is set, the req/gnt signals are compliant with the AXI style vld/rdy
|
||||
/// handshake. Namely, upstream vld (req) must not depend on rdy (gnt), as it can be deasserted
|
||||
/// again even though vld is asserted. Enabling `AxiVldRdy` leads to a reduction of arbiter
|
||||
/// delay and area.
|
||||
///
|
||||
/// Set to `1'b1` to treat req/gnt as vld/rdy.
|
||||
parameter bit AxiVldRdy = 1'b0,
|
||||
/// The `LockIn` option prevents the arbiter from changing the arbitration
|
||||
/// decision when the arbiter is disabled. I.e., the index of the first request
|
||||
/// that wins the arbitration will be locked in case the destination is not
|
||||
/// able to grant the request in the same cycle.
|
||||
///
|
||||
/// Set to `1'b1` to enable.
|
||||
parameter bit LockIn = 1'b0,
|
||||
/// When set, ensures that throughput gets distributed evenly between all inputs.
|
||||
///
|
||||
/// Set to `1'b0` to disable.
|
||||
parameter bit FairArb = 1'b1,
|
||||
/// Dependent parameter, do **not** overwrite.
|
||||
/// Width of the arbitration priority signal and the arbitrated index.
|
||||
parameter int unsigned IdxWidth = (NumIn > 32'd1) ? unsigned'($clog2(NumIn)) : 32'd1,
|
||||
/// Dependent parameter, do **not** overwrite.
|
||||
/// Type for defining the arbitration priority and arbitrated index signal.
|
||||
parameter type idx_t = logic [IdxWidth-1:0]
|
||||
) (
|
||||
/// Clock, positive edge triggered.
|
||||
input logic clk_i,
|
||||
/// Asynchronous reset, active low.
|
||||
input logic rst_ni,
|
||||
/// Clears the arbiter state. Only used if `ExtPrio` is `1'b0` or `LockIn` is `1'b1`.
|
||||
input logic flush_i,
|
||||
/// External round-robin priority. Only used if `ExtPrio` is `1'b1.`
|
||||
input idx_t rr_i,
|
||||
/// Input requests arbitration.
|
||||
input logic [NumIn-1:0] req_i,
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
/// Input request is granted.
|
||||
output logic [NumIn-1:0] gnt_o,
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
/// Input data for arbitration.
|
||||
input DataType [NumIn-1:0] data_i,
|
||||
/// Output request is valid.
|
||||
output logic req_o,
|
||||
/// Output request is granted.
|
||||
input logic gnt_i,
|
||||
/// Output data.
|
||||
output DataType data_o,
|
||||
/// Index from which input the data came from.
|
||||
output idx_t idx_o
|
||||
);
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
`ifndef XSIM
|
||||
// Default SVA reset
|
||||
default disable iff (!rst_ni || flush_i);
|
||||
`endif
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
// just pass through in this corner case
|
||||
if (NumIn == unsigned'(1)) begin : gen_pass_through
|
||||
assign req_o = req_i[0];
|
||||
assign gnt_o[0] = gnt_i;
|
||||
assign data_o = data_i[0];
|
||||
assign idx_o = '0;
|
||||
// non-degenerate cases
|
||||
end else begin : gen_arbiter
|
||||
localparam int unsigned NumLevels = unsigned'($clog2(NumIn));
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
idx_t [2**NumLevels-2:0] index_nodes; // used to propagate the indices
|
||||
DataType [2**NumLevels-2:0] data_nodes; // used to propagate the data
|
||||
logic [2**NumLevels-2:0] gnt_nodes; // used to propagate the grant to masters
|
||||
logic [2**NumLevels-2:0] req_nodes; // used to propagate the requests to slave
|
||||
/* lint_off */
|
||||
idx_t rr_q;
|
||||
logic [NumIn-1:0] req_d;
|
||||
|
||||
// the final arbitration decision can be taken from the root of the tree
|
||||
assign req_o = req_nodes[0];
|
||||
assign data_o = data_nodes[0];
|
||||
assign idx_o = index_nodes[0];
|
||||
|
||||
if (ExtPrio) begin : gen_ext_rr
|
||||
assign rr_q = rr_i;
|
||||
assign req_d = req_i;
|
||||
end else begin : gen_int_rr
|
||||
idx_t rr_d;
|
||||
|
||||
// lock arbiter decision in case we got at least one req and no acknowledge
|
||||
if (LockIn) begin : gen_lock
|
||||
logic lock_d, lock_q;
|
||||
logic [NumIn-1:0] req_q;
|
||||
|
||||
assign lock_d = req_o & ~gnt_i;
|
||||
assign req_d = (lock_q) ? req_q : req_i;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_lock_reg
|
||||
if (!rst_ni) begin
|
||||
lock_q <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
lock_q <= '0;
|
||||
end else begin
|
||||
lock_q <= lock_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
lock: assert property(
|
||||
@(posedge clk_i) LockIn |-> req_o &&
|
||||
(!gnt_i && !flush_i) |=> idx_o == $past(idx_o)) else
|
||||
$fatal (1, "Lock implies same arbiter decision in next cycle if output is not \
|
||||
ready.");
|
||||
|
||||
logic [NumIn-1:0] req_tmp;
|
||||
assign req_tmp = req_q & req_i;
|
||||
lock_req: assume property(
|
||||
@(posedge clk_i) LockIn |-> lock_d |=> req_tmp == req_q) else
|
||||
$fatal (1, "It is disallowed to deassert unserved request signals when LockIn is \
|
||||
enabled.");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_req_regs
|
||||
if (!rst_ni) begin
|
||||
req_q <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
req_q <= '0;
|
||||
end else begin
|
||||
req_q <= req_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin : gen_no_lock
|
||||
assign req_d = req_i;
|
||||
end
|
||||
|
||||
if (FairArb) begin : gen_fair_arb
|
||||
logic [NumIn-1:0] upper_mask, lower_mask;
|
||||
idx_t upper_idx, lower_idx, next_idx;
|
||||
logic upper_empty, lower_empty;
|
||||
|
||||
for (genvar i = 0; i < NumIn; i++) begin : gen_mask
|
||||
assign upper_mask[i] = (i > rr_q) ? req_d[i] : 1'b0;
|
||||
assign lower_mask[i] = (i <= rr_q) ? req_d[i] : 1'b0;
|
||||
end
|
||||
|
||||
lzc #(
|
||||
.WIDTH ( NumIn ),
|
||||
.MODE ( 1'b0 )
|
||||
) i_lzc_upper (
|
||||
.in_i ( upper_mask ),
|
||||
.cnt_o ( upper_idx ),
|
||||
.empty_o ( upper_empty )
|
||||
);
|
||||
|
||||
lzc #(
|
||||
.WIDTH ( NumIn ),
|
||||
.MODE ( 1'b0 )
|
||||
) i_lzc_lower (
|
||||
.in_i ( lower_mask ),
|
||||
.cnt_o ( lower_idx ),
|
||||
.empty_o ( /*unused*/ )
|
||||
);
|
||||
|
||||
assign next_idx = upper_empty ? lower_idx : upper_idx;
|
||||
assign rr_d = (gnt_i && req_o) ? next_idx : rr_q;
|
||||
|
||||
end else begin : gen_unfair_arb
|
||||
assign rr_d = (gnt_i && req_o) ? ((rr_q == idx_t'(NumIn-1)) ? '0 : rr_q + 1'b1) : rr_q;
|
||||
end
|
||||
|
||||
// this holds the highest priority
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : p_rr_regs
|
||||
if (!rst_ni) begin
|
||||
rr_q <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
rr_q <= '0;
|
||||
end else begin
|
||||
rr_q <= rr_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign gnt_nodes[0] = gnt_i;
|
||||
|
||||
// arbiter tree
|
||||
for (genvar level = 0; unsigned'(level) < NumLevels; level++) begin : gen_levels
|
||||
for (genvar l = 0; l < 2**level; l++) begin : gen_level
|
||||
// local select signal
|
||||
logic sel;
|
||||
// index calcs
|
||||
localparam int unsigned Idx0 = 2**level-1+l;// current node
|
||||
localparam int unsigned Idx1 = 2**(level+1)-1+l*2;
|
||||
//////////////////////////////////////////////////////////////
|
||||
// uppermost level where data is fed in from the inputs
|
||||
if (unsigned'(level) == NumLevels-1) begin : gen_first_level
|
||||
// if two successive indices are still in the vector...
|
||||
if (unsigned'(l) * 2 < NumIn-1) begin : gen_reduce
|
||||
assign req_nodes[Idx0] = req_d[l*2] | req_d[l*2+1];
|
||||
|
||||
// arbitration: round robin
|
||||
assign sel = ~req_d[l*2] | req_d[l*2+1] & rr_q[NumLevels-1-level];
|
||||
|
||||
assign index_nodes[Idx0] = idx_t'(sel);
|
||||
assign data_nodes[Idx0] = (sel) ? data_i[l*2+1] : data_i[l*2];
|
||||
assign gnt_o[l*2] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l*2]) & ~sel;
|
||||
assign gnt_o[l*2+1] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l*2+1]) & sel;
|
||||
end
|
||||
// if only the first index is still in the vector...
|
||||
if (unsigned'(l) * 2 == NumIn-1) begin : gen_first
|
||||
assign req_nodes[Idx0] = req_d[l*2];
|
||||
assign index_nodes[Idx0] = '0;// always zero in this case
|
||||
assign data_nodes[Idx0] = data_i[l*2];
|
||||
assign gnt_o[l*2] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l*2]);
|
||||
end
|
||||
// if index is out of range, fill up with zeros (will get pruned)
|
||||
if (unsigned'(l) * 2 > NumIn-1) begin : gen_out_of_range
|
||||
assign req_nodes[Idx0] = 1'b0;
|
||||
assign index_nodes[Idx0] = idx_t'('0);
|
||||
assign data_nodes[Idx0] = DataType'('0);
|
||||
end
|
||||
//////////////////////////////////////////////////////////////
|
||||
// general case for other levels within the tree
|
||||
end else begin : gen_other_levels
|
||||
assign req_nodes[Idx0] = req_nodes[Idx1] | req_nodes[Idx1+1];
|
||||
|
||||
// arbitration: round robin
|
||||
assign sel = ~req_nodes[Idx1] | req_nodes[Idx1+1] & rr_q[NumLevels-1-level];
|
||||
|
||||
assign index_nodes[Idx0] = (sel) ?
|
||||
idx_t'({1'b1, index_nodes[Idx1+1][NumLevels-unsigned'(level)-2:0]}) :
|
||||
idx_t'({1'b0, index_nodes[Idx1][NumLevels-unsigned'(level)-2:0]});
|
||||
|
||||
assign data_nodes[Idx0] = (sel) ? data_nodes[Idx1+1] : data_nodes[Idx1];
|
||||
assign gnt_nodes[Idx1] = gnt_nodes[Idx0] & ~sel;
|
||||
assign gnt_nodes[Idx1+1] = gnt_nodes[Idx0] & sel;
|
||||
end
|
||||
//////////////////////////////////////////////////////////////
|
||||
end
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
`ifndef XSIM
|
||||
initial begin : p_assert
|
||||
assert(NumIn)
|
||||
else $fatal(1, "Input must be at least one element wide.");
|
||||
assert(!(LockIn && ExtPrio))
|
||||
else $fatal(1,"Cannot use LockIn feature together with external ExtPrio.");
|
||||
end
|
||||
|
||||
hot_one : assert property(
|
||||
@(posedge clk_i) $onehot0(gnt_o))
|
||||
else $fatal (1, "Grant signal must be hot1 or zero.");
|
||||
|
||||
gnt0 : assert property(
|
||||
@(posedge clk_i) |gnt_o |-> gnt_i)
|
||||
else $fatal (1, "Grant out implies grant in.");
|
||||
|
||||
gnt1 : assert property(
|
||||
@(posedge clk_i) req_o |-> gnt_i |-> |gnt_o)
|
||||
else $fatal (1, "Req out and grant in implies grant out.");
|
||||
|
||||
gnt_idx : assert property(
|
||||
@(posedge clk_i) req_o |-> gnt_i |-> gnt_o[idx_o])
|
||||
else $fatal (1, "Idx_o / gnt_o do not match.");
|
||||
|
||||
req0 : assert property(
|
||||
@(posedge clk_i) |req_i |-> req_o)
|
||||
else $fatal (1, "Req in implies req out.");
|
||||
|
||||
req1 : assert property(
|
||||
@(posedge clk_i) req_o |-> |req_i)
|
||||
else $fatal (1, "Req out implies req in.");
|
||||
`endif
|
||||
`endif
|
||||
// pragma translate_on
|
||||
end
|
||||
|
||||
endmodule : rr_arb_tree
|
30
vendor/pulp-platform/common_cells/src/rstgen.sv
vendored
Normal file
30
vendor/pulp-platform/common_cells/src/rstgen.sv
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Davide Rossi <davide.rossi@unibo.it>
|
||||
|
||||
module rstgen (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic test_mode_i,
|
||||
output logic rst_no,
|
||||
output logic init_no
|
||||
);
|
||||
|
||||
rstgen_bypass i_rstgen_bypass (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.rst_test_mode_ni ( rst_ni ),
|
||||
.test_mode_i ( test_mode_i ),
|
||||
.rst_no ( rst_no ),
|
||||
.init_no ( init_no )
|
||||
);
|
||||
|
||||
endmodule
|
57
vendor/pulp-platform/common_cells/src/rstgen_bypass.sv
vendored
Normal file
57
vendor/pulp-platform/common_cells/src/rstgen_bypass.sv
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
// Description: This module is a reset synchronizer with a dedicated reset bypass pin for testmode reset.
|
||||
// Pro Tip: The wise Dr. Schaffner recommends at least 4 registers!
|
||||
|
||||
module rstgen_bypass #(
|
||||
parameter int unsigned NumRegs = 4
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic rst_test_mode_ni,
|
||||
input logic test_mode_i,
|
||||
output logic rst_no,
|
||||
output logic init_no
|
||||
);
|
||||
|
||||
// internal reset
|
||||
logic rst_n;
|
||||
|
||||
logic [NumRegs-1:0] synch_regs_q;
|
||||
// bypass mode
|
||||
always_comb begin
|
||||
if (test_mode_i == 1'b0) begin
|
||||
rst_n = rst_ni;
|
||||
rst_no = synch_regs_q[NumRegs-1];
|
||||
init_no = synch_regs_q[NumRegs-1];
|
||||
end else begin
|
||||
rst_n = rst_test_mode_ni;
|
||||
rst_no = rst_test_mode_ni;
|
||||
init_no = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_i or negedge rst_n) begin
|
||||
if (~rst_n) begin
|
||||
synch_regs_q <= 0;
|
||||
end else begin
|
||||
synch_regs_q <= {synch_regs_q[NumRegs-2:0], 1'b1};
|
||||
end
|
||||
end
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin : p_assertions
|
||||
if (NumRegs < 1) $fatal(1, "At least one register is required.");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
50
vendor/pulp-platform/common_cells/src/serial_deglitch.sv
vendored
Normal file
50
vendor/pulp-platform/common_cells/src/serial_deglitch.sv
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba
|
||||
// Description: Deglitches a serial line by taking multiple samples until
|
||||
// asserting the output high/low.
|
||||
|
||||
module serial_deglitch #(
|
||||
parameter int unsigned SIZE = 4
|
||||
)(
|
||||
input logic clk_i, // clock
|
||||
input logic rst_ni, // asynchronous reset active low
|
||||
input logic en_i, // enable
|
||||
input logic d_i, // serial data in
|
||||
output logic q_o // filtered data out
|
||||
);
|
||||
logic [SIZE-1:0] count_q;
|
||||
logic q;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
count_q <= '0;
|
||||
q <= 1'b0;
|
||||
end else begin
|
||||
if (en_i) begin
|
||||
if (d_i == 1'b1 && count_q != SIZE[SIZE-1:0]) begin
|
||||
count_q <= count_q + 1;
|
||||
end else if (d_i == 1'b0 && count_q != SIZE[SIZE-1:0]) begin
|
||||
count_q <= count_q - 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// output process
|
||||
always_comb begin
|
||||
if (count_q == SIZE[SIZE-1:0]) begin
|
||||
q_o = 1'b1;
|
||||
end else if (count_q == 0) begin
|
||||
q_o = 1'b0;
|
||||
end
|
||||
end
|
||||
endmodule
|
53
vendor/pulp-platform/common_cells/src/shift_reg.sv
vendored
Normal file
53
vendor/pulp-platform/common_cells/src/shift_reg.sv
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
|
||||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: <zarubaf@iis.ee.ethz.ch>
|
||||
//
|
||||
// Description: Simple shift register for arbitrary depth and types
|
||||
|
||||
module shift_reg #(
|
||||
parameter type dtype = logic,
|
||||
parameter int unsigned Depth = 1
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input dtype d_i,
|
||||
output dtype d_o
|
||||
);
|
||||
|
||||
// register of depth 0 is a wire
|
||||
if (Depth == 0) begin : gen_pass_through
|
||||
assign d_o = d_i;
|
||||
// register of depth 1 is a simple register
|
||||
end else if (Depth == 1) begin : gen_register
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
d_o <= '0;
|
||||
end else begin
|
||||
d_o <= d_i;
|
||||
end
|
||||
end
|
||||
// if depth is greater than 1 it becomes a shift register
|
||||
end else if (Depth > 1) begin : gen_shift_reg
|
||||
dtype [Depth-1:0] reg_d, reg_q;
|
||||
assign d_o = reg_q[Depth-1];
|
||||
assign reg_d = {reg_q[Depth-2:0], d_i};
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
reg_q <= '0;
|
||||
end else begin
|
||||
reg_q <= reg_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
46
vendor/pulp-platform/common_cells/src/spill_register.sv
vendored
Normal file
46
vendor/pulp-platform/common_cells/src/spill_register.sv
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
|
||||
|
||||
/// Wrapper around the flushable spill register to maintain back-ward
|
||||
/// compatibility.
|
||||
module spill_register #(
|
||||
parameter type T = logic,
|
||||
parameter bit Bypass = 1'b0 // make this spill register transparent
|
||||
) (
|
||||
input logic clk_i ,
|
||||
input logic rst_ni ,
|
||||
input logic valid_i ,
|
||||
output logic ready_o ,
|
||||
input T data_i ,
|
||||
output logic valid_o ,
|
||||
input logic ready_i ,
|
||||
output T data_o
|
||||
);
|
||||
|
||||
spill_register_flushable #(
|
||||
.T(T),
|
||||
.Bypass(Bypass)
|
||||
) spill_register_flushable_i (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.valid_i,
|
||||
.flush_i(1'b0),
|
||||
.ready_o,
|
||||
.data_i,
|
||||
.valid_o,
|
||||
.ready_i,
|
||||
.data_o
|
||||
);
|
||||
|
||||
endmodule
|
105
vendor/pulp-platform/common_cells/src/spill_register_flushable.sv
vendored
Normal file
105
vendor/pulp-platform/common_cells/src/spill_register_flushable.sv
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
// Copyright 2021 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
|
||||
|
||||
|
||||
/// A register with handshakes that completely cuts any combinational paths
|
||||
/// between the input and output. This spill register can be flushed.
|
||||
module spill_register_flushable #(
|
||||
parameter type T = logic,
|
||||
parameter bit Bypass = 1'b0 // make this spill register transparent
|
||||
) (
|
||||
input logic clk_i ,
|
||||
input logic rst_ni ,
|
||||
input logic valid_i ,
|
||||
input logic flush_i ,
|
||||
output logic ready_o ,
|
||||
input T data_i ,
|
||||
output logic valid_o ,
|
||||
input logic ready_i ,
|
||||
output T data_o
|
||||
);
|
||||
|
||||
if (Bypass) begin : gen_bypass
|
||||
assign valid_o = valid_i;
|
||||
assign ready_o = ready_i;
|
||||
assign data_o = data_i;
|
||||
end else begin : gen_spill_reg
|
||||
// The A register.
|
||||
T a_data_q;
|
||||
logic a_full_q;
|
||||
logic a_fill, a_drain;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : ps_a_data
|
||||
if (!rst_ni)
|
||||
a_data_q <= '0;
|
||||
else if (a_fill)
|
||||
a_data_q <= data_i;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : ps_a_full
|
||||
if (!rst_ni)
|
||||
a_full_q <= 0;
|
||||
else if (a_fill || a_drain)
|
||||
a_full_q <= a_fill;
|
||||
end
|
||||
|
||||
// The B register.
|
||||
T b_data_q;
|
||||
logic b_full_q;
|
||||
logic b_fill, b_drain;
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : ps_b_data
|
||||
if (!rst_ni)
|
||||
b_data_q <= '0;
|
||||
else if (b_fill)
|
||||
b_data_q <= a_data_q;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : ps_b_full
|
||||
if (!rst_ni)
|
||||
b_full_q <= 0;
|
||||
else if (b_fill || b_drain)
|
||||
b_full_q <= b_fill;
|
||||
end
|
||||
|
||||
// Fill the A register when the A or B register is empty. Drain the A register
|
||||
// whenever it is full and being filled, or if a flush is requested.
|
||||
assign a_fill = valid_i && ready_o && (!flush_i);
|
||||
assign a_drain = (a_full_q && !b_full_q) || flush_i;
|
||||
|
||||
// Fill the B register whenever the A register is drained, but the downstream
|
||||
// circuit is not ready. Drain the B register whenever it is full and the
|
||||
// downstream circuit is ready, or if a flush is requested.
|
||||
assign b_fill = a_drain && (!ready_i) && (!flush_i);
|
||||
assign b_drain = (b_full_q && ready_i) || flush_i;
|
||||
|
||||
// We can accept input as long as register B is not full.
|
||||
// Note: flush_i and valid_i must not be high at the same time,
|
||||
// otherwise an invalid handshake may occur
|
||||
assign ready_o = !a_full_q || !b_full_q;
|
||||
|
||||
// The unit provides output as long as one of the registers is filled.
|
||||
assign valid_o = a_full_q | b_full_q;
|
||||
|
||||
// We empty the spill register before the slice register.
|
||||
assign data_o = b_full_q ? b_data_q : a_data_q;
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
flush_valid : assert property (
|
||||
@(posedge clk_i) disable iff (~rst_ni) (flush_i |-> ~valid_i)) else
|
||||
$warning("Trying to flush and feed the spill register simultaneously. You will lose data!");
|
||||
`endif
|
||||
// pragma translate_on
|
||||
end
|
||||
endmodule
|
49
vendor/pulp-platform/common_cells/src/stream_arbiter.sv
vendored
Normal file
49
vendor/pulp-platform/common_cells/src/stream_arbiter.sv
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Stream arbiter: Arbitrates a parametrizable number of input streams (i.e., valid-ready
|
||||
// handshaking with dependency rules as in AXI4) to a single output stream. Once `oup_valid_o` is
|
||||
// asserted, `oup_data_o` remains invariant until the output handshake has occurred. The
|
||||
// arbitration scheme is round-robin with "look ahead", see the `rrarbiter` for details.
|
||||
|
||||
module stream_arbiter #(
|
||||
parameter type DATA_T = logic, // Vivado requires a default value for type parameters.
|
||||
parameter integer N_INP = -1, // Synopsys DC requires a default value for parameters.
|
||||
parameter ARBITER = "rr" // "rr" or "prio"
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input DATA_T [N_INP-1:0] inp_data_i,
|
||||
input logic [N_INP-1:0] inp_valid_i,
|
||||
output logic [N_INP-1:0] inp_ready_o,
|
||||
|
||||
output DATA_T oup_data_o,
|
||||
output logic oup_valid_o,
|
||||
input logic oup_ready_i
|
||||
);
|
||||
|
||||
stream_arbiter_flushable #(
|
||||
.DATA_T (DATA_T),
|
||||
.N_INP (N_INP),
|
||||
.ARBITER (ARBITER)
|
||||
) i_arb (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.flush_i (1'b0),
|
||||
.inp_data_i (inp_data_i),
|
||||
.inp_valid_i (inp_valid_i),
|
||||
.inp_ready_o (inp_ready_o),
|
||||
.oup_data_o (oup_data_o),
|
||||
.oup_valid_o (oup_valid_o),
|
||||
.oup_ready_i (oup_ready_i)
|
||||
);
|
||||
|
||||
endmodule
|
82
vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv
vendored
Normal file
82
vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Stream arbiter: Arbitrates a parametrizable number of input streams (i.e., valid-ready
|
||||
// handshaking with dependency rules as in AXI4) to a single output stream. Once `oup_valid_o` is
|
||||
// asserted, `oup_data_o` remains invariant until the output handshake has occurred. The
|
||||
// arbitration scheme is fair round-robin tree, see `rr_arb_tree` for details.
|
||||
|
||||
module stream_arbiter_flushable #(
|
||||
parameter type DATA_T = logic, // Vivado requires a default value for type parameters.
|
||||
parameter integer N_INP = -1, // Synopsys DC requires a default value for parameters.
|
||||
parameter ARBITER = "rr" // "rr" or "prio"
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic flush_i,
|
||||
|
||||
input DATA_T [N_INP-1:0] inp_data_i,
|
||||
input logic [N_INP-1:0] inp_valid_i,
|
||||
output logic [N_INP-1:0] inp_ready_o,
|
||||
|
||||
output DATA_T oup_data_o,
|
||||
output logic oup_valid_o,
|
||||
input logic oup_ready_i
|
||||
);
|
||||
|
||||
if (ARBITER == "rr") begin : gen_rr_arb
|
||||
rr_arb_tree #(
|
||||
.NumIn (N_INP),
|
||||
.DataType (DATA_T),
|
||||
.ExtPrio (1'b0),
|
||||
.AxiVldRdy (1'b1),
|
||||
.LockIn (1'b1)
|
||||
) i_arbiter (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.rr_i ('0),
|
||||
.req_i (inp_valid_i),
|
||||
.gnt_o (inp_ready_o),
|
||||
.data_i (inp_data_i),
|
||||
.gnt_i (oup_ready_i),
|
||||
.req_o (oup_valid_o),
|
||||
.data_o (oup_data_o),
|
||||
.idx_o ()
|
||||
);
|
||||
|
||||
end else if (ARBITER == "prio") begin : gen_prio_arb
|
||||
rr_arb_tree #(
|
||||
.NumIn (N_INP),
|
||||
.DataType (DATA_T),
|
||||
.ExtPrio (1'b1),
|
||||
.AxiVldRdy (1'b1),
|
||||
.LockIn (1'b1)
|
||||
) i_arbiter (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.rr_i ('0),
|
||||
.req_i (inp_valid_i),
|
||||
.gnt_o (inp_ready_o),
|
||||
.data_i (inp_data_i),
|
||||
.gnt_i (oup_ready_i),
|
||||
.req_o (oup_valid_o),
|
||||
.data_o (oup_data_o),
|
||||
.idx_o ()
|
||||
);
|
||||
|
||||
end else begin : gen_arb_error
|
||||
// pragma translate_off
|
||||
$fatal(1, "Invalid value for parameter 'ARBITER'!");
|
||||
// pragma translate_on
|
||||
end
|
||||
|
||||
endmodule
|
132
vendor/pulp-platform/common_cells/src/stream_delay.sv
vendored
Normal file
132
vendor/pulp-platform/common_cells/src/stream_delay.sv
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba, zarubaf@iis.ee.ethz.ch
|
||||
// Description: Delay (or randomize) AXI-like handshaking
|
||||
|
||||
module stream_delay #(
|
||||
parameter bit StallRandom = 0,
|
||||
parameter int FixedDelay = 1,
|
||||
parameter type payload_t = logic
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input payload_t payload_i,
|
||||
output logic ready_o,
|
||||
input logic valid_i,
|
||||
|
||||
output payload_t payload_o,
|
||||
input logic ready_i,
|
||||
output logic valid_o
|
||||
);
|
||||
|
||||
if (FixedDelay == 0 && !StallRandom) begin : gen_pass_through
|
||||
assign ready_o = ready_i;
|
||||
assign valid_o = valid_i;
|
||||
assign payload_o = payload_i;
|
||||
end else begin : gen_delay
|
||||
|
||||
localparam int unsigned CounterBits = 4;
|
||||
|
||||
typedef enum logic [1:0] {
|
||||
Idle, Valid, Ready
|
||||
} state_e;
|
||||
|
||||
state_e state_d, state_q;
|
||||
|
||||
logic load;
|
||||
logic [3:0] count_out;
|
||||
logic en;
|
||||
|
||||
logic [CounterBits-1:0] counter_load;
|
||||
|
||||
assign payload_o = payload_i;
|
||||
|
||||
always_comb begin
|
||||
state_d = state_q;
|
||||
valid_o = 1'b0;
|
||||
ready_o = 1'b0;
|
||||
load = 1'b0;
|
||||
en = 1'b0;
|
||||
|
||||
unique case (state_q)
|
||||
Idle: begin
|
||||
if (valid_i) begin
|
||||
load = 1'b1;
|
||||
state_d = Valid;
|
||||
// Just one cycle delay
|
||||
if (FixedDelay == 1 || (StallRandom && counter_load == 1)) begin
|
||||
state_d = Ready;
|
||||
end
|
||||
|
||||
if (StallRandom && counter_load == 0) begin
|
||||
valid_o = 1'b1;
|
||||
ready_o = ready_i;
|
||||
if (ready_i) state_d = Idle;
|
||||
else state_d = Ready;
|
||||
end
|
||||
end
|
||||
end
|
||||
Valid: begin
|
||||
en = 1'b1;
|
||||
if (count_out == 0) begin
|
||||
state_d = Ready;
|
||||
end
|
||||
end
|
||||
|
||||
Ready: begin
|
||||
valid_o = 1'b1;
|
||||
ready_o = ready_i;
|
||||
if (ready_i) state_d = Idle;
|
||||
end
|
||||
default : /* default */;
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
if (StallRandom) begin : gen_random_stall
|
||||
lfsr_16bit #(
|
||||
.WIDTH ( 16 )
|
||||
) i_lfsr_16bit (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.en_i ( load ),
|
||||
.refill_way_oh ( ),
|
||||
.refill_way_bin ( counter_load )
|
||||
);
|
||||
end else begin : gen_fixed_delay
|
||||
assign counter_load = FixedDelay;
|
||||
end
|
||||
|
||||
counter #(
|
||||
.WIDTH ( CounterBits )
|
||||
) i_counter (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.clear_i ( 1'b0 ),
|
||||
.en_i ( en ),
|
||||
.load_i ( load ),
|
||||
.down_i ( 1'b1 ),
|
||||
.d_i ( counter_load ),
|
||||
.q_o ( count_out ),
|
||||
.overflow_o ( )
|
||||
);
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
state_q <= Idle;
|
||||
end else begin
|
||||
state_q <= state_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
36
vendor/pulp-platform/common_cells/src/stream_demux.sv
vendored
Normal file
36
vendor/pulp-platform/common_cells/src/stream_demux.sv
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/// Connects the input stream (valid-ready) handshake to one of `N_OUP` output stream handshakes.
|
||||
///
|
||||
/// This module has no data ports because stream data does not need to be demultiplexed: the data of
|
||||
/// the input stream can just be applied at all output streams.
|
||||
module stream_demux #(
|
||||
/// Number of connected outputs.
|
||||
parameter int unsigned N_OUP = 32'd1,
|
||||
/// Dependent parameters, DO NOT OVERRIDE!
|
||||
parameter int unsigned LOG_N_OUP = (N_OUP > 32'd1) ? unsigned'($clog2(N_OUP)) : 1'b1
|
||||
) (
|
||||
input logic inp_valid_i,
|
||||
output logic inp_ready_o,
|
||||
|
||||
input logic [LOG_N_OUP-1:0] oup_sel_i,
|
||||
|
||||
output logic [N_OUP-1:0] oup_valid_o,
|
||||
input logic [N_OUP-1:0] oup_ready_i
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
oup_valid_o = '0;
|
||||
oup_valid_o[oup_sel_i] = inp_valid_i;
|
||||
end
|
||||
assign inp_ready_o = oup_ready_i[oup_sel_i];
|
||||
|
||||
endmodule
|
66
vendor/pulp-platform/common_cells/src/stream_fifo.sv
vendored
Normal file
66
vendor/pulp-platform/common_cells/src/stream_fifo.sv
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Georg Rutishauser <georgr@iis.ee.ethz.ch>
|
||||
|
||||
module stream_fifo #(
|
||||
/// FIFO is in fall-through mode
|
||||
parameter bit FALL_THROUGH = 1'b0,
|
||||
/// Default data width if the fifo is of type logic
|
||||
parameter int unsigned DATA_WIDTH = 32,
|
||||
/// Depth can be arbitrary from 0 to 2**32
|
||||
parameter int unsigned DEPTH = 8,
|
||||
parameter type T = logic [DATA_WIDTH-1:0],
|
||||
// DO NOT OVERWRITE THIS PARAMETER
|
||||
parameter int unsigned ADDR_DEPTH = (DEPTH > 1) ? $clog2(DEPTH) : 1
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // flush the fifo
|
||||
input logic testmode_i, // test_mode to bypass clock gating
|
||||
output logic [ADDR_DEPTH-1:0] usage_o, // fill pointer
|
||||
// input interface
|
||||
input T data_i, // data to push into the fifo
|
||||
input logic valid_i, // input data valid
|
||||
output logic ready_o, // fifo is not full
|
||||
// output interface
|
||||
output T data_o, // output data
|
||||
output logic valid_o, // fifo is not empty
|
||||
input logic ready_i // pop head from fifo
|
||||
);
|
||||
|
||||
logic push, pop;
|
||||
logic empty, full;
|
||||
|
||||
assign push = valid_i & ~full;
|
||||
assign pop = ready_i & ~empty;
|
||||
assign ready_o = ~full;
|
||||
assign valid_o = ~empty;
|
||||
|
||||
fifo_v3 #(
|
||||
.FALL_THROUGH (FALL_THROUGH),
|
||||
.DATA_WIDTH (DATA_WIDTH),
|
||||
.DEPTH (DEPTH),
|
||||
.dtype(T)
|
||||
) fifo_i (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.testmode_i,
|
||||
.full_o (full),
|
||||
.empty_o (empty),
|
||||
.usage_o,
|
||||
.data_i,
|
||||
.push_i (push),
|
||||
.data_o,
|
||||
.pop_i (pop)
|
||||
);
|
||||
|
||||
endmodule
|
26
vendor/pulp-platform/common_cells/src/stream_filter.sv
vendored
Normal file
26
vendor/pulp-platform/common_cells/src/stream_filter.sv
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Stream filter: If `drop_i` is `1`, signal `ready` to the upstream regardless of the downstream,
|
||||
// and do not propagate `valid` downstream. Otherwise, connect upstream to downstream.
|
||||
module stream_filter (
|
||||
input logic valid_i,
|
||||
output logic ready_o,
|
||||
|
||||
input logic drop_i,
|
||||
|
||||
output logic valid_o,
|
||||
input logic ready_i
|
||||
);
|
||||
|
||||
assign valid_o = drop_i ? 1'b0 : valid_i;
|
||||
assign ready_o = drop_i ? 1'b1 : ready_i;
|
||||
|
||||
endmodule
|
133
vendor/pulp-platform/common_cells/src/stream_fork.sv
vendored
Normal file
133
vendor/pulp-platform/common_cells/src/stream_fork.sv
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Stream fork: Connects the input stream (ready-valid) handshake to *all* of `N_OUP` output stream
|
||||
// handshakes. For each input stream handshake, every output stream handshakes exactly once. The
|
||||
// input stream only handshakes when all output streams have handshaked, but the output streams do
|
||||
// not have to handshake simultaneously.
|
||||
//
|
||||
// This module has no data ports because stream data does not need to be forked: the data of the
|
||||
// input stream can just be applied at all output streams.
|
||||
|
||||
module stream_fork #(
|
||||
parameter int unsigned N_OUP = 0 // Synopsys DC requires a default value for parameters.
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic valid_i,
|
||||
output logic ready_o,
|
||||
output logic [N_OUP-1:0] valid_o,
|
||||
input logic [N_OUP-1:0] ready_i
|
||||
);
|
||||
|
||||
typedef enum logic {READY, WAIT} state_t;
|
||||
|
||||
logic [N_OUP-1:0] oup_ready,
|
||||
all_ones;
|
||||
|
||||
state_t inp_state_d, inp_state_q;
|
||||
|
||||
// Input control FSM
|
||||
always_comb begin
|
||||
// ready_o = 1'b0;
|
||||
inp_state_d = inp_state_q;
|
||||
|
||||
unique case (inp_state_q)
|
||||
READY: begin
|
||||
if (valid_i) begin
|
||||
if (valid_o == all_ones && ready_i == all_ones) begin
|
||||
// If handshake on all outputs, handshake on input.
|
||||
ready_o = 1'b1;
|
||||
end else begin
|
||||
ready_o = 1'b0;
|
||||
// Otherwise, wait for inputs that did not handshake yet.
|
||||
inp_state_d = WAIT;
|
||||
end
|
||||
end else begin
|
||||
ready_o = 1'b0;
|
||||
end
|
||||
end
|
||||
WAIT: begin
|
||||
if (valid_i && oup_ready == all_ones) begin
|
||||
ready_o = 1'b1;
|
||||
inp_state_d = READY;
|
||||
end else begin
|
||||
ready_o = 1'b0;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
inp_state_d = READY;
|
||||
ready_o = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
inp_state_q <= READY;
|
||||
end else begin
|
||||
inp_state_q <= inp_state_d;
|
||||
end
|
||||
end
|
||||
|
||||
// Output control FSM
|
||||
for (genvar i = 0; i < N_OUP; i++) begin: gen_oup_state
|
||||
state_t oup_state_d, oup_state_q;
|
||||
|
||||
always_comb begin
|
||||
oup_ready[i] = 1'b1;
|
||||
valid_o[i] = 1'b0;
|
||||
oup_state_d = oup_state_q;
|
||||
|
||||
unique case (oup_state_q)
|
||||
READY: begin
|
||||
if (valid_i) begin
|
||||
valid_o[i] = 1'b1;
|
||||
if (ready_i[i]) begin // Output handshake
|
||||
if (!ready_o) begin // No input handshake yet
|
||||
oup_state_d = WAIT;
|
||||
end
|
||||
end else begin // No output handshake
|
||||
oup_ready[i] = 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
WAIT: begin
|
||||
if (valid_i && ready_o) begin // Input handshake
|
||||
oup_state_d = READY;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
oup_state_d = READY;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
oup_state_q <= READY;
|
||||
end else begin
|
||||
oup_state_q <= oup_state_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign all_ones = '1; // Synthesis fix for Vivado, which does not correctly compute the width
|
||||
// of the '1 literal when assigned to a port of parametrized width.
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin: p_assertions
|
||||
assert (N_OUP >= 1) else $fatal(1, "Number of outputs must be at least 1!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule
|
95
vendor/pulp-platform/common_cells/src/stream_fork_dynamic.sv
vendored
Normal file
95
vendor/pulp-platform/common_cells/src/stream_fork_dynamic.sv
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Authors:
|
||||
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
|
||||
|
||||
/// Dynamic stream fork: Connects the input stream (ready-valid) handshake to a combination of output
|
||||
/// stream handshake. The combination is determined dynamically through another stream, which
|
||||
/// provides a bitmask for the fork. For each input stream handshake, every output stream handshakes
|
||||
/// exactly once. The input stream only handshakes when all output streams have handshaked, but the
|
||||
/// output streams do not have to handshake simultaneously.
|
||||
///
|
||||
/// This module has no data ports because stream data does not need to be forked: the data of the
|
||||
/// input stream can just be applied at all output streams.
|
||||
module stream_fork_dynamic #(
|
||||
/// Number of output streams
|
||||
parameter int unsigned N_OUP = 32'd0 // Synopsys DC requires a default value for parameters.
|
||||
) (
|
||||
/// Clock
|
||||
input logic clk_i,
|
||||
/// Asynchronous reset, active low
|
||||
input logic rst_ni,
|
||||
/// Input stream valid handshake,
|
||||
input logic valid_i,
|
||||
/// Input stream ready handshake
|
||||
output logic ready_o,
|
||||
/// Selection mask for the output handshake
|
||||
input logic [N_OUP-1:0] sel_i,
|
||||
/// Selection mask valid
|
||||
input logic sel_valid_i,
|
||||
/// Selection mask ready
|
||||
output logic sel_ready_o,
|
||||
/// Output streams valid handshakes
|
||||
output logic [N_OUP-1:0] valid_o,
|
||||
/// Output streams ready handshakes
|
||||
input logic [N_OUP-1:0] ready_i
|
||||
);
|
||||
|
||||
logic int_inp_valid, int_inp_ready;
|
||||
logic [N_OUP-1:0] int_oup_valid, int_oup_ready;
|
||||
|
||||
// Output handshaking
|
||||
for (genvar i = 0; i < N_OUP; i++) begin : gen_oups
|
||||
always_comb begin
|
||||
valid_o[i] = 1'b0;
|
||||
int_oup_ready[i] = 1'b0;
|
||||
if (sel_valid_i) begin
|
||||
if (sel_i[i]) begin
|
||||
valid_o[i] = int_oup_valid[i];
|
||||
int_oup_ready[i] = ready_i[i];
|
||||
end else begin
|
||||
int_oup_ready[i] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Input handshaking
|
||||
always_comb begin
|
||||
int_inp_valid = 1'b0;
|
||||
ready_o = 1'b0;
|
||||
sel_ready_o = 1'b0;
|
||||
if (sel_valid_i) begin
|
||||
int_inp_valid = valid_i;
|
||||
ready_o = int_inp_ready;
|
||||
sel_ready_o = int_inp_ready;
|
||||
end
|
||||
end
|
||||
|
||||
stream_fork #(
|
||||
.N_OUP ( N_OUP )
|
||||
) i_fork (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.valid_i ( int_inp_valid ),
|
||||
.ready_o ( int_inp_ready ),
|
||||
.valid_o ( int_oup_valid ),
|
||||
.ready_i ( int_oup_ready )
|
||||
);
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin: p_assertions
|
||||
assert (N_OUP >= 1) else $fatal(1, "N_OUP must be at least 1!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
49
vendor/pulp-platform/common_cells/src/stream_intf.sv
vendored
Normal file
49
vendor/pulp-platform/common_cells/src/stream_intf.sv
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
//
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
/// A stream interface with custom payload of type `payload_t`.
|
||||
/// Handshaking rules as defined in the AXI standard.
|
||||
interface STREAM_DV #(
|
||||
/// Custom payload type.
|
||||
parameter type payload_t = logic
|
||||
)(
|
||||
/// Interface clock.
|
||||
input logic clk_i
|
||||
);
|
||||
payload_t data;
|
||||
logic valid;
|
||||
logic ready;
|
||||
|
||||
modport In (
|
||||
output ready,
|
||||
input valid, data
|
||||
);
|
||||
|
||||
modport Out (
|
||||
output valid, data,
|
||||
input ready
|
||||
);
|
||||
|
||||
/// Passive modport for scoreboard and monitors.
|
||||
modport Passive (
|
||||
input valid, ready, data
|
||||
);
|
||||
|
||||
// Make sure that the handshake and payload is stable
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
assert property (@(posedge clk_i) (valid && !ready |=> $stable(data)));
|
||||
assert property (@(posedge clk_i) (valid && !ready |=> valid));
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endinterface
|
43
vendor/pulp-platform/common_cells/src/stream_join.sv
vendored
Normal file
43
vendor/pulp-platform/common_cells/src/stream_join.sv
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Authors:
|
||||
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
|
||||
|
||||
/// Stream join: Joins a parametrizable number of input streams (i.e., valid-ready handshaking with
|
||||
/// dependency rules as in AXI4) to a single output stream. The output handshake happens only once
|
||||
/// all inputs are valid. The data channel flows outside of this module.
|
||||
module stream_join #(
|
||||
/// Number of input streams
|
||||
parameter int unsigned N_INP = 32'd0 // Synopsys DC requires a default value for parameters.
|
||||
) (
|
||||
/// Input streams valid handshakes
|
||||
input logic [N_INP-1:0] inp_valid_i,
|
||||
/// Input streams ready handshakes
|
||||
output logic [N_INP-1:0] inp_ready_o,
|
||||
/// Output stream valid handshake
|
||||
output logic oup_valid_o,
|
||||
/// Output stream ready handshake
|
||||
input logic oup_ready_i
|
||||
);
|
||||
|
||||
assign oup_valid_o = (&inp_valid_i);
|
||||
for (genvar i = 0; i < N_INP; i++) begin : gen_inp_ready
|
||||
assign inp_ready_o[i] = oup_valid_o & oup_ready_i;
|
||||
end
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin: p_assertions
|
||||
assert (N_INP >= 1) else $fatal(1, "N_INP must be at least 1!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
46
vendor/pulp-platform/common_cells/src/stream_mux.sv
vendored
Normal file
46
vendor/pulp-platform/common_cells/src/stream_mux.sv
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/// Stream multiplexer: connects the output to one of `N_INP` data streams with valid-ready
|
||||
/// handshaking.
|
||||
|
||||
module stream_mux #(
|
||||
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 value parameters.
|
||||
/// Dependent parameters, DO NOT OVERRIDE!
|
||||
parameter integer LOG_N_INP = $clog2(N_INP)
|
||||
) (
|
||||
input DATA_T [N_INP-1:0] inp_data_i,
|
||||
input logic [N_INP-1:0] inp_valid_i,
|
||||
output logic [N_INP-1:0] inp_ready_o,
|
||||
|
||||
input logic [LOG_N_INP-1:0] inp_sel_i,
|
||||
|
||||
output DATA_T oup_data_o,
|
||||
output logic oup_valid_o,
|
||||
input logic oup_ready_i
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
inp_ready_o = '0;
|
||||
inp_ready_o[inp_sel_i] = oup_ready_i;
|
||||
end
|
||||
assign oup_data_o = inp_data_i[inp_sel_i];
|
||||
assign oup_valid_o = inp_valid_i[inp_sel_i];
|
||||
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
initial begin: p_assertions
|
||||
assert (N_INP >= 1) else $fatal (1, "The number of inputs must be at least 1!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
|
||||
endmodule
|
301
vendor/pulp-platform/common_cells/src/stream_omega_net.sv
vendored
Normal file
301
vendor/pulp-platform/common_cells/src/stream_omega_net.sv
vendored
Normal file
|
@ -0,0 +1,301 @@
|
|||
// Copyright (c) 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Wolfgang Roenninger <wroennin@ethz.ch>
|
||||
|
||||
/// Omega network using multiple `stream_xbar` as switches.
|
||||
///
|
||||
/// An omega network is isomorphic to a butterfly network.
|
||||
///
|
||||
/// Handshaking rules as defined by the `AMBA AXI` standard on default.
|
||||
module stream_omega_net #(
|
||||
/// Number of inputs into the network (`> 0`).
|
||||
parameter int unsigned NumInp = 32'd0,
|
||||
/// Number of outputs from the network (`> 0`).
|
||||
parameter int unsigned NumOut = 32'd0,
|
||||
/// Radix of the individual switch points of the network.
|
||||
/// Currently supported are `32'd2` and `32'd4`.
|
||||
parameter int unsigned Radix = 32'd2,
|
||||
/// 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`.
|
||||
parameter type payload_t = logic [DataWidth-1:0],
|
||||
/// Adds a spill register stage at each output.
|
||||
parameter bit SpillReg = 1'b0,
|
||||
/// Use external priority for the individual `rr_arb_trees`.
|
||||
parameter int unsigned ExtPrio = 1'b0,
|
||||
/// Use strict AXI valid ready handshaking.
|
||||
/// To be protocol conform also the parameter `LockIn` has to be set.
|
||||
parameter int unsigned AxiVldRdy = 1'b1,
|
||||
/// Lock in the arbitration decision of the `rr_arb_tree`.
|
||||
/// When this is set, valids have to be asserted until the corresponding transaction is indicated
|
||||
/// by ready.
|
||||
parameter int unsigned LockIn = 1'b1,
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Width of the output selection signal.
|
||||
parameter int unsigned SelWidth = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1,
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Signal type definition for selecting the output at the inputs.
|
||||
parameter type sel_oup_t = logic[SelWidth-1:0],
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Width of the input index signal.
|
||||
parameter int unsigned IdxWidth = (NumInp > 32'd1) ? unsigned'($clog2(NumInp)) : 32'd1,
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Signal type definition indicating from which input the output came.
|
||||
parameter type idx_inp_t = logic[IdxWidth-1:0]
|
||||
) (
|
||||
/// Clock, positive edge triggered.
|
||||
input logic clk_i,
|
||||
/// Asynchronous reset, active low.
|
||||
input logic rst_ni,
|
||||
/// Flush the state of the internal `rr_arb_tree` modules.
|
||||
/// If not used set to `0`.
|
||||
/// Flush should only be used if there are no active `valid_i`, otherwise it will
|
||||
/// not adhere to the AXI handshaking.
|
||||
input logic flush_i,
|
||||
/// Provide an external state for the `rr_arb_tree` models.
|
||||
/// Will only do something if ExtPrio is `1` otherwise tie to `0`.
|
||||
input idx_inp_t [NumOut-1:0] rr_i,
|
||||
/// Input data ports.
|
||||
/// Has to be stable as long as `valid_i` is asserted when parameter `AxiVldRdy` is set.
|
||||
input payload_t [NumInp-1:0] data_i,
|
||||
/// Selection of the output port where the data should be routed.
|
||||
/// Has to be stable as long as `valid_i` is asserted and parameter `AxiVldRdy` is set.
|
||||
input sel_oup_t [NumInp-1:0] sel_i,
|
||||
/// Input is valid.
|
||||
input logic [NumInp-1:0] valid_i,
|
||||
/// Input is ready to accept data.
|
||||
output logic [NumInp-1:0] ready_o,
|
||||
/// Output data ports. Valid if `valid_o = 1`
|
||||
output payload_t [NumOut-1:0] data_o,
|
||||
/// Index of the input port where data came from.
|
||||
output idx_inp_t [NumOut-1:0] idx_o,
|
||||
/// Output is valid.
|
||||
output logic [NumOut-1:0] valid_o,
|
||||
/// Output can be accepted.
|
||||
input logic [NumOut-1:0] ready_i
|
||||
);
|
||||
if (NumInp <= Radix && NumOut <= Radix) begin : gen_degenerate_omega_net
|
||||
// If both Number of inputs and number of outputs are smaller or the same as the radix
|
||||
// just instantiate a `stream_xbar`.
|
||||
stream_xbar #(
|
||||
.NumInp ( NumInp ),
|
||||
.NumOut ( NumOut ),
|
||||
.payload_t ( payload_t ),
|
||||
.OutSpillReg ( SpillReg ),
|
||||
.ExtPrio ( ExtPrio ),
|
||||
.AxiVldRdy ( AxiVldRdy ),
|
||||
.LockIn ( LockIn )
|
||||
) i_stream_xbar (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.rr_i ( rr_i ),
|
||||
.data_i ( data_i ),
|
||||
.sel_i ( sel_i ),
|
||||
.valid_i ( valid_i ),
|
||||
.ready_o ( ready_o ),
|
||||
.data_o ( data_o ),
|
||||
.idx_o ( idx_o ),
|
||||
.valid_o ( valid_o ),
|
||||
.ready_i ( ready_i )
|
||||
);
|
||||
end else begin : gen_omega_net
|
||||
// Find the next power of radix of either the number of inputs or number of outputs.
|
||||
// This normalizes the network to a power of the radix. Unused inputs and outputs are tied off.
|
||||
// If the radix is poorly chosen with respect to the number of input/outputs ports
|
||||
// will lead to an explosion of tied off lanes, which will be removed during optimization.
|
||||
// Can lead however to RTL simulation overhead.
|
||||
// Dividing through the log base 2 of `Radix` leads to a change of base.
|
||||
localparam int unsigned NumLanes = (NumOut > NumInp) ?
|
||||
unsigned'(Radix**(cf_math_pkg::ceil_div($clog2(NumOut), $clog2(Radix)))) :
|
||||
unsigned'(Radix**(cf_math_pkg::ceil_div($clog2(NumInp), $clog2(Radix))));
|
||||
|
||||
// Find the number of routing levels needed.
|
||||
localparam int unsigned NumLevels = unsigned'(($clog2(NumLanes)+$clog2(Radix)-1)/$clog2(Radix));
|
||||
|
||||
// Find the number of routes per network stage. Can use a normal division here, as
|
||||
// `NumLanes % Radix == 0`.
|
||||
localparam int unsigned NumRouters = NumLanes / Radix;
|
||||
|
||||
// Define the type of sel signal to send through the network. It has to be sliced for the
|
||||
// individual sel signals of a stage. This slicing has to align with `$clog2(Radix)`.
|
||||
// For example `Radix = 4`, `NumOut = 17` will lead to the sel signal of an individual stage to
|
||||
// be 2 bit wide, whereas signal `sel_i` of the module will be 5 bit wide.
|
||||
// To prevent slicing into an undefined field the overall sel signal is then defined with
|
||||
// width 6.
|
||||
typedef logic [$clog2(NumLanes)-1:0] sel_dst_t;
|
||||
|
||||
// Selection signal type of an individual router
|
||||
localparam int unsigned SelW = unsigned'($clog2(Radix));
|
||||
initial begin : proc_selw
|
||||
$display("SelW is: %0d", SelW);
|
||||
$display("SelDstW is: %0d", $bits(sel_dst_t));
|
||||
end
|
||||
typedef logic [SelW-1:0] sel_t;
|
||||
|
||||
// Define the payload which should be routed through the network.
|
||||
typedef struct packed {
|
||||
sel_dst_t sel_oup; // Selection of output, where it should be routed
|
||||
payload_t payload; // External payload data
|
||||
idx_inp_t idx_inp; // Index of the input of this packet
|
||||
} omega_data_t;
|
||||
|
||||
// signal definitions
|
||||
omega_data_t [NumLevels-1:0][NumRouters-1:0][Radix-1:0] inp_router_data;
|
||||
logic [NumLevels-1:0][NumRouters-1:0][Radix-1:0] inp_router_valid, inp_router_ready;
|
||||
omega_data_t [NumLevels-1:0][NumRouters-1:0][Radix-1:0] out_router_data;
|
||||
logic [NumLevels-1:0][NumRouters-1:0][Radix-1:0] out_router_valid, out_router_ready;
|
||||
|
||||
// Generate the shuffling between the routers
|
||||
for (genvar i = 0; unsigned'(i) < NumLevels-1; i++) begin : gen_shuffle_levels
|
||||
for (genvar j = 0; unsigned'(j) < NumRouters; j++) begin : gen_shuffle_routers
|
||||
for (genvar k = 0; unsigned'(k) < Radix; k++) begin : gen_shuffle_radix
|
||||
// This parameter is from `0` to `NumLanes-1`
|
||||
localparam int unsigned IdxLane = Radix * j + k;
|
||||
// Do the perfect shuffle
|
||||
assign inp_router_data[i+1][IdxLane%NumRouters][IdxLane/NumRouters] =
|
||||
out_router_data[i][j][k];
|
||||
|
||||
assign inp_router_valid[i+1][IdxLane%NumRouters][IdxLane/NumRouters] =
|
||||
out_router_valid[i][j][k];
|
||||
|
||||
assign out_router_ready[i][j][k] =
|
||||
inp_router_ready[i+1][IdxLane%NumRouters][IdxLane/NumRouters];
|
||||
|
||||
// Do the first input shuffle of layer 0.
|
||||
// The inputs are connected in reverse. The reason is that then the optimization
|
||||
// leaves then the biggest possible network diameter.
|
||||
if (i == 0) begin : gen_shuffle_inp
|
||||
// Reverse the order of the input ports
|
||||
if ((NumLanes-IdxLane) <= NumInp) begin : gen_inp_ports
|
||||
localparam int unsigned IdxInp = NumLanes - IdxLane - 32'd1;
|
||||
assign inp_router_data[0][IdxLane%NumRouters][IdxLane/NumRouters] = '{
|
||||
sel_oup: sel_dst_t'(sel_i[IdxInp]),
|
||||
payload: data_i[IdxInp],
|
||||
idx_inp: idx_inp_t'(IdxInp)
|
||||
};
|
||||
|
||||
assign inp_router_valid[0][IdxLane%NumRouters][IdxLane/NumRouters] = valid_i[IdxInp];
|
||||
assign ready_o[IdxInp] = inp_router_ready[0][IdxLane%NumRouters][IdxLane/NumRouters];
|
||||
|
||||
end else begin : gen_tie_off
|
||||
assign inp_router_data[0][IdxLane%NumRouters][IdxLane/NumRouters] = '{ default: '0};
|
||||
assign inp_router_valid[0][IdxLane%NumRouters][IdxLane/NumRouters] = 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Generate the `stream_xbar_routers`
|
||||
for (genvar i = 0; unsigned'(i) < NumLevels; i++) begin : gen_router_levels
|
||||
for (genvar j = 0; unsigned'(j) < NumRouters; j++) begin : gen_routers
|
||||
sel_t [Radix-1:0] sel_router;
|
||||
for (genvar k = 0; unsigned'(k) < Radix; k++) begin : gen_router_sel
|
||||
// For the inter stage routing some bits of the overall selection are important.
|
||||
// The `MSB` is for stage `0`, `MSB-1` for stage `1` and so on for the `Radix=2` case.
|
||||
// For higher radices's a bit slice following the same pattern is used.
|
||||
// This is the reason that the internal network is expanded to a power of two, so that
|
||||
// the selection slicing always has a valid index.
|
||||
assign sel_router[k] = inp_router_data[i][j][k].sel_oup[SelW*(NumLevels-i-1)+:SelW];
|
||||
end
|
||||
|
||||
stream_xbar #(
|
||||
.NumInp ( Radix ),
|
||||
.NumOut ( Radix ),
|
||||
.payload_t ( omega_data_t ),
|
||||
.OutSpillReg ( SpillReg ),
|
||||
.ExtPrio ( 1'b0 ),
|
||||
.AxiVldRdy ( AxiVldRdy ),
|
||||
.LockIn ( LockIn )
|
||||
) i_stream_xbar (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.rr_i ( '0 ),
|
||||
.data_i ( inp_router_data[i][j] ),
|
||||
.sel_i ( sel_router ),
|
||||
.valid_i ( inp_router_valid[i][j] ),
|
||||
.ready_o ( inp_router_ready[i][j] ),
|
||||
.data_o ( out_router_data[i][j] ),
|
||||
.idx_o ( /* not used */ ),
|
||||
.valid_o ( out_router_valid[i][j] ),
|
||||
.ready_i ( out_router_ready[i][j] )
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
// outputs are on the last level
|
||||
for (genvar i = 0; unsigned'(i) < NumLanes; i++) begin : gen_outputs
|
||||
if (i < NumOut) begin : gen_connect
|
||||
assign data_o[i] = out_router_data[NumLevels-1][i/Radix][i%Radix].payload;
|
||||
assign idx_o[i] = out_router_data[NumLevels-1][i/Radix][i%Radix].idx_inp;
|
||||
assign valid_o[i] = out_router_valid[NumLevels-1][i/Radix][i%Radix];
|
||||
assign out_router_ready[NumLevels-1][i/Radix][i%Radix] = ready_i[i];
|
||||
end else begin : gen_tie_off
|
||||
assign out_router_ready[NumLevels-1][i/Radix][i%Radix] = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin : proc_debug_print
|
||||
$display("NumInp: %0d", NumInp);
|
||||
$display("NumOut: %0d", NumOut);
|
||||
$display("Radix: %0d", Radix);
|
||||
$display("NumLanes: %0d", NumLanes);
|
||||
$display("NumLevels: %0d", NumLevels);
|
||||
$display("NumRouters: %0d", NumRouters);
|
||||
end
|
||||
|
||||
// Assertions
|
||||
// Make sure that the handshake and payload is stable
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
default disable iff rst_ni;
|
||||
for (genvar i = 0; unsigned'(i) < NumInp; i++) begin : gen_sel_assertions
|
||||
assert property (@(posedge clk_i) (valid_i[i] |-> sel_i[i] < sel_oup_t'(NumOut))) else
|
||||
$fatal(1, "Non-existing output is selected!");
|
||||
end
|
||||
|
||||
if (AxiVldRdy) begin : gen_handshake_assertions
|
||||
for (genvar i = 0; unsigned'(i) < NumInp; i++) begin : gen_inp_assertions
|
||||
assert property (@(posedge clk_i) (valid_i[i] && !ready_o[i] |=> $stable(data_i[i]))) else
|
||||
$error("data_i is unstable at input: %0d", i);
|
||||
assert property (@(posedge clk_i) (valid_i[i] && !ready_o[i] |=> $stable(sel_i[i]))) else
|
||||
$error("sel_i is unstable at input: %0d", i);
|
||||
assert property (@(posedge clk_i) (valid_i[i] && !ready_o[i] |=> valid_i[i])) else
|
||||
$error("valid_i at input %0d has been taken away without a ready.", i);
|
||||
end
|
||||
for (genvar i = 0; unsigned'(i) < NumOut; i++) begin : gen_out_assertions
|
||||
assert property (@(posedge clk_i) (valid_o[i] && !ready_i[i] |=> $stable(data_o[i]))) else
|
||||
$error("data_o is unstable at output: %0d Check that parameter LockIn is set.", i);
|
||||
assert property (@(posedge clk_i) (valid_o[i] && !ready_i[i] |=> $stable(idx_o[i]))) else
|
||||
$error("idx_o is unstable at output: %0d Check that parameter LockIn is set.", i);
|
||||
assert property (@(posedge clk_i) (valid_o[i] && !ready_i[i] |=> valid_o[i])) else
|
||||
$error("valid_o at output %0d has been taken away without a ready.", i);
|
||||
end
|
||||
end
|
||||
|
||||
initial begin : proc_parameter_assertions
|
||||
assert ((2**$clog2(Radix) == Radix) && (Radix > 32'd1)) else
|
||||
$fatal(1, "Radix %0d is not power of two.", Radix);
|
||||
assert (2**$clog2(NumRouters) == NumRouters) else
|
||||
$fatal(1, "NumRouters %0d is not power of two.", NumRouters);
|
||||
assert ($clog2(NumLanes) % SelW == 0) else
|
||||
$fatal(1, "Bit slicing of the internal selection signal is broken.");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
end
|
||||
endmodule
|
57
vendor/pulp-platform/common_cells/src/stream_register.sv
vendored
Normal file
57
vendor/pulp-platform/common_cells/src/stream_register.sv
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/// Register with a simple stream-like ready/valid handshake.
|
||||
/// This register does not cut combinatorial paths on all control signals; if you need a complete
|
||||
/// cut, use the `spill_register`.
|
||||
module stream_register #(
|
||||
parameter type T = logic // Vivado requires a default value for type parameters.
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous active-low reset
|
||||
input logic clr_i, // Synchronous clear
|
||||
input logic testmode_i, // Test mode to bypass clock gating
|
||||
// Input port
|
||||
input logic valid_i,
|
||||
output logic ready_o,
|
||||
input T data_i,
|
||||
// Output port
|
||||
output logic valid_o,
|
||||
input logic ready_i,
|
||||
output T data_o
|
||||
);
|
||||
|
||||
logic fifo_empty,
|
||||
fifo_full;
|
||||
|
||||
fifo_v2 #(
|
||||
.FALL_THROUGH (1'b0),
|
||||
.DATA_WIDTH ($bits(T)),
|
||||
.DEPTH (1),
|
||||
.dtype (T)
|
||||
) i_fifo (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.flush_i (clr_i),
|
||||
.testmode_i (testmode_i),
|
||||
.full_o (fifo_full),
|
||||
.empty_o (fifo_empty),
|
||||
.alm_full_o ( ),
|
||||
.alm_empty_o ( ),
|
||||
.data_i (data_i),
|
||||
.push_i (valid_i & ~fifo_full),
|
||||
.data_o (data_o),
|
||||
.pop_i (ready_i & ~fifo_empty)
|
||||
);
|
||||
|
||||
assign ready_o = ~fifo_full;
|
||||
assign valid_o = ~fifo_empty;
|
||||
|
||||
endmodule
|
134
vendor/pulp-platform/common_cells/src/stream_to_mem.sv
vendored
Normal file
134
vendor/pulp-platform/common_cells/src/stream_to_mem.sv
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Authors:
|
||||
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
|
||||
|
||||
/// `stream_to_mem`: Allows to use memories with flow control (`valid`/`ready`) for requests but without flow
|
||||
/// control for output data to be used in streams.
|
||||
`include "common_cells/registers.svh"
|
||||
module stream_to_mem #(
|
||||
/// Memory request payload type, usually write enable, write data, etc.
|
||||
parameter type mem_req_t = logic,
|
||||
/// Memory response payload type, usually read data
|
||||
parameter type mem_resp_t = logic,
|
||||
/// Number of buffered responses (fall-through, thus no additional latency). This defines the
|
||||
/// maximum number of outstanding requests on the memory interface. If the attached memory
|
||||
/// responds in the same cycle a request is applied, this MUST be 0. If the attached memory
|
||||
/// responds at least one cycle after a request, this MUST be >= 1 and should be equal to the
|
||||
/// response latency of the memory to saturate bandwidth.
|
||||
parameter int unsigned BufDepth = 32'd1
|
||||
) (
|
||||
/// Clock
|
||||
input logic clk_i,
|
||||
/// Asynchronous reset, active low
|
||||
input logic rst_ni,
|
||||
/// Request stream interface, payload
|
||||
input mem_req_t req_i,
|
||||
/// Request stream interface, payload is valid for transfer
|
||||
input logic req_valid_i,
|
||||
/// Request stream interface, payload can be accepted
|
||||
output logic req_ready_o,
|
||||
/// Response stream interface, payload
|
||||
output mem_resp_t resp_o,
|
||||
/// Response stream interface, payload is valid for transfer
|
||||
output logic resp_valid_o,
|
||||
/// Response stream interface, payload can be accepted
|
||||
input logic resp_ready_i,
|
||||
/// Memory request interface, payload
|
||||
output mem_req_t mem_req_o,
|
||||
/// Memory request interface, payload is valid for transfer
|
||||
output logic mem_req_valid_o,
|
||||
/// Memory request interface, payload can be accepted
|
||||
input logic mem_req_ready_i,
|
||||
/// Memory response interface, payload
|
||||
input mem_resp_t mem_resp_i,
|
||||
/// Memory response interface, payload is valid
|
||||
input logic mem_resp_valid_i
|
||||
);
|
||||
|
||||
typedef logic [$clog2(BufDepth+1):0] cnt_t;
|
||||
|
||||
cnt_t cnt_d, cnt_q;
|
||||
logic buf_ready,
|
||||
req_ready;
|
||||
|
||||
if (BufDepth > 0) begin : gen_buf
|
||||
// Count number of outstanding requests.
|
||||
always_comb begin
|
||||
cnt_d = cnt_q;
|
||||
if (req_valid_i && req_ready_o) begin
|
||||
cnt_d++;
|
||||
end
|
||||
if (resp_valid_o && resp_ready_i) begin
|
||||
cnt_d--;
|
||||
end
|
||||
end
|
||||
|
||||
// Can issue another request if the counter is not at its limit or a response is delivered in
|
||||
// the current cycle.
|
||||
assign req_ready = (cnt_q < BufDepth) | (resp_valid_o & resp_ready_i);
|
||||
|
||||
// Control request and memory request interface handshakes.
|
||||
assign req_ready_o = mem_req_ready_i & req_ready;
|
||||
assign mem_req_valid_o = req_valid_i & req_ready;
|
||||
|
||||
// Buffer responses.
|
||||
stream_fifo #(
|
||||
.FALL_THROUGH ( 1'b1 ),
|
||||
.DEPTH ( BufDepth ),
|
||||
.T ( mem_resp_t )
|
||||
) i_resp_buf (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i ( 1'b0 ),
|
||||
.testmode_i ( 1'b0 ),
|
||||
.data_i ( mem_resp_i ),
|
||||
.valid_i ( mem_resp_valid_i ),
|
||||
.ready_o ( buf_ready ),
|
||||
.data_o ( resp_o ),
|
||||
.valid_o ( resp_valid_o ),
|
||||
.ready_i ( resp_ready_i ),
|
||||
.usage_o ( /* unused */ )
|
||||
);
|
||||
|
||||
// Register
|
||||
`FFARN(cnt_q, cnt_d, '0, clk_i, rst_ni)
|
||||
|
||||
end else begin : gen_no_buf
|
||||
// Control request, memory request, and response interface handshakes.
|
||||
assign mem_req_valid_o = req_valid_i;
|
||||
assign resp_valid_o = mem_req_valid_o & mem_req_ready_i & mem_resp_valid_i;
|
||||
assign req_ready_o = resp_ready_i & resp_valid_o;
|
||||
|
||||
// Forward responses.
|
||||
assign resp_o = mem_resp_i;
|
||||
end
|
||||
|
||||
// Forward requests.
|
||||
assign mem_req_o = req_i;
|
||||
|
||||
// Assertions
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
if (BufDepth > 0) begin : gen_buf_asserts
|
||||
assert property (@(posedge clk_i) mem_resp_valid_i |-> buf_ready)
|
||||
else $error("Memory response lost!");
|
||||
assert property (@(posedge clk_i) cnt_q == '0 |=> cnt_q != '1)
|
||||
else $error("Counter underflowed!");
|
||||
assert property (@(posedge clk_i) cnt_q == BufDepth |=> cnt_q != BufDepth + 1)
|
||||
else $error("Counter overflowed!");
|
||||
end else begin : gen_no_buf_asserts
|
||||
assume property (@(posedge clk_i) mem_req_valid_o & mem_req_ready_i |-> mem_resp_valid_i)
|
||||
else $error("Without BufDepth = 0, the memory must respond in the same cycle!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
198
vendor/pulp-platform/common_cells/src/stream_xbar.sv
vendored
Normal file
198
vendor/pulp-platform/common_cells/src/stream_xbar.sv
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
// Copyright (c) 2020 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Wolfgang Roenninger <wroennin@ethz.ch>
|
||||
|
||||
/// Fully connected stream crossbar.
|
||||
///
|
||||
/// Handshaking rules as defined by the `AMBA AXI` standard on default.
|
||||
module stream_xbar #(
|
||||
/// Number of inputs into the crossbar (`> 0`).
|
||||
parameter int unsigned NumInp = 32'd0,
|
||||
/// Number of outputs from the crossbar (`> 0`).
|
||||
parameter int unsigned NumOut = 32'd0,
|
||||
/// 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`.
|
||||
parameter type payload_t = logic [DataWidth-1:0],
|
||||
/// Adds a spill register stage at each output.
|
||||
parameter bit OutSpillReg = 1'b0,
|
||||
/// Use external priority for the individual `rr_arb_trees`.
|
||||
parameter int unsigned ExtPrio = 1'b0,
|
||||
/// Use strict AXI valid ready handshaking.
|
||||
/// To be protocol conform also the parameter `LockIn` has to be set.
|
||||
parameter int unsigned AxiVldRdy = 1'b1,
|
||||
/// Lock in the arbitration decision of the `rr_arb_tree`.
|
||||
/// When this is set, valids have to be asserted until the corresponding transaction is indicated
|
||||
/// by ready.
|
||||
parameter int unsigned LockIn = 1'b1,
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Width of the output selection signal.
|
||||
parameter int unsigned SelWidth = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1,
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Signal type definition for selecting the output at the inputs.
|
||||
parameter type sel_oup_t = logic[SelWidth-1:0],
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Width of the input index signal.
|
||||
parameter int unsigned IdxWidth = (NumInp > 32'd1) ? unsigned'($clog2(NumInp)) : 32'd1,
|
||||
/// Derived parameter, do **not** overwrite!
|
||||
///
|
||||
/// Signal type definition indicating from which input the output came.
|
||||
parameter type idx_inp_t = logic[IdxWidth-1:0]
|
||||
) (
|
||||
/// Clock, positive edge triggered.
|
||||
input logic clk_i,
|
||||
/// Asynchronous reset, active low.
|
||||
input logic rst_ni,
|
||||
/// Flush the state of the internal `rr_arb_tree` modules.
|
||||
/// If not used set to `0`.
|
||||
/// Flush should only be used if there are no active `valid_i`, otherwise it will
|
||||
/// not adhere to the AXI handshaking.
|
||||
input logic flush_i,
|
||||
/// Provide an external state for the `rr_arb_tree` models.
|
||||
/// Will only do something if ExtPrio is `1` otherwise tie to `0`.
|
||||
input idx_inp_t [NumOut-1:0] rr_i,
|
||||
/// Input data ports.
|
||||
/// Has to be stable as long as `valid_i` is asserted when parameter `AxiVldRdy` is set.
|
||||
input payload_t [NumInp-1:0] data_i,
|
||||
/// Selection of the output port where the data should be routed.
|
||||
/// Has to be stable as long as `valid_i` is asserted and parameter `AxiVldRdy` is set.
|
||||
input sel_oup_t [NumInp-1:0] sel_i,
|
||||
/// Input is valid.
|
||||
input logic [NumInp-1:0] valid_i,
|
||||
/// Input is ready to accept data.
|
||||
output logic [NumInp-1:0] ready_o,
|
||||
/// Output data ports. Valid if `valid_o = 1`
|
||||
output payload_t [NumOut-1:0] data_o,
|
||||
/// Index of the input port where data came from.
|
||||
output idx_inp_t [NumOut-1:0] idx_o,
|
||||
/// Output is valid.
|
||||
output logic [NumOut-1:0] valid_o,
|
||||
/// Output can be accepted.
|
||||
input logic [NumOut-1:0] ready_i
|
||||
);
|
||||
typedef struct packed {
|
||||
payload_t data;
|
||||
idx_inp_t idx;
|
||||
} spill_data_t;
|
||||
|
||||
logic [NumInp-1:0][NumOut-1:0] inp_valid;
|
||||
logic [NumInp-1:0][NumOut-1:0] inp_ready;
|
||||
|
||||
payload_t [NumOut-1:0][NumInp-1:0] out_data;
|
||||
logic [NumOut-1:0][NumInp-1:0] out_valid;
|
||||
logic [NumOut-1:0][NumInp-1:0] out_ready;
|
||||
|
||||
// Generate the input selection
|
||||
for (genvar i = 0; unsigned'(i) < NumInp; i++) begin : gen_inps
|
||||
stream_demux #(
|
||||
.N_OUP ( NumOut )
|
||||
) i_stream_demux (
|
||||
.inp_valid_i ( valid_i[i] ),
|
||||
.inp_ready_o ( ready_o[i] ),
|
||||
.oup_sel_i ( sel_i[i] ),
|
||||
.oup_valid_o ( inp_valid[i] ),
|
||||
.oup_ready_i ( inp_ready[i] )
|
||||
);
|
||||
|
||||
// Do the switching cross of the signals.
|
||||
for (genvar j = 0; unsigned'(j) < NumOut; j++) begin : gen_cross
|
||||
// Propagate the data from this input to all outputs.
|
||||
assign out_data[j][i] = data_i[i];
|
||||
// switch handshaking
|
||||
assign out_valid[j][i] = inp_valid[i][j];
|
||||
assign inp_ready[i][j] = out_ready[j][i];
|
||||
end
|
||||
end
|
||||
|
||||
// Generate the output arbitration.
|
||||
for (genvar j = 0; unsigned'(j) < NumOut; j++) begin : gen_outs
|
||||
spill_data_t arb;
|
||||
logic arb_valid, arb_ready;
|
||||
|
||||
rr_arb_tree #(
|
||||
.NumIn ( NumInp ),
|
||||
.DataType ( payload_t ),
|
||||
.ExtPrio ( ExtPrio ),
|
||||
.AxiVldRdy ( AxiVldRdy ),
|
||||
.LockIn ( LockIn )
|
||||
) i_rr_arb_tree (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i,
|
||||
.rr_i ( rr_i[j] ),
|
||||
.req_i ( out_valid[j] ),
|
||||
.gnt_o ( out_ready[j] ),
|
||||
.data_i ( out_data[j] ),
|
||||
.req_o ( arb_valid ),
|
||||
.gnt_i ( arb_ready ),
|
||||
.data_o ( arb.data ),
|
||||
.idx_o ( arb.idx )
|
||||
);
|
||||
|
||||
spill_data_t spill;
|
||||
|
||||
spill_register #(
|
||||
.T ( spill_data_t ),
|
||||
.Bypass ( !OutSpillReg )
|
||||
) i_spill_register (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.valid_i ( arb_valid ),
|
||||
.ready_o ( arb_ready ),
|
||||
.data_i ( arb ),
|
||||
.valid_o ( valid_o[j] ),
|
||||
.ready_i ( ready_i[j] ),
|
||||
.data_o ( spill )
|
||||
);
|
||||
// Assign the outputs (deaggregate the data).
|
||||
assign data_o[j] = spill.data;
|
||||
assign idx_o[j] = spill.idx;
|
||||
end
|
||||
|
||||
// Assertions
|
||||
// Make sure that the handshake and payload is stable
|
||||
// pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
default disable iff rst_ni;
|
||||
for (genvar i = 0; unsigned'(i) < NumInp; i++) begin : gen_sel_assertions
|
||||
assert property (@(posedge clk_i) (valid_i[i] |-> sel_i[i] < sel_oup_t'(NumOut))) else
|
||||
$fatal(1, "Non-existing output is selected!");
|
||||
end
|
||||
|
||||
if (AxiVldRdy) begin : gen_handshake_assertions
|
||||
for (genvar i = 0; unsigned'(i) < NumInp; i++) begin : gen_inp_assertions
|
||||
assert property (@(posedge clk_i) (valid_i[i] && !ready_o[i] |=> $stable(data_i[i]))) else
|
||||
$error("data_i is unstable at input: %0d", i);
|
||||
assert property (@(posedge clk_i) (valid_i[i] && !ready_o[i] |=> $stable(sel_i[i]))) else
|
||||
$error("sel_i is unstable at input: %0d", i);
|
||||
assert property (@(posedge clk_i) (valid_i[i] && !ready_o[i] |=> valid_i[i])) else
|
||||
$error("valid_i at input %0d has been taken away without a ready.", i);
|
||||
end
|
||||
for (genvar i = 0; unsigned'(i) < NumOut; i++) begin : gen_out_assertions
|
||||
assert property (@(posedge clk_i) (valid_o[i] && !ready_i[i] |=> $stable(data_o[i]))) else
|
||||
$error("data_o is unstable at output: %0d Check that parameter LockIn is set.", i);
|
||||
assert property (@(posedge clk_i) (valid_o[i] && !ready_i[i] |=> $stable(idx_o[i]))) else
|
||||
$error("idx_o is unstable at output: %0d Check that parameter LockIn is set.", i);
|
||||
assert property (@(posedge clk_i) (valid_o[i] && !ready_i[i] |=> valid_o[i])) else
|
||||
$error("valid_o at output %0d has been taken away without a ready.", i);
|
||||
end
|
||||
end
|
||||
|
||||
initial begin : proc_parameter_assertions
|
||||
assert (NumInp > 32'd0) else $fatal(1, "NumInp has to be > 0!");
|
||||
assert (NumOut > 32'd0) else $fatal(1, "NumOut has to be > 0!");
|
||||
end
|
||||
`endif
|
||||
// pragma translate_on
|
||||
endmodule
|
173
vendor/pulp-platform/common_cells/src/sub_per_hash.sv
vendored
Normal file
173
vendor/pulp-platform/common_cells/src/sub_per_hash.sv
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
// Copyright (c) 2019 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Author: Wolfgang Roenninger <wroennin@ethz.ch>
|
||||
|
||||
// This module implements a fully parameterizable substitution-permutation hash
|
||||
// function. The hash is structured in stages consisting of a shuffle of the input bits
|
||||
// and then xoring for each bit 3 pseudo-random bits of the shuffeled vector.
|
||||
// The hash function is NOT cryptographically secure!
|
||||
// From the keys it computes a sequence of pseudo-random numbers, which determine the permutations
|
||||
// and substitutions. As pseudo random generator a multiplicative linear congruential
|
||||
// generator is used and uses different constants for the computation of the permutation
|
||||
// and substitution respectively.
|
||||
// The permutation shuffles the bits using a variant of the Fisher-Yates shuffle algorithm.
|
||||
// The substitution per stage is the xor of 3 pseudo random bits of the previous stage.
|
||||
// As shifting and xoring of a signal do not change its distribution, the distribution
|
||||
// of the output hash is the same as the one of the input data.
|
||||
//
|
||||
// Parameters:
|
||||
// - `InpWidth`: The input width of the vector `data_i`.
|
||||
// - `HashWidth`: The output width of the substitution-permutation hash.
|
||||
// - `NoRounds`: The amount of permutation, substitution stages generated. Translates
|
||||
// into how many levels of xor's there will be before optimization.
|
||||
// - `PermuteKey`: The Key for the pseudo-random generator used for determining the exact
|
||||
// permutation (shuffled wiring between each xor stage) at compile/elaboration.
|
||||
// Any `int unsigned` value can be used as key, however one should examine the
|
||||
// output of the hash function.
|
||||
// - `XorKey`: The Key for the pseudo-random generator used for determining the xor
|
||||
// of bits between stages. The same principles as for `PermuteKey` applies,
|
||||
// however one should look that both keys have a greatest common divisor of 1.
|
||||
|
||||
module sub_per_hash #(
|
||||
parameter int unsigned InpWidth = 32'd11,
|
||||
parameter int unsigned HashWidth = 32'd5,
|
||||
parameter int unsigned NoRounds = 32'd1,
|
||||
parameter int unsigned PermuteKey = 32'd299034753,
|
||||
parameter int unsigned XorKey = 32'd4094834
|
||||
) (
|
||||
// is purely combinational
|
||||
input logic [InpWidth-1:0] data_i,
|
||||
output logic [HashWidth-1:0] hash_o,
|
||||
output logic [2**HashWidth-1:0] hash_onehot_o
|
||||
);
|
||||
|
||||
// typedefs and respective localparams
|
||||
typedef int unsigned perm_lists_t [NoRounds][InpWidth];
|
||||
localparam perm_lists_t PERMUTATIONS = get_permutations(PermuteKey);
|
||||
// encoding for inner most array:
|
||||
// position 0 indicates the number of inputs, 2 or 3
|
||||
// the other positions 1 - 3 indicate the inputs
|
||||
typedef int unsigned xor_stages_t [NoRounds][InpWidth][3];
|
||||
localparam xor_stages_t XorStages = get_xor_stages(XorKey);
|
||||
|
||||
// stage signals
|
||||
logic [NoRounds-1:0][InpWidth-1:0] permuted, xored;
|
||||
|
||||
// for each round
|
||||
for (genvar r = 0; r < NoRounds; r++) begin : gen_round
|
||||
// for each bit
|
||||
for (genvar i = 0; i < InpWidth ; i++) begin : gen_sub_per
|
||||
|
||||
// assign the permutation
|
||||
if (r == 0) begin : gen_input
|
||||
assign permuted[r][i] = data_i[PERMUTATIONS[r][i]];
|
||||
end else begin : gen_permutation
|
||||
assign permuted[r][i] = permuted[r-1][PERMUTATIONS[r][i]];
|
||||
end
|
||||
|
||||
// assign the xor substitution
|
||||
assign xored[r][i] = permuted[r][XorStages[r][i][0]] ^
|
||||
permuted[r][XorStages[r][i][1]] ^
|
||||
permuted[r][XorStages[r][i][2]];
|
||||
end
|
||||
end
|
||||
|
||||
// output assignment, take the bottom bits of the last round
|
||||
assign hash_o = xored[NoRounds-1][HashWidth-1:0];
|
||||
// for onehot run trough a decoder
|
||||
assign hash_onehot_o = 1 << hash_o;
|
||||
|
||||
// PRG is MLCG (multiplicative linear congruential generator)
|
||||
// Constant values the same as RtlUniform from Native API
|
||||
// X(n+1) = (a*X(n)+c) mod m
|
||||
// a: large prime
|
||||
// c: increment
|
||||
// m: range
|
||||
// Shuffling is a variation of the Fisher-Yates shuffle algorithm
|
||||
function automatic perm_lists_t get_permutations(input int unsigned seed);
|
||||
perm_lists_t indices;
|
||||
perm_lists_t perm_array;
|
||||
longint unsigned A = 2147483629;
|
||||
longint unsigned C = 2147483587;
|
||||
longint unsigned M = 2**31 - 1;
|
||||
longint unsigned index = 0;
|
||||
longint unsigned advance = 0;
|
||||
longint unsigned rand_number = (A * seed + C) % M;
|
||||
|
||||
// do it for each round
|
||||
for (int unsigned r = 0; r < NoRounds; r++) begin
|
||||
// initialize the index array
|
||||
for (int unsigned i = 0; i < InpWidth; i++) begin
|
||||
indices[r][i] = i;
|
||||
end
|
||||
// do the shuffling
|
||||
for (int unsigned i = 0; i < InpWidth; i++) begin
|
||||
// get the 'random' number
|
||||
if (i > 0) begin
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
index = rand_number % i;
|
||||
end
|
||||
// do the shuffling
|
||||
if (i != index) begin
|
||||
perm_array[r][i] = perm_array[r][index];
|
||||
perm_array[r][index] = indices[r][i];
|
||||
end
|
||||
end
|
||||
// advance the PRG a bit
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
advance = rand_number % NoRounds;
|
||||
for (int unsigned i = 0; i < advance; i++) begin
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
end
|
||||
end
|
||||
return perm_array;
|
||||
endfunction : get_permutations
|
||||
|
||||
// PRG is MLCG (multiplicative linear congruential generator)
|
||||
// Constant values the same as Numerical Recipes
|
||||
// X(n+1) = (a*X(n)+c) mod m
|
||||
// a: large prime
|
||||
// c: increment
|
||||
// m: range
|
||||
function automatic xor_stages_t get_xor_stages(input int unsigned seed);
|
||||
xor_stages_t xor_array;
|
||||
longint unsigned A = 1664525;
|
||||
longint unsigned C = 1013904223;
|
||||
longint unsigned M = 2**32;
|
||||
longint unsigned index = 0;
|
||||
// int unsigned even = 0;
|
||||
longint unsigned advance = 0;
|
||||
longint unsigned rand_number = (A * seed + C) % M;
|
||||
|
||||
// fill the array with 'randon' inputs
|
||||
// for each xor, a even random number is two input, uneven is tree
|
||||
// for each round
|
||||
for (int unsigned r = 0; r < NoRounds; r++) begin
|
||||
// for each bit
|
||||
for (int unsigned i = 0; i < InpWidth; i++) begin
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
// even = rand_number[3];
|
||||
for (int unsigned j = 0; j < 3; j++) begin
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
index = rand_number % InpWidth;
|
||||
xor_array[r][i][j] = index;
|
||||
end
|
||||
end
|
||||
// advance the PRG a bit
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
advance = rand_number % NoRounds;
|
||||
for (int unsigned i = 0; i < advance; i++) begin
|
||||
rand_number = (A * rand_number + C) % M;
|
||||
end
|
||||
end
|
||||
return xor_array;
|
||||
endfunction : get_xor_stages
|
||||
endmodule
|
35
vendor/pulp-platform/common_cells/src/sync.sv
vendored
Normal file
35
vendor/pulp-platform/common_cells/src/sync.sv
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module sync #(
|
||||
parameter int unsigned STAGES = 2,
|
||||
parameter bit ResetValue = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic serial_i,
|
||||
output logic serial_o
|
||||
);
|
||||
|
||||
logic [STAGES-1:0] reg_q;
|
||||
|
||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
reg_q <= {STAGES{ResetValue}};
|
||||
end else begin
|
||||
reg_q <= {reg_q[STAGES-2:0], serial_i};
|
||||
end
|
||||
end
|
||||
|
||||
assign serial_o = reg_q[STAGES-1];
|
||||
|
||||
endmodule
|
56
vendor/pulp-platform/common_cells/src/sync_wedge.sv
vendored
Normal file
56
vendor/pulp-platform/common_cells/src/sync_wedge.sv
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
// Antonio Pullini <pullinia@iis.ee.ethz.ch>
|
||||
|
||||
module sync_wedge #(
|
||||
parameter int unsigned STAGES = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic en_i,
|
||||
input logic serial_i,
|
||||
output logic r_edge_o,
|
||||
output logic f_edge_o,
|
||||
output logic serial_o
|
||||
);
|
||||
logic clk;
|
||||
logic serial, serial_q;
|
||||
|
||||
assign serial_o = serial_q;
|
||||
assign f_edge_o = (~serial) & serial_q;
|
||||
assign r_edge_o = serial & (~serial_q);
|
||||
|
||||
sync #(
|
||||
.STAGES (STAGES)
|
||||
) i_sync (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.serial_i,
|
||||
.serial_o ( serial )
|
||||
);
|
||||
|
||||
pulp_clock_gating i_pulp_clock_gating (
|
||||
.clk_i,
|
||||
.en_i,
|
||||
.test_en_i ( 1'b0 ),
|
||||
.clk_o ( clk )
|
||||
);
|
||||
|
||||
always_ff @(posedge clk, negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
serial_q <= 1'b0;
|
||||
end else begin
|
||||
if (en_i) begin
|
||||
serial_q <= serial;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
21
vendor/pulp-platform/common_cells/src/unread.sv
vendored
Normal file
21
vendor/pulp-platform/common_cells/src/unread.sv
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 29.10.2018
|
||||
// Description: Dummy circuit to mitigate Open Pin warnings
|
||||
|
||||
/* verilator lint_off UNUSED */
|
||||
module unread (
|
||||
input logic d_i
|
||||
);
|
||||
|
||||
endmodule
|
||||
/* verilator lint_on UNUSED */
|
3
vendor/pulp-platform/fpnew/.gitignore
vendored
Normal file
3
vendor/pulp-platform/fpnew/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*~
|
||||
html
|
||||
Bender.lock
|
176
vendor/pulp-platform/fpnew/LICENSE
vendored
Normal file
176
vendor/pulp-platform/fpnew/LICENSE
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
SOLDERPAD HARDWARE LICENSE version 0.51
|
||||
|
||||
This license is based closely on the Apache License Version 2.0, but is not
|
||||
approved or endorsed by the Apache Foundation. A copy of the non-modified
|
||||
Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
As this license is not currently OSI or FSF approved, the Licensor permits any
|
||||
Work licensed under this License, at the option of the Licensee, to be treated
|
||||
as licensed under the Apache License Version 2.0 (which is so approved).
|
||||
|
||||
This License is licensed under the terms of this License and in particular
|
||||
clause 7 below (Disclaimer of Warranties) applies in relation to its use.
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
“License” shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
“Licensor” shall mean the Rights owner or entity authorized by the Rights owner
|
||||
that is granting the License.
|
||||
|
||||
“Legal Entity” shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, “control” means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
“You” (or “Your”) shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
“Rights” means copyright and any similar right including design right (whether
|
||||
registered or unregistered), semiconductor topography (mask) rights and
|
||||
database rights (but excluding Patents and Trademarks).
|
||||
|
||||
“Source” form shall mean the preferred form for making modifications, including
|
||||
but not limited to source code, net lists, board layouts, CAD files,
|
||||
documentation source, and configuration files.
|
||||
|
||||
“Object” form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object
|
||||
code, generated documentation, the instantiation of a hardware design and
|
||||
conversions to other media types, including intermediate forms such as
|
||||
bytecodes, FPGA bitstreams, artwork and semiconductor topographies (mask
|
||||
works).
|
||||
|
||||
“Work” shall mean the work of authorship, whether in Source form or other
|
||||
Object form, made available under the License, as indicated by a Rights notice
|
||||
that is included in or attached to the work (an example is provided in the
|
||||
Appendix below).
|
||||
|
||||
“Derivative Works” shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) or physically connect to or interoperate with the interfaces of, the Work
|
||||
and Derivative Works thereof.
|
||||
|
||||
“Contribution” shall mean any design or work of authorship, including the
|
||||
original version of the Work and any modifications or additions to that Work or
|
||||
Derivative Works thereof, that is intentionally submitted to Licensor for
|
||||
inclusion in the Work by the Rights owner or by an individual or Legal Entity
|
||||
authorized to submit on behalf of the Rights owner. For the purposes of this
|
||||
definition, “submitted” means any form of electronic, verbal, or written
|
||||
communication sent to the Licensor or its representatives, including but not
|
||||
limited to communication on electronic mailing lists, source code control
|
||||
systems, and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but excluding
|
||||
communication that is conspicuously marked or otherwise designated in writing
|
||||
by the Rights owner as “Not a Contribution.”
|
||||
|
||||
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of License. Subject to the terms and conditions of this License, each
|
||||
Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable license under the Rights to reproduce,
|
||||
prepare Derivative Works of, publicly display, publicly perform, sublicense,
|
||||
and distribute the Work and such Derivative Works in Source or Object form and
|
||||
do anything in relation to the Work as if the Rights did not exist.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this
|
||||
License, each Contributor hereby grants to You a perpetual, worldwide,
|
||||
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
|
||||
section) patent license to make, have made, use, offer to sell, sell, import,
|
||||
and otherwise transfer the Work, where such license applies only to those
|
||||
patent claims licensable by such Contributor that are necessarily infringed by
|
||||
their Contribution(s) alone or by combination of their Contribution(s) with the
|
||||
Work to which such Contribution(s) was submitted. If You institute patent
|
||||
litigation against any entity (including a cross-claim or counterclaim in a
|
||||
lawsuit) alleging that the Work or a Contribution incorporated within the Work
|
||||
constitutes direct or contributory patent infringement, then any patent
|
||||
licenses granted to You under this License for that Work shall terminate as of
|
||||
the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||
Derivative Works thereof in any medium, with or without modifications, and in
|
||||
Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy
|
||||
of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that
|
||||
You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You
|
||||
distribute, all copyright, patent, trademark, and attribution notices from
|
||||
the Source form of the Work, excluding those notices that do not pertain to
|
||||
any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a “NOTICE” text file as part of its distribution, then
|
||||
any Derivative Works that You distribute must include a readable copy of
|
||||
the attribution notices contained within such NOTICE file, excluding those
|
||||
notices that do not pertain to any part of the Derivative Works, in at
|
||||
least one of the following places: within a NOTICE text file distributed as
|
||||
part of the Derivative Works; within the Source form or documentation, if
|
||||
provided along with the Derivative Works; or, within a display generated by
|
||||
the Derivative Works, if and wherever such third-party notices normally
|
||||
appear. The contents of the NOTICE file are for informational purposes only
|
||||
and do not modify the License. You may add Your own attribution notices
|
||||
within Derivative Works that You distribute, alongside or as an addendum to
|
||||
the NOTICE text from the Work, provided that such additional attribution
|
||||
notices cannot be construed as modifying the License. You may add Your own
|
||||
copyright statement to Your modifications and may provide additional or
|
||||
different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a
|
||||
whole, provided Your use, reproduction, and distribution of the Work
|
||||
otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||
Licensor shall be under the terms and conditions of this License, without any
|
||||
additional terms or conditions. Notwithstanding the above, nothing herein shall
|
||||
supersede or modify the terms of any separate license agreement you may have
|
||||
executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names,
|
||||
trademarks, service marks, or product names of the Licensor, except as required
|
||||
for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
|
||||
writing, Licensor provides the Work (and each Contributor provides its
|
||||
Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied, including, without limitation, any warranties
|
||||
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any risks
|
||||
associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in
|
||||
tort (including negligence), contract, or otherwise, unless required by
|
||||
applicable law (such as deliberate and grossly negligent acts) or agreed to in
|
||||
writing, shall any Contributor be liable to You for damages, including any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character arising as a result of this License or out of the use or inability to
|
||||
use the Work (including but not limited to damages for loss of goodwill, work
|
||||
stoppage, computer failure or malfunction, or any and all other commercial
|
||||
damages or losses), even if such Contributor has been advised of the
|
||||
possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or
|
||||
Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||
acceptance of support, warranty, indemnity, or other liability obligations
|
||||
and/or rights consistent with this License. However, in accepting such
|
||||
obligations, You may act only on Your own behalf and on Your sole
|
||||
responsibility, not on behalf of any other Contributor, and only if You agree
|
||||
to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
147
vendor/pulp-platform/fpnew/README.md
vendored
Normal file
147
vendor/pulp-platform/fpnew/README.md
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
# FPnew - New Floating-Point Unit with Transprecision Capabilities
|
||||
|
||||
Parametric floating-point unit with support for standard RISC-V formats and operations as well as transprecision formats, written in SystemVerilog.
|
||||
|
||||
Maintainer: Stefan Mach <smach@iis.ee.ethz.ch>
|
||||
|
||||
## Features
|
||||
|
||||
The FPU is a parametric design that allows generating FP hardware units for various use cases.
|
||||
Even though mainly designed for use in RISC-V processors, the FPU or its sub-blocks can easily be utilized in other environments.
|
||||
Our design aims to be compliant with IEEE 754-2008 and provides the following features:
|
||||
|
||||
### Formats
|
||||
Any IEEE 754-2008 style binary floating-point format can be supported, including single-, double-, quad- and half-precision (`binary32`, `binary64`, `binary128`, `binary16`).
|
||||
Formats can be defined with arbitrary number of exponent and mantissa bits through parameters and are always symmetrically biased.
|
||||
Multiple FP formats can be supported concurrently, and the number of formats supported is not limited.
|
||||
|
||||
Multiple integer formats with arbitrary number of bits (as source or destionation of conversions) can also be defined.
|
||||
|
||||
### Operations
|
||||
- Addition/Subtraction
|
||||
- Multiplication
|
||||
- Fused multiply-add in four flavours (`fmadd`, `fmsub`, `fnmadd`, `fnmsub`)
|
||||
- Division<sup>1</sup>
|
||||
- Square root<sup>1</sup>
|
||||
- Minimum/Maximum<sup>2</sup>
|
||||
- Comparisons
|
||||
- Sign-Injections (`copy`, `abs`, `negate`, `copySign` etc.)
|
||||
- Conversions among all supported FP formats
|
||||
- Conversions between FP formats and integers (signed & unsigned) and vice versa
|
||||
- Classification
|
||||
|
||||
Multi-format FMA operations (i.e. multiplication in one format, accumulation in another) are optionally supported.
|
||||
|
||||
Optionally, *packed-SIMD* versions of all the above operations can be generated for formats narrower than the FPU datapath width.
|
||||
E.g.: Support for double-precision (64bit) operations and two simultaneous single-precision (32bit) operations.
|
||||
|
||||
It is also possible to generate only a subset of operations if e.g. divisions are not needed.
|
||||
|
||||
<sup>1</sup>Some compliance issues with IEEE 754-2008 are currently known to exist<br>
|
||||
<sup>2</sup>Implementing IEEE 754-201x `minimumNumber` and `maximumNumber`, respectively
|
||||
|
||||
### Rounding modes
|
||||
All IEEE 754-2008 rounding modes are supported, namely
|
||||
- `roundTiesToEven`
|
||||
- `roundTiesToAway`
|
||||
- `roundTowardPositive`
|
||||
- `roundTowardNegative`
|
||||
- `roundTowardZero`
|
||||
|
||||
### Status Flags
|
||||
All IEEE 754-2008 status flags are supported, namely
|
||||
- Invalid operation (`NV`)
|
||||
- Division by zero (`DZ`)
|
||||
- Overflow (`OF`)
|
||||
- Underflow (`UF`)
|
||||
- Inexact (`NX`)
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Dependencies
|
||||
|
||||
FPnew currently depends on the following:
|
||||
- `lzc` and `rr_arb_tree` from the `common_cells` repository (https://github.com/pulp-platform/common_cells.git)
|
||||
- optional: Divider and square-root unit from the `fpu-div-sqrt-mvp` repository (https://github.com/pulp-platform/fpu_div_sqrt_mvp.git)
|
||||
|
||||
These two repositories are included in the source code directory as git submodules, use
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
if you want to load these dependencies there.
|
||||
|
||||
Consider using [Bender](https://github.com/fabianschuiki/bender.git) for managing dependencies in your projects. FPnew comes with Bender support!
|
||||
|
||||
### Usage
|
||||
|
||||
The top-level module of the FPU is called `fpnew_top` and can be directly instantiated in your design.
|
||||
Make sure you compile the package `fpnew_pkg` ahead of any files making references to types, parameters or functions defined there.
|
||||
|
||||
It is discouraged to `import` all of `fpnew_pkg` into your source files. Instead, explicitly scope references into the package like so: `fpnew_pkg::foo`.
|
||||
|
||||
#### Example Instantiation
|
||||
|
||||
```SystemVerilog
|
||||
// FPU instance
|
||||
fpnew_top #(
|
||||
.Features ( fpnew_pkg::RV64D ),
|
||||
.Implementation ( fpnew_pkg::DEFAULT_NOREGS ),
|
||||
.TagType ( logic )
|
||||
) i_fpnew_top (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.operands_i,
|
||||
.rnd_mode_i,
|
||||
.op_i,
|
||||
.op_mod_i,
|
||||
.src_fmt_i,
|
||||
.dst_fmt_i,
|
||||
.int_fmt_i,
|
||||
.vectorial_op_i,
|
||||
.tag_i,
|
||||
.in_valid_i,
|
||||
.in_ready_o,
|
||||
.flush_i,
|
||||
.result_o,
|
||||
.status_o,
|
||||
.tag_o,
|
||||
.out_valid_o,
|
||||
.out_ready_i,
|
||||
.busy_o
|
||||
);
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
More in-depth documentation on the FPnew configuration, interfaces and architecture is provided in [`docs/README.md`](docs/README.md).
|
||||
|
||||
### Issues and Contributing
|
||||
|
||||
In case you find any issues with FPnew that have not been reported yet, don't hesitate to open a new [issue](https://github.com/pulp-platform/fpnew/issues) here on Github.
|
||||
Please, don't use the issue tracker for support questions.
|
||||
Instead, consider contacting the maintainers or consulting the [PULP forums](https://pulp-platform.org/community/index.php).
|
||||
|
||||
In case you would like to contribute to the project, please refer to the contributing guidelines in [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md) before opening a pull request.
|
||||
|
||||
|
||||
### Repository Structure
|
||||
|
||||
HDL source code can be found in the `src` directory while documentation is located in `docs`.
|
||||
A changelog is kept at [`docs/CHANGELOG.md`](docs/CHANGELOG.md).
|
||||
|
||||
This repository loosely follows the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model.
|
||||
This means that the `master` branch is considered stable and used to publish releases of the FPU while the `develop` branch contains features and bugfixes that have not yet been properly released.
|
||||
|
||||
Furthermore, this repository tries to adhere to [SemVer](https://semver.org/), as outlined in the [changelog](docs/CHANGELOG.md).
|
||||
|
||||
## Licensing
|
||||
|
||||
FPnew is released under the *SolderPad Hardware License*, which is a permissive license based on Apache 2.0. Please refer to the [license file](LICENSE) for further information.
|
||||
|
||||
## Acknowledgement
|
||||
|
||||
This project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement No 732631.
|
||||
|
||||
For further information, visit [oprecomp.eu](http://oprecomp.eu).
|
||||
|
||||

|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue