ZLayout EDA Library v1.0.0
Advanced Electronic Design Automation Layout Library with Bilingual Documentation
Loading...
Searching...
No Matches
component_interface.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""
3EDA组件接口 - 统一的组件管理接口
4提供数据库存储组件和类定义逻辑电路的统一访问接口
5"""
6
7from typing import Dict, Any, Optional, Union, List
8from abc import ABC, abstractmethod
9import json
10from enum import Enum
11
12from .component_db import ComponentDatabase, ComponentSpec
13from .logic_circuits import (
14 FlipFlop, Counter, ProcessorFSM, StateMachine,
15 SequentialLogic, Signal, LogicState
16)
17
18class ComponentJSONEncoder(json.JSONEncoder):
19 """Custom JSON encoder for component objects"""
20
21 def default(self, obj):
22 if isinstance(obj, LogicState):
23 # Convert LogicState to its name (string representation)
24 return obj.name
25 elif isinstance(obj, Enum):
26 # Handle other enums by converting to their value
27 return obj.value
28 elif hasattr(obj, '__dict__'):
29 # For other complex objects, try to serialize their __dict__
30 return obj.__dict__
31 else:
32 # Let the base class default method raise the TypeError
33 return super().default(obj)
34
35class ComponentType(Enum):
36 """组件类型枚举"""
37 DATABASE = "database" # 数据库存储的组件
38 LOGIC_CLASS = "logic_class" # 类定义的逻辑电路
39 MODULE = "module" # 复合模块
40
42 """组件类别枚举"""
43 PASSIVE = "passive" # 无源器件 (R, L, C)
44 ACTIVE = "active" # 有源器件 (运放, 晶体管)
45 DIGITAL = "digital" # 数字逻辑
46 ANALOG = "analog" # 模拟电路
47 MIXED_SIGNAL = "mixed_signal" # 混合信号
48 CUSTOM = "custom" # 用户自定义
49
51 """组件接口基类"""
52
53 def __init__(self, name: str, category: ComponentCategory):
54 self.name = name
55 self.category = category
56 self.component_type = None
57 self.parameters = {}
58 self.connections = {}
59
60 @abstractmethod
61 def get_parameters(self) -> Dict[str, Any]:
62 """获取组件参数"""
63 pass
64
65 @abstractmethod
66 def set_parameter(self, name: str, value: Any):
67 """设置组件参数"""
68 pass
69
70 @abstractmethod
71 def get_info(self) -> Dict[str, Any]:
72 """获取组件信息"""
73 pass
74
75 @abstractmethod
76 def connect(self, pin: str, target, target_pin=None):
77 """连接组件"""
78 pass
79
81 """数据库存储组件的包装器"""
82
83 def __init__(self, component_spec: ComponentSpec, db: ComponentDatabase):
84 super().__init__(component_spec.name, ComponentCategory.CUSTOM)
85 self.component_type = ComponentType.DATABASE
86 self.spec = component_spec
87 self.db = db
88 self.parameters = component_spec.parameters.copy()
89
90 def get_parameters(self) -> Dict[str, Any]:
91 return self.parameters
92
93 def set_parameter(self, name: str, value: Any):
94 self.parameters[name] = value
95 # 更新组件规格
96 self.spec.parameters[name] = value
97
98 def get_info(self) -> Dict[str, Any]:
99 return {
100 "name": self.name,
101 "type": self.component_type.value,
102 "category": self.category.value,
103 "parameters": self.parameters,
104 "electrical_params": self.spec.electrical_params,
105 "physical_params": self.spec.physical_params,
106 "description": self.spec.description
107 }
108
109 def connect(self, pin: str, target, target_pin=None):
110 if isinstance(target, str):
111 self.connections[pin] = {"target": target, "target_pin": target_pin}
112 else:
113 self.connections[pin] = {"target": target.name, "target_pin": target_pin}
114
116 """逻辑电路组件的包装器"""
117
118 def __init__(self, logic_circuit):
119 super().__init__(logic_circuit.name, ComponentCategory.DIGITAL)
120 self.component_type = ComponentType.LOGIC_CLASS
121 self.logic_circuit = logic_circuit
122 self.parameters = {}
123
124 # 安全地提取逻辑电路的参数
125 if hasattr(logic_circuit, 'width'):
126 self.parameters['width'] = getattr(logic_circuit, 'width')
127 if hasattr(logic_circuit, 'ff_type'):
128 self.parameters['flip_flop_type'] = getattr(logic_circuit, 'ff_type')
129 if hasattr(logic_circuit, 'count_up'):
130 self.parameters['count_up'] = getattr(logic_circuit, 'count_up')
131
132 def get_parameters(self) -> Dict[str, Any]:
133 # 动态获取当前状态
134 if hasattr(self.logic_circuit, 'internal_state'):
135 self.parameters['current_state'] = self.logic_circuit.internal_state
136 if hasattr(self.logic_circuit, 'current_state'):
137 self.parameters['fsm_state'] = self.logic_circuit.current_state
138 return self.parameters
139
140 def set_parameter(self, name: str, value: Any):
141 self.parameters[name] = value
142 # 某些参数可能需要重新配置逻辑电路
143 if name == 'width' and hasattr(self.logic_circuit, 'width'):
144 setattr(self.logic_circuit, 'width', value)
145 elif name == 'count_up' and hasattr(self.logic_circuit, 'count_up'):
146 setattr(self.logic_circuit, 'count_up', value)
147
148 def get_info(self) -> Dict[str, Any]:
149 info = {
150 "name": self.name,
151 "type": self.component_type.value,
152 "category": self.category.value,
153 "parameters": self.get_parameters(),
154 "description": f"{self.logic_circuit.__class__.__name__} 逻辑电路"
155 }
156
157 # 添加逻辑电路特有信息
158 if hasattr(self.logic_circuit, 'inputs'):
159 info['inputs'] = list(self.logic_circuit.inputs.keys())
160 if hasattr(self.logic_circuit, 'outputs'):
161 info['outputs'] = list(self.logic_circuit.outputs.keys())
162 if hasattr(self.logic_circuit, 'states'):
163 info['states'] = list(self.logic_circuit.states)
164
165 return info
166
167 def connect(self, pin: str, target, target_pin=None):
168 if isinstance(target, str):
169 self.connections[pin] = {"target": target, "target_pin": target_pin}
170 else:
171 self.connections[pin] = {"target": target.name, "target_pin": target_pin}
172
173 def set_input(self, input_name: str, value: LogicState):
174 """设置逻辑输入"""
175 if hasattr(self.logic_circuit, 'inputs') and input_name in self.logic_circuit.inputs:
176 self.logic_circuit.inputs[input_name].set_state(value)
177
178 def get_output(self, output_name: str) -> LogicState:
179 """获取逻辑输出"""
180 if hasattr(self.logic_circuit, 'outputs') and output_name in self.logic_circuit.outputs:
181 return self.logic_circuit.outputs[output_name].state
182 return LogicState.UNKNOWN
183
184 def simulate_step(self):
185 """执行一步仿真"""
186 if hasattr(self.logic_circuit, 'on_clock_edge'):
187 self.logic_circuit.on_clock_edge()
188 elif hasattr(self.logic_circuit, 'process_inputs'):
189 self.logic_circuit.process_inputs()
190
192 """组件工厂类"""
193
194 def __init__(self, db: ComponentDatabase):
195 self.db = db
196 self.custom_types = {}
197
198 def create_component(self, component_name: str, component_type: str = None, **kwargs) -> ComponentInterface:
199 """创建组件实例"""
200
201 # 首先尝试从数据库创建
202 try:
203 spec = self.db.get_component(component_name)
204 if spec:
205 return DatabaseComponent(spec, self.db)
206 except:
207 pass
208
209 # 尝试创建逻辑电路
210 if component_type:
211 logic_circuit = self._create_logic_circuit(component_name, component_type, **kwargs)
212 if logic_circuit:
213 return LogicComponent(logic_circuit)
214
215 # 创建自定义组件
216 component_id = self.db.create_custom_component(component_name, **kwargs)
217 spec = self.db.get_component(component_id)
218 if spec:
219 return DatabaseComponent(spec, self.db)
220 else:
221 raise ValueError(f"Failed to create component {component_name}")
222
223 def _create_logic_circuit(self, name: str, circuit_type: str, **kwargs):
224 """创建逻辑电路"""
225 circuit_type = circuit_type.lower()
226
227 if circuit_type == "flipflop":
228 ff_type = kwargs.get("flip_flop_type", "D")
229 return FlipFlop(name, ff_type)
230 elif circuit_type == "counter":
231 width = kwargs.get("width", 8)
232 count_up = kwargs.get("count_up", True)
233 return Counter(name, width, count_up)
234 elif circuit_type == "statemachine":
235 return StateMachine(name)
236 elif circuit_type == "processorfsm":
237 return ProcessorFSM(name)
238 elif circuit_type in self.custom_types:
239 return self.custom_types[circuit_type](name, **kwargs)
240
241 return None
242
243 def register_custom_type(self, type_name: str, circuit_class):
244 """注册自定义逻辑电路类型"""
245 self.custom_types[type_name] = circuit_class
246
248 """组件管理器 - 提供统一的组件管理接口"""
249
250 def __init__(self, db_path: str = "components.db"):
251 self.db = ComponentDatabase(db_path)
253 self.components = {} # 实例化的组件
254 self.modules = {} # 模块定义
255
256 def create_component(self, name: str, component_type: str = None, **kwargs) -> ComponentInterface:
257 """创建组件"""
258 component = self.factory.create_component(name, component_type, **kwargs)
259 self.components[name] = component
260 return component
261
262 def get_component(self, name: str) -> Optional[ComponentInterface]:
263 """获取组件"""
264 return self.components.get(name)
265
266 def list_components(self) -> List[str]:
267 """列出所有组件"""
268 return list(self.components.keys())
269
270 def create_module(self, name: str, components: List[ComponentInterface],
271 connections: List[Dict[str, Any]] = None) -> Dict[str, Any]:
272 """创建模块"""
273 if connections is None:
274 connections = []
275 module = {
276 "name": name,
277 "components": {comp.name: comp for comp in components},
278 "connections": connections,
279 "type": ComponentType.MODULE
280 }
281 self.modules[name] = module
282 return module
283
284 def get_module(self, name: str) -> Optional[Dict[str, Any]]:
285 """获取模块"""
286 return self.modules.get(name)
287
288 def connect_components(self, source: str, source_pin: str, target: str, target_pin: str):
289 """连接组件"""
290 source_comp = self.get_component(source)
291 target_comp = self.get_component(target)
292
293 if source_comp and target_comp:
294 source_comp.connect(source_pin, target_comp, target_pin)
295
296 def simulate_system(self, steps: int = 1):
297 """系统仿真"""
298 for _ in range(steps):
299 for component in self.components.values():
300 if isinstance(component, LogicComponent):
301 component.simulate_step()
302
303 def get_system_info(self) -> Dict[str, Any]:
304 """获取系统信息"""
305 return {
306 "components": {name: comp.get_info() for name, comp in self.components.items()},
307 "modules": {name: {
308 "name": module["name"],
309 "component_count": len(module["components"]),
310 "connection_count": len(module["connections"])
311 } for name, module in self.modules.items()},
312 "database_stats": self.db.get_component_library()
313 }
314
315 def export_design(self, filename: str):
316 """导出设计"""
317 design = {
318 "components": {name: comp.get_info() for name, comp in self.components.items()},
319 "modules": self.modules,
320 "connections": {name: comp.connections for name, comp in self.components.items()}
321 }
322
323 with open(filename, 'w', encoding='utf-8') as f:
324 json.dump(design, f, indent=2, ensure_ascii=False, cls=ComponentJSONEncoder)
325
326 def close(self):
327 """关闭数据库连接"""
328 self.db.close()
329
330# 便捷函数
331def create_component_manager(db_path: str = "components.db") -> ComponentManager:
332 """创建组件管理器"""
333 return ComponentManager(db_path)
334
335def create_resistor(name: str, resistance: float, tolerance: float = 0.05) -> ComponentInterface:
336 """创建电阻器"""
337 manager = ComponentManager()
338 return manager.create_component(
339 name,
340 parameters={"resistance": resistance, "tolerance": tolerance},
341 electrical_params={"max_voltage": 50.0, "power_rating": 0.25},
342 description=f"{resistance}Ω 电阻器"
343 )
344
345def create_capacitor(name: str, capacitance: float, voltage_rating: float = 50.0) -> ComponentInterface:
346 """创建电容器"""
347 manager = ComponentManager()
348 return manager.create_component(
349 name,
350 parameters={"capacitance": capacitance},
351 electrical_params={"voltage_rating": voltage_rating},
352 description=f"{capacitance}F 电容器"
353 )
354
355def create_flipflop(name: str, ff_type: str = "D") -> ComponentInterface:
356 """创建触发器"""
357 manager = ComponentManager()
358 return manager.create_component(name, "flipflop", flip_flop_type=ff_type)
359
360def create_counter(name: str, width: int = 8, count_up: bool = True) -> ComponentInterface:
361 """创建计数器"""
362 manager = ComponentManager()
363 return manager.create_component(name, "counter", width=width, count_up=count_up)
_create_logic_circuit(self, str name, str circuit_type, **kwargs)
register_custom_type(self, str type_name, circuit_class)
ComponentInterface create_component(self, str component_name, str component_type=None, **kwargs)
connect(self, str pin, target, target_pin=None)
__init__(self, str name, ComponentCategory category)
ComponentInterface create_component(self, str name, str component_type=None, **kwargs)
__init__(self, str db_path="components.db")
Optional[ComponentInterface] get_component(self, str name)
Dict[str, Any] create_module(self, str name, List[ComponentInterface] components, List[Dict[str, Any]] connections=None)
connect_components(self, str source, str source_pin, str target, str target_pin)
Optional[Dict[str, Any]] get_module(self, str name)
__init__(self, ComponentSpec component_spec, ComponentDatabase db)
connect(self, str pin, target, target_pin=None)
connect(self, str pin, target, target_pin=None)
set_input(self, str input_name, LogicState value)
LogicState get_output(self, str output_name)
ComponentInterface create_counter(str name, int width=8, bool count_up=True)
ComponentInterface create_capacitor(str name, float capacitance, float voltage_rating=50.0)
ComponentInterface create_flipflop(str name, str ff_type="D")
ComponentInterface create_resistor(str name, float resistance, float tolerance=0.05)
ComponentManager create_component_manager(str db_path="components.db")
SystemInfo get_system_info()
Definition zlayout.cpp:137