@@ -576,16 +576,23 @@ package experimental {
576576
577577    private  val  _ports  =  new  ArrayBuffer [(Data , SourceInfo )]()
578578
579+     private  val  _associations  =  new  HashMap [Data , LinkedHashSet [Data ]]()
580+ 
581+     protected [chisel3] def  getAssociations :  scala.collection.immutable.Map [Data , LinkedHashSet [Data ]] = 
582+       _associations.toMap
583+ 
579584    //  getPorts unfortunately already used for tester compatibility
580585    protected [chisel3] def  getModulePorts :  Seq [Data ] =  {
581586      require(_closed, " Can't get ports before module close"  )
582587      _ports.iterator.collect { case  (d : Data , _) =>  d }.toSeq
583588    }
584589
585590    //  gets Ports along with there source locators
586-     private [chisel3] def  getModulePortsAndLocators :  Seq [(Data , SourceInfo )] =  {
591+     private [chisel3] def  getModulePortsAndLocators :  Seq [(Data , SourceInfo ,  Seq [ Data ] )] =  {
587592      require(_closed, " Can't get ports before module close"  )
588-       _ports.toSeq
593+       _ports.toSeq.map { case  (port, info) => 
594+         (port, info, _associations.get(port).map(_.toSeq).getOrElse(Seq .empty[Data ]))
595+       }
589596    }
590597
591598    /**  Get IOs that are currently bound to this module. 
@@ -608,6 +615,22 @@ package experimental {
608615
609616    protected  def  portsSize :  Int  =  _ports.size
610617
618+     /*  Associate a port of this module with one or more domains. */ 
619+     final  def  associate (port : Data , domain : Data , domains : Data * )(implicit  si : SourceInfo ):  Unit  =  {
620+       val  allDomains  =  Seq (domain) ++  domains
621+       if  (! portsContains(port)) {
622+         Builder .error(s """ Unable to associate port ' $port' to domains ' ${allDomains.mkString(
623+             " , " 
624+           )}' because the port does not exist in this module """ )(si)
625+         println(getModulePorts)
626+         return 
627+       }
628+       _associations.updateWith(port) {
629+         case  Some (acc) =>  Some (acc ++=  allDomains)
630+         case  None       =>  Some (LinkedHashSet .empty[Data ] ++=  allDomains)
631+       }
632+     }
633+ 
611634    /**  Generates the FIRRTL Component (Module or Blackbox) of this Module. 
612635      * Also closes the module so no more construction can happen inside. 
613636      */  
@@ -618,7 +641,7 @@ package experimental {
618641    private [chisel3] def  initializeInParent ():  Unit 
619642
620643    private [chisel3] def  namePorts ():  Unit  =  {
621-       for  ((port, source) <-  getModulePortsAndLocators) {
644+       for  ((port, source, _ ) <-  getModulePortsAndLocators) {
622645        port._computeName(None ) match  {
623646          case  Some (name) => 
624647            if  (_namespace.contains(name)) {
@@ -882,7 +905,7 @@ package experimental {
882905    private [chisel3] def  addSecretIO [A  <:  Data ](iodef : A )(implicit  sourceInfo : SourceInfo ):  A  =  {
883906      val  name  =  iodef._computeName(None ).getOrElse(" secret"  )
884907      iodef.setRef(ModuleIO (this , _namespace.name(name)))
885-       val  newPort  =  new  Port (iodef, iodef.specifiedDirection, sourceInfo)
908+       val  newPort  =  new  Port (iodef, iodef.specifiedDirection, Seq .empty,  sourceInfo)
886909      if  (_closed) {
887910        _component.get.secretPorts +=  newPort
888911      } else  secretPorts +=  newPort
@@ -905,7 +928,9 @@ package experimental {
905928      * TODO(twigg): Specifically walk the Data definition to call out which nodes 
906929      * are problematic. 
907930      */  
908-     protected  def  IO [T  <:  Data ](iodef : =>  T )(implicit  sourceInfo : SourceInfo ):  T  =  {
931+     protected  def  IO [T  <:  Data ](iodef : =>  T )(
932+       implicit  sourceInfo : SourceInfo 
933+     ):  T  =  {
909934      chisel3.IO .apply(iodef)
910935    }
911936
0 commit comments