1#![allow(unused)]
6#![allow(clippy::arc_with_non_send_sync)]
7
8use xlsynth_sys::{self as sys};
9
10use std::{
11 ffi::CString,
12 os::raw::c_char,
13 sync::{Arc, Mutex},
14};
15
16use crate::{
17 c_str_to_rust, ir_value::IrFormatPreference, lib_support::xls_format_preference_from_string,
18 xls_parse_typed_value, XlsynthError,
19};
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25pub enum ModulePortDirection {
26 Input,
27 Output,
28}
29
30pub struct ModulePort {
31 inner: *mut sys::CVastModulePort,
32 parent: Arc<Mutex<VastFilePtr>>, }
34
35impl ModulePort {
36 pub fn direction(&self) -> ModulePortDirection {
37 let _locked = self.parent.lock().unwrap();
38 let dir = unsafe { sys::xls_vast_verilog_module_port_get_direction(self.inner) };
39 match dir {
40 x if x == sys::XLS_VAST_MODULE_PORT_DIRECTION_INPUT => ModulePortDirection::Input,
41 x if x == sys::XLS_VAST_MODULE_PORT_DIRECTION_OUTPUT => ModulePortDirection::Output,
42 _ => panic!("Invalid port direction: {}", dir),
43 }
44 }
45
46 pub fn name(&self) -> String {
47 let _locked = self.parent.lock().unwrap();
48 let def_ptr = unsafe { sys::xls_vast_verilog_module_port_get_def(self.inner) };
49 let c_str = unsafe { sys::xls_vast_def_get_name(def_ptr) };
50 unsafe { c_str_to_rust(c_str) }
51 }
52
53 pub fn data_type(&self) -> VastDataType {
54 let _locked = self.parent.lock().unwrap();
55 let def_ptr = unsafe { sys::xls_vast_verilog_module_port_get_def(self.inner) };
56 let dt_ptr = unsafe { sys::xls_vast_def_get_data_type(def_ptr) };
57 VastDataType {
58 inner: dt_ptr,
59 parent: self.parent.clone(),
60 }
61 }
62
63 pub fn width(&self) -> i64 {
65 self.data_type()
66 .flat_bit_count_as_int64()
67 .unwrap_or_default()
68 }
69}
70
71impl VastDataType {
72 pub fn width_as_int64(&self) -> Result<i64, XlsynthError> {
74 let _locked = self.parent.lock().unwrap();
75 let mut width_out: i64 = 0;
76 let mut error_out: *mut c_char = std::ptr::null_mut();
77 let success = unsafe {
78 sys::xls_vast_data_type_width_as_int64(self.inner, &mut width_out, &mut error_out)
79 };
80 if success {
81 Ok(width_out)
82 } else {
83 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
84 }
85 }
86
87 pub fn flat_bit_count_as_int64(&self) -> Result<i64, XlsynthError> {
89 let _locked = self.parent.lock().unwrap();
90 let mut count_out: i64 = 0;
91 let mut error_out: *mut c_char = std::ptr::null_mut();
92 let success = unsafe {
93 sys::xls_vast_data_type_flat_bit_count_as_int64(
94 self.inner,
95 &mut count_out,
96 &mut error_out,
97 )
98 };
99 if success {
100 Ok(count_out)
101 } else {
102 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
103 }
104 }
105
106 pub fn width_expr(&self) -> Option<Expr> {
108 let _locked = self.parent.lock().unwrap();
109 let expr_ptr = unsafe { sys::xls_vast_data_type_width(self.inner) };
110 if expr_ptr.is_null() {
111 None
112 } else {
113 Some(Expr {
114 inner: expr_ptr,
115 parent: self.parent.clone(),
116 })
117 }
118 }
119
120 pub fn is_signed(&self) -> bool {
122 let _locked = self.parent.lock().unwrap();
123 unsafe { sys::xls_vast_data_type_is_signed(self.inner) }
124 }
125}
126
127impl VastModule {
129 pub fn ports(&self) -> Vec<ModulePort> {
131 let _locked = self.parent.lock().unwrap();
132 let mut count: usize = 0;
133 let ports_ptr = unsafe { sys::xls_vast_verilog_module_get_ports(self.inner, &mut count) };
134 if ports_ptr.is_null() || count == 0 {
135 return Vec::new();
136 }
137 let slice = unsafe { std::slice::from_raw_parts(ports_ptr, count) };
138 let result = slice
139 .iter()
140 .map(|&ptr| ModulePort {
141 inner: ptr,
142 parent: self.parent.clone(),
143 })
144 .collect::<Vec<_>>();
145 unsafe { sys::xls_vast_verilog_module_free_ports(ports_ptr, count) };
147 result
148 }
149
150 pub fn input_ports(&self) -> Vec<ModulePort> {
152 self.ports()
153 .into_iter()
154 .filter(|p| p.direction() == ModulePortDirection::Input)
155 .collect()
156 }
157
158 pub fn output_ports(&self) -> Vec<ModulePort> {
160 self.ports()
161 .into_iter()
162 .filter(|p| p.direction() == ModulePortDirection::Output)
163 .collect()
164 }
165}
166
167struct VastFilePtr(pub *mut sys::CVastFile);
168
169enum VastOperatorKind {
170 Negate = 0,
172 BitwiseNot = 1,
173 LogicalNot = 2,
174 AndReduce = 3,
175 OrReduce = 4,
176 XorReduce = 5,
177
178 Add = 6,
180 LogicalAnd = 7,
181 BitwiseAnd = 8,
182 Ne = 9,
183 CaseNe = 10,
184 Eq = 11,
185 CaseEq = 12,
186 Ge = 13,
187 Gt = 14,
188 Le = 15,
189 Lt = 16,
190 Div = 17,
191 Mod = 18,
192 Mul = 19,
193 Power = 20,
194 BitwiseOr = 21,
195 LogicalOr = 22,
196 BitwiseXor = 23,
197 Shll = 24,
198 Shra = 25,
199 Shrl = 26,
200 Sub = 27,
201 NeX = 28,
202 EqX = 29,
203}
204
205impl Drop for VastFilePtr {
206 fn drop(&mut self) {
207 unsafe { sys::xls_vast_verilog_file_free(self.0) }
208 }
209}
210
211#[derive(Clone)]
212pub struct VastDataType {
213 inner: *mut sys::CVastDataType,
214 parent: Arc<Mutex<VastFilePtr>>,
215}
216
217#[derive(Clone)]
218pub struct LogicRef {
219 inner: *mut sys::CVastLogicRef,
220 parent: Arc<Mutex<VastFilePtr>>,
221}
222
223impl LogicRef {
224 pub fn name(&self) -> String {
225 let locked = self.parent.lock().unwrap();
226 let inner = unsafe { sys::xls_vast_logic_ref_get_name(self.inner) };
227 unsafe { c_str_to_rust(inner) }
228 }
229
230 pub fn to_expr(&self) -> Expr {
231 let locked = self.parent.lock().unwrap();
232 let inner = unsafe { sys::xls_vast_logic_ref_as_expression(self.inner) };
233 Expr {
234 inner,
235 parent: self.parent.clone(),
236 }
237 }
238 pub fn to_indexable_expr(&self) -> IndexableExpr {
239 let locked = self.parent.lock().unwrap();
240 let inner = unsafe { sys::xls_vast_logic_ref_as_indexable_expression(self.inner) };
241 IndexableExpr {
242 inner,
243 parent: self.parent.clone(),
244 }
245 }
246}
247
248#[derive(Clone)]
249pub struct Expr {
250 inner: *mut sys::CVastExpression,
251 parent: Arc<Mutex<VastFilePtr>>,
252}
253
254impl Expr {
255 pub fn emit(&self) -> String {
256 let _locked = self.parent.lock().unwrap();
257 let c_str = unsafe { sys::xls_vast_expression_emit(self.inner) };
258 unsafe { c_str_to_rust(c_str) }
259 }
260}
261
262#[derive(Clone)]
263pub struct IndexableExpr {
264 inner: *mut sys::CVastIndexableExpression,
265 parent: Arc<Mutex<VastFilePtr>>,
266}
267
268impl IndexableExpr {
269 pub fn to_expr(&self) -> Expr {
270 let locked = self.parent.lock().unwrap();
271 let inner = unsafe { sys::xls_vast_indexable_expression_as_expression(self.inner) };
272 Expr {
273 inner,
274 parent: self.parent.clone(),
275 }
276 }
277}
278
279pub struct VastModule {
280 inner: *mut sys::CVastModule,
281 parent: Arc<Mutex<VastFilePtr>>,
282}
283
284pub struct Slice {
285 inner: *mut sys::CVastSlice,
286 parent: Arc<Mutex<VastFilePtr>>,
287}
288
289impl Slice {
290 pub fn to_expr(&self) -> Expr {
291 let locked = self.parent.lock().unwrap();
292 let inner = unsafe { sys::xls_vast_slice_as_expression(self.inner) };
293 Expr {
294 inner,
295 parent: self.parent.clone(),
296 }
297 }
298}
299
300pub struct Index {
301 inner: *mut sys::CVastIndex,
302 parent: Arc<Mutex<VastFilePtr>>,
303}
304
305impl Index {
306 pub fn to_expr(&self) -> Expr {
307 let locked = self.parent.lock().unwrap();
308 let inner = unsafe { sys::xls_vast_index_as_expression(self.inner) };
309 Expr {
310 inner,
311 parent: self.parent.clone(),
312 }
313 }
314
315 pub fn to_indexable_expr(&self) -> IndexableExpr {
316 let locked = self.parent.lock().unwrap();
317 let inner = unsafe { sys::xls_vast_index_as_indexable_expression(self.inner) };
318 IndexableExpr {
319 inner,
320 parent: self.parent.clone(),
321 }
322 }
323}
324
325pub struct Instantiation {
326 inner: *mut sys::CVastInstantiation,
327 parent: Arc<Mutex<VastFilePtr>>,
328}
329
330pub struct BlankLine {
331 inner: *mut sys::CVastBlankLine,
332 parent: Arc<Mutex<VastFilePtr>>,
333}
334
335pub struct InlineVerilogStatement {
336 inner: *mut sys::CVastInlineVerilogStatement,
337 parent: Arc<Mutex<VastFilePtr>>,
338}
339
340pub struct Comment {
341 inner: *mut sys::CVastComment,
342 parent: Arc<Mutex<VastFilePtr>>,
343}
344
345pub struct MacroRef {
346 inner: *mut sys::CVastMacroRef,
347 parent: Arc<Mutex<VastFilePtr>>,
348}
349
350pub struct MacroStatement {
351 inner: *mut sys::CVastMacroStatement,
352 parent: Arc<Mutex<VastFilePtr>>,
353}
354
355pub struct ContinuousAssignment {
356 inner: *mut sys::CVastContinuousAssignment,
357 parent: Arc<Mutex<VastFilePtr>>,
358}
359
360pub struct VastAlwaysBase {
361 inner: *mut sys::CVastAlwaysBase,
362 parent: Arc<Mutex<VastFilePtr>>,
363}
364
365pub struct VastStatementBlock {
366 inner: *mut sys::CVastStatementBlock,
367 parent: Arc<Mutex<VastFilePtr>>,
368}
369
370pub struct VastStatement {
371 inner: *mut sys::CVastStatement,
372 parent: Arc<Mutex<VastFilePtr>>,
373}
374
375pub struct Conditional {
376 inner: *mut sys::CVastConditional,
377 parent: Arc<Mutex<VastFilePtr>>,
378}
379
380pub struct CaseStatement {
381 inner: *mut sys::CVastCaseStatement,
382 parent: Arc<Mutex<VastFilePtr>>,
383}
384
385pub struct GenerateLoop {
386 inner: *mut sys::CVastGenerateLoop,
387 parent: Arc<Mutex<VastFilePtr>>,
388}
389
390pub struct ParameterRef {
391 inner: *mut sys::CVastParameterRef,
392 parent: Arc<Mutex<VastFilePtr>>,
393}
394
395pub struct LocalparamRef {
396 inner: *mut sys::CVastLocalparamRef,
397 parent: Arc<Mutex<VastFilePtr>>,
398}
399
400impl LocalparamRef {
401 pub fn to_expr(&self) -> Expr {
402 let locked = self.parent.lock().unwrap();
403 let inner = unsafe { sys::xls_vast_localparam_ref_as_expression(self.inner) };
404 Expr {
405 inner,
406 parent: self.parent.clone(),
407 }
408 }
409}
410pub struct Def {
411 inner: *mut sys::CVastDef,
412 parent: Arc<Mutex<VastFilePtr>>,
413}
414
415#[derive(Clone, Copy, Debug, PartialEq, Eq)]
416pub enum DataKind {
417 Reg,
418 Wire,
419 Logic,
420 Integer,
421 Int,
422 User,
423 UntypedEnum,
424 Genvar,
425}
426
427impl DataKind {
428 fn to_sys(self) -> i32 {
429 match self {
430 DataKind::Reg => sys::XLS_VAST_DATA_KIND_REG,
431 DataKind::Wire => sys::XLS_VAST_DATA_KIND_WIRE,
432 DataKind::Logic => sys::XLS_VAST_DATA_KIND_LOGIC,
433 DataKind::Integer => sys::XLS_VAST_DATA_KIND_INTEGER,
434 DataKind::Int => sys::XLS_VAST_DATA_KIND_INT,
435 DataKind::User => sys::XLS_VAST_DATA_KIND_USER,
436 DataKind::UntypedEnum => sys::XLS_VAST_DATA_KIND_UNTYPED_ENUM,
437 DataKind::Genvar => sys::XLS_VAST_DATA_KIND_GENVAR,
438 }
439 }
440}
441
442pub enum AlwaysKind {
443 AlwaysFF,
444 AlwaysAt,
445 AlwaysComb,
446}
447
448impl VastModule {
449 pub fn name(&self) -> String {
450 let locked = self.parent.lock().unwrap();
451 let inner = unsafe { sys::xls_vast_verilog_module_get_name(self.inner) };
452 unsafe { c_str_to_rust(inner) }
453 }
454
455 pub fn add_parameter_port(&mut self, name: &str, value: &Expr) -> LogicRef {
456 let c_name = CString::new(name).unwrap();
457 let _locked = self.parent.lock().unwrap();
458 let c_logic_ref = unsafe {
459 sys::xls_vast_verilog_module_add_parameter_port(
460 self.inner,
461 c_name.as_ptr(),
462 value.inner,
463 )
464 };
465 LogicRef {
466 inner: c_logic_ref,
467 parent: self.parent.clone(),
468 }
469 }
470
471 pub fn add_typed_parameter_port(
472 &mut self,
473 name: &str,
474 data_type: &VastDataType,
475 value: &Expr,
476 ) -> LogicRef {
477 let c_name = CString::new(name).unwrap();
478 let _locked = self.parent.lock().unwrap();
479 let c_logic_ref = unsafe {
480 sys::xls_vast_verilog_module_add_typed_parameter_port(
481 self.inner,
482 c_name.as_ptr(),
483 data_type.inner,
484 value.inner,
485 )
486 };
487 LogicRef {
488 inner: c_logic_ref,
489 parent: self.parent.clone(),
490 }
491 }
492
493 pub fn add_input(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
494 let c_name = CString::new(name).unwrap();
495 let _locked = self.parent.lock().unwrap();
496 let c_logic_ref = unsafe {
497 sys::xls_vast_verilog_module_add_input(self.inner, c_name.as_ptr(), data_type.inner)
498 };
499 LogicRef {
500 inner: c_logic_ref,
501 parent: self.parent.clone(),
502 }
503 }
504
505 pub fn add_output(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
506 let c_name = CString::new(name).unwrap();
507 let _locked = self.parent.lock().unwrap();
508 let c_logic_ref = unsafe {
509 sys::xls_vast_verilog_module_add_output(self.inner, c_name.as_ptr(), data_type.inner)
510 };
511 LogicRef {
512 inner: c_logic_ref,
513 parent: self.parent.clone(),
514 }
515 }
516
517 pub fn add_inout(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
518 let c_name = CString::new(name).unwrap();
519 let _locked = self.parent.lock().unwrap();
520 let c_logic_ref = unsafe {
521 sys::xls_vast_verilog_module_add_inout(self.inner, c_name.as_ptr(), data_type.inner)
522 };
523 LogicRef {
524 inner: c_logic_ref,
525 parent: self.parent.clone(),
526 }
527 }
528
529 pub fn add_logic_input(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
530 let c_name = CString::new(name).unwrap();
531 let _locked = self.parent.lock().unwrap();
532 let c_logic_ref = unsafe {
533 sys::xls_vast_verilog_module_add_logic_input(
534 self.inner,
535 c_name.as_ptr(),
536 data_type.inner,
537 )
538 };
539 LogicRef {
540 inner: c_logic_ref,
541 parent: self.parent.clone(),
542 }
543 }
544
545 pub fn add_logic_output(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
546 let c_name = CString::new(name).unwrap();
547 let _locked = self.parent.lock().unwrap();
548 let c_logic_ref = unsafe {
549 sys::xls_vast_verilog_module_add_logic_output(
550 self.inner,
551 c_name.as_ptr(),
552 data_type.inner,
553 )
554 };
555 LogicRef {
556 inner: c_logic_ref,
557 parent: self.parent.clone(),
558 }
559 }
560
561 pub fn add_wire(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
562 let c_name = CString::new(name).unwrap();
563 let _locked = self.parent.lock().unwrap();
564 let c_logic_ref = unsafe {
565 sys::xls_vast_verilog_module_add_wire(self.inner, c_name.as_ptr(), data_type.inner)
566 };
567 LogicRef {
568 inner: c_logic_ref,
569 parent: self.parent.clone(),
570 }
571 }
572
573 pub fn add_generate_loop(
574 &mut self,
575 genvar_name: &str,
576 init: &Expr,
577 limit: &Expr,
578 label: Option<&str>,
579 ) -> GenerateLoop {
580 let c_name = CString::new(genvar_name).unwrap();
581 let c_label =
582 CString::new(label.unwrap_or("")).expect("label should not contain NUL characters");
583 let _locked = self.parent.lock().unwrap();
584 let inner = unsafe {
585 sys::xls_vast_verilog_module_add_generate_loop(
586 self.inner,
587 c_name.as_ptr(),
588 init.inner,
589 limit.inner,
590 c_label.as_ptr(),
591 )
592 };
593 GenerateLoop {
594 inner,
595 parent: self.parent.clone(),
596 }
597 }
598
599 pub fn add_member_instantiation(&mut self, instantiation: Instantiation) {
603 let _locked = self.parent.lock().unwrap();
604 unsafe {
605 sys::xls_vast_verilog_module_add_member_instantiation(self.inner, instantiation.inner)
606 }
607 }
608
609 pub fn add_member_continuous_assignment(&mut self, assignment: ContinuousAssignment) {
615 let _locked = self.parent.lock().unwrap();
616 unsafe {
617 sys::xls_vast_verilog_module_add_member_continuous_assignment(
618 self.inner,
619 assignment.inner,
620 )
621 }
622 }
623
624 pub fn add_member_blank_line(&mut self, blank: BlankLine) {
625 let _locked = self.parent.lock().unwrap();
626 unsafe { sys::xls_vast_verilog_module_add_member_blank_line(self.inner, blank.inner) }
627 }
628
629 pub fn add_member_comment(&mut self, comment: Comment) {
630 let _locked = self.parent.lock().unwrap();
631 unsafe { sys::xls_vast_verilog_module_add_member_comment(self.inner, comment.inner) }
632 }
633
634 pub fn add_member_inline_statement(&mut self, stmt: InlineVerilogStatement) {
635 let _locked = self.parent.lock().unwrap();
636 unsafe { sys::xls_vast_verilog_module_add_member_inline_statement(self.inner, stmt.inner) }
637 }
638
639 pub fn add_member_macro_statement(&mut self, stmt: MacroStatement) {
640 let _locked = self.parent.lock().unwrap();
641 unsafe { sys::xls_vast_verilog_module_add_member_macro_statement(self.inner, stmt.inner) }
642 }
643
644 pub fn add_conditional(&mut self, cond: &Expr) -> Conditional {
645 let _locked = self.parent.lock().unwrap();
646 let inner = unsafe { sys::xls_vast_verilog_module_add_conditional(self.inner, cond.inner) };
647 Conditional {
648 inner,
649 parent: self.parent.clone(),
650 }
651 }
652
653 pub fn add_reg(
654 &mut self,
655 name: &str,
656 data_type: &VastDataType,
657 ) -> Result<LogicRef, XlsynthError> {
658 let c_name = CString::new(name).unwrap();
659 let _locked = self.parent.lock().unwrap();
660 let mut reg_ref_out: *mut sys::CVastLogicRef = std::ptr::null_mut();
661 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
662 let success = unsafe {
663 sys::xls_vast_verilog_module_add_reg(
664 self.inner,
665 c_name.as_ptr(),
666 data_type.inner,
667 &mut reg_ref_out,
668 &mut error_out,
669 )
670 };
671 if success {
672 Ok(LogicRef {
673 inner: reg_ref_out,
674 parent: self.parent.clone(),
675 })
676 } else {
677 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
678 }
679 }
680
681 pub fn add_logic(
682 &mut self,
683 name: &str,
684 data_type: &VastDataType,
685 ) -> Result<LogicRef, XlsynthError> {
686 let c_name = CString::new(name).unwrap();
687 let _locked = self.parent.lock().unwrap();
688 let mut reg_ref_out: *mut sys::CVastLogicRef = std::ptr::null_mut();
689 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
690 let success = unsafe {
691 sys::xls_vast_verilog_module_add_logic(
692 self.inner,
693 c_name.as_ptr(),
694 data_type.inner,
695 &mut reg_ref_out,
696 &mut error_out,
697 )
698 };
699 if success {
700 Ok(LogicRef {
701 inner: reg_ref_out,
702 parent: self.parent.clone(),
703 })
704 } else {
705 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
706 }
707 }
708
709 fn add_always_block(
710 &mut self,
711 sensitivity_list: &[&Expr],
712 always_kind: AlwaysKind,
713 ) -> Result<VastAlwaysBase, XlsynthError> {
714 let _locked = self.parent.lock().unwrap();
715 let mut expr_ptrs: Vec<*mut sys::CVastExpression> =
716 sensitivity_list.iter().map(|expr| expr.inner).collect();
717 let mut always_base_out: *mut sys::CVastAlwaysBase = std::ptr::null_mut();
718 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
719 let success = unsafe {
720 match always_kind {
721 AlwaysKind::AlwaysFF => sys::xls_vast_verilog_module_add_always_ff(
722 self.inner,
723 expr_ptrs.as_mut_ptr(),
724 expr_ptrs.len(),
725 &mut always_base_out,
726 &mut error_out,
727 ),
728 AlwaysKind::AlwaysAt => sys::xls_vast_verilog_module_add_always_at(
729 self.inner,
730 expr_ptrs.as_mut_ptr(),
731 expr_ptrs.len(),
732 &mut always_base_out,
733 &mut error_out,
734 ),
735 AlwaysKind::AlwaysComb => sys::xls_vast_verilog_module_add_always_comb(
736 self.inner,
737 &mut always_base_out,
738 &mut error_out,
739 ),
740 }
741 };
742 if success {
743 Ok(VastAlwaysBase {
744 inner: always_base_out,
745 parent: self.parent.clone(),
746 })
747 } else {
748 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
749 }
750 }
751
752 pub fn add_always_ff(
754 &mut self,
755 sensitivity_list: &[&Expr],
756 ) -> Result<VastAlwaysBase, XlsynthError> {
757 self.add_always_block(sensitivity_list, AlwaysKind::AlwaysFF)
758 }
759
760 pub fn add_always_at(
761 &mut self,
762 sensitivity_list: &[&Expr],
763 ) -> Result<VastAlwaysBase, XlsynthError> {
764 self.add_always_block(sensitivity_list, AlwaysKind::AlwaysAt)
765 }
766
767 pub fn add_always_comb(&mut self) -> Result<VastAlwaysBase, XlsynthError> {
768 self.add_always_block(&[], AlwaysKind::AlwaysComb)
769 }
770
771 pub fn add_parameter(&mut self, name: &str, rhs: &Expr) -> ParameterRef {
772 let c_name = CString::new(name).unwrap();
773 let _locked = self.parent.lock().unwrap();
774 let inner = unsafe {
775 sys::xls_vast_verilog_module_add_parameter(self.inner, c_name.as_ptr(), rhs.inner)
776 };
777 ParameterRef {
778 inner,
779 parent: self.parent.clone(),
780 }
781 }
782
783 pub fn add_parameter_with_def(&mut self, def: &Def, rhs: &Expr) -> ParameterRef {
784 let _locked = self.parent.lock().unwrap();
785 let inner = unsafe {
786 sys::xls_vast_verilog_module_add_parameter_with_def(self.inner, def.inner, rhs.inner)
787 };
788 ParameterRef {
789 inner,
790 parent: self.parent.clone(),
791 }
792 }
793
794 pub fn add_localparam(&mut self, name: &str, rhs: &Expr) -> LocalparamRef {
795 let c_name = CString::new(name).unwrap();
796 let _locked = self.parent.lock().unwrap();
797 let inner = unsafe {
798 sys::xls_vast_verilog_module_add_localparam(self.inner, c_name.as_ptr(), rhs.inner)
799 };
800 LocalparamRef {
801 inner,
802 parent: self.parent.clone(),
803 }
804 }
805
806 pub fn add_typed_localparam(&mut self, def: &Def, rhs: &Expr) -> LocalparamRef {
807 let _locked = self.parent.lock().unwrap();
808 let inner = unsafe {
809 sys::xls_vast_verilog_module_add_localparam_with_def(self.inner, def.inner, rhs.inner)
810 };
811 LocalparamRef {
812 inner,
813 parent: self.parent.clone(),
814 }
815 }
816
817 pub fn add_int_localparam(&mut self, name: &str, rhs: &Expr) -> LocalparamRef {
819 let c_name = CString::new(name).unwrap();
820 let locked = self.parent.lock().unwrap();
821 let int_def =
822 unsafe { sys::xls_vast_verilog_file_make_int_def(locked.0, c_name.as_ptr(), true) };
823 let inner = unsafe {
824 sys::xls_vast_verilog_module_add_localparam_with_def(self.inner, int_def, rhs.inner)
825 };
826 LocalparamRef {
827 inner,
828 parent: self.parent.clone(),
829 }
830 }
831}
832
833impl VastAlwaysBase {
834 pub fn get_statement_block(&self) -> VastStatementBlock {
835 let _locked = self.parent.lock().unwrap();
836 let inner = unsafe { sys::xls_vast_always_base_get_statement_block(self.inner) };
837 VastStatementBlock {
838 inner,
839 parent: self.parent.clone(),
840 }
841 }
842}
843
844impl VastStatementBlock {
845 pub fn add_blocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
846 let _locked = self.parent.lock().unwrap();
847 let inner = unsafe {
848 sys::xls_vast_statement_block_add_blocking_assignment(self.inner, lhs.inner, rhs.inner)
849 };
850 VastStatement {
851 inner,
852 parent: self.parent.clone(),
853 }
854 }
855
856 pub fn add_continuous_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
857 let _locked = self.parent.lock().unwrap();
858 let inner = unsafe {
859 sys::xls_vast_statement_block_add_continuous_assignment(
860 self.inner, lhs.inner, rhs.inner,
861 )
862 };
863 VastStatement {
864 inner,
865 parent: self.parent.clone(),
866 }
867 }
868
869 pub fn add_nonblocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
870 let _locked = self.parent.lock().unwrap();
871 let inner = unsafe {
872 sys::xls_vast_statement_block_add_nonblocking_assignment(
873 self.inner, lhs.inner, rhs.inner,
874 )
875 };
876 VastStatement {
877 inner,
878 parent: self.parent.clone(),
879 }
880 }
881
882 pub fn add_comment_text(&mut self, text: &str) -> VastStatement {
883 let c_text = CString::new(text).unwrap();
884 let _locked = self.parent.lock().unwrap();
885 let inner =
886 unsafe { sys::xls_vast_statement_block_add_comment_text(self.inner, c_text.as_ptr()) };
887 VastStatement {
888 inner,
889 parent: self.parent.clone(),
890 }
891 }
892
893 pub fn add_blank_line(&mut self) -> VastStatement {
894 let _locked = self.parent.lock().unwrap();
895 let inner = unsafe { sys::xls_vast_statement_block_add_blank_line(self.inner) };
896 VastStatement {
897 inner,
898 parent: self.parent.clone(),
899 }
900 }
901
902 pub fn add_inline_text(&mut self, text: &str) -> VastStatement {
903 let c_text = CString::new(text).unwrap();
904 let _locked = self.parent.lock().unwrap();
905 let inner =
906 unsafe { sys::xls_vast_statement_block_add_inline_text(self.inner, c_text.as_ptr()) };
907 VastStatement {
908 inner,
909 parent: self.parent.clone(),
910 }
911 }
912
913 pub fn add_cond(&mut self, cond: &Expr) -> Conditional {
914 let _locked = self.parent.lock().unwrap();
915 let inner =
916 unsafe { sys::xls_vast_statement_block_add_conditional(self.inner, cond.inner) };
917 Conditional {
918 inner,
919 parent: self.parent.clone(),
920 }
921 }
922
923 pub fn add_case(&mut self, selector: &Expr) -> CaseStatement {
924 let _locked = self.parent.lock().unwrap();
925 let inner = unsafe { sys::xls_vast_statement_block_add_case(self.inner, selector.inner) };
926 CaseStatement {
927 inner,
928 parent: self.parent.clone(),
929 }
930 }
931}
932
933impl Conditional {
934 pub fn then_block(&self) -> VastStatementBlock {
935 let _locked = self.parent.lock().unwrap();
936 let inner = unsafe { sys::xls_vast_conditional_get_then_block(self.inner) };
937 VastStatementBlock {
938 inner,
939 parent: self.parent.clone(),
940 }
941 }
942
943 pub fn add_else_if(&self, cond: &Expr) -> VastStatementBlock {
944 let _locked = self.parent.lock().unwrap();
945 let inner = unsafe { sys::xls_vast_conditional_add_else_if(self.inner, cond.inner) };
946 VastStatementBlock {
947 inner,
948 parent: self.parent.clone(),
949 }
950 }
951
952 pub fn add_else(&self) -> VastStatementBlock {
953 let _locked = self.parent.lock().unwrap();
954 let inner = unsafe { sys::xls_vast_conditional_add_else(self.inner) };
955 VastStatementBlock {
956 inner,
957 parent: self.parent.clone(),
958 }
959 }
960}
961
962impl CaseStatement {
963 pub fn add_item(&self, match_expr: &Expr) -> VastStatementBlock {
964 let _locked = self.parent.lock().unwrap();
965 let inner = unsafe { sys::xls_vast_case_statement_add_item(self.inner, match_expr.inner) };
966 VastStatementBlock {
967 inner,
968 parent: self.parent.clone(),
969 }
970 }
971
972 pub fn add_default(&self) -> VastStatementBlock {
973 let _locked = self.parent.lock().unwrap();
974 let inner = unsafe { sys::xls_vast_case_statement_add_default(self.inner) };
975 VastStatementBlock {
976 inner,
977 parent: self.parent.clone(),
978 }
979 }
980}
981
982impl GenerateLoop {
983 pub fn get_genvar(&self) -> LogicRef {
984 let _locked = self.parent.lock().unwrap();
985 let inner = unsafe { sys::xls_vast_generate_loop_get_genvar(self.inner) };
986 LogicRef {
987 inner,
988 parent: self.parent.clone(),
989 }
990 }
991
992 pub fn add_generate_loop(
993 &mut self,
994 genvar_name: &str,
995 init: &Expr,
996 limit: &Expr,
997 label: Option<&str>,
998 ) -> GenerateLoop {
999 let c_name = CString::new(genvar_name).unwrap();
1000 let c_label = CString::new(label.unwrap_or("")).unwrap();
1001 let _locked = self.parent.lock().unwrap();
1002 let inner = unsafe {
1003 sys::xls_vast_generate_loop_add_generate_loop(
1004 self.inner,
1005 c_name.as_ptr(),
1006 init.inner,
1007 limit.inner,
1008 c_label.as_ptr(),
1009 )
1010 };
1011 GenerateLoop {
1012 inner,
1013 parent: self.parent.clone(),
1014 }
1015 }
1016
1017 pub fn add_always_comb(&mut self) -> Result<VastAlwaysBase, XlsynthError> {
1018 let _locked = self.parent.lock().unwrap();
1019 let mut always_base_out: *mut sys::CVastAlwaysBase = std::ptr::null_mut();
1020 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
1021 let success = unsafe {
1022 sys::xls_vast_generate_loop_add_always_comb(
1023 self.inner,
1024 &mut always_base_out,
1025 &mut error_out,
1026 )
1027 };
1028 if success {
1029 Ok(VastAlwaysBase {
1030 inner: always_base_out,
1031 parent: self.parent.clone(),
1032 })
1033 } else {
1034 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
1035 }
1036 }
1037
1038 pub fn add_always_ff(
1039 &mut self,
1040 sensitivity_list: &[&Expr],
1041 ) -> Result<VastAlwaysBase, XlsynthError> {
1042 let _locked = self.parent.lock().unwrap();
1043 let mut expr_ptrs: Vec<*mut sys::CVastExpression> =
1044 sensitivity_list.iter().map(|e| e.inner).collect();
1045 let mut always_base_out: *mut sys::CVastAlwaysBase = std::ptr::null_mut();
1046 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
1047 let success = unsafe {
1048 sys::xls_vast_generate_loop_add_always_ff(
1049 self.inner,
1050 expr_ptrs.as_mut_ptr(),
1051 expr_ptrs.len(),
1052 &mut always_base_out,
1053 &mut error_out,
1054 )
1055 };
1056 if success {
1057 Ok(VastAlwaysBase {
1058 inner: always_base_out,
1059 parent: self.parent.clone(),
1060 })
1061 } else {
1062 Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
1063 }
1064 }
1065
1066 pub fn add_localparam(&mut self, name: &str, rhs: &Expr) -> LocalparamRef {
1067 let c_name = CString::new(name).unwrap();
1068 let _locked = self.parent.lock().unwrap();
1069 let inner = unsafe {
1070 sys::xls_vast_generate_loop_add_localparam(self.inner, c_name.as_ptr(), rhs.inner)
1071 };
1072 LocalparamRef {
1073 inner,
1074 parent: self.parent.clone(),
1075 }
1076 }
1077
1078 pub fn add_typed_localparam(&mut self, def: &Def, rhs: &Expr) -> LocalparamRef {
1079 let _locked = self.parent.lock().unwrap();
1080 let inner = unsafe {
1081 sys::xls_vast_generate_loop_add_localparam_with_def(self.inner, def.inner, rhs.inner)
1082 };
1083 LocalparamRef {
1084 inner,
1085 parent: self.parent.clone(),
1086 }
1087 }
1088
1089 pub fn add_continuous_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
1090 let _locked = self.parent.lock().unwrap();
1091 let inner = unsafe {
1092 sys::xls_vast_generate_loop_add_continuous_assignment(self.inner, lhs.inner, rhs.inner)
1093 };
1094 VastStatement {
1095 inner,
1096 parent: self.parent.clone(),
1097 }
1098 }
1099
1100 pub fn add_conditional(&mut self, cond: &Expr) -> Conditional {
1101 let _locked = self.parent.lock().unwrap();
1102 let inner = unsafe { sys::xls_vast_generate_loop_add_conditional(self.inner, cond.inner) };
1103 Conditional {
1104 inner,
1105 parent: self.parent.clone(),
1106 }
1107 }
1108
1109 pub fn add_blank_line(&mut self) {
1110 let _locked = self.parent.lock().unwrap();
1111 unsafe { sys::xls_vast_generate_loop_add_blank_line(self.inner) }
1112 }
1113
1114 pub fn add_comment(&mut self, comment: &Comment) {
1115 let _locked = self.parent.lock().unwrap();
1116 unsafe { sys::xls_vast_generate_loop_add_comment(self.inner, comment.inner) }
1117 }
1118
1119 pub fn add_instantiation(&mut self, inst: &Instantiation) {
1120 let _locked = self.parent.lock().unwrap();
1121 unsafe { sys::xls_vast_generate_loop_add_instantiation(self.inner, inst.inner) }
1122 }
1123
1124 pub fn add_inline_statement(&mut self, stmt: &InlineVerilogStatement) {
1125 let _locked = self.parent.lock().unwrap();
1126 unsafe { sys::xls_vast_generate_loop_add_inline_verilog_statement(self.inner, stmt.inner) }
1127 }
1128
1129 pub fn add_macro_statement(&mut self, macro_statement: &MacroStatement) {
1130 let _locked = self.parent.lock().unwrap();
1131 unsafe {
1132 sys::xls_vast_generate_loop_add_macro_statement(self.inner, macro_statement.inner)
1133 }
1134 }
1135}
1136
1137pub enum VastFileType {
1138 Verilog,
1139 SystemVerilog,
1140}
1141
1142pub struct VastFile {
1143 ptr: Arc<Mutex<VastFilePtr>>,
1144}
1145
1146impl VastFile {
1147 pub fn new(file_type: VastFileType) -> Self {
1149 let c_file_type = match file_type {
1150 VastFileType::Verilog => 0,
1151 VastFileType::SystemVerilog => 1,
1152 };
1153 Self {
1154 ptr: Arc::new(Mutex::new(VastFilePtr(unsafe {
1155 sys::xls_vast_make_verilog_file(c_file_type)
1156 }))),
1157 }
1158 }
1159
1160 pub fn add_include(&mut self, include: &str) {
1162 let c_include = CString::new(include).unwrap();
1163 let locked = self.ptr.lock().unwrap();
1164 unsafe { sys::xls_vast_verilog_file_add_include(locked.0, c_include.as_ptr()) }
1165 }
1166
1167 pub fn add_blank_line(&mut self, blank_line: BlankLine) {
1169 let locked = self.ptr.lock().unwrap();
1170 unsafe { sys::xls_vast_verilog_file_add_blank_line(locked.0, blank_line.inner) }
1171 }
1172
1173 pub fn add_comment_text(&mut self, text: &str) {
1175 let c_text = CString::new(text).unwrap();
1176 let locked = self.ptr.lock().unwrap();
1177 unsafe { sys::xls_vast_verilog_file_add_comment(locked.0, c_text.as_ptr()) }
1178 }
1179
1180 pub fn add_module(&mut self, name: &str) -> VastModule {
1181 let c_name = CString::new(name).unwrap();
1182 let locked = self.ptr.lock().unwrap();
1183 let module = unsafe { sys::xls_vast_verilog_file_add_module(locked.0, c_name.as_ptr()) };
1184 VastModule {
1185 inner: module,
1186 parent: self.ptr.clone(),
1187 }
1188 }
1189
1190 pub fn make_instantiation(
1206 &mut self,
1207 module_name: &str,
1208 instance_name: &str,
1209 parameter_port_names: &[&str],
1210 parameter_expressions: &[&Expr],
1211 connection_port_names: &[&str],
1212 connection_expressions: &[Option<&Expr>],
1213 ) -> Instantiation {
1214 let c_module_name = CString::new(module_name).unwrap();
1215 let c_instance_name = CString::new(instance_name).unwrap();
1216
1217 fn to_cstrings_and_ptrs(strings: &[&str]) -> (Vec<CString>, Vec<*const c_char>) {
1221 let cstrings: Vec<CString> =
1222 strings.iter().map(|&s| CString::new(s).unwrap()).collect();
1223 let ptrs = cstrings.iter().map(|s| s.as_ptr()).collect();
1224 (cstrings, ptrs)
1225 }
1226
1227 let (c_param_names, c_param_name_ptrs) = to_cstrings_and_ptrs(parameter_port_names);
1228 let (c_conn_names, c_conn_name_ptrs) = to_cstrings_and_ptrs(connection_port_names);
1229
1230 fn to_expr_ptrs(exprs: &[&Expr]) -> Vec<*const sys::CVastExpression> {
1231 exprs
1232 .iter()
1233 .map(|expr| expr.inner as *const sys::CVastExpression)
1234 .collect()
1235 }
1236
1237 fn to_opt_expr_ptrs(exprs: &[Option<&Expr>]) -> Vec<*const sys::CVastExpression> {
1238 exprs
1239 .iter()
1240 .map(|expr| {
1241 if let Some(expr) = expr {
1242 expr.inner as *const sys::CVastExpression
1243 } else {
1244 std::ptr::null()
1245 }
1246 })
1247 .collect()
1248 }
1249
1250 let c_param_expr_ptrs = to_expr_ptrs(parameter_expressions);
1251 let c_conn_expr_ptrs = to_opt_expr_ptrs(connection_expressions);
1252
1253 let locked = self.ptr.lock().unwrap();
1254
1255 let instantiation = unsafe {
1256 sys::xls_vast_verilog_file_make_instantiation(
1257 locked.0,
1258 c_module_name.as_ptr(),
1259 c_instance_name.as_ptr(),
1260 c_param_name_ptrs.as_ptr(),
1261 c_param_expr_ptrs.as_ptr(),
1262 c_param_expr_ptrs.len(),
1263 c_conn_name_ptrs.as_ptr(),
1264 c_conn_expr_ptrs.as_ptr(),
1265 c_conn_expr_ptrs.len(),
1266 )
1267 };
1268
1269 Instantiation {
1270 inner: instantiation,
1271 parent: self.ptr.clone(),
1272 }
1273 }
1274
1275 pub fn make_literal(
1282 &mut self,
1283 s: &str,
1284 fmt: &IrFormatPreference,
1285 ) -> Result<Expr, XlsynthError> {
1286 let v = xls_parse_typed_value(s).unwrap();
1287 let mut fmt = xls_format_preference_from_string(fmt.to_string()).unwrap();
1288
1289 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
1290 let mut literal_out: *mut sys::CVastLiteral = std::ptr::null_mut();
1291
1292 unsafe {
1293 let success = sys::xls_vast_verilog_file_make_literal(
1294 self.ptr.lock().unwrap().0,
1295 v.to_bits().unwrap().ptr,
1296 fmt,
1297 true,
1298 &mut error_out,
1299 &mut literal_out,
1300 );
1301
1302 if success {
1303 Ok(Expr {
1304 inner: sys::xls_vast_literal_as_expression(literal_out),
1305 parent: self.ptr.clone(),
1306 })
1307 } else {
1308 Err(XlsynthError(c_str_to_rust(error_out)))
1309 }
1310 }
1311 }
1312 pub fn make_plain_literal(&mut self, value: i32, fmt: &IrFormatPreference) -> Expr {
1313 let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
1314 let mut literal_out: *mut sys::CVastLiteral = std::ptr::null_mut();
1315 let literal = unsafe {
1316 sys::xls_vast_verilog_file_make_plain_literal(self.ptr.lock().unwrap().0, value)
1317 };
1318 Expr {
1319 inner: unsafe { sys::xls_vast_literal_as_expression(literal) },
1320 parent: self.ptr.clone(),
1321 }
1322 }
1323
1324 pub fn make_comment(&mut self, text: &str) -> Comment {
1325 let locked = self.ptr.lock().unwrap();
1326 let c_text = CString::new(text).unwrap();
1327 let inner = unsafe { sys::xls_vast_verilog_file_make_comment(locked.0, c_text.as_ptr()) };
1328 Comment {
1329 inner,
1330 parent: self.ptr.clone(),
1331 }
1332 }
1333
1334 pub fn make_scalar_type(&mut self) -> VastDataType {
1335 let locked = self.ptr.lock().unwrap();
1336 let data_type = unsafe { sys::xls_vast_verilog_file_make_scalar_type(locked.0) };
1337 VastDataType {
1338 inner: data_type,
1339 parent: self.ptr.clone(),
1340 }
1341 }
1342
1343 pub fn make_bit_vector_type(&mut self, bit_count: i64, is_signed: bool) -> VastDataType {
1344 let locked = self.ptr.lock().unwrap();
1345 let data_type = unsafe {
1346 sys::xls_vast_verilog_file_make_bit_vector_type(locked.0, bit_count, is_signed)
1347 };
1348 VastDataType {
1349 inner: data_type,
1350 parent: self.ptr.clone(),
1351 }
1352 }
1353
1354 pub fn make_bit_vector_type_expr(
1357 &mut self,
1358 width_expr: &Expr,
1359 is_signed: bool,
1360 ) -> VastDataType {
1361 let locked = self.ptr.lock().unwrap();
1362 let data_type = unsafe {
1363 sys::xls_vast_verilog_file_make_bit_vector_type_with_expression(
1364 locked.0,
1365 width_expr.inner,
1366 is_signed,
1367 )
1368 };
1369 VastDataType {
1370 inner: data_type,
1371 parent: self.ptr.clone(),
1372 }
1373 }
1374
1375 pub fn make_extern_type(&mut self, entity_name: &str) -> VastDataType {
1376 let locked = self.ptr.lock().unwrap();
1377 let c_entity_name = CString::new(entity_name).unwrap();
1378 let data_type = unsafe {
1379 sys::xls_vast_verilog_file_make_extern_type(locked.0, c_entity_name.as_ptr())
1380 };
1381 VastDataType {
1382 inner: data_type,
1383 parent: self.ptr.clone(),
1384 }
1385 }
1386
1387 pub fn make_extern_package_type(
1388 &mut self,
1389 package_name: &str,
1390 type_name: &str,
1391 ) -> VastDataType {
1392 let locked = self.ptr.lock().unwrap();
1393 let c_package_name = CString::new(package_name).unwrap();
1394 let c_type_name = CString::new(type_name).unwrap();
1395 let data_type = unsafe {
1396 sys::xls_vast_verilog_file_make_extern_package_type(
1397 locked.0,
1398 c_package_name.as_ptr(),
1399 c_type_name.as_ptr(),
1400 )
1401 };
1402 VastDataType {
1403 inner: data_type,
1404 parent: self.ptr.clone(),
1405 }
1406 }
1407
1408 pub fn make_integer_type(&mut self, is_signed: bool) -> VastDataType {
1409 let locked = self.ptr.lock().unwrap();
1410 let data_type =
1411 unsafe { sys::xls_vast_verilog_file_make_integer_type(locked.0, is_signed) };
1412 VastDataType {
1413 inner: data_type,
1414 parent: self.ptr.clone(),
1415 }
1416 }
1417
1418 pub fn make_int_type(&mut self, is_signed: bool) -> VastDataType {
1419 let locked = self.ptr.lock().unwrap();
1420 let data_type = unsafe { sys::xls_vast_verilog_file_make_int_type(locked.0, is_signed) };
1421 VastDataType {
1422 inner: data_type,
1423 parent: self.ptr.clone(),
1424 }
1425 }
1426
1427 pub fn make_packed_array_type(
1428 &mut self,
1429 element_type: VastDataType,
1430 dimensions: &[i64],
1431 ) -> VastDataType {
1432 let locked = self.ptr.lock().unwrap();
1433 let data_type = unsafe {
1434 sys::xls_vast_verilog_file_make_packed_array_type(
1435 locked.0,
1436 element_type.inner,
1437 dimensions.as_ptr(),
1438 dimensions.len(),
1439 )
1440 };
1441 VastDataType {
1442 inner: data_type,
1443 parent: self.ptr.clone(),
1444 }
1445 }
1446
1447 pub fn make_unpacked_array_type(
1448 &mut self,
1449 element_type: VastDataType,
1450 dimensions: &[i64],
1451 ) -> VastDataType {
1452 let locked = self.ptr.lock().unwrap();
1453 let data_type = unsafe {
1454 sys::xls_vast_verilog_file_make_unpacked_array_type(
1455 locked.0,
1456 element_type.inner,
1457 dimensions.as_ptr(),
1458 dimensions.len(),
1459 )
1460 };
1461 VastDataType {
1462 inner: data_type,
1463 parent: self.ptr.clone(),
1464 }
1465 }
1466
1467 pub fn make_slice(&mut self, indexable: &IndexableExpr, hi: i64, lo: i64) -> Slice {
1468 let locked = self.ptr.lock().unwrap();
1469 let inner =
1470 unsafe { sys::xls_vast_verilog_file_make_slice_i64(locked.0, indexable.inner, hi, lo) };
1471 Slice {
1472 inner,
1473 parent: self.ptr.clone(),
1474 }
1475 }
1476
1477 pub fn make_slice_expr(&mut self, indexable: &IndexableExpr, hi: &Expr, lo: &Expr) -> Slice {
1478 let locked = self.ptr.lock().unwrap();
1479 let inner = unsafe {
1480 sys::xls_vast_verilog_file_make_slice(locked.0, indexable.inner, hi.inner, lo.inner)
1481 };
1482 Slice {
1483 inner,
1484 parent: self.ptr.clone(),
1485 }
1486 }
1487
1488 pub fn make_index(&mut self, indexable: &IndexableExpr, index: i64) -> Index {
1489 let locked = self.ptr.lock().unwrap();
1490 let inner =
1491 unsafe { sys::xls_vast_verilog_file_make_index_i64(locked.0, indexable.inner, index) };
1492 Index {
1493 inner,
1494 parent: self.ptr.clone(),
1495 }
1496 }
1497
1498 pub fn make_index_expr(&mut self, indexable: &IndexableExpr, index: &Expr) -> Index {
1499 let locked = self.ptr.lock().unwrap();
1500 let inner = unsafe {
1501 sys::xls_vast_verilog_file_make_index(locked.0, indexable.inner, index.inner)
1502 };
1503 Index {
1504 inner,
1505 parent: self.ptr.clone(),
1506 }
1507 }
1508
1509 pub fn make_concat(&mut self, exprs: &[&Expr]) -> Expr {
1510 let locked = self.ptr.lock().unwrap();
1511 let mut expr_ptrs: Vec<*mut sys::CVastExpression> =
1512 exprs.iter().map(|expr| expr.inner).collect();
1513 let inner = unsafe {
1514 sys::xls_vast_verilog_file_make_concat(locked.0, expr_ptrs.as_mut_ptr(), exprs.len())
1515 };
1516 Expr {
1517 inner,
1518 parent: self.ptr.clone(),
1519 }
1520 }
1521
1522 pub fn make_replicated_concat(&mut self, replication: &Expr, elements: &[&Expr]) -> Expr {
1523 let locked = self.ptr.lock().unwrap();
1524 let mut elem_ptrs: Vec<*mut sys::CVastExpression> =
1525 elements.iter().map(|e| e.inner).collect();
1526 let concat_ptr = unsafe {
1527 sys::xls_vast_verilog_file_make_replicated_concat(
1528 locked.0,
1529 replication.inner,
1530 elem_ptrs.as_mut_ptr(),
1531 elem_ptrs.len(),
1532 )
1533 };
1534 let inner = unsafe { sys::xls_vast_concat_as_expression(concat_ptr) };
1535 Expr {
1536 inner,
1537 parent: self.ptr.clone(),
1538 }
1539 }
1540
1541 pub fn make_replicated_concat_i64(
1542 &mut self,
1543 replication_count: i64,
1544 elements: &[&Expr],
1545 ) -> Expr {
1546 let locked = self.ptr.lock().unwrap();
1547 let mut elem_ptrs: Vec<*mut sys::CVastExpression> =
1548 elements.iter().map(|e| e.inner).collect();
1549 let concat_ptr = unsafe {
1550 sys::xls_vast_verilog_file_make_replicated_concat_i64(
1551 locked.0,
1552 replication_count,
1553 elem_ptrs.as_mut_ptr(),
1554 elem_ptrs.len(),
1555 )
1556 };
1557 let inner = unsafe { sys::xls_vast_concat_as_expression(concat_ptr) };
1558 Expr {
1559 inner,
1560 parent: self.ptr.clone(),
1561 }
1562 }
1563
1564 pub fn make_array_assignment_pattern(&mut self, elements: &[&Expr]) -> Expr {
1565 let locked = self.ptr.lock().unwrap();
1566 let mut element_ptrs: Vec<*mut sys::CVastExpression> =
1567 elements.iter().map(|e| e.inner).collect();
1568 let inner = unsafe {
1569 sys::xls_vast_verilog_file_make_array_assignment_pattern(
1570 locked.0,
1571 element_ptrs.as_mut_ptr(),
1572 element_ptrs.len(),
1573 )
1574 };
1575 Expr {
1576 inner,
1577 parent: self.ptr.clone(),
1578 }
1579 }
1580
1581 pub fn make_macro_ref(&mut self, name: &str) -> MacroRef {
1582 let locked = self.ptr.lock().unwrap();
1583 let c_name = CString::new(name).unwrap();
1584 let inner = unsafe { sys::xls_vast_verilog_file_make_macro_ref(locked.0, c_name.as_ptr()) };
1585 MacroRef {
1586 inner,
1587 parent: self.ptr.clone(),
1588 }
1589 }
1590
1591 pub fn make_macro_ref_with_args(&mut self, name: &str, args: &[&Expr]) -> MacroRef {
1592 let locked = self.ptr.lock().unwrap();
1593 let c_name = CString::new(name).unwrap();
1594 let mut arg_ptrs: Vec<*mut sys::CVastExpression> = args.iter().map(|e| e.inner).collect();
1595 let inner = unsafe {
1596 sys::xls_vast_verilog_file_make_macro_ref_with_args(
1597 locked.0,
1598 c_name.as_ptr(),
1599 arg_ptrs.as_mut_ptr(),
1600 arg_ptrs.len(),
1601 )
1602 };
1603 MacroRef {
1604 inner,
1605 parent: self.ptr.clone(),
1606 }
1607 }
1608
1609 pub fn make_macro_statement(
1610 &mut self,
1611 macro_ref: &MacroRef,
1612 emit_semicolon: bool,
1613 ) -> MacroStatement {
1614 let locked = self.ptr.lock().unwrap();
1615 let inner = unsafe {
1616 sys::xls_vast_verilog_file_make_macro_statement(
1617 locked.0,
1618 macro_ref.inner,
1619 emit_semicolon,
1620 )
1621 };
1622 MacroStatement {
1623 inner,
1624 parent: self.ptr.clone(),
1625 }
1626 }
1627
1628 fn make_unary(&mut self, op: VastOperatorKind, expr: &Expr) -> Expr {
1629 let locked = self.ptr.lock().unwrap();
1630 let op_i32 = op as i32;
1631 let inner = unsafe { sys::xls_vast_verilog_file_make_unary(locked.0, expr.inner, op_i32) };
1632 Expr {
1633 inner,
1634 parent: self.ptr.clone(),
1635 }
1636 }
1637
1638 pub fn make_not(&mut self, expr: &Expr) -> Expr {
1639 self.make_unary(VastOperatorKind::BitwiseNot, expr)
1640 }
1641
1642 pub fn make_negate(&mut self, expr: &Expr) -> Expr {
1643 self.make_unary(VastOperatorKind::Negate, expr)
1644 }
1645
1646 pub fn make_logical_not(&mut self, expr: &Expr) -> Expr {
1647 self.make_unary(VastOperatorKind::LogicalNot, expr)
1648 }
1649
1650 pub fn make_and_reduce(&mut self, expr: &Expr) -> Expr {
1651 self.make_unary(VastOperatorKind::AndReduce, expr)
1652 }
1653
1654 pub fn make_or_reduce(&mut self, expr: &Expr) -> Expr {
1655 self.make_unary(VastOperatorKind::OrReduce, expr)
1656 }
1657
1658 pub fn make_xor_reduce(&mut self, expr: &Expr) -> Expr {
1659 self.make_unary(VastOperatorKind::XorReduce, expr)
1660 }
1661
1662 fn make_binary(&mut self, op: VastOperatorKind, lhs: &Expr, rhs: &Expr) -> Expr {
1667 let locked = self.ptr.lock().unwrap();
1668 let op_i32 = op as i32;
1669 let inner = unsafe {
1670 sys::xls_vast_verilog_file_make_binary(locked.0, lhs.inner, rhs.inner, op_i32)
1671 };
1672 Expr {
1673 inner,
1674 parent: self.ptr.clone(),
1675 }
1676 }
1677
1678 pub fn make_add(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1679 self.make_binary(VastOperatorKind::Add, lhs, rhs)
1680 }
1681
1682 pub fn make_sub(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1683 self.make_binary(VastOperatorKind::Sub, lhs, rhs)
1684 }
1685
1686 pub fn make_mul(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1687 self.make_binary(VastOperatorKind::Mul, lhs, rhs)
1688 }
1689
1690 pub fn make_div(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1691 self.make_binary(VastOperatorKind::Div, lhs, rhs)
1692 }
1693
1694 pub fn make_mod(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1695 self.make_binary(VastOperatorKind::Mod, lhs, rhs)
1696 }
1697
1698 pub fn make_power(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1699 self.make_binary(VastOperatorKind::Power, lhs, rhs)
1700 }
1701
1702 pub fn make_bitwise_and(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1703 self.make_binary(VastOperatorKind::BitwiseAnd, lhs, rhs)
1704 }
1705
1706 pub fn make_bitwise_or(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1707 self.make_binary(VastOperatorKind::BitwiseOr, lhs, rhs)
1708 }
1709
1710 pub fn make_bitwise_xor(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1711 self.make_binary(VastOperatorKind::BitwiseXor, lhs, rhs)
1712 }
1713
1714 pub fn make_bitwise_not(&mut self, expr: &Expr) -> Expr {
1715 self.make_unary(VastOperatorKind::BitwiseNot, expr)
1716 }
1717
1718 pub fn make_shll(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1719 self.make_binary(VastOperatorKind::Shll, lhs, rhs)
1720 }
1721
1722 pub fn make_shra(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1723 self.make_binary(VastOperatorKind::Shra, lhs, rhs)
1724 }
1725
1726 pub fn make_shrl(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1727 self.make_binary(VastOperatorKind::Shrl, lhs, rhs)
1728 }
1729
1730 pub fn make_ne(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1731 self.make_binary(VastOperatorKind::Ne, lhs, rhs)
1732 }
1733
1734 pub fn make_case_ne(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1735 self.make_binary(VastOperatorKind::CaseNe, lhs, rhs)
1736 }
1737
1738 pub fn make_eq(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1739 self.make_binary(VastOperatorKind::Eq, lhs, rhs)
1740 }
1741
1742 pub fn make_case_eq(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1743 self.make_binary(VastOperatorKind::CaseEq, lhs, rhs)
1744 }
1745
1746 pub fn make_ge(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1747 self.make_binary(VastOperatorKind::Ge, lhs, rhs)
1748 }
1749
1750 pub fn make_gt(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1751 self.make_binary(VastOperatorKind::Gt, lhs, rhs)
1752 }
1753
1754 pub fn make_le(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1755 self.make_binary(VastOperatorKind::Le, lhs, rhs)
1756 }
1757
1758 pub fn make_lt(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1759 self.make_binary(VastOperatorKind::Lt, lhs, rhs)
1760 }
1761
1762 pub fn make_logical_and(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1763 self.make_binary(VastOperatorKind::LogicalAnd, lhs, rhs)
1764 }
1765
1766 pub fn make_logical_or(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1767 self.make_binary(VastOperatorKind::LogicalOr, lhs, rhs)
1768 }
1769
1770 pub fn make_ne_x(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1771 self.make_binary(VastOperatorKind::NeX, lhs, rhs)
1772 }
1773
1774 pub fn make_eq_x(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
1775 self.make_binary(VastOperatorKind::EqX, lhs, rhs)
1776 }
1777
1778 pub fn make_ternary(&mut self, cond: &Expr, then_expr: &Expr, else_expr: &Expr) -> Expr {
1781 let locked = self.ptr.lock().unwrap();
1782 let inner = unsafe {
1783 sys::xls_vast_verilog_file_make_ternary(
1784 locked.0,
1785 cond.inner,
1786 then_expr.inner,
1787 else_expr.inner,
1788 )
1789 };
1790 Expr {
1791 inner,
1792 parent: self.ptr.clone(),
1793 }
1794 }
1795
1796 pub fn make_width_cast(&mut self, width: &Expr, value: &Expr) -> Expr {
1797 let locked = self.ptr.lock().unwrap();
1798 let inner = unsafe {
1799 sys::xls_vast_verilog_file_make_width_cast(locked.0, width.inner, value.inner)
1800 };
1801 Expr {
1802 inner,
1803 parent: self.ptr.clone(),
1804 }
1805 }
1806
1807 pub fn make_type_cast(&mut self, data_type: &VastDataType, value: &Expr) -> Expr {
1808 let locked = self.ptr.lock().unwrap();
1809 let inner = unsafe {
1810 sys::xls_vast_verilog_file_make_type_cast(locked.0, data_type.inner, value.inner)
1811 };
1812 Expr {
1813 inner,
1814 parent: self.ptr.clone(),
1815 }
1816 }
1817
1818 pub fn make_continuous_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> ContinuousAssignment {
1821 let locked = self.ptr.lock().unwrap();
1822 let inner = unsafe {
1823 sys::xls_vast_verilog_file_make_continuous_assignment(locked.0, lhs.inner, rhs.inner)
1824 };
1825 ContinuousAssignment {
1826 inner,
1827 parent: self.ptr.clone(),
1828 }
1829 }
1830
1831 pub fn make_pos_edge(&mut self, expr: &Expr) -> Expr {
1832 let locked = self.ptr.lock().unwrap();
1833 let inner = unsafe { sys::xls_vast_verilog_file_make_pos_edge(locked.0, expr.inner) };
1834 Expr {
1835 inner,
1836 parent: self.ptr.clone(),
1837 }
1838 }
1839
1840 pub fn make_nonblocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
1841 let locked = self.ptr.lock().unwrap();
1842 let inner = unsafe {
1843 sys::xls_vast_verilog_file_make_nonblocking_assignment(locked.0, lhs.inner, rhs.inner)
1844 };
1845 VastStatement {
1846 inner,
1847 parent: self.ptr.clone(),
1848 }
1849 }
1850
1851 pub fn make_blocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
1852 let locked = self.ptr.lock().unwrap();
1853 let inner = unsafe {
1854 sys::xls_vast_verilog_file_make_blocking_assignment(locked.0, lhs.inner, rhs.inner)
1855 };
1856 VastStatement {
1857 inner,
1858 parent: self.ptr.clone(),
1859 }
1860 }
1861
1862 pub fn make_blank_line(&mut self) -> BlankLine {
1863 let locked = self.ptr.lock().unwrap();
1864 let inner = unsafe { sys::xls_vast_verilog_file_make_blank_line(locked.0) };
1865 BlankLine {
1866 inner,
1867 parent: self.ptr.clone(),
1868 }
1869 }
1870
1871 pub fn make_inline_verilog_statement(&mut self, text: &str) -> InlineVerilogStatement {
1872 let c_text = CString::new(text).unwrap();
1873 let locked = self.ptr.lock().unwrap();
1874 let inner = unsafe {
1875 sys::xls_vast_verilog_file_make_inline_verilog_statement(locked.0, c_text.as_ptr())
1876 };
1877 InlineVerilogStatement {
1878 inner,
1879 parent: self.ptr.clone(),
1880 }
1881 }
1882
1883 pub fn make_unsized_one_literal(&mut self) -> Expr {
1885 let locked = self.ptr.lock().unwrap();
1886 let inner = unsafe { sys::xls_vast_verilog_file_make_unsized_one_literal(locked.0) };
1887 Expr {
1888 inner,
1889 parent: self.ptr.clone(),
1890 }
1891 }
1892
1893 pub fn make_unsized_zero_literal(&mut self) -> Expr {
1895 let locked = self.ptr.lock().unwrap();
1896 let inner = unsafe { sys::xls_vast_verilog_file_make_unsized_zero_literal(locked.0) };
1897 Expr {
1898 inner,
1899 parent: self.ptr.clone(),
1900 }
1901 }
1902
1903 pub fn make_unsized_x_literal(&mut self) -> Expr {
1905 let locked = self.ptr.lock().unwrap();
1906 let inner = unsafe { sys::xls_vast_verilog_file_make_unsized_x_literal(locked.0) };
1907 Expr {
1908 inner,
1909 parent: self.ptr.clone(),
1910 }
1911 }
1912
1913 pub fn make_def(&mut self, name: &str, kind: DataKind, ty: &VastDataType) -> Def {
1914 let c_name = CString::new(name).unwrap();
1915 let locked = self.ptr.lock().unwrap();
1916 let inner = unsafe {
1917 sys::xls_vast_verilog_file_make_def(locked.0, c_name.as_ptr(), kind.to_sys(), ty.inner)
1918 };
1919 Def {
1920 inner,
1921 parent: self.ptr.clone(),
1922 }
1923 }
1924
1925 pub fn emit(&self) -> String {
1926 let locked = self.ptr.lock().unwrap();
1927 let c_str = unsafe { sys::xls_vast_verilog_file_emit(locked.0) };
1928 unsafe { c_str_to_rust(c_str) }
1929 }
1930}
1931
1932impl ParameterRef {
1933 pub fn to_expr(&self) -> Expr {
1934 let _locked = self.parent.lock().unwrap();
1935 let inner = unsafe { sys::xls_vast_parameter_ref_as_expression(self.inner) };
1936 Expr {
1937 inner,
1938 parent: self.parent.clone(),
1939 }
1940 }
1941
1942 pub fn to_indexable_expr(&self) -> IndexableExpr {
1943 let _locked = self.parent.lock().unwrap();
1944 let inner = unsafe { sys::xls_vast_parameter_ref_as_indexable_expression(self.inner) };
1945 IndexableExpr {
1946 inner,
1947 parent: self.parent.clone(),
1948 }
1949 }
1950}
1951
1952impl MacroRef {
1953 pub fn to_expr(&self) -> Expr {
1954 let _locked = self.parent.lock().unwrap();
1955 let inner = unsafe { sys::xls_vast_macro_ref_as_expression(self.inner) };
1956 Expr {
1957 inner,
1958 parent: self.parent.clone(),
1959 }
1960 }
1961}