#![allow(unused)]
#![allow(clippy::arc_with_non_send_sync)]
use xlsynth_sys::{self as sys};
use std::{
ffi::CString,
os::raw::c_char,
sync::{Arc, Mutex},
};
use crate::{
c_str_to_rust, ir_value::IrFormatPreference, lib_support::xls_format_preference_from_string,
xls_parse_typed_value, XlsynthError,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ModulePortDirection {
Input,
Output,
}
pub struct ModulePort {
inner: *mut sys::CVastModulePort,
parent: Arc<Mutex<VastFilePtr>>, }
impl ModulePort {
pub fn direction(&self) -> ModulePortDirection {
let _locked = self.parent.lock().unwrap();
let dir = unsafe { sys::xls_vast_verilog_module_port_get_direction(self.inner) };
match dir {
x if x == sys::XLS_VAST_MODULE_PORT_DIRECTION_INPUT => ModulePortDirection::Input,
x if x == sys::XLS_VAST_MODULE_PORT_DIRECTION_OUTPUT => ModulePortDirection::Output,
_ => panic!("Invalid port direction: {}", dir),
}
}
pub fn name(&self) -> String {
let _locked = self.parent.lock().unwrap();
let def_ptr = unsafe { sys::xls_vast_verilog_module_port_get_def(self.inner) };
let c_str = unsafe { sys::xls_vast_def_get_name(def_ptr) };
unsafe { c_str_to_rust(c_str) }
}
pub fn data_type(&self) -> VastDataType {
let _locked = self.parent.lock().unwrap();
let def_ptr = unsafe { sys::xls_vast_verilog_module_port_get_def(self.inner) };
let dt_ptr = unsafe { sys::xls_vast_def_get_data_type(def_ptr) };
VastDataType {
inner: dt_ptr,
parent: self.parent.clone(),
}
}
pub fn width(&self) -> i64 {
self.data_type()
.flat_bit_count_as_int64()
.unwrap_or_default()
}
}
impl VastDataType {
pub fn width_as_int64(&self) -> Result<i64, XlsynthError> {
let _locked = self.parent.lock().unwrap();
let mut width_out: i64 = 0;
let mut error_out: *mut c_char = std::ptr::null_mut();
let success = unsafe {
sys::xls_vast_data_type_width_as_int64(self.inner, &mut width_out, &mut error_out)
};
if success {
Ok(width_out)
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
pub fn flat_bit_count_as_int64(&self) -> Result<i64, XlsynthError> {
let _locked = self.parent.lock().unwrap();
let mut count_out: i64 = 0;
let mut error_out: *mut c_char = std::ptr::null_mut();
let success = unsafe {
sys::xls_vast_data_type_flat_bit_count_as_int64(
self.inner,
&mut count_out,
&mut error_out,
)
};
if success {
Ok(count_out)
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
pub fn width_expr(&self) -> Option<Expr> {
let _locked = self.parent.lock().unwrap();
let expr_ptr = unsafe { sys::xls_vast_data_type_width(self.inner) };
if expr_ptr.is_null() {
None
} else {
Some(Expr {
inner: expr_ptr,
parent: self.parent.clone(),
})
}
}
pub fn is_signed(&self) -> bool {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_data_type_is_signed(self.inner) }
}
}
impl VastModule {
pub fn ports(&self) -> Vec<ModulePort> {
let _locked = self.parent.lock().unwrap();
let mut count: usize = 0;
let ports_ptr = unsafe { sys::xls_vast_verilog_module_get_ports(self.inner, &mut count) };
if ports_ptr.is_null() || count == 0 {
return Vec::new();
}
let slice = unsafe { std::slice::from_raw_parts(ports_ptr, count) };
let result = slice
.iter()
.map(|&ptr| ModulePort {
inner: ptr,
parent: self.parent.clone(),
})
.collect::<Vec<_>>();
unsafe { sys::xls_vast_verilog_module_free_ports(ports_ptr, count) };
result
}
pub fn input_ports(&self) -> Vec<ModulePort> {
self.ports()
.into_iter()
.filter(|p| p.direction() == ModulePortDirection::Input)
.collect()
}
pub fn output_ports(&self) -> Vec<ModulePort> {
self.ports()
.into_iter()
.filter(|p| p.direction() == ModulePortDirection::Output)
.collect()
}
}
struct VastFilePtr(pub *mut sys::CVastFile);
enum VastOperatorKind {
Negate = 0,
BitwiseNot = 1,
LogicalNot = 2,
AndReduce = 3,
OrReduce = 4,
XorReduce = 5,
Add = 6,
LogicalAnd = 7,
BitwiseAnd = 8,
Ne = 9,
CaseNe = 10,
Eq = 11,
CaseEq = 12,
Ge = 13,
Gt = 14,
Le = 15,
Lt = 16,
Div = 17,
Mod = 18,
Mul = 19,
Power = 20,
BitwiseOr = 21,
LogicalOr = 22,
BitwiseXor = 23,
Shll = 24,
Shra = 25,
Shrl = 26,
Sub = 27,
NeX = 28,
EqX = 29,
}
impl Drop for VastFilePtr {
fn drop(&mut self) {
unsafe { sys::xls_vast_verilog_file_free(self.0) }
}
}
#[derive(Clone)]
pub struct VastDataType {
inner: *mut sys::CVastDataType,
parent: Arc<Mutex<VastFilePtr>>,
}
#[derive(Clone)]
pub struct LogicRef {
inner: *mut sys::CVastLogicRef,
parent: Arc<Mutex<VastFilePtr>>,
}
impl LogicRef {
pub fn name(&self) -> String {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_logic_ref_get_name(self.inner) };
unsafe { c_str_to_rust(inner) }
}
pub fn to_expr(&self) -> Expr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_logic_ref_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
pub fn to_indexable_expr(&self) -> IndexableExpr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_logic_ref_as_indexable_expression(self.inner) };
IndexableExpr {
inner,
parent: self.parent.clone(),
}
}
}
#[derive(Clone)]
pub struct Expr {
inner: *mut sys::CVastExpression,
parent: Arc<Mutex<VastFilePtr>>,
}
impl Expr {
pub fn emit(&self) -> String {
let _locked = self.parent.lock().unwrap();
let c_str = unsafe { sys::xls_vast_expression_emit(self.inner) };
unsafe { c_str_to_rust(c_str) }
}
}
#[derive(Clone)]
pub struct IndexableExpr {
inner: *mut sys::CVastIndexableExpression,
parent: Arc<Mutex<VastFilePtr>>,
}
impl IndexableExpr {
pub fn to_expr(&self) -> Expr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_indexable_expression_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
}
pub struct VastModule {
inner: *mut sys::CVastModule,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct Slice {
inner: *mut sys::CVastSlice,
parent: Arc<Mutex<VastFilePtr>>,
}
impl Slice {
pub fn to_expr(&self) -> Expr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_slice_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
}
pub struct Index {
inner: *mut sys::CVastIndex,
parent: Arc<Mutex<VastFilePtr>>,
}
impl Index {
pub fn to_expr(&self) -> Expr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_index_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
pub fn to_indexable_expr(&self) -> IndexableExpr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_index_as_indexable_expression(self.inner) };
IndexableExpr {
inner,
parent: self.parent.clone(),
}
}
}
pub struct Instantiation {
inner: *mut sys::CVastInstantiation,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct BlankLine {
inner: *mut sys::CVastBlankLine,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct InlineVerilogStatement {
inner: *mut sys::CVastInlineVerilogStatement,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct Comment {
inner: *mut sys::CVastComment,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct MacroRef {
inner: *mut sys::CVastMacroRef,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct MacroStatement {
inner: *mut sys::CVastMacroStatement,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct ContinuousAssignment {
inner: *mut sys::CVastContinuousAssignment,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct VastAlwaysBase {
inner: *mut sys::CVastAlwaysBase,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct VastStatementBlock {
inner: *mut sys::CVastStatementBlock,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct VastStatement {
inner: *mut sys::CVastStatement,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct Conditional {
inner: *mut sys::CVastConditional,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct CaseStatement {
inner: *mut sys::CVastCaseStatement,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct GenerateLoop {
inner: *mut sys::CVastGenerateLoop,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct ParameterRef {
inner: *mut sys::CVastParameterRef,
parent: Arc<Mutex<VastFilePtr>>,
}
pub struct LocalparamRef {
inner: *mut sys::CVastLocalparamRef,
parent: Arc<Mutex<VastFilePtr>>,
}
impl LocalparamRef {
pub fn to_expr(&self) -> Expr {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_localparam_ref_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
}
pub struct Def {
inner: *mut sys::CVastDef,
parent: Arc<Mutex<VastFilePtr>>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DataKind {
Reg,
Wire,
Logic,
Integer,
Int,
User,
UntypedEnum,
Genvar,
}
impl DataKind {
fn to_sys(self) -> i32 {
match self {
DataKind::Reg => sys::XLS_VAST_DATA_KIND_REG,
DataKind::Wire => sys::XLS_VAST_DATA_KIND_WIRE,
DataKind::Logic => sys::XLS_VAST_DATA_KIND_LOGIC,
DataKind::Integer => sys::XLS_VAST_DATA_KIND_INTEGER,
DataKind::Int => sys::XLS_VAST_DATA_KIND_INT,
DataKind::User => sys::XLS_VAST_DATA_KIND_USER,
DataKind::UntypedEnum => sys::XLS_VAST_DATA_KIND_UNTYPED_ENUM,
DataKind::Genvar => sys::XLS_VAST_DATA_KIND_GENVAR,
}
}
}
pub enum AlwaysKind {
AlwaysFF,
AlwaysAt,
AlwaysComb,
}
impl VastModule {
pub fn name(&self) -> String {
let locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_module_get_name(self.inner) };
unsafe { c_str_to_rust(inner) }
}
pub fn add_parameter_port(&mut self, name: &str, value: &Expr) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_parameter_port(
self.inner,
c_name.as_ptr(),
value.inner,
)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_typed_parameter_port(
&mut self,
name: &str,
data_type: &VastDataType,
value: &Expr,
) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_typed_parameter_port(
self.inner,
c_name.as_ptr(),
data_type.inner,
value.inner,
)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_input(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_input(self.inner, c_name.as_ptr(), data_type.inner)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_output(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_output(self.inner, c_name.as_ptr(), data_type.inner)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_inout(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_inout(self.inner, c_name.as_ptr(), data_type.inner)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_logic_input(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_logic_input(
self.inner,
c_name.as_ptr(),
data_type.inner,
)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_logic_output(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_logic_output(
self.inner,
c_name.as_ptr(),
data_type.inner,
)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_wire(&mut self, name: &str, data_type: &VastDataType) -> LogicRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let c_logic_ref = unsafe {
sys::xls_vast_verilog_module_add_wire(self.inner, c_name.as_ptr(), data_type.inner)
};
LogicRef {
inner: c_logic_ref,
parent: self.parent.clone(),
}
}
pub fn add_generate_loop(
&mut self,
genvar_name: &str,
init: &Expr,
limit: &Expr,
label: Option<&str>,
) -> GenerateLoop {
let c_name = CString::new(genvar_name).unwrap();
let c_label =
CString::new(label.unwrap_or("")).expect("label should not contain NUL characters");
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_module_add_generate_loop(
self.inner,
c_name.as_ptr(),
init.inner,
limit.inner,
c_label.as_ptr(),
)
};
GenerateLoop {
inner,
parent: self.parent.clone(),
}
}
pub fn add_member_instantiation(&mut self, instantiation: Instantiation) {
let _locked = self.parent.lock().unwrap();
unsafe {
sys::xls_vast_verilog_module_add_member_instantiation(self.inner, instantiation.inner)
}
}
pub fn add_member_continuous_assignment(&mut self, assignment: ContinuousAssignment) {
let _locked = self.parent.lock().unwrap();
unsafe {
sys::xls_vast_verilog_module_add_member_continuous_assignment(
self.inner,
assignment.inner,
)
}
}
pub fn add_member_blank_line(&mut self, blank: BlankLine) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_verilog_module_add_member_blank_line(self.inner, blank.inner) }
}
pub fn add_member_comment(&mut self, comment: Comment) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_verilog_module_add_member_comment(self.inner, comment.inner) }
}
pub fn add_member_inline_statement(&mut self, stmt: InlineVerilogStatement) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_verilog_module_add_member_inline_statement(self.inner, stmt.inner) }
}
pub fn add_member_macro_statement(&mut self, stmt: MacroStatement) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_verilog_module_add_member_macro_statement(self.inner, stmt.inner) }
}
pub fn add_conditional(&mut self, cond: &Expr) -> Conditional {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_module_add_conditional(self.inner, cond.inner) };
Conditional {
inner,
parent: self.parent.clone(),
}
}
pub fn add_reg(
&mut self,
name: &str,
data_type: &VastDataType,
) -> Result<LogicRef, XlsynthError> {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let mut reg_ref_out: *mut sys::CVastLogicRef = std::ptr::null_mut();
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let success = unsafe {
sys::xls_vast_verilog_module_add_reg(
self.inner,
c_name.as_ptr(),
data_type.inner,
&mut reg_ref_out,
&mut error_out,
)
};
if success {
Ok(LogicRef {
inner: reg_ref_out,
parent: self.parent.clone(),
})
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
pub fn add_logic(
&mut self,
name: &str,
data_type: &VastDataType,
) -> Result<LogicRef, XlsynthError> {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let mut reg_ref_out: *mut sys::CVastLogicRef = std::ptr::null_mut();
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let success = unsafe {
sys::xls_vast_verilog_module_add_logic(
self.inner,
c_name.as_ptr(),
data_type.inner,
&mut reg_ref_out,
&mut error_out,
)
};
if success {
Ok(LogicRef {
inner: reg_ref_out,
parent: self.parent.clone(),
})
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
fn add_always_block(
&mut self,
sensitivity_list: &[&Expr],
always_kind: AlwaysKind,
) -> Result<VastAlwaysBase, XlsynthError> {
let _locked = self.parent.lock().unwrap();
let mut expr_ptrs: Vec<*mut sys::CVastExpression> =
sensitivity_list.iter().map(|expr| expr.inner).collect();
let mut always_base_out: *mut sys::CVastAlwaysBase = std::ptr::null_mut();
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let success = unsafe {
match always_kind {
AlwaysKind::AlwaysFF => sys::xls_vast_verilog_module_add_always_ff(
self.inner,
expr_ptrs.as_mut_ptr(),
expr_ptrs.len(),
&mut always_base_out,
&mut error_out,
),
AlwaysKind::AlwaysAt => sys::xls_vast_verilog_module_add_always_at(
self.inner,
expr_ptrs.as_mut_ptr(),
expr_ptrs.len(),
&mut always_base_out,
&mut error_out,
),
AlwaysKind::AlwaysComb => sys::xls_vast_verilog_module_add_always_comb(
self.inner,
&mut always_base_out,
&mut error_out,
),
}
};
if success {
Ok(VastAlwaysBase {
inner: always_base_out,
parent: self.parent.clone(),
})
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
pub fn add_always_ff(
&mut self,
sensitivity_list: &[&Expr],
) -> Result<VastAlwaysBase, XlsynthError> {
self.add_always_block(sensitivity_list, AlwaysKind::AlwaysFF)
}
pub fn add_always_at(
&mut self,
sensitivity_list: &[&Expr],
) -> Result<VastAlwaysBase, XlsynthError> {
self.add_always_block(sensitivity_list, AlwaysKind::AlwaysAt)
}
pub fn add_always_comb(&mut self) -> Result<VastAlwaysBase, XlsynthError> {
self.add_always_block(&[], AlwaysKind::AlwaysComb)
}
pub fn add_parameter(&mut self, name: &str, rhs: &Expr) -> ParameterRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_module_add_parameter(self.inner, c_name.as_ptr(), rhs.inner)
};
ParameterRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_parameter_with_def(&mut self, def: &Def, rhs: &Expr) -> ParameterRef {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_module_add_parameter_with_def(self.inner, def.inner, rhs.inner)
};
ParameterRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_localparam(&mut self, name: &str, rhs: &Expr) -> LocalparamRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_module_add_localparam(self.inner, c_name.as_ptr(), rhs.inner)
};
LocalparamRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_typed_localparam(&mut self, def: &Def, rhs: &Expr) -> LocalparamRef {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_module_add_localparam_with_def(self.inner, def.inner, rhs.inner)
};
LocalparamRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_int_localparam(&mut self, name: &str, rhs: &Expr) -> LocalparamRef {
let c_name = CString::new(name).unwrap();
let locked = self.parent.lock().unwrap();
let int_def =
unsafe { sys::xls_vast_verilog_file_make_int_def(locked.0, c_name.as_ptr(), true) };
let inner = unsafe {
sys::xls_vast_verilog_module_add_localparam_with_def(self.inner, int_def, rhs.inner)
};
LocalparamRef {
inner,
parent: self.parent.clone(),
}
}
}
impl VastAlwaysBase {
pub fn get_statement_block(&self) -> VastStatementBlock {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_always_base_get_statement_block(self.inner) };
VastStatementBlock {
inner,
parent: self.parent.clone(),
}
}
}
impl VastStatementBlock {
pub fn add_blocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_statement_block_add_blocking_assignment(self.inner, lhs.inner, rhs.inner)
};
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_continuous_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_statement_block_add_continuous_assignment(
self.inner, lhs.inner, rhs.inner,
)
};
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_nonblocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_statement_block_add_nonblocking_assignment(
self.inner, lhs.inner, rhs.inner,
)
};
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_comment_text(&mut self, text: &str) -> VastStatement {
let c_text = CString::new(text).unwrap();
let _locked = self.parent.lock().unwrap();
let inner =
unsafe { sys::xls_vast_statement_block_add_comment_text(self.inner, c_text.as_ptr()) };
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_blank_line(&mut self) -> VastStatement {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_statement_block_add_blank_line(self.inner) };
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_inline_text(&mut self, text: &str) -> VastStatement {
let c_text = CString::new(text).unwrap();
let _locked = self.parent.lock().unwrap();
let inner =
unsafe { sys::xls_vast_statement_block_add_inline_text(self.inner, c_text.as_ptr()) };
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_cond(&mut self, cond: &Expr) -> Conditional {
let _locked = self.parent.lock().unwrap();
let inner =
unsafe { sys::xls_vast_statement_block_add_conditional(self.inner, cond.inner) };
Conditional {
inner,
parent: self.parent.clone(),
}
}
pub fn add_case(&mut self, selector: &Expr) -> CaseStatement {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_statement_block_add_case(self.inner, selector.inner) };
CaseStatement {
inner,
parent: self.parent.clone(),
}
}
}
impl Conditional {
pub fn then_block(&self) -> VastStatementBlock {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_conditional_get_then_block(self.inner) };
VastStatementBlock {
inner,
parent: self.parent.clone(),
}
}
pub fn add_else_if(&self, cond: &Expr) -> VastStatementBlock {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_conditional_add_else_if(self.inner, cond.inner) };
VastStatementBlock {
inner,
parent: self.parent.clone(),
}
}
pub fn add_else(&self) -> VastStatementBlock {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_conditional_add_else(self.inner) };
VastStatementBlock {
inner,
parent: self.parent.clone(),
}
}
}
impl CaseStatement {
pub fn add_item(&self, match_expr: &Expr) -> VastStatementBlock {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_case_statement_add_item(self.inner, match_expr.inner) };
VastStatementBlock {
inner,
parent: self.parent.clone(),
}
}
pub fn add_default(&self) -> VastStatementBlock {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_case_statement_add_default(self.inner) };
VastStatementBlock {
inner,
parent: self.parent.clone(),
}
}
}
impl GenerateLoop {
pub fn get_genvar(&self) -> LogicRef {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_generate_loop_get_genvar(self.inner) };
LogicRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_generate_loop(
&mut self,
genvar_name: &str,
init: &Expr,
limit: &Expr,
label: Option<&str>,
) -> GenerateLoop {
let c_name = CString::new(genvar_name).unwrap();
let c_label = CString::new(label.unwrap_or("")).unwrap();
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_generate_loop_add_generate_loop(
self.inner,
c_name.as_ptr(),
init.inner,
limit.inner,
c_label.as_ptr(),
)
};
GenerateLoop {
inner,
parent: self.parent.clone(),
}
}
pub fn add_always_comb(&mut self) -> Result<VastAlwaysBase, XlsynthError> {
let _locked = self.parent.lock().unwrap();
let mut always_base_out: *mut sys::CVastAlwaysBase = std::ptr::null_mut();
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let success = unsafe {
sys::xls_vast_generate_loop_add_always_comb(
self.inner,
&mut always_base_out,
&mut error_out,
)
};
if success {
Ok(VastAlwaysBase {
inner: always_base_out,
parent: self.parent.clone(),
})
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
pub fn add_always_ff(
&mut self,
sensitivity_list: &[&Expr],
) -> Result<VastAlwaysBase, XlsynthError> {
let _locked = self.parent.lock().unwrap();
let mut expr_ptrs: Vec<*mut sys::CVastExpression> =
sensitivity_list.iter().map(|e| e.inner).collect();
let mut always_base_out: *mut sys::CVastAlwaysBase = std::ptr::null_mut();
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let success = unsafe {
sys::xls_vast_generate_loop_add_always_ff(
self.inner,
expr_ptrs.as_mut_ptr(),
expr_ptrs.len(),
&mut always_base_out,
&mut error_out,
)
};
if success {
Ok(VastAlwaysBase {
inner: always_base_out,
parent: self.parent.clone(),
})
} else {
Err(XlsynthError(unsafe { c_str_to_rust(error_out) }))
}
}
pub fn add_localparam(&mut self, name: &str, rhs: &Expr) -> LocalparamRef {
let c_name = CString::new(name).unwrap();
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_generate_loop_add_localparam(self.inner, c_name.as_ptr(), rhs.inner)
};
LocalparamRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_typed_localparam(&mut self, def: &Def, rhs: &Expr) -> LocalparamRef {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_generate_loop_add_localparam_with_def(self.inner, def.inner, rhs.inner)
};
LocalparamRef {
inner,
parent: self.parent.clone(),
}
}
pub fn add_continuous_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
let _locked = self.parent.lock().unwrap();
let inner = unsafe {
sys::xls_vast_generate_loop_add_continuous_assignment(self.inner, lhs.inner, rhs.inner)
};
VastStatement {
inner,
parent: self.parent.clone(),
}
}
pub fn add_conditional(&mut self, cond: &Expr) -> Conditional {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_generate_loop_add_conditional(self.inner, cond.inner) };
Conditional {
inner,
parent: self.parent.clone(),
}
}
pub fn add_blank_line(&mut self) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_generate_loop_add_blank_line(self.inner) }
}
pub fn add_comment(&mut self, comment: &Comment) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_generate_loop_add_comment(self.inner, comment.inner) }
}
pub fn add_instantiation(&mut self, inst: &Instantiation) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_generate_loop_add_instantiation(self.inner, inst.inner) }
}
pub fn add_inline_statement(&mut self, stmt: &InlineVerilogStatement) {
let _locked = self.parent.lock().unwrap();
unsafe { sys::xls_vast_generate_loop_add_inline_verilog_statement(self.inner, stmt.inner) }
}
pub fn add_macro_statement(&mut self, macro_statement: &MacroStatement) {
let _locked = self.parent.lock().unwrap();
unsafe {
sys::xls_vast_generate_loop_add_macro_statement(self.inner, macro_statement.inner)
}
}
}
pub enum VastFileType {
Verilog,
SystemVerilog,
}
pub struct VastFile {
ptr: Arc<Mutex<VastFilePtr>>,
}
impl VastFile {
pub fn new(file_type: VastFileType) -> Self {
let c_file_type = match file_type {
VastFileType::Verilog => 0,
VastFileType::SystemVerilog => 1,
};
Self {
ptr: Arc::new(Mutex::new(VastFilePtr(unsafe {
sys::xls_vast_make_verilog_file(c_file_type)
}))),
}
}
pub fn add_include(&mut self, include: &str) {
let c_include = CString::new(include).unwrap();
let locked = self.ptr.lock().unwrap();
unsafe { sys::xls_vast_verilog_file_add_include(locked.0, c_include.as_ptr()) }
}
pub fn add_blank_line(&mut self, blank_line: BlankLine) {
let locked = self.ptr.lock().unwrap();
unsafe { sys::xls_vast_verilog_file_add_blank_line(locked.0, blank_line.inner) }
}
pub fn add_comment_text(&mut self, text: &str) {
let c_text = CString::new(text).unwrap();
let locked = self.ptr.lock().unwrap();
unsafe { sys::xls_vast_verilog_file_add_comment(locked.0, c_text.as_ptr()) }
}
pub fn add_module(&mut self, name: &str) -> VastModule {
let c_name = CString::new(name).unwrap();
let locked = self.ptr.lock().unwrap();
let module = unsafe { sys::xls_vast_verilog_file_add_module(locked.0, c_name.as_ptr()) };
VastModule {
inner: module,
parent: self.ptr.clone(),
}
}
pub fn make_instantiation(
&mut self,
module_name: &str,
instance_name: &str,
parameter_port_names: &[&str],
parameter_expressions: &[&Expr],
connection_port_names: &[&str],
connection_expressions: &[Option<&Expr>],
) -> Instantiation {
let c_module_name = CString::new(module_name).unwrap();
let c_instance_name = CString::new(instance_name).unwrap();
fn to_cstrings_and_ptrs(strings: &[&str]) -> (Vec<CString>, Vec<*const c_char>) {
let cstrings: Vec<CString> =
strings.iter().map(|&s| CString::new(s).unwrap()).collect();
let ptrs = cstrings.iter().map(|s| s.as_ptr()).collect();
(cstrings, ptrs)
}
let (c_param_names, c_param_name_ptrs) = to_cstrings_and_ptrs(parameter_port_names);
let (c_conn_names, c_conn_name_ptrs) = to_cstrings_and_ptrs(connection_port_names);
fn to_expr_ptrs(exprs: &[&Expr]) -> Vec<*const sys::CVastExpression> {
exprs
.iter()
.map(|expr| expr.inner as *const sys::CVastExpression)
.collect()
}
fn to_opt_expr_ptrs(exprs: &[Option<&Expr>]) -> Vec<*const sys::CVastExpression> {
exprs
.iter()
.map(|expr| {
if let Some(expr) = expr {
expr.inner as *const sys::CVastExpression
} else {
std::ptr::null()
}
})
.collect()
}
let c_param_expr_ptrs = to_expr_ptrs(parameter_expressions);
let c_conn_expr_ptrs = to_opt_expr_ptrs(connection_expressions);
let locked = self.ptr.lock().unwrap();
let instantiation = unsafe {
sys::xls_vast_verilog_file_make_instantiation(
locked.0,
c_module_name.as_ptr(),
c_instance_name.as_ptr(),
c_param_name_ptrs.as_ptr(),
c_param_expr_ptrs.as_ptr(),
c_param_expr_ptrs.len(),
c_conn_name_ptrs.as_ptr(),
c_conn_expr_ptrs.as_ptr(),
c_conn_expr_ptrs.len(),
)
};
Instantiation {
inner: instantiation,
parent: self.ptr.clone(),
}
}
pub fn make_literal(
&mut self,
s: &str,
fmt: &IrFormatPreference,
) -> Result<Expr, XlsynthError> {
let v = xls_parse_typed_value(s).unwrap();
let mut fmt = xls_format_preference_from_string(fmt.to_string()).unwrap();
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let mut literal_out: *mut sys::CVastLiteral = std::ptr::null_mut();
unsafe {
let success = sys::xls_vast_verilog_file_make_literal(
self.ptr.lock().unwrap().0,
v.to_bits().unwrap().ptr,
fmt,
true,
&mut error_out,
&mut literal_out,
);
if success {
Ok(Expr {
inner: sys::xls_vast_literal_as_expression(literal_out),
parent: self.ptr.clone(),
})
} else {
Err(XlsynthError(c_str_to_rust(error_out)))
}
}
}
pub fn make_plain_literal(&mut self, value: i32, fmt: &IrFormatPreference) -> Expr {
let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut();
let mut literal_out: *mut sys::CVastLiteral = std::ptr::null_mut();
let literal = unsafe {
sys::xls_vast_verilog_file_make_plain_literal(self.ptr.lock().unwrap().0, value)
};
Expr {
inner: unsafe { sys::xls_vast_literal_as_expression(literal) },
parent: self.ptr.clone(),
}
}
pub fn make_comment(&mut self, text: &str) -> Comment {
let locked = self.ptr.lock().unwrap();
let c_text = CString::new(text).unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_comment(locked.0, c_text.as_ptr()) };
Comment {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_scalar_type(&mut self) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type = unsafe { sys::xls_vast_verilog_file_make_scalar_type(locked.0) };
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_bit_vector_type(&mut self, bit_count: i64, is_signed: bool) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type = unsafe {
sys::xls_vast_verilog_file_make_bit_vector_type(locked.0, bit_count, is_signed)
};
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_bit_vector_type_expr(
&mut self,
width_expr: &Expr,
is_signed: bool,
) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type = unsafe {
sys::xls_vast_verilog_file_make_bit_vector_type_with_expression(
locked.0,
width_expr.inner,
is_signed,
)
};
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_extern_type(&mut self, entity_name: &str) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let c_entity_name = CString::new(entity_name).unwrap();
let data_type = unsafe {
sys::xls_vast_verilog_file_make_extern_type(locked.0, c_entity_name.as_ptr())
};
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_extern_package_type(
&mut self,
package_name: &str,
type_name: &str,
) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let c_package_name = CString::new(package_name).unwrap();
let c_type_name = CString::new(type_name).unwrap();
let data_type = unsafe {
sys::xls_vast_verilog_file_make_extern_package_type(
locked.0,
c_package_name.as_ptr(),
c_type_name.as_ptr(),
)
};
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_integer_type(&mut self, is_signed: bool) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type =
unsafe { sys::xls_vast_verilog_file_make_integer_type(locked.0, is_signed) };
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_int_type(&mut self, is_signed: bool) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type = unsafe { sys::xls_vast_verilog_file_make_int_type(locked.0, is_signed) };
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_packed_array_type(
&mut self,
element_type: VastDataType,
dimensions: &[i64],
) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type = unsafe {
sys::xls_vast_verilog_file_make_packed_array_type(
locked.0,
element_type.inner,
dimensions.as_ptr(),
dimensions.len(),
)
};
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_unpacked_array_type(
&mut self,
element_type: VastDataType,
dimensions: &[i64],
) -> VastDataType {
let locked = self.ptr.lock().unwrap();
let data_type = unsafe {
sys::xls_vast_verilog_file_make_unpacked_array_type(
locked.0,
element_type.inner,
dimensions.as_ptr(),
dimensions.len(),
)
};
VastDataType {
inner: data_type,
parent: self.ptr.clone(),
}
}
pub fn make_slice(&mut self, indexable: &IndexableExpr, hi: i64, lo: i64) -> Slice {
let locked = self.ptr.lock().unwrap();
let inner =
unsafe { sys::xls_vast_verilog_file_make_slice_i64(locked.0, indexable.inner, hi, lo) };
Slice {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_slice_expr(&mut self, indexable: &IndexableExpr, hi: &Expr, lo: &Expr) -> Slice {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_slice(locked.0, indexable.inner, hi.inner, lo.inner)
};
Slice {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_index(&mut self, indexable: &IndexableExpr, index: i64) -> Index {
let locked = self.ptr.lock().unwrap();
let inner =
unsafe { sys::xls_vast_verilog_file_make_index_i64(locked.0, indexable.inner, index) };
Index {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_index_expr(&mut self, indexable: &IndexableExpr, index: &Expr) -> Index {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_index(locked.0, indexable.inner, index.inner)
};
Index {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_concat(&mut self, exprs: &[&Expr]) -> Expr {
let locked = self.ptr.lock().unwrap();
let mut expr_ptrs: Vec<*mut sys::CVastExpression> =
exprs.iter().map(|expr| expr.inner).collect();
let inner = unsafe {
sys::xls_vast_verilog_file_make_concat(locked.0, expr_ptrs.as_mut_ptr(), exprs.len())
};
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_replicated_concat(&mut self, replication: &Expr, elements: &[&Expr]) -> Expr {
let locked = self.ptr.lock().unwrap();
let mut elem_ptrs: Vec<*mut sys::CVastExpression> =
elements.iter().map(|e| e.inner).collect();
let concat_ptr = unsafe {
sys::xls_vast_verilog_file_make_replicated_concat(
locked.0,
replication.inner,
elem_ptrs.as_mut_ptr(),
elem_ptrs.len(),
)
};
let inner = unsafe { sys::xls_vast_concat_as_expression(concat_ptr) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_replicated_concat_i64(
&mut self,
replication_count: i64,
elements: &[&Expr],
) -> Expr {
let locked = self.ptr.lock().unwrap();
let mut elem_ptrs: Vec<*mut sys::CVastExpression> =
elements.iter().map(|e| e.inner).collect();
let concat_ptr = unsafe {
sys::xls_vast_verilog_file_make_replicated_concat_i64(
locked.0,
replication_count,
elem_ptrs.as_mut_ptr(),
elem_ptrs.len(),
)
};
let inner = unsafe { sys::xls_vast_concat_as_expression(concat_ptr) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_array_assignment_pattern(&mut self, elements: &[&Expr]) -> Expr {
let locked = self.ptr.lock().unwrap();
let mut element_ptrs: Vec<*mut sys::CVastExpression> =
elements.iter().map(|e| e.inner).collect();
let inner = unsafe {
sys::xls_vast_verilog_file_make_array_assignment_pattern(
locked.0,
element_ptrs.as_mut_ptr(),
element_ptrs.len(),
)
};
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_macro_ref(&mut self, name: &str) -> MacroRef {
let locked = self.ptr.lock().unwrap();
let c_name = CString::new(name).unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_macro_ref(locked.0, c_name.as_ptr()) };
MacroRef {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_macro_ref_with_args(&mut self, name: &str, args: &[&Expr]) -> MacroRef {
let locked = self.ptr.lock().unwrap();
let c_name = CString::new(name).unwrap();
let mut arg_ptrs: Vec<*mut sys::CVastExpression> = args.iter().map(|e| e.inner).collect();
let inner = unsafe {
sys::xls_vast_verilog_file_make_macro_ref_with_args(
locked.0,
c_name.as_ptr(),
arg_ptrs.as_mut_ptr(),
arg_ptrs.len(),
)
};
MacroRef {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_macro_statement(
&mut self,
macro_ref: &MacroRef,
emit_semicolon: bool,
) -> MacroStatement {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_macro_statement(
locked.0,
macro_ref.inner,
emit_semicolon,
)
};
MacroStatement {
inner,
parent: self.ptr.clone(),
}
}
fn make_unary(&mut self, op: VastOperatorKind, expr: &Expr) -> Expr {
let locked = self.ptr.lock().unwrap();
let op_i32 = op as i32;
let inner = unsafe { sys::xls_vast_verilog_file_make_unary(locked.0, expr.inner, op_i32) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_not(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::BitwiseNot, expr)
}
pub fn make_negate(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::Negate, expr)
}
pub fn make_logical_not(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::LogicalNot, expr)
}
pub fn make_and_reduce(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::AndReduce, expr)
}
pub fn make_or_reduce(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::OrReduce, expr)
}
pub fn make_xor_reduce(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::XorReduce, expr)
}
fn make_binary(&mut self, op: VastOperatorKind, lhs: &Expr, rhs: &Expr) -> Expr {
let locked = self.ptr.lock().unwrap();
let op_i32 = op as i32;
let inner = unsafe {
sys::xls_vast_verilog_file_make_binary(locked.0, lhs.inner, rhs.inner, op_i32)
};
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_add(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Add, lhs, rhs)
}
pub fn make_sub(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Sub, lhs, rhs)
}
pub fn make_mul(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Mul, lhs, rhs)
}
pub fn make_div(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Div, lhs, rhs)
}
pub fn make_mod(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Mod, lhs, rhs)
}
pub fn make_power(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Power, lhs, rhs)
}
pub fn make_bitwise_and(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::BitwiseAnd, lhs, rhs)
}
pub fn make_bitwise_or(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::BitwiseOr, lhs, rhs)
}
pub fn make_bitwise_xor(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::BitwiseXor, lhs, rhs)
}
pub fn make_bitwise_not(&mut self, expr: &Expr) -> Expr {
self.make_unary(VastOperatorKind::BitwiseNot, expr)
}
pub fn make_shll(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Shll, lhs, rhs)
}
pub fn make_shra(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Shra, lhs, rhs)
}
pub fn make_shrl(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Shrl, lhs, rhs)
}
pub fn make_ne(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Ne, lhs, rhs)
}
pub fn make_case_ne(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::CaseNe, lhs, rhs)
}
pub fn make_eq(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Eq, lhs, rhs)
}
pub fn make_case_eq(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::CaseEq, lhs, rhs)
}
pub fn make_ge(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Ge, lhs, rhs)
}
pub fn make_gt(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Gt, lhs, rhs)
}
pub fn make_le(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Le, lhs, rhs)
}
pub fn make_lt(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::Lt, lhs, rhs)
}
pub fn make_logical_and(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::LogicalAnd, lhs, rhs)
}
pub fn make_logical_or(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::LogicalOr, lhs, rhs)
}
pub fn make_ne_x(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::NeX, lhs, rhs)
}
pub fn make_eq_x(&mut self, lhs: &Expr, rhs: &Expr) -> Expr {
self.make_binary(VastOperatorKind::EqX, lhs, rhs)
}
pub fn make_ternary(&mut self, cond: &Expr, then_expr: &Expr, else_expr: &Expr) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_ternary(
locked.0,
cond.inner,
then_expr.inner,
else_expr.inner,
)
};
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_width_cast(&mut self, width: &Expr, value: &Expr) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_width_cast(locked.0, width.inner, value.inner)
};
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_type_cast(&mut self, data_type: &VastDataType, value: &Expr) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_type_cast(locked.0, data_type.inner, value.inner)
};
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_continuous_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> ContinuousAssignment {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_continuous_assignment(locked.0, lhs.inner, rhs.inner)
};
ContinuousAssignment {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_pos_edge(&mut self, expr: &Expr) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_pos_edge(locked.0, expr.inner) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_nonblocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_nonblocking_assignment(locked.0, lhs.inner, rhs.inner)
};
VastStatement {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_blocking_assignment(&mut self, lhs: &Expr, rhs: &Expr) -> VastStatement {
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_blocking_assignment(locked.0, lhs.inner, rhs.inner)
};
VastStatement {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_blank_line(&mut self) -> BlankLine {
let locked = self.ptr.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_blank_line(locked.0) };
BlankLine {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_inline_verilog_statement(&mut self, text: &str) -> InlineVerilogStatement {
let c_text = CString::new(text).unwrap();
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_inline_verilog_statement(locked.0, c_text.as_ptr())
};
InlineVerilogStatement {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_unsized_one_literal(&mut self) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_unsized_one_literal(locked.0) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_unsized_zero_literal(&mut self) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_unsized_zero_literal(locked.0) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_unsized_x_literal(&mut self) -> Expr {
let locked = self.ptr.lock().unwrap();
let inner = unsafe { sys::xls_vast_verilog_file_make_unsized_x_literal(locked.0) };
Expr {
inner,
parent: self.ptr.clone(),
}
}
pub fn make_def(&mut self, name: &str, kind: DataKind, ty: &VastDataType) -> Def {
let c_name = CString::new(name).unwrap();
let locked = self.ptr.lock().unwrap();
let inner = unsafe {
sys::xls_vast_verilog_file_make_def(locked.0, c_name.as_ptr(), kind.to_sys(), ty.inner)
};
Def {
inner,
parent: self.ptr.clone(),
}
}
pub fn emit(&self) -> String {
let locked = self.ptr.lock().unwrap();
let c_str = unsafe { sys::xls_vast_verilog_file_emit(locked.0) };
unsafe { c_str_to_rust(c_str) }
}
}
impl ParameterRef {
pub fn to_expr(&self) -> Expr {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_parameter_ref_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
pub fn to_indexable_expr(&self) -> IndexableExpr {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_parameter_ref_as_indexable_expression(self.inner) };
IndexableExpr {
inner,
parent: self.parent.clone(),
}
}
}
impl MacroRef {
pub fn to_expr(&self) -> Expr {
let _locked = self.parent.lock().unwrap();
let inner = unsafe { sys::xls_vast_macro_ref_as_expression(self.inner) };
Expr {
inner,
parent: self.parent.clone(),
}
}
}