fn emit_port_connections(
        &mut self,
        port_list: &PortList<'gcx>,
        inst: &InstDetails<'gcx>,
        inputs: &[ModulePort<'gcx>],
        outputs: &[ModulePort<'gcx>],
    ) -> Result<(Vec<HybridValue>, Vec<HybridValue>)> {
        // Map the values associated with the external ports to internal
        // ports.
        let mut port_mapping_int: HashMap<NodeId, NodeEnvId> = HashMap::new();
        for port in &port_list.ext_pos {
            let mapping = match inst.ports.find(port.id) {
                Some(m) => m,
                None => continue,
            };
            if port.exprs.len() > 1 {
                self.emit(
                    DiagBuilder2::bug("port expressions with concatenations not supported")
                        .span(inst.hir.span())
                        .add_note("Port declared here:")
                        .span(port.span),
                );
                continue;
            }
            let expr = match port.exprs.iter().next() {
                Some(m) => m,
                None => continue,
            };
            if !expr.selects.is_empty() {
                self.emit(
                    DiagBuilder2::bug("port expressions with selections not supported")
                        .span(inst.hir.span())
                        .add_note("Port declared here:")
                        .span(port.span),
                );
                continue;
            }
            let int = &port_list.int[expr.port];
            if port_mapping_int.insert(int.id, mapping).is_some() {
                self.emit(
                    DiagBuilder2::error(format!("port `{}` connected multiple times", int.name))
                        .span(self.span(mapping.id())),
                );
            }
        }
        trace!("Internal Port Mapping: {:?}", port_mapping_int);

        // Connect to the actual internal ports emitted as the module's port
        // interface.
        let mut map_port = |port: &ModulePort<'gcx>, lvalue: bool| {
            trace!(
                "Mapping port `{}` of type `{}` as {}",
                port.name,
                port.ty,
                match lvalue {
                    true => "lvalue",
                    false => "rvalue",
                }
            );
            if let Some(&mapping) = port_mapping_int.get(&port.port.id) {
                // Emit the assigned node as rvalue or lvalue, depending on
                // the port direction.
                if lvalue {
                    let mir = self.mir_lvalue(mapping.id(), mapping.env());
                    if mir.is_error() {
                        return Err(());
                    }
                    let mir = match port.kind {
                        ModulePortKind::Port => mir,
                        ModulePortKind::IntfSignal { decl_id, env, .. } => {
                            self.arena().alloc_mir_lvalue(mir::Lvalue {
                                id: NodeId::alloc(),
                                origin: mir.origin,
                                env,
                                span: mir.span,
                                ty: port.ty,
                                kind: mir::LvalueKind::IntfSignal(mir, decl_id),
                            })
                        }
                    };
                    self.emit_mir_lvalue(mir).map(|x| x.0)
                } else {
                    let mir = self.mir_rvalue(mapping.id(), mapping.env());
                    if mir.is_error() {
                        return Err(());
                    }
                    let mir = match port.kind {
                        ModulePortKind::Port => mir,
                        ModulePortKind::IntfSignal { decl_id, env, .. } => {
                            self.arena().alloc_mir_rvalue(mir::Rvalue {
                                id: NodeId::alloc(),
                                origin: mir.origin,
                                env,
                                span: mir.span,
                                ty: port.ty,
                                kind: mir::RvalueKind::IntfSignal(mir, decl_id),
                                konst: false,
                            })
                        }
                    };
                    self.emit_mir_rvalue_mode(mir, Mode::Signal)
                }
            } else {
                // Emit an auxiliary signal with the default value for this
                // port or type.
                let ty = self.type_of_int_port(Ref(port.port), inst.inner_env);
                let value = match port.port.data.as_ref().and_then(|d| d.default) {
                    Some(default) => {
                        self.emit_rvalue_mode(default, inst.inner_env, Mode::Signal)?
                    }
                    None => {
                        let v = self.type_default_value(ty);
                        let v = self.emit_const(v, inst.inner_env, port.port.span)?;
                        (
                            self.builder.ins().sig(v.0),
                            circt::llhd::SignalOp::new(
                                self.mlir_builder,
                                &self.unique_names.add_tmp(),
                                v.1,
                            )
                            .into(),
                        )
                    }
                };
                self.builder
                    .set_name(value.0, format!("{}.{}.default", inst.hir.name, port.name));
                Ok(value)
            }
        };
        let inputs = inputs
            .iter()
            .map(|p| map_port(p, false))
            .collect::<Result<Vec<_>>>()?;
        let outputs = outputs
            .iter()
            .map(|p| map_port(p, true))
            .collect::<Result<Vec<_>>>()?;
        Ok((inputs, outputs))
    }
/// Emit code for the connections made in a port list.
Emit code for the connections made in a port list.
Emit code for the connections made in a port list .
fn emit_port_connections(
        &mut self,
        port_list: &PortList<'gcx>,
        inst: &InstDetails<'gcx>,
        inputs: &[ModulePort<'gcx>],
        outputs: &[ModulePort<'gcx>],
    ) -> Result<(Vec<HybridValue>, Vec<HybridValue>)> {
        // Map the values associated with the external ports to internal
        // ports.
        let mut port_mapping_int: HashMap<NodeId, NodeEnvId> = HashMap::new();
        for port in &port_list.ext_pos {
            let mapping = match inst.ports.find(port.id) {
                Some(m) => m,
                None => continue,
            };
            if port.exprs.len() > 1 {
                self.emit(
                    DiagBuilder2::bug("port expressions with concatenations not supported")
                        .span(inst.hir.span())
                        .add_note("Port declared here:")
                        .span(port.span),
                );
                continue;
            }
            let expr = match port.exprs.iter().next() {
                Some(m) => m,
                None => continue,
            };
            if !expr.selects.is_empty() {
                self.emit(
                    DiagBuilder2::bug("port expressions with selections not supported")
                        .span(inst.hir.span())
                        .add_note("Port declared here:")
                        .span(port.span),
                );
                continue;
            }
            let int = &port_list.int[expr.port];
            if port_mapping_int.insert(int.id, mapping).is_some() {
                self.emit(
                    DiagBuilder2::error(format!("port `{}` connected multiple times", int.name))
                        .span(self.span(mapping.id())),
                );
            }
        }
        trace!("Internal Port Mapping: {:?}", port_mapping_int);
        // Connect to the actual internal ports emitted as the module's port
        // interface.
        let mut map_port = |port: &ModulePort<'gcx>, lvalue: bool| {
            trace!(
                "Mapping port `{}` of type `{}` as {}",
                port.name,
                port.ty,
                match lvalue {
                    true => "lvalue",
                    false => "rvalue",
                }
            );
            if let Some(&mapping) = port_mapping_int.get(&port.port.id) {
                // Emit the assigned node as rvalue or lvalue, depending on
                // the port direction.
                if lvalue {
                    let mir = self.mir_lvalue(mapping.id(), mapping.env());
                    if mir.is_error() {
                        return Err(());
                    }
                    let mir = match port.kind {
                        ModulePortKind::Port => mir,
                        ModulePortKind::IntfSignal { decl_id, env, .. } => {
                            self.arena().alloc_mir_lvalue(mir::Lvalue {
                                id: NodeId::alloc(),
                                origin: mir.origin,
                                env,
                                span: mir.span,
                                ty: port.ty,
                                kind: mir::LvalueKind::IntfSignal(mir, decl_id),
                            })
                        }
                    };
                    self.emit_mir_lvalue(mir).map(|x| x.0)
                } else {
                    let mir = self.mir_rvalue(mapping.id(), mapping.env());
                    if mir.is_error() {
                        return Err(());
                    }
                    let mir = match port.kind {
                        ModulePortKind::Port => mir,
                        ModulePortKind::IntfSignal { decl_id, env, .. } => {
                            self.arena().alloc_mir_rvalue(mir::Rvalue {
                                id: NodeId::alloc(),
                                origin: mir.origin,
                                env,
                                span: mir.span,
                                ty: port.ty,
                                kind: mir::RvalueKind::IntfSignal(mir, decl_id),
                                konst: false,
                            })
                        }
                    };
                    self.emit_mir_rvalue_mode(mir, Mode::Signal)
                }
            } else {
                // Emit an auxiliary signal with the default value for this
                // port or type.
                let ty = self.type_of_int_port(Ref(port.port), inst.inner_env);
                let value = match port.port.data.as_ref().and_then(|d| d.default) {
                    Some(default) => {
                        self.emit_rvalue_mode(default, inst.inner_env, Mode::Signal)?
                    }
                    None => {
                        let v = self.type_default_value(ty);
                        let v = self.emit_const(v, inst.inner_env, port.port.span)?;
                        (
                            self.builder.ins().sig(v.0),
                            circt::llhd::SignalOp::new(
                                self.mlir_builder,
                                &self.unique_names.add_tmp(),
                                v.1,
                            )
                            .into(),
                        )
                    }
                };
                self.builder
                    .set_name(value.0, format!("{}.{}.default", inst.hir.name, port.name));
                Ok(value)
            }
        };
        let inputs = inputs
            .iter()
            .map(|p| map_port(p, false))
            .collect::<Result<Vec<_>>>()?;
        let outputs = outputs
            .iter()
            .map(|p| map_port(p, true))
            .collect::<Result<Vec<_>>>()?;
        Ok((inputs, outputs))
    }
fn emit_port_connections ( & mut self , port_list : & PortList < ' gcx > , inst : & InstDetails < ' gcx > , inputs : & [ ModulePort < ' gcx > ] , outputs : & [ ModulePort < ' gcx > ] , ) -> Result < ( Vec < HybridValue > , Vec < HybridValue > ) > { // Map the values associated with the external ports to internal // ports. let mut port_mapping_int : HashMap < NodeId , NodeEnvId > = HashMap :: new ( ) ; for port in & port_list . ext_pos { let mapping = match inst . ports . find ( port . id ) { Some ( m ) => m , None => continue , } ; if port . exprs . len ( ) > 1 { self . emit ( DiagBuilder2 :: bug ( " " ) . span ( inst . hir . span ( ) ) . add_note ( " " ) . span ( port . span ) , ) ; continue ; } let expr = match port . exprs . iter ( ) . next ( ) { Some ( m ) => m , None => continue , } ; if ! expr . selects . is_empty ( ) { self . emit ( DiagBuilder2 :: bug ( " " ) . span ( inst . hir . span ( ) ) . add_note ( " " ) . span ( port . span ) , ) ; continue ; } let int = & port_list . int [ expr . port ] ; if port_mapping_int . insert ( int . id , mapping ) . is_some ( ) { self . emit ( DiagBuilder2 :: error ( format ! ( " " int name ) ) . span ( self . span ( mapping . id ( ) ) ) , ) ; } } trace ! ( " " port_mapping_int ) ; // Connect to the actual internal ports emitted as the module's port // interface. let mut map_port = | port : & ModulePort < ' gcx > , lvalue : bool | { trace ! ( " " port name port ty match lvalue { true " " false " " } ) ; if let Some ( & mapping ) = port_mapping_int . get ( & port . port . id ) { // Emit the assigned node as rvalue or lvalue, depending on // the port direction. if lvalue { let mir = self . mir_lvalue ( mapping . id ( ) , mapping . env ( ) ) ; if mir . is_error ( ) { return Err ( ( ) ) ; } let mir = match port . kind { ModulePortKind :: Port => mir , ModulePortKind :: IntfSignal { decl_id , env , .. } => { self . arena ( ) . alloc_mir_lvalue ( mir :: Lvalue { id : NodeId :: alloc ( ) , origin : mir . origin , env , span : mir . span , ty : port . ty , kind : mir :: LvalueKind :: IntfSignal ( mir , decl_id ) , } ) } } ; self . emit_mir_lvalue ( mir ) . map ( | x | x . 0 ) } else { let mir = self . mir_rvalue ( mapping . id ( ) , mapping . env ( ) ) ; if mir . is_error ( ) { return Err ( ( ) ) ; } let mir = match port . kind { ModulePortKind :: Port => mir , ModulePortKind :: IntfSignal { decl_id , env , .. } => { self . arena ( ) . alloc_mir_rvalue ( mir :: Rvalue { id : NodeId :: alloc ( ) , origin : mir . origin , env , span : mir . span , ty : port . ty , kind : mir :: RvalueKind :: IntfSignal ( mir , decl_id ) , konst : false , } ) } } ; self . emit_mir_rvalue_mode ( mir , Mode :: Signal ) } } else { // Emit an auxiliary signal with the default value for this // port or type. let ty = self . type_of_int_port ( Ref ( port . port ) , inst . inner_env ) ; let value = match port . port . data . as_ref ( ) . and_then ( | d | d . default ) { Some ( default ) => { self . emit_rvalue_mode ( default , inst . inner_env , Mode :: Signal ) ? } None => { let v = self . type_default_value ( ty ) ; let v = self . emit_const ( v , inst . inner_env , port . port . span ) ? ; ( self . builder . ins ( ) . sig ( v . 0 ) , circt :: llhd :: SignalOp :: new ( self . mlir_builder , & self . unique_names . add_tmp ( ) , v . 1 , ) . into ( ) , ) } } ; self . builder . set_name ( value . 0 , format ! ( " " inst hir name port name ) ) ; Ok ( value ) } } ; let inputs = inputs . iter ( ) . map ( | p | map_port ( p , false ) ) . collect :: < Result < Vec < _ > > > ( ) ? ; let outputs = outputs . iter ( ) . map ( | p | map_port ( p , true ) ) . collect :: < Result < Vec < _ > > > ( ) ? ; Ok ( ( inputs , outputs ) ) }
Emit code for the connections made in a port list.
Emit code for the connections made in a port list .
&mut self
port_list
&PortList<'gcx>
inst
&InstDetails<'gcx>
inputs
&[ModulePort<'gcx>]
outputs
&[ModulePort<'gcx>]
&mut self
port_list
&PortList<'gcx>
inst
&InstDetails<'gcx>
inputs
&[ModulePort<'gcx>]
outputs
&[ModulePort<'gcx>]