Make any implicit truncation in an assignment explicit.
(vl-assign-trunc x delta) → (mv assign delta)
Function:
(defun vl-assign-trunc (x delta) (declare (xargs :guard (and (vl-assign-p x) (vl-delta-p delta)))) (let ((__function__ 'vl-assign-trunc)) (declare (ignorable __function__)) (b* ((x (vl-assign-fix x)) (delta (vl-delta-fix delta)) ((vl-assign x) x) (lhsw (vl-expr->finalwidth x.lvalue)) (rhsw (vl-expr->finalwidth x.expr)) ((when (or (not (posp lhsw)) (not (posp rhsw)) (< rhsw lhsw))) (mv x (dwarn :type :vl-programming-error :msg "~a0: expected widths to be computed and never ~ thought lhs would never be wider than rhs. LHS ~ width: ~x1. RHS width: ~x2. LHS: ~a3. RHS: ~ ~a4." :args (list x lhsw rhsw x.lvalue x.expr) :fatalp t))) ((when (eql lhsw rhsw)) (mv x delta)) ((when (and (vl-fast-atom-p x.expr) (vl-fast-constint-p (vl-atom->guts x.expr)) (eq (vl-expr->finaltype x.expr) :vl-unsigned) (vl-expr-welltyped-p x.expr))) (b* ((new-rhs (vl-truncate-constint lhsw x.expr)) (x-prime (change-vl-assign x :expr new-rhs))) (mv x-prime delta))) ((when (and (vl-fast-atom-p x.expr) (vl-fast-weirdint-p (vl-atom->guts x.expr)) (eq (vl-expr->finaltype x.expr) :vl-unsigned) (vl-expr-welltyped-p x.expr))) (b* ((new-rhs (vl-truncate-weirdint lhsw x.expr)) (x-prime (change-vl-assign x :expr new-rhs))) (mv x-prime delta))) ((vl-delta delta) delta) ((mv tmp-name nf) (vl-namefactory-indexed-name "trunc" delta.nf)) (tmp-expr (vl-idexpr tmp-name rhsw :vl-unsigned)) (type (change-vl-coretype *vl-plain-old-wire-type* :pdims (list (vl-make-n-bit-range rhsw)))) (tmp-decl (make-vl-vardecl :loc x.loc :name tmp-name :nettype :vl-wire :type type)) (tmp-assign (make-vl-assign :loc x.loc :lvalue tmp-expr :expr x.expr)) (delta (change-vl-delta delta :vardecls (cons tmp-decl delta.vardecls) :assigns (cons tmp-assign delta.assigns) :nf nf)) (chop-expr (vl-make-chopped-id tmp-name rhsw lhsw)) (x-prime (change-vl-assign x :expr chop-expr :atts (acons (cat "TRUNC_" (natstr lhsw)) nil x.atts)))) (mv x-prime delta))))
Theorem:
(defthm vl-assign-p-of-vl-assign-trunc.assign (b* (((mv acl2::?assign ?delta) (vl-assign-trunc x delta))) (vl-assign-p assign)) :rule-classes :rewrite)
Theorem:
(defthm vl-delta-p-of-vl-assign-trunc.delta (b* (((mv acl2::?assign ?delta) (vl-assign-trunc x delta))) (vl-delta-p delta)) :rule-classes :rewrite)
Theorem:
(defthm vl-assign-trunc-of-vl-assign-fix-x (equal (vl-assign-trunc (vl-assign-fix x) delta) (vl-assign-trunc x delta)))
Theorem:
(defthm vl-assign-trunc-vl-assign-equiv-congruence-on-x (implies (vl-assign-equiv x x-equiv) (equal (vl-assign-trunc x delta) (vl-assign-trunc x-equiv delta))) :rule-classes :congruence)
Theorem:
(defthm vl-assign-trunc-of-vl-delta-fix-delta (equal (vl-assign-trunc x (vl-delta-fix delta)) (vl-assign-trunc x delta)))
Theorem:
(defthm vl-assign-trunc-vl-delta-equiv-congruence-on-delta (implies (vl-delta-equiv delta delta-equiv) (equal (vl-assign-trunc x delta) (vl-assign-trunc x delta-equiv))) :rule-classes :congruence)