virtuoso_cli/client/
schematic_ops.rs1use crate::client::bridge::escape_skill_string;
2
3#[derive(Default)]
4pub struct SchematicOps;
5
6impl SchematicOps {
7 pub fn new() -> Self {
8 Self
9 }
10
11 pub fn create_instance(
12 &self,
13 lib: &str,
14 cell: &str,
15 view: &str,
16 name: &str,
17 origin: (i64, i64),
18 ) -> String {
19 let lib = escape_skill_string(lib);
20 let cell = escape_skill_string(cell);
21 let view = escape_skill_string(view);
22 let name = escape_skill_string(name);
23 let (x, y) = origin;
24 format!(
25 r#"let((cv master inst) cv = RB_SCH_CV master = dbOpenCellViewByType("{lib}" "{cell}" "{view}" nil "r") inst = dbCreateInst(cv master "{name}" list({x} {y}) "R0" 1) inst)"#
26 )
27 }
28
29 pub fn create_wire(&self, points: &[(i64, i64)], layer: &str, net_name: &str) -> String {
30 let layer = escape_skill_string(layer);
31 let net_name = escape_skill_string(net_name);
32 let pts: String = points
33 .iter()
34 .map(|(x, y)| format!("list({x} {y})"))
35 .collect::<Vec<_>>()
36 .join(" ");
37 format!(
38 r#"let((cv) cv = RB_SCH_CV dbCreateWire(cv dbMakeNet(cv "{net_name}") dbFindLayerByName(cv "{layer}") list({pts})))"#
39 )
40 }
41
42 pub fn create_wire_between_terms(
43 &self,
44 inst1: &str,
45 term1: &str,
46 inst2: &str,
47 term2: &str,
48 net_name: &str,
49 ) -> String {
50 let inst1 = escape_skill_string(inst1);
51 let inst2 = escape_skill_string(inst2);
52 let net_name = escape_skill_string(net_name);
53 format!(
54 r#"let((cv net) cv = RB_SCH_CV net = dbMakeNet(cv "{net_name}") dbCreateWire(net dbFindTermByName(cv "{inst1}") dbFindTermByName(cv "{inst2}")))"#
55 )
56 }
57
58 pub fn create_wire_label(&self, net_name: &str, origin: (i64, i64)) -> String {
59 let net_name = escape_skill_string(net_name);
60 let (x, y) = origin;
61 format!(
62 r#"let((cv net) cv = RB_SCH_CV net = dbFindNetByName(cv "{net_name}") when(net dbCreateLabel(cv net "{net_name}" list({x} {y}) "centerCenter" "R0" "stick" 0.0625)))"#
63 )
64 }
65
66 pub fn create_pin(&self, net_name: &str, pin_type: &str, origin: (i64, i64)) -> String {
67 let net_name = escape_skill_string(net_name);
68 let (x, y) = origin;
69 format!(
70 r#"let((cv net pinInst) cv = RB_SCH_CV net = dbMakeNet(cv "{net_name}") pinInst = dbCreateInst(cv dbOpenCellViewByType("basic" "ipin" "symbol" nil "r") "PIN_{net_name}" list({x} {y}) "R0" 1) dbCreatePin(net pinInst))"#
71 )
72 }
73
74 pub fn check(&self) -> String {
75 r#"let((cv) cv = RB_SCH_CV schCheck(cv))"#.into()
76 }
77
78 pub fn open_cellview(&self, lib: &str, cell: &str, view: &str) -> String {
79 let lib = escape_skill_string(lib);
80 let cell = escape_skill_string(cell);
81 let view = escape_skill_string(view);
82 format!(
86 r#"RB_SCH_CV = dbOpenCellViewByType("{lib}" "{cell}" "{view}" "schematic" "a")"#
87 )
88 }
89
90 pub fn save(&self) -> String {
91 r#"let((cv) cv = RB_SCH_CV dbSave(cv))"#.into()
92 }
93
94 pub fn set_instance_param(&self, inst_name: &str, param: &str, value: &str) -> String {
95 let inst_name = escape_skill_string(inst_name);
96 let param = escape_skill_string(param);
97 let value = escape_skill_string(value);
98 format!(
99 r#"let((cv inst) cv = RB_SCH_CV inst = car(setof(i cv~>instances i~>name == "{inst_name}")) when(inst dbReplaceProp(inst "{param}" "string" "{value}")))"#
100 )
101 }
102
103 pub fn generate_connection_script(
106 &self,
107 connections: &[(String, String, String)], ) -> String {
109 let mut lines = Vec::new();
110 lines.push("let((cv inst iterm net)".to_string());
111 lines.push("cv = RB_SCH_CV".to_string());
112 for (inst_name, term_name, net_name) in connections {
113 let inst_name = escape_skill_string(inst_name);
114 let term_name = escape_skill_string(term_name);
115 let net_name = escape_skill_string(net_name);
116 lines.push(format!(
117 r#"inst = car(setof(i cv~>instances strcmp(i~>name "{inst_name}")==0))"#
118 ));
119 lines.push(format!(
120 r#"iterm = car(setof(x inst~>instTerms strcmp(x~>name "{term_name}")==0))"#
121 ));
122 lines.push(format!(
123 r#"net = dbMakeNet(cv "{net_name}")"#
124 ));
125 lines.push(r#"when(iterm schCreateWire(cv net "draw" "full" list(list(0 0) list(0 0))))"#.to_string());
127 }
128 lines.push("t)".to_string());
129 lines.join("\n")
130 }
131
132 pub fn assign_net(&self, inst_name: &str, term_name: &str, net_name: &str) -> String {
135 let inst_name = escape_skill_string(inst_name);
136 let term_name = escape_skill_string(term_name);
137 let net_name = escape_skill_string(net_name);
138 format!(
139 r#"RB_INST = car(setof(i RB_SCH_CV~>instances strcmp(i~>name "{inst_name}")==0)) RB_ITERM = car(setof(x RB_INST~>instTerms strcmp(x~>name "{term_name}")==0)) RB_NET = dbMakeNet(RB_SCH_CV "{net_name}") schCreateWire(RB_SCH_CV RB_NET "draw" "full" list(list(0 0) list(0 0)))"#
140 )
141 }
142}