sv_api/
info.rs

1/*
2 * File:    info.rs
3 * Brief:   TODO
4 *
5 * Copyright (C) 2023 John Jekel
6 * See the LICENSE file at the root of the project for licensing info.
7 *
8 * TODO longer description
9 *
10*/
11
12/*!
13 * TODO rustdoc for this file here
14*/
15
16/* ------------------------------------------------------------------------------------------------
17 * Submodules
18 * --------------------------------------------------------------------------------------------- */
19
20//TODO (includes "mod ..." and "pub mod ...")
21
22/* ------------------------------------------------------------------------------------------------
23 * Uses
24 * --------------------------------------------------------------------------------------------- */
25
26use crate::startup::panic_if_in_startup_routine;
27use crate::startup::panic_if_not_main_thread;
28
29/* ------------------------------------------------------------------------------------------------
30 * Macros
31 * --------------------------------------------------------------------------------------------- */
32
33//TODO (also pub(crate) use the_macro statements here too)
34
35/* ------------------------------------------------------------------------------------------------
36 * Constants
37 * --------------------------------------------------------------------------------------------- */
38
39//TODO
40
41/* ------------------------------------------------------------------------------------------------
42 * Static Variables
43 * --------------------------------------------------------------------------------------------- */
44
45//TODO
46
47/* ------------------------------------------------------------------------------------------------
48 * Types
49 * --------------------------------------------------------------------------------------------- */
50
51#[derive(Debug)]
52pub struct SimulatorInfo<'a> {
53    arguments: Vec<&'a str>,
54    product_name: &'a str,
55    version: &'a str
56}
57
58/* ------------------------------------------------------------------------------------------------
59 * Associated Functions and Methods
60 * --------------------------------------------------------------------------------------------- */
61
62//TODO
63
64/* ------------------------------------------------------------------------------------------------
65 * Traits And Default Implementations
66 * --------------------------------------------------------------------------------------------- */
67
68//TODO
69
70/* ------------------------------------------------------------------------------------------------
71 * Trait Implementations
72 * --------------------------------------------------------------------------------------------- */
73
74//TODO
75
76/* ------------------------------------------------------------------------------------------------
77 * Functions
78 * --------------------------------------------------------------------------------------------- */
79
80//TODO is 'static a correct assumption? Do the string pointers we are passed last forever?
81pub fn get_simulator_info() -> Option<SimulatorInfo<'static>> {
82    panic_if_in_startup_routine!();
83    panic_if_not_main_thread!();
84
85    let mut raw_info = sv_bindings::t_vpi_vlog_info {
86        argc: 0,
87        argv: std::ptr::null_mut(),
88        product: std::ptr::null_mut(),
89        version: std::ptr::null_mut(),
90    };
91
92    //SAFETY: vpi_get_vlog_info() is safe to call from the main thread
93    //and we are not in a startup routine so we're good.
94    unsafe {
95        if sv_bindings::vpi_get_vlog_info(&mut raw_info) != 1 {
96            return None;
97        }
98    }
99
100    //Package up command line arguments/arguments from an "options" file into a Vec
101    let num_args = raw_info.argc.try_into().ok()?;
102    let mut arguments = Vec::with_capacity(num_args);
103    for i in 0..num_args {
104        //SAFETY: We are only offsetting in argv by at most num_args - 1
105        //which is the number of elements in argv guaranteed by the LRM.
106        let arg_str_ptr = unsafe { *(raw_info.argv.add(i)) };
107
108        if arg_str_ptr.is_null() {
109            return None;//This should never happen, but just in case it does...
110        }
111
112        //SAFETY: We should have been given a valid null-terminated string
113        let arg_str = unsafe { std::ffi::CStr::from_ptr(arg_str_ptr) }.to_str().ok()?;
114
115        arguments.push(arg_str);
116    }
117
118    //Package up the simulator's product name and version
119    if raw_info.product.is_null() || raw_info.version.is_null() {
120        return None;//This should never happen, but just in case it does...
121    }
122
123    //SAFETY: We should have been given a valid null-terminated string
124    let product_name    = unsafe { std::ffi::CStr::from_ptr(raw_info.product) }.to_str().ok()?;
125    let version         = unsafe { std::ffi::CStr::from_ptr(raw_info.version) }.to_str().ok()?;
126
127    Some(SimulatorInfo {
128        arguments:      arguments,
129        product_name:   product_name,
130        version:        version
131    })
132}
133
134pub fn get_dpi_version() -> &'static str {
135    panic_if_in_startup_routine!();
136    panic_if_not_main_thread!();
137    unsafe {
138        //FIXME is the string pointer guaranteed to always be valid (or should we make a copy)?
139        std::ffi::CStr::from_ptr(sv_bindings::svDpiVersion())
140    }.to_str().unwrap()
141}
142
143/* ------------------------------------------------------------------------------------------------
144 * Tests
145 * --------------------------------------------------------------------------------------------- */
146
147//TODO
148
149/* ------------------------------------------------------------------------------------------------
150 * Benchmarks
151 * --------------------------------------------------------------------------------------------- */
152
153//TODO