1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! Utility functions.
use hazardflow_macro::magic;
use crate::prelude::*;
/// Returns ceiling log2.
pub const fn clog2(value: usize) -> usize {
if value == 0 {
0
} else if value == 1 {
1
} else {
(::core::mem::size_of::<usize>() * 8) - (value - 1).leading_zeros() as usize
}
}
/// Returns minimum value.
pub const fn min(lhs: usize, rhs: usize) -> usize {
if lhs < rhs {
lhs
} else {
rhs
}
}
/// Returns maximum value.
pub const fn max(lhs: usize, rhs: usize) -> usize {
if lhs > rhs {
lhs
} else {
rhs
}
}
/// Display function
#[magic(system::display)]
pub fn display<V: Copy>(_fstring: &str, _args: V) {
compiler_magic!()
}
/// Display macro
///
/// This macro will be compiled as `fdisplay` system task of verilog.
#[macro_export]
macro_rules! display {
($string: expr) => {
$crate::std::utils::display($string, ())
};
($fstring: expr, $($arg:expr),+) => {
$crate::std::utils::display($fstring, ($($arg,)*))
};
}
/// Assertion function
#[magic(system::assert)]
pub fn assert<V: Copy>(_cond: bool, _fstring: &str, _args: V) {
compiler_magic!()
}
/// Assert macro
///
/// ## Syntax
///
/// \<assert> :=
/// hassert!(cond, string) | hassert!(cond, format_string, arg1, arg2, ...)
///
/// This macro will be compiled as below.
/// ```verilog
/// if (~cond {& current path condition}) begin
/// $fdisplay(format_string, arg1, arg2, ...);
/// $finish;
/// end
/// ```
///
/// ## Formatting
///
/// For the format string, use the syntax of verilog `$display` system task.
#[macro_export]
macro_rules! hassert {
($cond: expr, $string: expr) => {
$crate::std::utils::assert($cond, $string, ())
};
($cond: expr, $fstring: expr, $($arg:expr),+) => {
$crate::std::utils::assert($cond, $fstring, ($($arg,)*))
};
}
/// Panic macro
///
/// ## Syntax
///
/// \<panic> :=
/// hpanic!(cond, string) | hpanic!(cond, format_string, arg1, arg2, ...)
///
/// This macro will be compiled as below.
/// ```verilog
/// if (true {& current path condition}) begin
/// $fdisplay(format_string, arg1, arg2, ...);
/// $finish;
/// end
/// ```
///
/// ## Formatting
///
/// For the format string, use the syntax of verilog `$display` system task.
///
/// NOTE: Currently we do not support printing composite types like structs, tuples or arrays.
#[macro_export]
macro_rules! hpanic {
($fstring: expr, $($arg:expr),+) => {
unsafe {
$crate::std::utils::assert(false, $fstring, ($($arg,)*));
$crate::std::value::x()
}
};
($string: expr) => {
unsafe {
$crate::std::utils::assert(false, $string, ());
$crate::std::value::x()
}
};
}