Skip to main content

litex/runtime/
runtime_define_parameter.rs

1use crate::prelude::*;
2
3impl Runtime {
4    /// After `store_identifier_obj`, run param-type-specific work (type facts, storage, and later hooks).
5    pub fn define_parameter_by_binding_param_type(
6        &mut self,
7        name: &str,
8        param_type: &ParamType,
9        binding_kind: ParamObjType,
10    ) -> Result<InferResult, RuntimeError> {
11        match param_type {
12            ParamType::Obj(obj) => match obj {
13                Obj::FamilyObj(family_ty) => {
14                    self.define_parameter_by_binding_family(name, family_ty, binding_kind)
15                }
16                Obj::FiniteSeqSet(fs) => {
17                    let fn_set = self.finite_seq_set_to_fn_set(fs, default_line_file());
18                    let type_fact = InFact::new(
19                        param_binding_element_obj_for_store(name.to_string(), binding_kind),
20                        fn_set.into(),
21                        default_line_file(),
22                    )
23                    .into();
24                    self.verify_well_defined_and_store_and_infer_with_default_verify_state(
25                        type_fact,
26                    )
27                }
28                Obj::SeqSet(ss) => {
29                    let fn_set = self.seq_set_to_fn_set(ss, default_line_file());
30                    let type_fact = InFact::new(
31                        param_binding_element_obj_for_store(name.to_string(), binding_kind),
32                        fn_set.into(),
33                        default_line_file(),
34                    )
35                    .into();
36                    self.verify_well_defined_and_store_and_infer_with_default_verify_state(
37                        type_fact,
38                    )
39                }
40                Obj::MatrixSet(ms) => {
41                    let fn_set = self.matrix_set_to_fn_set(ms, default_line_file());
42                    let type_fact = InFact::new(
43                        param_binding_element_obj_for_store(name.to_string(), binding_kind),
44                        fn_set.into(),
45                        default_line_file(),
46                    )
47                    .into();
48                    self.verify_well_defined_and_store_and_infer_with_default_verify_state(
49                        type_fact,
50                    )
51                }
52                _ => self.define_parameter_by_binding_obj(name, obj, binding_kind),
53            },
54            ParamType::Set(set) => self.define_parameter_by_binding_set(name, set, binding_kind),
55            ParamType::NonemptySet(nonempty_set) => {
56                self.define_parameter_by_binding_nonempty_set(name, nonempty_set, binding_kind)
57            }
58            ParamType::FiniteSet(finite_set) => {
59                self.define_parameter_by_binding_finite_set(name, finite_set, binding_kind)
60            }
61            ParamType::Restrictive(fn_set) => {
62                self.define_parameter_by_binding_restrictive(name, fn_set, binding_kind)
63            }
64        }
65    }
66
67    fn define_parameter_by_binding_restrictive(
68        &mut self,
69        name: &str,
70        fn_set: &FnSet,
71        binding_kind: ParamObjType,
72    ) -> Result<InferResult, RuntimeError> {
73        let element = param_binding_element_obj_for_store(name.to_string(), binding_kind);
74        let restrict_fact: Fact =
75            RestrictFact::new(element, fn_set.clone().into(), default_line_file()).into();
76        self.verify_well_defined_and_store_and_infer_with_default_verify_state(restrict_fact)
77    }
78
79    fn define_parameter_by_binding_family(
80        &mut self,
81        name: &str,
82        family_ty: &FamilyObj,
83        binding_kind: ParamObjType,
84    ) -> Result<InferResult, RuntimeError> {
85        self.infer_membership_in_family_for_param_binding(name, family_ty, binding_kind)
86    }
87
88    fn define_parameter_by_binding_obj(
89        &mut self,
90        name: &str,
91        obj: &Obj,
92        binding_kind: ParamObjType,
93    ) -> Result<InferResult, RuntimeError> {
94        let type_fact = InFact::new(
95            param_binding_element_obj_for_store(name.to_string(), binding_kind),
96            obj.clone(),
97            default_line_file(),
98        )
99        .into();
100        self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
101    }
102
103    fn define_parameter_by_binding_set(
104        &mut self,
105        name: &str,
106        _set: &Set,
107        binding_kind: ParamObjType,
108    ) -> Result<InferResult, RuntimeError> {
109        let type_fact = IsSetFact::new(
110            param_binding_element_obj_for_store(name.to_string(), binding_kind),
111            default_line_file(),
112        )
113        .into();
114        self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
115    }
116
117    fn define_parameter_by_binding_nonempty_set(
118        &mut self,
119        name: &str,
120        _nonempty_set: &NonemptySet,
121        binding_kind: ParamObjType,
122    ) -> Result<InferResult, RuntimeError> {
123        let type_fact = IsNonemptySetFact::new(
124            param_binding_element_obj_for_store(name.to_string(), binding_kind),
125            default_line_file(),
126        )
127        .into();
128        self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
129    }
130
131    fn define_parameter_by_binding_finite_set(
132        &mut self,
133        name: &str,
134        _finite_set: &FiniteSet,
135        binding_kind: ParamObjType,
136    ) -> Result<InferResult, RuntimeError> {
137        let type_fact = IsFiniteSetFact::new(
138            param_binding_element_obj_for_store(name.to_string(), binding_kind),
139            default_line_file(),
140        )
141        .into();
142        self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
143    }
144
145    pub fn define_params_with_type(
146        &mut self,
147        param_defs: &ParamDefWithType,
148        check_type_nonempty: bool,
149        binding_kind: ParamObjType,
150    ) -> Result<InferResult, RuntimeError> {
151        let mut infer_result = InferResult::new();
152        for param_def in param_defs.groups.iter() {
153            self.verify_param_type_well_defined(&param_def.param_type, &VerifyState::new(0, false))
154                .map_err(|well_defined_error| {
155                    let param_names_text = param_def.params.join(", ");
156                    let error_line_file = well_defined_error.line_file().clone();
157                    RuntimeError::from(DefineParamsRuntimeError(RuntimeErrorStruct::new(
158                None,
159                format!(
160                            "define params with type: failed to verify type well-defined for params [{}] with type {}",
161                            param_names_text, param_def.param_type
162                        ),
163                error_line_file,
164                Some(well_defined_error),
165                vec![],
166            )))
167                })?;
168            self.verify_param_type_nonempty_if_required(&param_def.param_type, check_type_nonempty)
169                .map_err(|inner_exec_error| {
170                    let param_names_text = param_def.params.join(", ");
171                    RuntimeError::from(DefineParamsRuntimeError(RuntimeErrorStruct::new_with_msg_and_cause(format!(
172                            "define params with type: nonempty check failed for params [{}] with type {}",
173                            param_names_text, param_def.param_type
174                        ), inner_exec_error)))
175                })?;
176
177            for name in param_def.params.iter() {
178                self.store_free_param_or_identifier_name(name, binding_kind)
179                    .map_err(|runtime_error| {
180                        RuntimeError::from(DefineParamsRuntimeError(
181                            RuntimeErrorStruct::new_with_msg_and_cause(
182                                format!(
183                                    "define params with type: failed to declare parameter `{}`",
184                                    name
185                                ),
186                                runtime_error,
187                            ),
188                        ))
189                    })?;
190                let fact_infer_result = self
191                    .define_parameter_by_binding_param_type(
192                        name,
193                        &param_def.param_type,
194                        binding_kind,
195                    )
196                    .map_err(|runtime_error| {
197                        RuntimeError::from(DefineParamsRuntimeError(RuntimeErrorStruct::new_with_msg_and_cause(format!(
198                                "define params with type: failed to apply param type for parameter `{}` with type {}",
199                                name, param_def.param_type
200                            ), runtime_error)))
201                    })?;
202                infer_result.new_infer_result_inside(fact_infer_result);
203            }
204        }
205        Ok(infer_result)
206    }
207}