Sanity check and normalize interface port arguments by dropping
hierarchical modinst name components, e.g., transform
(vl-unhierarchicalize-interfaceport arg port ss inst warnings) → (mv warnings new-arg)
See SystemVerilog-2012 Section 25.5, especially at the top of Page
718. Suppose we have an interface called
module fooBuilder( IPipe.producer pipe ) ; // <-- .producer used in the module's port ... endmodule module top ; IPipe mypipe; fooBuilder prod ( mypipe.producer ); // <-- .producer used in module instance endmodule
Our goal here is to deal with the latter kind of usage. The basic idea is
to reduce such an argument to just
Function:
(defun vl-unhierarchicalize-interfaceport (arg port ss inst warnings) (declare (xargs :guard (and (vl-plainarg-p arg) (vl-port-p port) (vl-scopestack-p ss) (vl-modinst-p inst) (vl-warninglist-p warnings)))) (let ((__function__ 'vl-unhierarchicalize-interfaceport)) (declare (ignorable __function__)) (b* ((port (vl-port-fix port)) ((vl-plainarg arg) (vl-plainarg-fix arg)) ((vl-modinst inst) (vl-modinst-fix inst)) ((unless (vl-port-interface-p port)) (mv (ok) arg)) ((vl-interfaceport port)) (expr (vl-plainarg->expr arg)) ((unless expr) (mv (fatal :type :vl-instance-blank-interface-port :msg "~a0: interface port ~s1 is blank." :args (list inst port.name)) arg)) ((unless (vl-expr-case expr :vl-index)) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: interface port argument isn't an interface: .~s1(~a2)" :args (list inst port.name expr)) arg)) ((vl-index expr)) ((mv err trace ?context tail) (vl-follow-scopeexpr expr.scope ss :strictp nil)) ((when err) (mv (fatal :type :vl-instance-interface-port-unresolved :msg "~a0: error resolving interface port argument .~s1(~a2): ~@3" :args (list inst port.name expr err)) arg)) ((vl-hidstep step1) (first trace)) ((when (vl-scopeitem-modinst-p step1.item)) (b* (((vl-modinst step1.item)) (iface (vl-scopestack-find-definition step1.item.modname ss)) ((unless (and iface (vl-scopedef-interface-p iface))) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: interface port argument isn't an interface: .~s1(~a2)" :args (list inst port.name expr)) arg)) ((unless (equal step1.item.modname port.ifname)) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: type error: interface port ~s1 (type ~s2) ~ is connected to ~a3 (type ~s4)." :args (list inst port.name port.ifname expr step1.item.modname)) arg))) (mv (ok) arg))) ((when (vl-scopeitem-interfaceport-p step1.item)) (b* (((vl-interfaceport step1.item)) ((unless (equal step1.item.ifname port.ifname)) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: type error: interface port ~s1 (type ~s2) ~ is connected to ~a3 (type ~s4)." :args (list inst port.name port.ifname expr step1.item.ifname)) arg))) (mv (ok) arg))) ((unless (vl-scopeitem-modport-p step1.item)) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: interface port argument isn't an interface: .~s1(~a2)" :args (list inst port.name expr)) arg)) ((when (or (consp expr.indices) (not (vl-partselect-case expr.part :none)))) (mv (fatal :type :vl-instance-modport-indexing :msg "~a0: array indexing can't be applied to modport: .~s1(~a2)" :args (list inst port.name expr)) arg)) ((vl-modport step1.item)) ((unless (vl-hidexpr-case tail :end)) (mv (fatal :type :vl-instance-modport-indexing :msg "~a0: error resolving interface port argument .~s1(~a2): ~ trying to index through modport ~s3 with ~a4." :args (list inst port.name expr step1.item.name tail)) arg)) ((unless (consp (cdr trace))) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: interface port argument isn't an interface: .~s1(~a2)" :args (list inst port.name expr)) arg)) ((vl-hidstep step2) (second trace)) ((unless (vl-scopeitem-modinst-p step2.item)) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: unsupported interface port argument .~s1(~a2). ~ We currently only support arguments with modport ~ specifiers for direct interface instantiations, but ~ modport ~s3 is found via ~a4." :args (list inst port.name expr step1.item.name step2.item)) arg)) ((vl-modinst step2.item)) (iface (vl-scopestack-find-definition step2.item.modname ss)) ((unless (and iface (vl-scopedef-interface-p iface))) (mv (fatal :type :vl-programming-error :msg "~a0: unsupported interface port argument .~s1(~a2). ~ Expected the modport ~s3 to be inside an interface, ~ but found it inside ~s4 which is a ~a5. Thought ~ that modports should only occur in interfaces." :args (list inst port.name expr step1.item.name step2.name iface)) arg)) ((vl-interface iface)) ((unless (equal iface.name port.ifname)) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: type error: interface port ~s1 (type ~s2) is ~ connected to ~a3 (type ~s4)." :args (list inst port.name port.ifname expr iface.name)) arg)) ((unless (or (not port.modport) (equal port.modport step1.item.name))) (mv (fatal :type :vl-instance-interface-port-bad-connection :msg "~a0: modport clash for .~s1(~a2). In submodule ~s3 ~ the port is declared as modport ~s4, so you can't ~ instantiate it with modport ~s5." :args (list inst port.name expr inst.modname port.modport step1.item.name)) arg)) ((mv chop-okp new-scopeexpr indices ?lastname) (vl-scopeexpr-split-right expr.scope)) ((unless chop-okp) (mv (fatal :type :vl-programming-error :msg "~a0: reducing interface port .~s1(~a2) by dropping ~ modport ~s3: somehow failed to split the modport?" :args (list inst port.name expr step1.item.name)) arg)) ((when indices) (mv (fatal :type :vl-instance-interface-port-unsupported :msg "~a0: reducing interface port .~s1(~a2) by dropping ~ modport ~s3: indices on pre-modport expression? ~ BOZO we might need to support this for interface ~ arrays.") arg)) (modportname-as-expr (make-vl-literal :val (make-vl-string :value step1.item.name))) (interfacename-as-expr (make-vl-literal :val (make-vl-string :value port.ifname))) (new-atts (list* (cons "VL_REMOVED_EXPLICIT_MODPORT" modportname-as-expr) (cons "VL_INTERFACE_NAME" interfacename-as-expr) arg.atts)) (new-arg (change-vl-plainarg arg :expr (change-vl-index expr :scope new-scopeexpr) :atts new-atts))) (mv (ok) new-arg))))
Theorem:
(defthm vl-warninglist-p-of-vl-unhierarchicalize-interfaceport.warnings (b* (((mv ?warnings ?new-arg) (vl-unhierarchicalize-interfaceport arg port ss inst warnings))) (vl-warninglist-p warnings)) :rule-classes :rewrite)
Theorem:
(defthm vl-plainarg-p-of-vl-unhierarchicalize-interfaceport.new-arg (b* (((mv ?warnings ?new-arg) (vl-unhierarchicalize-interfaceport arg port ss inst warnings))) (vl-plainarg-p new-arg)) :rule-classes :rewrite)
Theorem:
(defthm vl-unhierarchicalize-interfaceport-of-vl-plainarg-fix-arg (equal (vl-unhierarchicalize-interfaceport (vl-plainarg-fix arg) port ss inst warnings) (vl-unhierarchicalize-interfaceport arg port ss inst warnings)))
Theorem:
(defthm vl-unhierarchicalize-interfaceport-vl-plainarg-equiv-congruence-on-arg (implies (vl-plainarg-equiv arg arg-equiv) (equal (vl-unhierarchicalize-interfaceport arg port ss inst warnings) (vl-unhierarchicalize-interfaceport arg-equiv port ss inst warnings))) :rule-classes :congruence)
Theorem:
(defthm vl-unhierarchicalize-interfaceport-of-vl-port-fix-port (equal (vl-unhierarchicalize-interfaceport arg (vl-port-fix port) ss inst warnings) (vl-unhierarchicalize-interfaceport arg port ss inst warnings)))
Theorem:
(defthm vl-unhierarchicalize-interfaceport-vl-port-equiv-congruence-on-port (implies (vl-port-equiv port port-equiv) (equal (vl-unhierarchicalize-interfaceport arg port ss inst warnings) (vl-unhierarchicalize-interfaceport arg port-equiv ss inst warnings))) :rule-classes :congruence)
Theorem:
(defthm vl-unhierarchicalize-interfaceport-of-vl-scopestack-fix-ss (equal (vl-unhierarchicalize-interfaceport arg port (vl-scopestack-fix ss) inst warnings) (vl-unhierarchicalize-interfaceport arg port ss inst warnings)))
Theorem:
(defthm vl-unhierarchicalize-interfaceport-vl-scopestack-equiv-congruence-on-ss (implies (vl-scopestack-equiv ss ss-equiv) (equal (vl-unhierarchicalize-interfaceport arg port ss inst warnings) (vl-unhierarchicalize-interfaceport arg port ss-equiv inst warnings))) :rule-classes :congruence)
Theorem:
(defthm vl-unhierarchicalize-interfaceport-of-vl-modinst-fix-inst (equal (vl-unhierarchicalize-interfaceport arg port ss (vl-modinst-fix inst) warnings) (vl-unhierarchicalize-interfaceport arg port ss inst warnings)))
Theorem:
(defthm vl-unhierarchicalize-interfaceport-vl-modinst-equiv-congruence-on-inst (implies (vl-modinst-equiv inst inst-equiv) (equal (vl-unhierarchicalize-interfaceport arg port ss inst warnings) (vl-unhierarchicalize-interfaceport arg port ss inst-equiv warnings))) :rule-classes :congruence)
Theorem:
(defthm vl-unhierarchicalize-interfaceport-of-vl-warninglist-fix-warnings (equal (vl-unhierarchicalize-interfaceport arg port ss inst (vl-warninglist-fix warnings)) (vl-unhierarchicalize-interfaceport arg port ss inst warnings)))
Theorem:
(defthm vl-unhierarchicalize-interfaceport-vl-warninglist-equiv-congruence-on-warnings (implies (vl-warninglist-equiv warnings warnings-equiv) (equal (vl-unhierarchicalize-interfaceport arg port ss inst warnings) (vl-unhierarchicalize-interfaceport arg port ss inst warnings-equiv))) :rule-classes :congruence)