rasta_verilog/
gen.rs

1use std::sync::Mutex;
2
3use super::*;
4
5pub static TOP_MODULE: Mutex<Option<String>> = Mutex::new(None);
6
7pub trait GenerateVerilog {
8    type Out;
9    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error>;
10}
11
12impl GenerateVerilog for VType {
13    type Out = ();
14    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
15        assert_eq!(self.star,0);
16        write!(code.borrow_mut(),"[{}:0]",match self.ty {
17            VTypeEnum::I8 => 8,
18            VTypeEnum::U64 => 64,
19            VTypeEnum::Void => 0,
20            _ => unimplemented!(),
21        }-1).unwrap();
22        Ok(())
23    }
24}
25
26impl GenerateVerilog for CompUnit {
27    type Out = ();
28    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
29        for item in self.global_items.iter() {
30            item.generate(code.clone())?;
31        }
32        Ok(())
33    }
34}
35
36impl GenerateVerilog for GlobalItem {
37    type Out = ();
38    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
39        match self {
40            GlobalItem::ConstDecl(decl) => decl.generate(code),
41            _ => unimplemented!()
42        }
43    }
44}
45
46impl GenerateVerilog for ConstDecl {
47    type Out = ();
48    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
49        write!(code.borrow_mut(),"module {}",self.id).unwrap();
50        self.init.generate(code.clone())?;
51        writeln!(code.borrow_mut(),"endmodule").unwrap();
52
53        if let Some(attr) = &self.attr {
54            if attr.attrs[0] == "top" {
55                if TOP_MODULE.lock().unwrap().is_some() {
56                    panic!("Duplicated top modules! {}",attr.span);
57                }
58                *TOP_MODULE.lock().unwrap() = Some(self.id.clone());
59            }
60        }
61
62        Ok(())
63    }
64}
65
66impl GenerateVerilog for ConstInitVal {
67    type Out = ();
68    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
69        match self {
70            Self::Function(func) => func.generate(code),
71            _ => unimplemented!(),
72        }
73    }
74}
75
76impl GenerateVerilog for FuncDef {
77    type Out = ();
78    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
79        write!(code.borrow_mut(),"(").unwrap();
80
81        for param in self.params.iter() {
82            write!(code.borrow_mut(),"input ").unwrap();
83            param.ty.generate(code.clone())?;
84            write!(code.borrow_mut()," {},",param.id).unwrap();
85        }
86
87        write!(code.borrow_mut(),"output ").unwrap();
88        self.func_type.generate(code.clone())?;
89        writeln!(code.borrow_mut(),"  out);").unwrap();
90
91        self.block.generate(code.clone())?;
92
93        Ok(())
94    }
95}
96
97impl GenerateVerilog for Block {
98    type Out = ();
99    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
100        for item in self.items.iter() {
101            item.generate(code.clone())?;
102        }
103        Ok(())
104    }
105}
106
107impl GenerateVerilog for BlockItem {
108    type Out = ();
109    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
110        match self {
111            BlockItem::Stmt(stmt) => stmt.generate(code),
112            _ => unimplemented!(),
113        }
114    }
115}
116
117impl GenerateVerilog for Stmt {
118    type Out = ();
119    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
120        match self {
121            Self::Return(ret) => ret.generate(code),
122            _ => unimplemented!(),
123        }
124    }
125}
126
127impl GenerateVerilog for Return {
128    type Out = ();
129
130    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
131        write!(code.borrow_mut(),"assign out = ").unwrap();
132        self.exp.generate(code.clone())?;
133        writeln!(code.borrow_mut(),";").unwrap();
134        Ok(())
135    }
136}
137
138impl GenerateVerilog for Exp {
139    type Out = ();
140    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
141        match self {
142            Self::Unary(unary, exp, _span) => {
143                write!(code.borrow_mut(),"{}",match unary {
144                    UnaryOp::Not => "~",
145                    UnaryOp::Negative => "-",
146                    _ => "",
147                }).unwrap();
148                exp.generate(code)
149            },
150            Self::Exp(exp, _span) => exp.generate(code),
151            Self::Number(number) => number.generate(code),
152            Self::LVal(lval) => lval.generate(code),
153            Self::Binary(lhs, op, rhs, _span) => {
154                lhs.generate(code.clone())?;
155                write!(code.borrow_mut()," {} ",match op {
156                    BinaryOp::Eq => "==",
157                    BinaryOp::Neq => "!=",
158                    BinaryOp::Add => "+",
159                    BinaryOp::Sub => "-",
160                    BinaryOp::Mul => "*",
161                    BinaryOp::Div => "/",
162                    BinaryOp::Ge => ">=",
163                    BinaryOp::Le => "<=",
164                    BinaryOp::Gt => ">",
165                    BinaryOp::Lt => "<",
166                    BinaryOp::Mod => "%",
167                }).unwrap();
168                rhs.generate(code.clone())?;
169                Ok(())
170            }
171            _ => unimplemented!(),
172        }
173    }
174}
175
176impl GenerateVerilog for Number {
177    type Out = ();
178    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
179        write!(code.borrow_mut(),"{}",self.num).unwrap();
180        Ok(())
181    }
182}
183
184impl GenerateVerilog for LVal {
185    type Out = ();
186    fn generate(&self, code: Rc<RefCell<String>>) -> Result<Self::Out, Error> {
187        write!(code.borrow_mut(),"{}",self.ids.join(".")).unwrap();
188        Ok(())
189    }
190}
191
192
193