diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 821490dca..eaf4a861f 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -25,6 +25,15 @@ YOSYS_NAMESPACE_BEGIN +/** + * This file implements BitPatternPool for efficiently storing + * sets of fixed-width 2-valued logic constants compressed as "bit patterns" + * represented as bits_t. A bit pattern is a signal in 3-valued logic: + * 0, 1, a ("any" or "don't care"). + * + * BitPatternPool does not permit adding new patterns, only removing. + * Its intended use case is in analysing cases in case/match constructs in HDL. + */ struct BitPatternPool { int width; @@ -67,6 +76,9 @@ struct BitPatternPool } } + /** + * Constructs a pool of all possible patterns (all don't-care bits) + */ BitPatternPool(int width) { this->width = width; @@ -78,6 +90,10 @@ struct BitPatternPool } } + /** + * Convert a constant SigSpec to a pattern. Normalize Yosys many-valued + * to three-valued logic. + */ bits_t sig2bits(RTLIL::SigSpec sig) { bits_t bits; @@ -88,6 +104,12 @@ struct BitPatternPool return bits; } + /** + * Do two patterns match? + * A pattern matches another when all their bits match. + * A bit matches another if their values are equal. + * A bit also matches another if either of their values is "any" + */ bool match(bits_t a, bits_t b) { log_assert(int(a.bitdata.size()) == width); @@ -98,6 +120,13 @@ struct BitPatternPool return true; } + /** + * Does sig match any pattern in the pool? + * For example: + * pool({aaa}).has_any(01a) == true + * pool({011}).has_any(01a) == true + * pool({111}).has_any(01a) == false + */ bool has_any(RTLIL::SigSpec sig) { bits_t bits = sig2bits(sig); @@ -107,6 +136,14 @@ struct BitPatternPool return false; } + /** + * Does sig match a pattern in the pool such that + * all non-"any" bits in sig are not "any" in the pattern? + * For example: + * pool({aaa}).has_all(01a) == false + * pool({011}).has_all(01a) == true + * pool({111}).has_any(01a) == false + */ bool has_all(RTLIL::SigSpec sig) { bits_t bits = sig2bits(sig); @@ -121,6 +158,12 @@ struct BitPatternPool return false; } + /** + * Remove a pattern from the pool, splitting what's left. True if success. + * For example: + * Taking 011 out of pool({01a}) -> pool({010}), returns true. + * Taking 011 out of pool({010}) does nothing, returns false. + */ bool take(RTLIL::SigSpec sig) { bool status = false; @@ -143,6 +186,9 @@ struct BitPatternPool return status; } + /** + * Remove all patterns. Returns false if already empty. + */ bool take_all() { if (database.empty())