rtlicious/
lib.rs

1#![deny(missing_docs)]
2//! Yosys RTLIL text representation parsing library.
3//! ```
4//! use rtlicious;
5//! let src =
6//! r#"module \test
7//! wire $a;
8//! end
9//! "#;
10//! let design = rtlicious::parse(src).unwrap();
11//! assert_eq!(design.modules().len(), 1);
12//! ```
13mod attribute;
14mod cell;
15mod characters;
16mod connect;
17mod constant;
18mod design;
19mod identifier;
20mod memory;
21mod module;
22mod process;
23mod sigspec;
24mod string;
25mod switch;
26mod sync;
27mod value;
28mod wire;
29
30use std::collections::HashMap;
31
32use getset::Getters;
33use nom_locate::LocatedSpan;
34use nom_tracable::TracableInfo;
35use serde::Serialize;
36
37/// Identifier struct
38#[derive(Debug, Clone, PartialEq, Serialize, Eq)]
39pub enum Id {
40    /// A public identifier
41    Public(String),
42    /// An identifier that was autogenerated by yosys
43    Autogen(String),
44}
45
46/// A design is optional autoindex statement followed by zero or more modules.
47#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
48#[getset(get = "pub")]
49pub struct Design {
50    /// The global autoindex value
51    autoidx: Option<i32>,
52    /// The modules in the design
53    modules: HashMap<String, Module>,
54}
55
56/// Represents a module
57/// A module is a collection of wires, memories, cells, processes, and connections
58#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
59#[getset(get = "pub")]
60pub struct Module {
61    /// The attributes of the module
62    attributes: HashMap<String, Constant>,
63    /// The parameters of the module
64    parameters: HashMap<String, Option<Constant>>,
65    /// The wires of the module
66    wires: HashMap<Id, Wire>,
67    /// The memories of the module
68    memories: HashMap<String, Memory>,
69    /// The cells of the module
70    cells: HashMap<String, Cell>,
71    /// The processes of the module
72    processes: HashMap<String, Process>,
73    /// The connections of the module
74    connections: Vec<(SigSpec, SigSpec)>,
75}
76
77/// Represents a logic cell
78#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
79#[getset(get = "pub")]
80pub struct Cell {
81    /// The type of the cell, ie. add, sub, etc.
82    cell_type: String,
83    /// The parameters of the cell
84    parameters: HashMap<String, Constant>,
85    /// The connections of the cell
86    connections: HashMap<String, SigSpec>,
87}
88
89/// Represents a wire
90#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
91#[getset(get = "pub")]
92pub struct Wire {
93    /// defaults to 1
94    width: usize,
95    /// defaults to 0
96    offset: usize,
97    /// if the wire is an input to the module
98    input: bool,
99    /// if the wire is an output to the module
100    output: bool,
101    /// if the wire is tristate?
102    inout: bool,
103    /// TODO: what is this?
104    upto: bool,
105    /// if the wire is signed? TODO: what is this?
106    signed: bool,
107    /// attributes of the wire
108    attributes: HashMap<String, Constant>,
109}
110
111/// Represents a memory cell
112#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
113#[getset(get = "pub")]
114pub struct Memory {
115    /// The width of the memory cell
116    width: usize,
117    /// The size of the memory cell
118    size: usize,
119    /// The offset of the memory cell
120    offset: usize,
121    /// The attributes of the memory cell
122    attributes: HashMap<String, Constant>,
123}
124
125/// Represents a process
126#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
127#[getset(get = "pub")]
128pub struct Process {
129    /// The attributes of the process
130    attributes: HashMap<String, Constant>,
131    /// The assignments of the process
132    assignments: Vec<(SigSpec, SigSpec)>,
133    /// The switch of the process
134    switches: Vec<Switch>,
135    /// The syncs of the process
136    syncs: Vec<Sync>,
137}
138
139/// Constant enum
140#[derive(Debug, Clone, PartialEq, Serialize)]
141pub enum Constant {
142    /// Value variant, contains a vector of characters, ie. vec!['x', 'z', '1', 'm']
143    Value(Vec<char>),
144    /// Integer variant, contains an i32
145    Integer(i32),
146    /// String variant, contains a String
147    String(String),
148}
149
150/// Represents a signal specification
151#[derive(Debug, Clone, PartialEq, Serialize)]
152pub enum SigSpec {
153    /// A constant value
154    Constant(Constant),
155    /// A wire id
156    WireId(String),
157    /// A range of bits from a wire
158    Range(Box<SigSpec>, usize, Option<usize>),
159    /// A concatenation of signals
160    Concat(Vec<SigSpec>),
161}
162
163/// Represents a case body
164#[derive(Debug, Clone, PartialEq, Serialize)]
165pub enum CaseBody {
166    /// another switch, nested
167    Switch(Switch),
168    /// assign statement
169    Assign((SigSpec, SigSpec)),
170}
171
172/// Represents a case
173#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
174#[getset(get = "pub")]
175pub struct Case {
176    /// The attributes of the case
177    pub(crate) attributes: HashMap<String, Constant>,
178    /// The signals to compare against
179    pub(crate) compare_against: Option<Vec<SigSpec>>,
180    /// The body of the case
181    pub(crate) case_bodies: Vec<CaseBody>,
182}
183
184/// Represents a switch
185#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
186#[getset(get = "pub")]
187pub struct Switch {
188    /// The attributes of the switch
189    pub(crate) attributes: HashMap<String, Constant>,
190    /// The signal to switch on, ie. compare against
191    pub(crate) switch_on_sigspec: SigSpec,
192    /// run CaseBody if true
193    pub(crate) cases: Vec<Case>,
194}
195
196/// Represents a sync statement
197#[derive(Debug, Clone, PartialEq, Serialize)]
198pub enum SyncOn {
199    /// Global sync
200    Global,
201    /// Initialization sync
202    Init,
203    /// Always sync
204    Always,
205    /// Signal sync
206    Signal(SignalSync, SigSpec),
207}
208
209/// Represents a
210#[derive(Debug, Clone, PartialEq, Serialize)]
211pub enum SignalSync {
212    /// Low level sync
213    Low,
214    /// High level sync
215    High,
216    /// Posedge sync
217    Posedge,
218    /// Negedge sync
219    Negedge,
220    /// Edge sync
221    Edge,
222}
223
224/// Represents a sync
225#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
226#[getset(get = "pub")]
227pub struct Sync {
228    /// The sync event
229    sync_event: SyncOn,
230    /// The updates to apply on the sync event
231    updates: Vec<(SigSpec, SigSpec)>,
232    /// memwr statements
233    memwrs: HashMap<String, Memwr>,
234}
235
236/// Represents a memwr statement
237#[derive(Debug, Clone, PartialEq, Getters, Serialize)]
238#[getset(get = "pub")]
239pub struct Memwr {
240    /// The attributes of the memwr
241    attributes: HashMap<String, Constant>,
242    /// The address of the memwr
243    address: SigSpec,
244    /// The data of the memwr
245    data: SigSpec,
246    /// The enable of the memwr
247    enable: SigSpec,
248    /// The priority mask of the memwr
249    priority_mask: SigSpec,
250}
251
252/// Input type must implement trait Tracable
253/// nom_locate::LocatedSpan<T, TracableInfo> implements it.
254type Span<'a> = LocatedSpan<&'a str, TracableInfo>;
255
256/// Parse a RTLIL design from a type that implements `AsRef<str>`.
257pub fn parse(input: &str) -> Result<Design, Span> {
258    Design::new_from_str(input)
259}
260
261#[cfg(test)]
262mod tests {
263    #[test]
264    fn test_sanity() {
265        assert_eq!(1 + 1, 2);
266    }
267}