Split up a multi-input
(vl-gatesplit-nand/nor/xnor x nf warnings) → (mv warnings new-decls new-gateinsts nf)
From Section 7.2,
nand(o, i1, i2, ..., iN) --> and(temp, i1, i2, ..., iN) not(o, temp);
nor(o, i1, i2, ..., iN) --> or(temp, i1, i2, ..., iN) not(o, temp);
xnor(o, i1, i2, ..., iN) --> xor(temp, i1, i2, ..., iN) not(o, temp);
This is basically similar to vl-gatesplit-and/or/xor, except that we need to add a "not" gate at the end.
Function:
(defun vl-gatesplit-nand/nor/xnor (x nf warnings) (declare (xargs :guard (and (vl-gateinst-p x) (vl-namefactory-p nf) (vl-warninglist-p warnings)))) (declare (xargs :guard (member (vl-gateinst->type x) '(:vl-nand :vl-nor :vl-xnor)))) (let ((__function__ 'vl-gatesplit-nand/nor/xnor)) (declare (ignorable __function__)) (b* ((args (list-fix (vl-gateinst->args x))) (nargs (length args)) (range (vl-gateinst->range x)) (loc (vl-gateinst->loc x)) (origname (or (vl-gateinst->name x) "unnamed")) ((when range) (mv (fatal :type :vl-bad-gate :msg "~a0: expected all instance arrays to have been ~ eliminated; did you forget to run the argresolve ~ transform?" :args (list x)) nil (list x) nf)) ((when (< nargs 2)) (mv (fatal :type :vl-bad-gate :msg "~a0: expected at least 2 arguments, but found ~x1." :args (list x nargs)) nil (list x) nf)) ((when (eql nargs 2)) (b* (((mv warnings new-x) (vl-degenerate-gate-to-buf x warnings))) (mv warnings nil (list new-x) nf))) ((when (eql nargs 3)) (mv (ok) nil (list x) nf)) (atts (cons (cons "VL_GATESPLIT" (make-vl-atom :guts (vl-string origname))) (vl-gateinst->atts x))) ((mv temp-exprs temp-decls nf) (vl-make-temporary-wires origname (- nargs 2) nf loc)) (all-args-out (vl-exprlist-to-plainarglist temp-exprs :dir :vl-output)) (all-args-in (vl-exprlist-to-plainarglist temp-exprs :dir :vl-input)) (temp-args-out (butlast all-args-out 1)) (temp-args-in (butlast all-args-in 1)) (main-arg-out (car (last all-args-out))) (main-arg-in (car (last all-args-in))) (o (car args)) (i1 (cadr args)) (i2-n (cddr args)) (outs (append temp-args-out (list main-arg-out))) (lhses (cons i1 temp-args-in)) (rhses i2-n) ((mv warnings gateinsts nf) (vl-make-gates-for-and/or/xor outs lhses rhses (case (vl-gateinst->type x) (:vl-nand :vl-and) (:vl-nor :vl-or) (:vl-xnor :vl-xor)) origname loc atts nf warnings)) ((mv final-name nf) (vl-namefactory-indexed-name origname nf)) (final-gate (make-vl-gateinst :type :vl-not :name final-name :range nil :atts atts :args (list o main-arg-in) :loc loc))) (mv (ok) temp-decls (append gateinsts (list final-gate)) nf))))
Theorem:
(defthm vl-warninglist-p-of-vl-gatesplit-nand/nor/xnor.warnings (b* (((mv ?warnings ?new-decls ?new-gateinsts ?nf) (vl-gatesplit-nand/nor/xnor x nf warnings))) (vl-warninglist-p warnings)) :rule-classes :rewrite)
Theorem:
(defthm vl-vardecllist-p-of-vl-gatesplit-nand/nor/xnor.new-decls (implies (and (force (vl-gateinst-p x)) (force (vl-namefactory-p nf)) (force (vl-warninglist-p warnings)) (force ((lambda (acl2::x acl2::l) (return-last 'acl2::mbe1-raw (acl2::member-eql-exec acl2::x acl2::l) (return-last 'progn (acl2::member-eql-exec$guard-check acl2::x acl2::l) (member-equal acl2::x acl2::l)))) (vl-gateinst->type$inline x) '(:vl-nand :vl-nor :vl-xnor)))) (b* (((mv ?warnings ?new-decls ?new-gateinsts ?nf) (vl-gatesplit-nand/nor/xnor x nf warnings))) (vl-vardecllist-p new-decls))) :rule-classes :rewrite)
Theorem:
(defthm vl-gateinstlist-p-of-vl-gatesplit-nand/nor/xnor.new-gateinsts (implies (and (force (vl-gateinst-p x)) (force (vl-namefactory-p nf)) (force (vl-warninglist-p warnings)) (force ((lambda (acl2::x acl2::l) (return-last 'acl2::mbe1-raw (acl2::member-eql-exec acl2::x acl2::l) (return-last 'progn (acl2::member-eql-exec$guard-check acl2::x acl2::l) (member-equal acl2::x acl2::l)))) (vl-gateinst->type$inline x) '(:vl-nand :vl-nor :vl-xnor)))) (b* (((mv ?warnings ?new-decls ?new-gateinsts ?nf) (vl-gatesplit-nand/nor/xnor x nf warnings))) (vl-gateinstlist-p new-gateinsts))) :rule-classes :rewrite)
Theorem:
(defthm vl-namefactory-p-of-vl-gatesplit-nand/nor/xnor.nf (implies (and (force (vl-gateinst-p x)) (force (vl-namefactory-p nf)) (force (vl-warninglist-p warnings)) (force ((lambda (acl2::x acl2::l) (return-last 'acl2::mbe1-raw (acl2::member-eql-exec acl2::x acl2::l) (return-last 'progn (acl2::member-eql-exec$guard-check acl2::x acl2::l) (member-equal acl2::x acl2::l)))) (vl-gateinst->type$inline x) '(:vl-nand :vl-nor :vl-xnor)))) (b* (((mv ?warnings ?new-decls ?new-gateinsts ?nf) (vl-gatesplit-nand/nor/xnor x nf warnings))) (vl-namefactory-p nf))) :rule-classes :rewrite)
Theorem:
(defthm vl-gatesplit-nand/nor/xnor-mvtypes-1 (true-listp (mv-nth 1 (vl-gatesplit-nand/nor/xnor x nf warnings))) :rule-classes :type-prescription)
Theorem:
(defthm vl-gatesplit-nand/nor/xnor-mvtypes-2 (true-listp (mv-nth 2 (vl-gatesplit-nand/nor/xnor x nf warnings))) :rule-classes :type-prescription)