// Copyright 2024 The Bedrock-RTL Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the 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.
= Bedrock-RTL
WARNING: UNDER CONSTRUCTION. Many things are broken.
High quality and composable base RTL libraries in Verilog
== Prerequisites
You need to have the following tools installed in your environment.
verilog_runner.py
.== Pre-Commit Hooks
We use pre-commit hooks to enforce basic coding style. To install the hooks, run:
They should automatically run on every commit. You can also run them manually via:
== Building and Testing
:bazel: https://bazel.build/
We use the powerful {bazel}[Bazel^] build system to assemble filelists and to run all tests (elaboration, lint, simulation, and formal).
A one-step command builds and runs all tests:
By default, the Bazel tests will fail because the repository does not currently provide any EDA tool plugins for the verilog_runner.py
tool.
We do this because:
//python/verilog_runner/eda_tool.py
for the tool(s) of interest and then point to them with the VERILOG_RUNNER_PLUGIN_PATH
environment variable.
You should also set this environment variable in the .bazelrc
file so that it is used in all Bazel test invocations.The Bazel test rule implementations at //bazel:verilog.bzl
shell out the //python/verilog_runner/verilog_runner.py
tool that presents a generic tool-agnostic API that actually implements the test.
== Continuous Integration
Using GitHub Actions, which currently just runs pre-commit checks.
== Style Guide
:xlsynth-verilog-style-guide: https://github.com/xlsynth/verilog-style-guides/blob/master/VerilogCodingStyle.md :lowrisc-verilog-style-guide: https://github.com/lowrisc/verilog-style-guides/blob/master/VerilogCodingStyle.md
We follow the {xlsynth-verilog-style-guide}[xlsynth Verilog Style Guide^], which is a fork of the {lowrisc-verilog-style-guide}[lowRISC style guide^] with some minor differences.
== Bazel Rules for Verilog
This repository defines several generally-helpful Bazel Verilog rules that you can use in your own projects.
=== verilog_library
(external)
:verilog-library: https://github.com/hdl/bazel_rules_hdl/blob/main/verilog/providers.bzl
The verilog_library
rule is used to collect Verilog source and header files and track their dependencies.
The original definition of the verilog_library
rule can be found {verilog-library}[here^].
We pick up that rule dependency transitively (see the top-level MODULE.bazel
).
verilog_library
[%collapsible]load("@rules_hdl//verilog:providers.bzl", "verilog_library")
verilog_library( name = "bar", srcs = ["bar.sv"], hdrs = ["baz.svh"] )
====
== Other rules
Please see link:bazel/verilog_rules.md[] for documentation on rules defined in this repository.
== Using Bedrock
:bzlmod: https://docs.bazel.build/versions/5.1.0/bzlmod.html
Usage is best illustrated with an example using the {bzlmod}[bzlmod^] dependency management system in Bazel.
TIP: You are not required to use Bazel to depend on Bedrock-RTL. You can also use the Verilog files directly in your own projects (e.g., with git submodule, git subtree, or some other method).
In your project's MODULE.bazel
:
MODULE.bazel
[%collapsible]module(name = "your-project")
bazel_dep(name = "bedrock-rtl", version = "0.0.1")
git_override(
module_name = "bedrock-rtl",
commit =
====
Then suppose you have the following SystemVerilog module called datapath_join.sv
:
datapath_join.sv
[%collapsible]// An example design using two Bedrock-RTL modules: br_flow_reg_fwd and br_flow_join. // // Joins two or more equal-width datapaths into a single output datapath. // Uses ready/valid protocol on all flows. // Push-side is registered.
`include "br_asserts.svh"
module datapath_join #( parameter int NumFlows = 2, // must be at least 2 parameter int WidthPerFlow = 32 // must be at least 1 ) ( input logic clk, input logic rst, output logic [NumFlows-1:0] push_ready, input logic [NumFlows-1:0] push_valid, input logic [NumFlows-1:0][WidthPerFlow-1:0] push_data, input logic pop_ready, output logic pop_valid, output logic [(NumFlows*WidthPerFlow)-1:0] pop_data );
BR_ASSERT_STATIC(numflows_gte_2_a, NumFlows >= 2)
BR_ASSERT_STATIC(widthperflow_gte_1_a, WidthPerFlow >= 1)
logic [NumFlows-1:0] inter_ready; logic [NumFlows-1:0] inter_valid; logic [NumFlows-1:0][WidthPerFlow-1:0] inter_data;
for (genvar i = 0; i < NumFlows; i++) begin : gen_regs br_flow_reg_fwd #( .Width(WidthPerFlow) ) br_flow_reg_fwd ( .clk, .rst, .push_ready(push_ready[i]), .push_valid(push_valid[i]), .push_data (push_data[i]), .pop_ready (inter_ready[i]), .pop_valid (inter_valid[i]), .pop_data (inter_data[i]) ); end
br_flow_join #( .NumFlows(NumFlows) ) br_flow_join ( .clk, .rst, .push_ready(inter_ready), .push_valid(inter_valid), .pop_ready (pop_ready), .pop_valid (pop_valid) );
assign pop_data = inter_data; // direct concat
====
Your BUILD.bazel
file could then do this:
BUILD.bazel
[%collapsible]load("@bedrock-rtl//bazel:verilog.bzl", "verilog_elab_and_lint_test_suite", "verilog_elab_test", "verilog_lint_test") load("@rules_hdl//verilog:providers.bzl", "verilog_library")
package(default_visibility = ["//visibility:private"])
verilog_library( name = "datapath_join", srcs = ["datapath_join.sv"], deps = [ "@bedrock-rtl//flow/rtl:br_flow_join", "@bedrock-rtl//flow/rtl:br_flow_reg_fwd", "@bedrock-rtl//macros:br_asserts", ], )
verilog_elab_test( name = "datapath_join_elab_test", deps = [":datapath_join"], )
verilog_lint_test( name = "datapath_join_lint_test", deps = [":datapath_join"], )
====
== macros
: Macros and Defines
=== br_registers.svh
: Flip-Flop Inference Macros
These macros conveniently wrap always_ff
blocks, improving readability and helping to structure user code into sequential and combinational portions.
The macros are named according to the following suffix convention.
A
: Asynchronous reset (if absent, then synchronous)I
: Initial value given (if absent, then 0)L
: Conditional load enable (if absent, then unconditional)N
: No reset (if absent, then reset)X
: Given explicit clock and reset names (if absent, then clk
and either rst
if synchronous or arst
if asynchronous)IMPORTANT: Clocks are always positive-edge triggered. Resets are always active-high.
[cols="1,4,1,1"] |=== | Macro/define | Description | Implemented | Tested
| BR_REGA
| Flip-flop register with unconditional load, asynchronous active-high reset named arst
, initial value 0, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGAIL
| Flip-flop register with conditional load enable, asynchronous active-high reset named arst
, initial value given, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGAI
| Flip-flop register with unconditional load, asynchronous active-high reset named arst
, initial value given, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGAL
| Flip-flop register with conditional load enable, asynchronous active-high reset named arst
, initial value 0, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGIL
| Flip-flop register with conditional load enable, synchronous active-high reset named rst
, initial value given, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGI
| Flip-flop register with unconditional load, synchronous active-high reset named rst
, initial value given, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGILX
| Flip-flop register with conditional load enable, synchronous active-high given reset, initial value given, positive-edge triggered given clock.
| Yes
| Yes
| BR_REGIX
| Flip-flop register with unconditional load, synchronous active-high given reset, initial value given, positive-edge triggered given clock.
| Yes
| Yes
| BR_REGLN
| Flip-flop register with load enable, no reset, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGLX
| Flip-flop register with conditional load enable, synchronous active-high reset, initial value 0, positive-edge triggered given clock.
| Yes
| Yes
| BR_REGL
| Flip-flop register with conditional load enable, synchronous active-high reset named rst
, initial value 0, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGN
| Flip-flop register with unconditional load, no reset, positive-edge triggered clock named clk
.
| Yes
| Yes
| BR_REGX
| Flip-flop register with unconditional load, synchronous active-high given reset, initial value 0, positive-edge triggered given clock.
| Yes
| Yes
| BR_REG
| Flip-flop register with unconditional load, synchronous active-high reset named rst
, initial value 0, positive-edge triggered clock named clk
.
| Yes
| Yes
|===
=== br_asserts.svh
: Public Assertions
These assertion macros are intended for use by the user in their own designs. They are guarded (enabled) by the following defines:
ifdef BR_ASSERT_ON
ifdef BR_ENABLE_ASSERT_COMB
- only for guarding BR_ASSERT_COMB
(off by default).IMPORTANT: Clocks are always positive-edge triggered. Resets are always active-high.
[cols="1,4,1,1"] |=== | Macro/define | Description | Implemented | Tested
| BR_ASSERT_STATIC
| Static (elaboration-time) assertion for use within modules
| Yes
| Yes
| BR_ASSERT_STATIC_IN_PACKAGE
| Static (elaboration-time) assertion for use within packages
| Yes
| Yes
| BR_ASSERT
| Concurrent assertion with implicit clk
and rst
names.
| Yes
| Yes
| BR_ASSERT_CR
| Concurrent assertion with explicit clock and reset names.
| Yes
| Yes
| BR_ASSERT_COMB
a| Combinational/immediate assertion. Also passes if the expression is unknown.
Enable by defining BR_ENABLE_ASSERT_COMB
.
| Yes
| Yes
| BR_COVER
| Concurrent cover with implicit clk
and rst
names.
| Yes
| Yes
| BR_COVER_CR
| Concurrent cover with explicit clock and reset names.
| Yes
| Yes
| BR_COVER_COMB
| Combinational/immediate cover.
| Yes
| Yes
| BR_ASSUME
| Concurrent assumption with implicit clk
and rst
names.
| Yes
| Yes
| BR_ASSUME_CR
| Concurrent assumption with explicit clock and reset names.
| Yes
| Yes
|===
=== br_asserts_internal.svh
: Bedrock-internal Assertions
These assertion macros wrap the public assertions. They are intended only for internal use inside Bedrock libraries, but the user needs to know about them. They are guarded (enabled) by the following defines:
ifndef BR_DISABLE_INTG_CHECKS
for the integration casesifdef BR_ENABLE_IMPL_CHECKS
for the implementation cases[cols="1,4,1,1"] |=== | Macro/define | Description | Implemented | Tested
| BR_ASSERT_INTG
a| Concurrent integration assertion with implicit clk
and rst
names.
Disable by defining BR_DISABLE_INTG_CHECKS
.
| Yes
| Yes
| BR_ASSERT_CR_INTG
a| Concurrent integration assertion with explicit clock and reset names.
Disable by defining BR_DISABLE_INTG_CHECKS
.
| Yes
| Yes
| BR_ASSERT_IMPL
a| Concurrent implementation assertion with implicit clk
and rst
names.
Enable by defining BR_ENABLE_IMPL_CHECKS
.
| Yes
| Yes
| BR_ASSERT_CR_IMPL
a| Concurrent implementation assertion with explicit clock and reset names.
Enable by defining BR_ENABLE_IMPL_CHECKS
.
| Yes
| Yes
| BR_ASSERT_COMB_INTG
a| Combinational/immediate integration assertion.
Disable by defining BR_DISABLE_INTG_CHECKS
.
| Yes
| Yes
| BR_ASSERT_COMB_IMPL
a| Combinational/immediate implementation assertion.
Enable by defining BR_ENABLE_IMPL_CHECKS
.
| Yes
| Yes
| BR_COVER_INTG
a| Concurrent integration cover with implicit clk
and rst
names.
Disable by defining BR_DISABLE_INTG_CHECKS
.
| Yes
| Yes
| BR_COVER_CR_INTG
a| Concurrent integration cover with explicit clock and reset names.
Disable by defining BR_DISABLE_INTG_CHECKS
.
| Yes
| Yes
| BR_COVER_IMPL
a| Concurrent implementation cover with implicit clk
and rst
names.
Enable by defining BR_ENABLE_IMPL_CHECKS
.
| Yes
| Yes
| BR_COVER_CR_IMPL
a| Concurrent implementation cover with explicit clock and reset names.
Enable by defining BR_ENABLE_IMPL_CHECKS
.
| Yes
| Yes
| BR_COVER_COMB_INTG
a| Combinational/immediate integration cover.
Disable by defining BR_DISABLE_INTG_CHECKS
.
| Yes
| Yes
| BR_COVER_COMB_IMPL
a| Combinational/immediate implementation cover.
Enable by defining BR_ENABLE_IMPL_CHECKS
.
| Yes
| Yes
|===
=== br_gates.svh
: Gate Convenience Wrappers
These macros conveniently wrap module instantiations from the gate
category.
[cols="1,4,1,1"] |=== | Macro/define | Description | Implemented | Tested
| BR_GATE_BUF
| Instantiates br_gate_buf
.
| Yes
| Yes
| BR_GATE_CLK_BUF
| Instantiates br_gate_clk_buf
.
| Yes
| Yes
| BR_GATE_INV
| Instantiates br_gate_inv
.
| Yes
| Yes
| BR_GATE_AND2
| Instantiates br_gate_and2
.
| Yes
| Yes
| BR_GATE_OR2
| Instantiates br_gate_or2
.
| Yes
| Yes
| BR_GATE_XOR2
| Instantiates br_gate_xor2
.
| Yes
| Yes
| BR_GATE_MUX2
| Instantiates br_gate_mux2
.
| Yes
| Yes
| BR_GATE_CLK_MUX2
| Instantiates br_gate_clk_mux2
.
| Yes
| Yes
| BR_GATE_ICG
| Instantiates br_gate_icg
.
| Yes
| Yes
|===
=== br_tieoff.svh
: Tie-off Convenience Wrappers
These macros conveniently wrap br_misc_tieoff*
module instantiations.
[cols="1,4,1,1"] |=== | Macro/define | Description | Implemented | Tested
| BR_TIEOFF_ZERO_NAMED
| Instantiates br_tieoff_zero
with a given submodule instance suffix.
| Yes
| Yes
| BR_TIEOFF_ONE_NAMED
| Instantiates br_tieoff_one
with a given submodule instance suffix.
| Yes
| Yes
| BR_TIEOFF_ZERO
| Instantiates br_tieoff_zero
with a derived submodule instance suffix.
| Yes
| Yes
| BR_TIEOFF_ONE
| Instantiates br_tieoff_one
with a derived submodule instance suffix.
| Yes
| Yes
| BR_TIEOFF_ZERO_TODO
a| Provided for convenience of the user grepping for TODO
in the codebase, to help prevent accidental tie-offs that result in bugs.
Instantiates br_tieoff_zero
with a derived submodule instance suffix.
| Yes
| Yes
| BR_TIEOFF_ONE_TODO
a| Provided for convenience of the user grepping for TODO
in the codebase, to help prevent accidental tie-offs that result in bugs.
Instantiates br_tieoff_one
with a derived submodule instance suffix.
| Yes
| Yes
|===
=== br_unused.svh
: Unused Signal Convenience Wrappers
These macros conveniently wrap br_misc_unused
module instantiations.
[cols="1,4,1,1"] |=== | Macro/define | Description | Implemented | Tested
| BR_UNUSED_NAMED
| Instantiates br_misc_unused
with a given submodule instance suffix.
| Yes
| Yes
| BR_UNUSED
| Instantiates br_misc_unused
with a derived submodule instance suffix.
| Yes
| Yes
| BR_UNUSED_TODO
a| Provided for convenience of the user grepping for TODO
in the codebase, to help prevent accidental unused signals that result in bugs.
Instantiates br_misc_unused
with a derived submodule instance suffix.
| Yes
| Yes
|===
== Modules
=== arb
: Arbiters
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_arb_fixed |
Fixed priority | Yes |
---|
br_arb_lru |
Least-recently used | Yes |
---|
br_arb_rr |
Round-robin | Yes |
---|
|===
=== cdc
: Clock Domain Crossings
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_cdc_bit |
Single-bit CDC |
---|---|
| br_cdc_fifo_ctrl_1r1w
a| Bus CDC using a dual-clock FIFO controller for a 1R1W dual-clock SRAM
Pop flow control: ready/valid |
---|
| br_cdc_fifo_flops
a| Bus CDC using a dual-clock FIFO with internal flop-RAM
Pop flow control: ready/valid |
---|
|===
=== counter
: Wrapping and Saturating Counters
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_counter_decr |
Decrementing counter | Yes |
---|
br_counter_incr |
Incrementing counter | Yes |
---|
br_counter_sat |
Up-down saturating counter |
---|---|
br_counter |
Up-down counter | Yes |
---|
|===
=== credit
: Credit/Valid Flow Control
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_credit_counter |
Credit counter | Yes |
---|
br_credit_receiver |
Credit/valid to ready/valid converter (credit-loop receiver-side) | Yes |
---|
br_credit_sender |
Ready/valid to credit/valid converter (credit-loop sender-side) | Yes |
---|
|===
=== delay
: Fixed-Delay Pipelines
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_delay |
With reset | Yes |
---|
br_delay_nr |
Without reset | Yes, but want to merge with br_delay (https://github.com/xlsynth/bedrock-rtl/issues/137) |
---|
br_delay_valid_next_nr |
With self-gating (valid-next) and without reset | Yes, but want to merge with br_delay_valid_next (https://github.com/xlsynth/bedrock-rtl/issues/137) |
---|
br_delay_valid_next |
With self-gating (valid-next) | Yes |
---|
br_delay_valid |
With self-gating (valid) | Yes |
---|
br_delay_shift_reg |
Loadable shift register | Yes |
---|
|===
=== demux
: Simple Demultiplexers
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_demux_onehot |
One-hot demultiplexer | Yes |
---|
br_demux_bin |
Binary-select demultiplexer | Yes |
---|
|===
=== enc
: Combinational encoders
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_enc_bin2gray |
Binary to gray | Yes |
---|
br_enc_bin2onehot |
Binary to onehot | Yes |
---|
br_enc_countones |
Count the number of ones in a vector | Yes |
---|
br_enc_gray2bin |
Gray to binary | Yes |
---|
br_enc_onehot2bin |
One-hot to binary | Yes |
---|
br_enc_priority_encoder |
Priority encoder | Yes |
---|
|===
=== ecc
: Error Correcting Codes
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_ecc_secded_decoder |
Single-error-correcting, double-error-detecting (SECDED) decoder | Yes |
---|
br_ecc_secded_encoder |
Single-error-correcting, double-error-detecting (SECDED) encoder | Yes |
---|
br_ecc_sed_decoder |
Single-error-detecting (SED) decoder | Yes |
---|
br_ecc_sed_encoder |
Single-error-detecting (SED) encoder | Yes |
---|
|===
=== fifo
: First-In-First-Out Queues
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
| br_fifo_ctrl_1r1w_bare
a| FIFO controller with external RAM port for 1R1W
Pop flow control: none |
---|
| br_fifo_ctrl_1r1w_pop_credit
a| FIFO controller with external RAM port for 1R1W
Pop flow control: credit/valid |
---|
| br_fifo_ctrl_1r1w_push_credit
a| FIFO controller with external RAM port for 1R1W
Pop flow control: ready/valid | Yes |
---|
| br_fifo_ctrl_1r1w
a| FIFO controller with external RAM port for 1R1W
Pop flow control: ready/valid | Yes |
---|
| br_fifo_flops_pop_credit
a| FIFO with internal flop RAM
Pop flow control: credit/valid |
---|
| br_fifo_flops_push_credit
a| FIFO with internal flop RAM
Pop flow control: ready/valid | Yes |
---|
| br_fifo_flops
a| FIFO with internal flop RAM
Pop flow control: ready/valid | Yes |
---|
|===
=== flow
: Ready/Valid Flow Control
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_flow_arb_fixed |
Fixed priority arbiter | Yes |
---|
br_flow_arb_lru |
Least-recently used arbiter | Yes |
---|
br_flow_arb_rr |
Round-robin arbiter | Yes |
---|
br_flow_demux_select |
Registered demultiplexer, external select | Yes |
---|
br_flow_demux_select_unstable |
Combinational demultiplexer, external select, with unstable flow control | Yes |
---|
br_flow_fork |
Datapath flow control split | Yes |
---|
br_flow_join |
Datapath flow control join | Yes |
---|
br_flow_mux_fixed |
Arbitrated multiplexer, fixed priority | Yes |
---|
br_flow_mux_lru |
Arbitrated multiplexer, least-recently used | Yes |
---|
br_flow_mux_rr |
Arbitrated multiplexer, round-robin | Yes |
---|
br_flow_mux_select |
Registered multiplexer, user select | Yes |
---|
br_flow_mux_select_unstable |
Combinational multiplexer, external select, with unstable flow control | Yes |
---|
br_flow_reg_both |
Pipeline register, registered forward and reverse signals | Yes |
---|
br_flow_reg_fwd |
Pipeline register, registered forward signals | Yes |
---|
br_flow_reg_rev |
Pipeline register, registered backward signals | Yes |
---|
|===
=== gate
: Behavioral Gate Primitives
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_gate_buf |
Wire buffer/repeater | Yes |
---|
br_gate_clk_buf |
Clock wire buffer/repeater | Yes |
---|
br_gate_inv |
Inverter | Yes |
---|
br_gate_and2 |
Two-input AND gate | Yes |
---|
br_gate_or2 |
Two-input OR gate | Yes |
---|
br_gate_xor2 |
Two-input XOR gate | Yes |
---|
br_gate_mux2 |
Two-input multiplexer | Yes |
---|
br_gate_clk_mux2 |
Two-input clock multiplexer | Yes |
---|
br_gate_icg |
Integrated clock gate | Yes |
---|
|===
=== misc
: Miscellaneous
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
| br_misc_tieoff_one
| Drive an expression to constant 1s and internally waive relevant lint rules
| Yes
| Yes
| br_misc_tieoff_zero
| Drive an expression to constant 0s and internally waive relevant lint rules
| Yes
| Yes
| br_misc_unused
| Sink an unused expression and internally waive relevant lint rules
| Yes
| Yes
|===
=== mux
: Simple Multiplexers
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_mux_onehot |
One-hot multiplexer | Yes |
---|
br_mux_bin |
Binary-select multiplexer | Yes |
---|
|===
=== ram
: Memories
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
br_ram_addr_decoder_tree |
Address decoder tree for a tiled RAM | WIP |
---|
br_ram_addr_decoder |
Address decoder for a tiled RAM | Yes |
---|
br_ram_flops_1r1w_tile |
One-tile flop-RAM with one read port and one write port | Yes |
---|
br_ram_flops_1r1w |
Tiled flop-RAM with one read port and one write port | Yes |
---|
br_ram_flops_1rw_tile |
One-tile flop-RAM with one port (shared for read and write) |
---|---|
br_ram_flops_1rw |
Tiled flop-RAM with one port (shared for read and write) |
---|---|
br_ram_data_rd_pipe |
Pipeline for reading data from a tiled RAM | Yes |
---|
|===
=== timer
: Saturating and Wrapping Timers
[cols="1,4,1,1"] |=== | Module | Description | Implemented | Verified
| br_timer_sat
| Tick down from a threshold and saturate at zero; signal continuously at zero
| br_timer
| Tick down from a threshold and signal a pulse every time when wrapping past zero
|===
== Packages
=== br_math
: Non-synthesizable Math Helper Functions
[cols="1,4,1,1"] |=== | Function | Description | Implemented | Tested
| ceil_div
| Return integer ceiling division
| Yes
| Yes
| floor_div
| Return integer floor division
| Yes
| Yes
| clogb
| Return integer ceiling of base-b
logarithm where b
is a power-of-2
| Yes
| Yes
| is_power_of_2
| Return 1 if an integer is a power of 2
| Yes
| Yes
| is_even
| Return 1 if an integer is even
| Yes
| Yes
|===