use super::value::{Expr, TypeInfo};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BinKind {
Normal,
Ignore,
Illegal,
}
#[derive(Clone, Debug, PartialEq)]
pub enum ArrayKind {
None,
Open,
Fixed(Expr),
}
#[derive(Clone, Debug, PartialEq)]
pub enum Bound {
Expr(Expr),
Dollar,
}
#[derive(Clone, Debug, PartialEq)]
pub enum RangeItem {
Single(Expr),
Range(Bound, Bound),
Tolerance {
center: Expr,
tol: Expr,
relative: bool,
},
}
#[derive(Clone, Debug, PartialEq)]
pub struct RepeatRange {
pub lo: Expr,
pub hi: Option<Expr>,
}
impl RepeatRange {
pub fn exactly(n: i128) -> RepeatRange {
RepeatRange {
lo: Expr::int(n),
hi: None,
}
}
pub fn between(lo: i128, hi: i128) -> RepeatRange {
RepeatRange {
lo: Expr::int(lo),
hi: Some(Expr::int(hi)),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum TransRep {
Once,
Consecutive(RepeatRange),
Goto(RepeatRange),
NonConsecutive(RepeatRange),
}
#[derive(Clone, Debug, PartialEq)]
pub struct TransItem {
pub values: Vec<RangeItem>,
pub rep: TransRep,
}
impl TransItem {
pub fn new(values: Vec<RangeItem>) -> TransItem {
TransItem {
values,
rep: TransRep::Once,
}
}
pub fn rep(mut self, rep: TransRep) -> TransItem {
self.rep = rep;
self
}
}
pub type TransSet = Vec<TransItem>;
#[derive(Clone, Debug, PartialEq)]
pub enum BinBody {
Trans(Vec<TransSet>),
DefaultSeq,
Ranges {
items: Vec<RangeItem>,
with: Option<Expr>,
},
Set(Expr),
Default,
}
#[derive(Clone, Debug, PartialEq)]
pub struct BinDecl {
pub name: String,
pub kind: BinKind,
pub array: ArrayKind,
pub wildcard: bool,
pub iff: Option<Expr>,
pub body: BinBody,
}
impl BinDecl {
pub fn ranges(name: &str, items: Vec<RangeItem>) -> BinDecl {
BinDecl {
name: name.to_string(),
kind: BinKind::Normal,
array: ArrayKind::None,
wildcard: false,
iff: None,
body: BinBody::Ranges { items, with: None },
}
}
pub fn kind(mut self, kind: BinKind) -> BinDecl {
self.kind = kind;
self
}
pub fn array(mut self, array: ArrayKind) -> BinDecl {
self.array = array;
self
}
pub fn wildcard(mut self) -> BinDecl {
self.wildcard = true;
self
}
pub fn iff(mut self, iff: Expr) -> BinDecl {
self.iff = Some(iff);
self
}
pub fn with(mut self, with: Expr) -> BinDecl {
if let BinBody::Ranges { with: w, .. } = &mut self.body {
*w = Some(with);
}
self
}
pub fn trans(name: &str, sets: Vec<TransSet>) -> BinDecl {
BinDecl {
name: name.to_string(),
kind: BinKind::Normal,
array: ArrayKind::None,
wildcard: false,
iff: None,
body: BinBody::Trans(sets),
}
}
pub fn default_seq(name: &str) -> BinDecl {
BinDecl {
name: name.to_string(),
kind: BinKind::Normal,
array: ArrayKind::None,
wildcard: false,
iff: None,
body: BinBody::DefaultSeq,
}
}
pub fn default_bin(name: &str) -> BinDecl {
BinDecl {
name: name.to_string(),
kind: BinKind::Normal,
array: ArrayKind::None,
wildcard: false,
iff: None,
body: BinBody::Default,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum Matches {
Count(Expr),
All,
}
impl Matches {
pub fn one() -> Matches {
Matches::Count(Expr::int(1))
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum SelectExpr {
Binsof {
cp: String,
bin: Option<String>,
intersect: Option<Vec<RangeItem>>,
},
Not(Box<SelectExpr>),
And(Box<SelectExpr>, Box<SelectExpr>),
Or(Box<SelectExpr>, Box<SelectExpr>),
With {
sel: Box<SelectExpr>,
expr: Expr,
matches: Matches,
},
All,
Set {
expr: Expr,
matches: Matches,
},
}
#[derive(Clone, Debug, PartialEq)]
pub struct CrossBinDecl {
pub name: String,
pub kind: BinKind,
pub select: SelectExpr,
pub iff: Option<Expr>,
}
impl CrossBinDecl {
pub fn new(name: &str, kind: BinKind, select: SelectExpr) -> CrossBinDecl {
CrossBinDecl {
name: name.to_string(),
kind,
select,
iff: None,
}
}
pub fn iff(mut self, iff: Expr) -> CrossBinDecl {
self.iff = Some(iff);
self
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct CrossDecl {
pub name: String,
pub items: Vec<String>,
pub iff: Option<Expr>,
pub bins: Vec<CrossBinDecl>,
pub options: Vec<(String, Expr)>,
pub type_options: Vec<(String, Expr)>,
}
impl CrossDecl {
pub fn new(name: &str, items: &[&str]) -> CrossDecl {
CrossDecl {
name: name.to_string(),
items: items.iter().map(|s| s.to_string()).collect(),
iff: None,
bins: Vec::new(),
options: Vec::new(),
type_options: Vec::new(),
}
}
pub fn bin(mut self, bin: CrossBinDecl) -> CrossDecl {
self.bins.push(bin);
self
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct CoverpointDecl {
pub name: String,
pub ty: TypeInfo,
pub expr: Expr,
pub iff: Option<Expr>,
pub bins: Vec<BinDecl>,
pub enum_values: Option<Vec<(String, i128)>>,
pub options: Vec<(String, Expr)>,
pub type_options: Vec<(String, Expr)>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct CovGroupDecl {
pub name: String,
pub options: Vec<(String, Expr)>,
pub type_options: Vec<(String, Expr)>,
pub coverpoints: Vec<CoverpointDecl>,
pub crosses: Vec<CrossDecl>,
}
impl CovGroupDecl {
pub fn new(name: &str) -> CovGroupDecl {
CovGroupDecl {
name: name.to_string(),
options: Vec::new(),
type_options: Vec::new(),
coverpoints: Vec::new(),
crosses: Vec::new(),
}
}
pub fn coverpoint(mut self, cp: CoverpointDecl) -> CovGroupDecl {
self.coverpoints.push(cp);
self
}
pub fn cross(mut self, x: CrossDecl) -> CovGroupDecl {
self.crosses.push(x);
self
}
pub fn option(mut self, name: &str, v: Expr) -> CovGroupDecl {
self.options.push((name.to_string(), v));
self
}
pub fn type_option(mut self, name: &str, v: Expr) -> CovGroupDecl {
self.type_options.push((name.to_string(), v));
self
}
}
impl CoverpointDecl {
pub fn new(name: &str, ty: TypeInfo, expr: Expr) -> CoverpointDecl {
CoverpointDecl {
name: name.to_string(),
ty,
expr,
iff: None,
bins: Vec::new(),
enum_values: None,
options: Vec::new(),
type_options: Vec::new(),
}
}
pub fn bin(mut self, bin: BinDecl) -> CoverpointDecl {
self.bins.push(bin);
self
}
}