完成 yosys 抽象架构组织

This commit is contained in:
锦恢 2024-12-21 00:02:37 +08:00
parent b4900b23e4
commit 1085a2fcf4
6 changed files with 1506 additions and 16 deletions

View File

@ -5,14 +5,65 @@
* @property {Record<string, YosysModel>} [models] - 模型定义的映射仅在使用 `-aig` 选项时存在 * @property {Record<string, YosysModel>} [models] - 模型定义的映射仅在使用 `-aig` 选项时存在
*/ */
/**
* @typedef {number | string} WireId 信号ID
*/
/**
* @typedef {'input' | 'output' | 'inout'} PortDirection
*/
/**
* @typedef {string} ParameterValue 参数值一般表示为二进制的字符串比如 "00000000000000000000000000001000" 表示 8
*/
/** /**
* @typedef YosysNetModule * @typedef YosysNetModule
* @property {ModuleAttribute} attributes - 模块的属性如是否为顶层模块及其源文件 * @property {ModuleAttribute} attributes - 模块的属性如是否为顶层模块及其源文件
* @property {Record<string, string>} [parameter_default_values] - 参数的默认值 * @property {Record<string, ParameterValue>} [parameter_default_values] - 参数的默认值
* @property {Record<string, YosysPort>} ports - 端口名称到端口定义的映射 * @property {Record<string, YosysPort>} ports - 端口名称到端口定义的映射
* @property {Record<string, YosysCell>} cells - 单元名称到单元定义的映射 * @property {Record<string, YosysCell>} cells - 单元名称到单元定义的映射
* @property {Record<string, YosysMemory>} [memories] - 内存名称到内存定义的映射 * @property {Record<string, YosysMemory>} [memories] - 内存名称到内存定义的映射
* @property {Record<string, YosysNetname>} netnames - 网络名称到网络定义的映射 * @property {Record<string, YosysNetname>} netnames 信号名称到网络定义的映射
*
* 信号名称大体分为两种
* 1. 普通信号
* 2. 中间变量信号
*
* ### 普通信号名
* 一般是 module port module scope 内定义的各类变量它们都有自己的名字
*
* ```json
* "A": {
"hide_name": 0,
"bits": [ 2 ],
"attributes": { ... }
}
* ```
* 此处信号名称就是 A它可能代表当前 module 的一个 port 的名字也可也是一个内部定义的 wire 或者 reg
*
* ### 中间变量信号
* 一些操作比如 `assign x = A & B | C` 这样的操作会产生中间变量比如 A & B 会产生一个中间值这个中间值在与 C 去发生计算
* yosys 中使用如下的格式来代表这样的中间变量
*
* `"${op_name}${define_path}:{define_line}${op_id}_{op_output_name}"`
*
* - `op_name`: 操作名称比如 `&` 就是 `and`
* - `define_path`: 发生这个操作的文件路径
* - `define_line`: 发生这个操作的行
* - `op_id`: 当前操作在当前 module 内的编号
* - `op_output_name`: 当前操作的输出值有的操作会有多个输出一般只有一个输出的简单操作输出的 name 都是 Y
*
*
* ```json
* "$xor$/home/dide/project/Digital-Test/DIDEtemp/user/src/language/vlog/dependence/utils/utils.v:32$4_Y": {
"hide_name": 1,
"bits": [ 11 ],
"attributes": { ... }
}
* ```
*
*
*/ */
/** /**
@ -24,23 +75,23 @@
*/ */
/** /**
* @typedef YosysPort * @typedef YosysPort 描述一个 module port
* @property {string} direction - 端口的方向例如 "input""output" "inout" * @property {PortDirection} direction - 端口的方向例如 "input""output" "inout"
* @property {number[]} bits - 与端口关联的位索引 * @property {WireId[]} bits - 当前 port 每一个位置 bit 的信号 ID. bits.length
* @property {number} [offset] - 使用的最低位索引如果非 0 * @property {number} [offset] - 使用的最低位索引如果非 0
* @property {number} [upto] - 如果端口位索引是 MSB-first则为 1 * @property {number} [upto] - 如果端口位索引是 MSB-first则为 1
* @property {number} [signed] - 如果端口是有符号的则为 1 * @property {number} [signed] - 如果端口是有符号的则为 1
*/ */
/** /**
* @typedef YosysCell * @typedef YosysCell 描述一个基本器件
* @property {number} hide_name - 是否隐藏单元名称1 表示是0 表示否 * @property {number} hide_name - 当前器件是否有具体的名字如果有则为 1否则为 0 加减乘除都是无名器件一般都为 0例化模块都是有名字的一般都为 1
* @property {string} type - 单元的类型例如 "$_AND_" "$_XOR_" * @property {string} type - 器件的类型例如 "$_AND_" 代表 yosys 内置的与门 full_adder_1bit 代表当前器件是一个单位全加器的例化模块
* @property {string} [model] - AIG 模型名称仅在使用 `-aig` 选项时存在 * @property {string} [model] - AIG 模型名称仅在使用 `-aig` 选项时存在
* @property {Record<string, any>} [parameters] - 与单元关联的参数如果有 * @property {Record<string, string>} [parameters] - 与单元关联的参数如果有
* @property {CellAttribute} attributes - 单元的属性如源文件和行号 * @property {CellAttribute} attributes - 单元的属性如源文件和行号
* @property {Record<string, string>} port_directions - 端口名称到端口方向的映射例如 "input""output" "inout" * @property {Record<string, PortDirection>} port_directions - 端口名称到端口方向的映射例如 "input""output" "inout"
* @property {Record<string, number[]>} connections - 端口名称到连接位索引的映射 * @property {Record<string, WireId[]>} connections - 端口名称到 信号ID 的映射
*/ */
/** /**
@ -58,9 +109,9 @@
*/ */
/** /**
* @typedef YosysNetname * @typedef YosysNetname 一个模块内部的所有变量port临时变量等等
* @property {number} hide_name - 是否隐藏网络名称1 表示是0 表示否 * @property {number} hide_name - 同上
* @property {number[]} bits - 与网络名称关联的位索引 * @property {WireId[]} bits - 与网络名称关联的位索引
* @property {number} [offset] - 使用的最低位索引如果非 0 * @property {number} [offset] - 使用的最低位索引如果非 0
* @property {number} [upto] - 如果端口位索引是 MSB-first则为 1 * @property {number} [upto] - 如果端口位索引是 MSB-first则为 1
* @property {number} [signed] - 如果端口是有符号的则为 1 * @property {number} [signed] - 如果端口是有符号的则为 1
@ -79,3 +130,50 @@
* @property {number} [node_index] - 节点索引如果节点类型为 "and" "nand" * @property {number} [node_index] - 节点索引如果节点类型为 "and" "nand"
* @property {Array<string>} [out_list] - 输出端口名称和位索引的列表 * @property {Array<string>} [out_list] - 输出端口名称和位索引的列表
*/ */
/**
* @typedef ElkGraph
* @property {string} id - 图形的唯一标识符
* @property {ElkNode[]} children - 图形的子节点列表
* @property {ElkEdge[]} edges - 图形中的边列表
* @property {ElkLayoutOptions} [layoutOptions] - 图形的布局选项可选
*/
/**
* @typedef ElkNode
* @property {string} id - 节点的唯一标识符
* @property {number} [x] - 节点的 X 坐标可选由布局算法生成
* @property {number} [y] - 节点的 Y 坐标可选由布局算法生成
* @property {number} [width] - 节点的宽度可选
* @property {number} [height] - 节点的高度可选
* @property {ElkPort[]} [ports] - 节点的端口列表可选
* @property {ElkLayoutOptions} [layoutOptions] - 节点的布局选项可选
*/
/**
* @typedef ElkPort
* @property {string} id - 端口的唯一标识符
* @property {number} [x] - 端口的 X 坐标可选由布局算法生成
* @property {number} [y] - 端口的 Y 坐标可选由布局算法生成
* @property {number} [width] - 端口的宽度可选
* @property {number} [height] - 端口的高度可选
* @property {ElkLayoutOptions} [layoutOptions] - 端口的布局选项可选
*/
/**
* @typedef ElkEdge
* @property {string} id - 边的唯一标识符
* @property {string[]} sources - 边的源节点列表
* @property {string[]} targets - 边的目标节点列表
* @property {ElkLayoutOptions} [layoutOptions] - 边的布局选项可选
*/
/**
* @typedef ElkLayoutOptions
* @property {string} [elk.algorithm] - 布局算法可选
* @property {string} [elk.direction] - 布局方向可选 "RIGHT", "DOWN"
* @property {number} [elk.spacing.nodeNode] - 节点之间的间距可选
* @property {number} [elk.spacing.edgeNode] - 边与节点之间的间距可选
* @property {string} [elk.port.side] - 端口的位置可选 "NORTH", "SOUTH", "EAST", "WEST"
*/

View File

@ -1,7 +1,39 @@
import * as d3 from 'd3'; import * as d3 from 'd3';
import { ModuleLayout } from './layout';
class NetlistRender { class NetlistRender {
constructor() { /**
*
* @param {YosysRawNet} rawNet
*/
constructor(rawNet) {
/**
* @type {YosysRawNet}
*/
this.rawNet = rawNet;
/**
* @type {ElkGraph}
*/
this.elkGraph = {
id: 'root',
children: [],
edges: []
};
this.loadYosysRawNet(rawNet);
}
/**
* @description 加载 yosys 格式的 json
* @param {YosysRawNet} rawNet
*/
loadYosysRawNet(rawNet) {
// 转换为 elkjs 格式的 graph
for (const [moduleName, module] of Object.entries(rawNet.modules)) {
} }
}
} }

212
src/hook/render/layout.js Normal file
View File

@ -0,0 +1,212 @@
/**
* 将各个节点转换为 elknode 的数据结构
*/
import { DEVICE_MAPPER } from "./yosys";
export const LAYOUT_CONSTANT = {
PORT_WIDTH: 50,
PORT_HEIGHT: 50,
INSTANTIATION_WIDTH: 50,
INSTANTIATION_HEIGHT: 50,
};
export class ModuleLayout {
/**
* @param {string} name
* @param {YosysNetModule} module
*/
constructor(name, module) {
this.module = module;
this.name = name;
this.initialise();
}
/**
* @description 初始化构建信息更加丰富的 RawYosysNet
*/
initialise() {
// 构建模块树
// 构建 wireId 到模块树节点的映射表
}
/**
* @description ports netnames 中创建所有变量相关的节点
* @returns {ElkNode[]}
*/
makeNetsElkNodes() {
const ports = this.module.ports;
const nets = this.module.netnames;
const moduleName = this.name;
const nodes = [];
// 绘制 ports
for (const [portName, port] of Object.entries(ports)) {
const portId = ElkNodeId.port(moduleName, portName);
// TODO: 把当前的 id 绑定到模块树上面
const node = {
id: portId,
width: LAYOUT_CONSTANT.PORT_WIDTH,
height: LAYOUT_CONSTANT.PORT_HEIGHT,
layoutOptions: {
"elk.port.side": port.direction === "input" ? "WEST" : "EAST"
}
}
nodes.push(node);
}
// 非 port 的其他内部变量的节点不需要绘制,因为它们总能被表示为中间变量
// 它们的操作可以表示为一系列器件的组合或者直连
return nodes;
}
/**
* @description cells 中创建节点
* @returns {ElkNode[]}
*/
makeCellsElkNodes() {
const cells = this.module.cells;
const moduleName = this.name;
const nodes = [];
for (const [cellName, cell] of Object.entries(cells)) {
const cellId = ElkNodeId.cell(moduleName, cellName);
// 查看当前的器件是否为 内置器件
if (DEVICE_MAPPER[cell.type]) {
// 是内置器件
// TODO: 查询内置器件的 size
const node = {
id: cellId,
width: 50,
height: 50,
layoutOptions: {
"elk.port.side": "NORTH"
}
};
nodes.push(node);
} else {
// 是例化模块
const node = {
id: cellId,
width: LAYOUT_CONSTANT.INSTANTIATION_WIDTH,
height: LAYOUT_CONSTANT.INSTANTIATION_HEIGHT,
layoutOptions: {
"elk.port.side": "NORTH"
}
};
nodes.push(node);
}
}
return nodes;
}
/**
* @description cells.connections 中创建边
* @returns {[ElkNode[], ElkEdge[]]}
*/
makeConnectionElkNodes() {
const cells = this.module.cells;
const moduleName = this.name;
const nodes = [];
const edges = [];
for (const [cellName, cell] of Object.entries(cells)) {
// 当前器件的 ID
const cellId = `${moduleName}.${cellName}`;
for (const [connectionName, wireIds] of Object.entries(cell.connections)) {
// 器件当前的端口的 ID为了区别与外层 module 的端口,起名为 connection
const connectionId = `${moduleName}.${cellName}.${connectionName}`;
// 遍历器件端口的每一个连接点
// 比如对于端口 input [31:0] data 它的32个位不一定是完全导向一个变量虽然我们愿意认为大部分情况下是这样
// 大部分情况下,👇的 wireIds.length 都是 1
for (let i = 0; i < wireIds.length; ++ i) {
const bit = wireIds[i];
// bit 可以是一个 id也可以是一个常数
if (typeof bit === 'string') {
// 常数
// 如果是常数,需要先创建代表常数的节点,常数一定是器件的输入,而非输出
const constant = parseInt(bit);
const constantBitId = ElkNodeId.constantBit(moduleName, cellName, connectionName, i, constant);
const node = {
id: constantBitId,
width: 50,
height: 50,
layoutOptions: {
"elk.port.side": "WEST"
}
};
nodes.push(node);
// 创建常数到器件的连线
const edge = {
id: constantBitId,
sources: [cellId],
targets: [node.id]
};
// TODO: 把创建的 edge 关联到模块树上
edges.push(edge);
} else {
// 如果不是一个常数连接,那么存在两种可能
// 1. 当前的器件的这个端口和某一个 port 连接
// 2. 当前的器件的这个端口和另一个器件的一个端口连接
// TODO: 把创建的 edge 关联到模块树上
}
}
}
}
return [nodes, edges];
}
}
/**
* @description 使用 . 把各个部分连接起来
* @param {string[]} args
*/
export function dotConnect(...args) {
const stringArgs = args.map(arg => arg.toString());
return stringArgs.join('.');
}
export namespace ElkNodeId {
export function module(moduleName) {
return dotConnect(moduleName);
}
export function port(moduleName, portName) {
return dotConnect(moduleName, portName);
}
export function cell(moduleName, cellName) {
return dotConnect(moduleName, cellName);
}
export function connection(moduleName, cellName, connectionName) {
return dotConnect(moduleName, cellName, connectionName);
}
export function constantBit(moduleName, cellName, connectionName, orderId, constant) {
return dotConnect(moduleName, cellName, connectionName, orderId, 'constant-' + constant);
}
export function commonBit(moduleName, cellName, connectionName, wireId) {
return dotConnect(moduleName, cellName, connectionName, wireId);
}
}

134
src/hook/render/yosys.js Normal file
View File

@ -0,0 +1,134 @@
/**
* @type {Record<string, string>} yosys 器件映射
* - key: 器件的 type比如 $_AND_
* - value: 器件对应的我们内部的名称用于检索皮肤系统的
*/
export const DEVICE_MAPPER = {
"$_AND_": "and",
"$_XOR_": "xor",
"$_NOT_": "not",
"$_OR_": "or",
"$_NAND_": "nand",
"$_NOR_": "nor",
"$_XNOR_": "xnor",
"$_MUX_": "mux",
"$_AOI3_": "aoi3",
"$_OAI3_": "oai3",
"$_AOI4_": "aoi4",
"$_OAI4_": "oai4",
"$_DFF_P_": "dff_pos",
"$_DFF_N_": "dff_neg",
"$_SR_NN_": "sr_nn",
"$_SR_NP_": "sr_np",
"$_SR_PN_": "sr_pn",
"$_SR_PP_": "sr_pp"
};
/**
* @description 模块树对象直接作为 treeview 的渲染视图加入运算
* 相比于 YosysNetModule, ModuleTree 只关心和渲染有关的那部分变量且不可被序列化
*/
export class ModuleTree {
/**
* @param {string} name
* @param {YosysNetModule} rawModule
*/
constructor(name, rawModule) {
this.name = name;
this.rawModule = rawModule;
}
get id() {
return this.name;
}
}
export class Port {
/**
* @description port 的抽象
* @param {ModuleTree} moduleTree
* @param {string} name
* @param {YosysPort} rawPort
*/
constructor(moduleTree, name, rawPort) {
this.moduleTree = moduleTree;
this.name = name;
this.rawPort = rawPort;
}
get id() {
return dotConnect(this.moduleTree.id, this.name);
}
}
export class Cell {
/**
* @description 器件的抽象
* @param {ModuleTree} moduleTree
* @param {string} name
* @param {YosysCell} rawCell
*/
constructor(moduleTree, name, rawCell) {
this.moduleTree = moduleTree;
this.name = name;
this.rawCell = rawCell;
}
get id() {
return dotConnect(this.moduleTree.id, this.name);
}
}
export class Connection {
/**
* @description connection 的抽象一个 connection 代表一个器件的一个端口是如何与外界连接的
* @param {Cell} cell
* @param {string} name
* @param {WireId[]} wireIds
*/
constructor(cell, name, wireIds) {
this.cell = cell;
this.name = name;
this.wireIds = wireIds;
}
get id() {
return dotConnect(this.cell.id, this.name);
}
}
export class Wire {
/**
* @description 一根线的抽象
* @param {Connection} connection
* @param {number} index
* @param {WireId} wireId
*/
constructor(connection, index, wireId) {
this.connection = connection;
this.index = index;
this.wireId = wireId;
}
get id() {
if (typeof this.wireId === 'string') {
// 常数连接
const num = parseInt(this.wireId);
return dotConnect(this.connection.id, this.index, 'c-' + num);
} else {
// 普通连接
return dotConnect(this.connection.id, this.wireId);
}
}
}
/**
* @description 使用 . 把各个部分连接起来
* @param {any[]} args
*/
export function dotConnect(...args) {
const stringArgs = args.map(arg => arg.toString());
return stringArgs.join('.');
}

333
src/static/analog.svg Normal file
View File

@ -0,0 +1,333 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:s="https://github.com/nturley/netlistsvg">
<s:properties
constants="false"
splitsAndJoins="false"
genericsLaterals="true">
<s:layoutEngine
org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers="5"
org.eclipse.elk.layered.compaction.postCompaction.strategy="4"
org.eclipse.elk.spacing.nodeNode= "35"
org.eclipse.elk.direction="DOWN"/>
</s:properties>
<style>
svg {
stroke: #000;
fill: none;
}
text {
fill: #000;
stroke: none;
font-size: 10px;
font-weight: bold;
font-family: "Courier New", monospace;
}
.nodelabel {
text-anchor: middle;
}
.inputPortLabel {
text-anchor: end;
}
.splitjoinBody {
fill: #000;
}
.symbol {
stroke-linejoin: round;
stroke-linecap: round;
stroke-width: 2;
}
.detail {
stroke-linejoin: round;
stroke-linecap: round;
fill: #000;
}
</style>
<!-- power -->
<g s:type="vcc" s:width="20" s:height="30" transform="translate(5,20)">
<s:alias val="vcc" />
<text x="10" y="-4" class="nodelabel $cell_id" s:attribute="name">name</text>
<path d="M0,0 H20 L10,15 Z M10,15 V30" class="$cell_id"/>
<g s:x="10" s:y="30" s:pid="A" s:position="bottom"/>
</g>
<g s:type="vee" s:width="20" s:height="30" transform="translate(40,35)">
\t <s:alias val="vee" />
\t <text x="10" y="10" class="nodelabel $cell_id" s:attribute="name">name</text>
\t <path d="M0,0 H20 L10,-15 Z M10,-15 V-30" class="$cell_id"/>
\t <g s:x="10" s:y="-30" s:pid="A" s:position="top"/>
\t</g>
<g s:type="gnd" s:width="20" s:height="30" transform="translate(80,35)">
<s:alias val="gnd"/>
<text x="30" y="20" class="nodelabel $cell_id" s:attribute="name">name</text>
<path d="M0,0 H20 M3,5 H17 M7,10 H13 M10,0 V-15" class="$cell_id"/>
<g s:x="10" s:y="-15" s:pid="A" s:position="top"/>
</g>
<!-- power -->
<!-- signal -->
<g s:type="inputExt" s:width="30" s:height="20" transform="translate(5,70)">
<text x="15" y="-4" class="$cell_id" s:attribute="ref">input</text>
<s:alias val="$_inputExt_"/>
<path d="M0,0 V20 H15 L30,10 15,0 Z" class="$cell_id"/>
<g s:x="30" s:y="10" s:pid="Y" s:position="right"/>
</g>
<g s:type="outputExt" s:width="30" s:height="20" transform="translate(60,70)">
<text x="15" y="-4" class="$cell_id" s:attribute="ref">output</text>
<s:alias val="$_outputExt_"/>
<path d="M30,0 V20 H15 L0,10 15,0 Z" class="$cell_id"/>
<g s:x="0" s:y="10" s:pid="A" s:position="left"/>
</g>
<!-- signal -->
<!-- passives -->
<g s:type="resistor_h" s:width="50" s:height="10" transform="translate(5,110)">
<s:alias val="r_h"/>
<text class="nodelabel $cell_id" x="25" y="-5" s:attribute="ref">X1</text>
<text class="nodelabel $cell_id" x="25" y="20" s:attribute="value">Xk</text>
<path d="M10,0 H40 V10 H10 Z" class="symbol $cell_id"/>
<path d="M0,5 H10 M40,5 H50" class="connect $cell_id"/>
<g s:x="0" s:y="5" s:pid="A" s:position="left"/>
<g s:x="50" s:y="5" s:pid="B" s:position="right"/>
</g>
<g s:type="resistor_v" s:width="10" s:height="50" transform="translate(25,130)">
<s:alias val="r_v"/>
<text x="15" y="15" s:attribute="ref" class="$cell_id">X1</text>
<text x="15" y="30" s:attribute="value" class="$cell_id" >Xk</text>
<path d="M0,10 V40 H10 V10 Z" class="symbol $cell_id"/>
<path d="M5,0 V10 M5,40 V50" class="connect $cell_id"/>
<g s:x="5" s:y="0" s:pid="A" s:position="top"/>
<g s:x="5" s:y="50" s:pid="B" s:position="bottom"/>
</g>
<g s:type="capacitor_h" s:width="50" s:height="30" transform="translate(60,100)">
<s:alias val="c_h"/>
<text x="35" y="5" s:attribute="ref" class="$cell_id">X1</text>
<text x="35" y="30" s:attribute="value" class="$cell_id">Xu</text>
<path d="M20,0 V30 M30,0 V30" class="symbol $cell_id"/>
<path d="M0,15 H20 M30,15 H50" class="connect $cell_id"/>
<g s:x="0" s:y="15" s:pid="A" s:position="left"/>
<g s:x="50" s:y="15" s:pid="B" s:position="right"/>
</g>
<g s:type="capacitor_v" s:width="30" s:height="50" transform="translate(70,130)">
<s:alias val="c_v"/>
<text x="25" y="10" s:attribute="ref" class="$cell_id">X1</text>
<text x="25" y="45" s:attribute="value" class="$cell_id">Xu</text>
<path d="M0,20 H30 M0,30 H30" class="symbol $cell_id"/>
<path d="M15,0 V20 M15,30 V50" class="connect $cell_id"/>
<g s:x="15" s:y="0" s:pid="A" s:position="top"/>
<g s:x="15" s:y="50" s:pid="B" s:position="bottom"/>
</g>
<g s:type="inductor_h" s:width="50" s:height="10" transform="translate(115,110)">
<s:alias val="l_h"/>
<text class="nodelabel $cell_id" x="25" y="-5" s:attribute="ref">X1</text>
<text class="nodelabel $cell_id" x="25" y="20" s:attribute="value">XpF</text>
<path d="M5,5 A5,5 0 0 1 15,5 A5,5 0 0 1 25,5 A5,5 0 0 1 35,5 A5,5 0 0 1 45,5" class="$cell_id"/>
<path d="M0,5 H5 M45,5 H50" class="connect $cell_id"/>
<g s:x="0" s:y="5" s:pid="A" s:position="left"/>
<g s:x="50" s:y="5" s:pid="B" s:position="right"/>
</g>
<g s:type="inductor_v" s:width="10" s:height="50" transform="translate(135,130)">
<s:alias val="l_v"/>
<text x="15" y="15" s:attribute="ref" class="$cell_id">X1</text>
<text x="15" y="35" s:attribute="value" class="$cell_id">XpF</text>
<path d="M5,5 A5,5 0 0 1 5,15 A5,5 0 0 1 5,25 A5,5 0 0 1 5,35 A5,5 0 0 1 5,45" class="$cell_id"/>
<path d="M5,0 V5 M5,45 V50" class="connect $cell_id"/>
<g s:x="5" s:y="0" s:pid="A" s:position="top"/>
<g s:x="5" s:y="50" s:pid="B" s:position="bottom"/>
</g>
<!-- passives -->
<!-- sources -->
<g s:type="voltage_source" s:width="32" s:height="52" transform="translate(20,180)">
<s:alias val="v"/>
<text x="35" y="20" s:attribute="ref" class="$cell_id">X1</text>
<text x="35" y="35" s:attribute="value" class="$cell_id">XV</text>
<circle cx="16" cy="26" r="16" class="symbol $cell_id"/>
<path d="M16,10 V42" class="detail $cell_id"/>
<path d="M16,0 V10 M16,42 V52" class="connect $cell_id"/>
<g s:x="16" s:y="0" s:pid="+" s:position="top"/>
<g s:x="16" s:y="52" s:pid="-" s:position="bottom"/>
</g>
<g s:type="current_source" s:width="32" s:height="52" transform="translate(75,180)">
<s:alias val="i"/>
<text x="35" y="20" s:attribute="ref" class="$cell_id">X1</text>
<text x="35" y="35" s:attribute="value" class="$cell_id">XA</text>
<circle cx="16" cy="26" r="16" class="symbol $cell_id"/>
<path d="M0,26 H32" class="detail $cell_id"/>
<path d="M16,0 V10 M16,42 V52" class="connect $cell_id"/>
<g s:x="16" s:y="0" s:pid="+" s:position="top"/>
<g s:x="16" s:y="52" s:pid="-" s:position="bottom"/>
</g>
<!-- sources -->
<!-- diodes -->
<g s:type="diode_h" s:width="50" s:height="20" transform="translate(5,250)">
<s:alias val="d_h"/>
<text class="nodelabel $cell_id" x="25" y="-5" s:attribute="ref">X1</text>
<path d="M15,0 V20 L35,10 Z M35,0 V20" class="symbol $cell_id"/>
<path d="M0,10 H15 M35,10 H50" class="connect $cell_id"/>
<g s:x="0" s:y="10" s:pid="+" s:position="left"/>
<g s:x="50" s:y="10" s:pid="-" s:position="right"/>
</g>
<g s:type="diode_v" s:width="20" s:height="50" transform="translate(20,280)">
<s:alias val="d_v"/>
<text x="25" y="25" s:attribute="ref" class="$cell_id">X1</text>
<path d="M0,15 H20 L10,35 Z M0,35 H20" class="symbol $cell_id"/>
<path d="M10,0 V15 M10,35 V50" class="connect $cell_id"/>
<g s:x="10" s:y="0" s:pid="+" s:position="top"/>
<g s:x="10" s:y="50" s:pid="-" s:position="bottom"/>
</g>
<g s:type="diode_schottky_h" s:width="50" s:height="20" transform="translate(60,250)">
<s:alias val="d_sk_h"/>
<text class="nodelabel $cell_id" x="25" y="-5" s:attribute="ref">X1</text>
<path d="M15,0 V20 L35,10 Z M35,0 V20" class="symbol $cell_id"/>
<path d="M0,10 H15 M35,10 H50" class="connect $cell_id"/>
<!-- schottky -->
<path d="M35,0 H40 M35,20 H30" class="symbol $cell_id"/>
<g s:x="0" s:y="10" s:pid="+" s:position="left"/>
<g s:x="50" s:y="10" s:pid="-" s:position="right"/>
</g>
<g s:type="diode_schottky_v" s:width="20" s:height="50" transform="translate(75,280)">
<s:alias val="d_sk_v"/>
<text x="25" y="25" s:attribute="ref" class="$cell_id">X1</text>
<path d="M0,15 H20 L10,35 Z M0,35 H20" class="symbol $cell_id"/>
<path d="M10,0 V15 M10,35 V50" class="connect $cell_id"/>
<!-- schottky -->
<path d="M0,35 V40 M20,35 V30" class="symbol $cell_id"/>
<g s:x="10" s:y="0" s:pid="+" s:position="top"/>
<g s:x="10" s:y="50" s:pid="-" s:position="bottom"/>
</g>
<g s:type="diode_led_h" s:width="50" s:height="20" transform="translate(115,250)">
<s:alias val="d_led_h"/>
<text class="nodelabel $cell_id" x="10" y="-5" s:attribute="ref">X1</text>
<path d="M15,0 V20 L35,10 Z M35,0 V20" class="symbol $cell_id"/>
<path d="M0,10 H15 M35,10 H50" class="connect $cell_id"/>
<!-- led -->
<path d="m20,-5 7,-7" class="detail $cell_id"/>
<path d="m24,-12 6,-3 -3,6 z" class="detail $cell_id"/>
<path d="m25,0 7,-7" class="detail $cell_id"/>
<path d="m29,-7 6,-3 -3,6 z" class="detail $cell_id"/>
<g s:x="0" s:y="10" s:pid="+" s:position="top"/>
<g s:x="50" s:y="10" s:pid="-" s:position="bottom"/>
</g>
<g s:type="diode_led_v" s:width="20" s:height="50" transform="translate(130,280)">
<s:alias val="d_led_v"/>
<text x="25" y="25" s:attribute="ref" class="$cell_id">X1</text>
<path d="M0,15 H20 L10,35 Z M0,35 H20" class="symbol $cell_id"/>
<path d="M10,0 V15 M10,35 V50" class="connect $cell_id"/>
<!-- led -->
<path d="m-5,20 -7,7" class="detail $cell_id"/>
<path d="m-12,24 -3,6 6,-3 z" class="detail $cell_id"/>
<path d="m0,25 -7,7" class="detail $cell_id"/>
<path d="m-7,29 -3,6 6,-3 z" class="detail $cell_id"/>
<g s:x="10" s:y="0" s:pid="+" s:position="top"/>
<g s:x="10" s:y="50" s:pid="-" s:position="bottom"/>
</g>
<!-- diodes -->
<!-- transistors -->
<g s:type="transistor_npn" s:width="32" s:height="32" transform="translate(15,350)">
<s:alias val="q_npn"/>
<text x="35" y="20" s:attribute="ref" class="$cell_id">X1</text>
<circle r="16" cx="16" cy="16" class="symbol $cell_id"/>
<path d="M0,16 H12 M12,6 V26" class="detail $cell_id"/>
<path d="m12,10 11,-8" class="detail $cell_id"/>
<path d="m12,21 11,8" class="detail $cell_id"/>
<!-- npn -->
<path d="m23,29 -6,-1 3,-5 z" style="fill:#000000" class="$cell_id"/>
<g s:x="22" s:y="2" s:pid="C" s:position="top"/>
<g s:x="0" s:y="16" s:pid="B" s:position="left"/>
<g s:x="23" s:y="29" s:pid="E" s:position="bottom"/>
</g>
<g s:type="transistor_pnp" s:width="32" s:height="32" transform="translate(85,350)">
<s:alias val="q_pnp"/>
<text x="35" y="20" s:attribute="ref" class="$cell_id">X1</text>
<circle r="16" cx="16" cy="16" class="symbol $cell_id"/>
<path d="M0,16 H12 M12,6 V26" class="detail $cell_id"/>
<path d="m12,10 11,-8" class="detail $cell_id"/>
<path d="m12,21 11,8" class="detail $cell_id"/>
<!-- pnp -->
<path d="m14,9 6,-1 -3,-5 z" style="fill:#000000" class="$cell_id"/>
<g s:x="22" s:y="2" s:pid="C" s:position="top"/>
<g s:x="0" s:y="16" s:pid="B" s:position="left"/>
<g s:x="23" s:y="29" s:pid="E" s:position="bottom"/>
</g>
<!-- transistors -->
<!-- builtin -->
<g s:type="generic" s:width="30" s:height="40" transform="translate(150, 400)">
<text x="15" y="-4" class="nodelabel $cell_id" s:attribute="ref">generic</text>
<rect width="30" height="40" x="0" y="0" s:generic="body" class="$cell_id"/>
<g transform="translate(30,10)"
s:x="30" s:y="10" s:pid="out0" s:position="right">
<text x="5" y="-4" class="$cell_id">out0</text>
</g>
<g transform="translate(30,30)"
s:x="30" s:y="30" s:pid="out1" s:position="right">
<text x="5" y="-4" class="$cell_id">out1</text>
</g>
<g transform="translate(0,10)"
s:x="0" s:y="10" s:pid="in0" s:position="left">
<text x="-3" y="-4" class="inputPortLabel $cell_id">in0</text>
</g>
<g transform="translate(0,30)"
s:x="0" s:y="30" s:pid="in1" s:position="left">
<text x="-3" y="-4" class="inputPortLabel $cell_id">in1</text>
</g>
</g>
<!-- builtin -->
<!-- misc -->
<g s:type="opamp" s:width="60" s:height="40" transform="translate(20,450)">
<s:alias val="op"/>
<text x="40" y="35" s:attribute="ref" class="$cell_id">X1</text>
<path d="M10,0 V40 L50,20 Z" class="symbol $cell_id"/>
<path d="M0,10 H10 M0,30 H10 M50,20 H60 M30,0 V10 M30,40 V30" class="connect $cell_id"/>
<path d="m15,10 5,0 m-2.5,-2.5 0,5" class="detail $cell_id"/>
<path d="m15,30 5,0" class="detail $cell_id"/>
<g s:x="0" s:y="10" s:pid="+" s:position="left"/>
<g s:x="0" s:y="30" s:pid="-" s:position="left"/>
<g s:x="60" s:y="20" s:pid="OUT" s:position="right"/>
<g s:x="30" s:y="0" s:pid="VCC" s:position="top"/>
<g s:x="30" s:y="40" s:pid="VEE" s:position="bottom"/>
</g>
<g s:type="xtal" s:width="40" s:height="30" transform="translate(90,450)">
<s:alias val="xtal"/>
<text class="nodelabel $cell_id" x="20" y="45" s:attribute="ref">X1</text>
<rect x="15" y="0" width="10" height="30" class="symbol $cell_id" />
<path d="M0,15 H10 M10,5 V25 M30,5 V25 M30,15 H40" class="$cell_id"/>
<g s:x="0" s:y="15" s:pid="A" s:position="left"/>
<g s:x="40" s:y="15" s:pid="B" s:position="right"/>
</g>
<g s:type="transformer_1p_1s" s:width="35" s:height="45" transform="translate(140,450)">
<s:alias val="transformer_1p_1s"/>
<text class="nodelabel $cell_id" x="25" y="55" s:attribute="ref">X1</text>
<path d="M10,0 A5,5 0 0 1 10,10 A5,5 0 0 1 10,20 A5,5 0 0 1 10,30 A5,5 0 0 1 10,40" class="$cell_id"/>
<path d="M35,0 A5,5 0 0 0 35,10 A5,5 0 0 0 35,20 A5,5 0 0 0 35,30 A5,5 0 0 0 35,40" class="$cell_id"/>
<path d="M20,0 V40 M25,0 V40" class="symbol $cell_id"/>
<path d="M0,0 H10 M0,40 H10 M35,0 H45 M35,40 H45" class="connect $cell_id"/>
<g s:x="0" s:y="0" s:pid="L1.1" s:position="left"/>
<g s:x="0" s:y="40" s:pid="L1.2" s:position="left"/>
<g s:x="40" s:y="0" s:pid="L2.1" s:position="right"/>
<g s:x="40" s:y="40" s:pid="L2.2" s:position="right"/>
</g>
<!-- misc -->
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

681
src/static/digital.svg Normal file
View File

@ -0,0 +1,681 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:s="https://github.com/nturley/netlistsvg"
width="800" height="500">
<s:properties>
<s:layoutEngine
org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers="35"
org.eclipse.elk.spacing.nodeNode= "35"
org.eclipse.elk.layered.layering.strategy= "LONGEST_PATH"
/>
<s:low_priority_alias val="$dff" />
</s:properties>
<style>
svg {
stroke:#000;
fill:none;
}
text {
fill:#000;
stroke:none;
font-size:10px;
font-weight: bold;
font-family: "Courier New", monospace;
}
line {
stroke-linecap: round;
}
.nodelabel {
text-anchor: middle;
}
.inputPortLabel {
text-anchor: end;
}
.splitjoinBody {
fill:#000;
}
</style>
<g s:type="mux" transform="translate(50, 50)" s:width="20" s:height="40">
<s:alias val="$pmux"/>
<s:alias val="$mux"/>
<s:alias val="$_MUX_"/>
<path style="fill:#eeaaff" d="M0,0 L20,10 L20,30 L0,40 Z" class="$cell_id"/>
<text x="5" y="13" class="nodelabel $cell_id" s:attribute="">0</text>
<text x="5" y="32" class="nodelabel $cell_id" s:attribute="">1</text>
<g s:x="0" s:y="10" s:pid="A"/>
<g s:x="0" s:y="30" s:pid="B"/>
<g s:x="10" s:y="35" s:pid="S"/>
<g s:x="20" s:y="20" s:pid="Y"/>
</g>
<g s:type="mux-bus" transform="translate(100, 50)" s:width="24" s:height="40" >
<s:alias val="$pmux-bus"/>
<s:alias val="$mux-bus"/>
<s:alias val="$_MUX_-bus"/>
<path style="fill:#eeaaff" d="M0,0 L20,10 L20,30 L0,40 Z" class="$cell_id"/>
<path d="M4,2 L4,0 L22,9 L22,31 L4,40 L4,38" class="$cell_id"/>
<path d="M8,2 L8,0 L24,8 L24,32 L8,40 L8,38" class="$cell_id"/>
<text x="5" y="13" class="nodelabel $cell_id" s:attribute="">A</text>
<text x="5" y="32" class="nodelabel $cell_id" s:attribute="">B</text>
<g s:x="-1" s:y="10" s:pid="A"/>
<g s:x="-1" s:y="30" s:pid="B"/>
<g s:x="12" s:y="38" s:pid="S"/>
<g s:x="24.5" s:y="20" s:pid="Y"/>
</g>
<!-- and -->
<g s:type="and" transform="translate(150,50)" s:width="30" s:height="25">
<s:alias val="$and"/>
<s:alias val="$logic_and"/>
<s:alias val="$_AND_"/>
<s:alias val="$reduce_and"/>
<path style="fill:#80D4FF" d="M0,0 L0,25 L15,25 A15 12.5 0 0 0 15,0 Z" class="$cell_id"/>
<g s:x="0" s:y="5" s:pid="A"/>
<g s:x="0" s:y="20" s:pid="B"/>
<g s:x="30" s:y="12.5" s:pid="Y"/>
<text x="3.0" y="15" class="smalltext">and</text>
</g>
<g s:type="nand" transform="translate(150,100)" s:width="30" s:height="25">
<s:alias val="$nand"/>
<s:alias val="$logic_nand"/>
<s:alias val="$_NAND_"/>
<s:alias val="$_ANDNOT_"/>
<path style="fill:#80D4FF" d="M0,0 L0,25 L15,25 A15 12.5 0 0 0 15,0 Z" class="$cell_id"/>
<circle cx="34" cy="12.5" r="3" class="$cell_id"/>
<g s:x="0" s:y="5" s:pid="A"/>
<g s:x="0" s:y="20" s:pid="B"/>
<g s:x="36" s:y="12.5" s:pid="Y"/>
<text x="3.0" y="15" class="smalltext">nand</text>
</g>
<!-- or -->
<g s:type="or" transform="translate(250,50)" s:width="30" s:height="25">
<s:alias val="$or"/>
<s:alias val="$logic_or"/>
<s:alias val="$_OR_"/>
<s:alias val="$reduce_or"/>
<s:alias val="$reduce_bool"/>
<path style="fill:#80D4FF" d="M0,25 L0,25 L15,25 A15 12.5 0 0 0 15,0 L0,0" class="$cell_id"/>
<path style="fill:#ffffff" d="M0,0 A30 25 0 0 1 0,25" class="$cell_id"/>
<g s:x="2" s:y="5" s:pid="A"/>
<g s:x="2" s:y="20" s:pid="B"/>
<g s:x="30" s:y="12.5" s:pid="Y"/>
<text x="8.0" y="15" class="smalltext">or</text>
</g>
<g s:type="reduce_nor" transform="translate(250, 100)" s:width="33" s:height="25">
<s:alias val="$nor"/>
<s:alias val="$reduce_nor"/>
<s:alias val="$_NOR_"/>
<s:alias val="$_ORNOT_"/>
<path style="fill:#80D4FF" d="M0,25 L0,25 L15,25 A15 12.5 0 0 0 15,0 L0,0" class="$cell_id"/>
<path style="fill:#ffffff" d="M0,0 A30 25 0 0 1 0,25" class="$cell_id"/>
<circle cx="34" cy="12.5" r="3" class="$cell_id"/>
<g s:x="2" s:y="5" s:pid="A"/>
<g s:x="2" s:y="20" s:pid="B"/>
<g s:x="36" s:y="12.5" s:pid="Y"/>
<text x="8.0" y="15" class="smalltext">nor</text>
</g>
<!--xor -->
<g s:type="reduce_xor" transform="translate(350, 50)" s:width="33" s:height="25">
<s:alias val="$xor"/>
<s:alias val="$reduce_xor"/>
<s:alias val="$_XOR_"/>
<path style="fill:#80D4FF" d="M3,0 A30 25 0 0 1 3,25 A30 25 0 0 0 33,12.5 A30 25 0 0 0 3,0" class="$cell_id"/>
<path style="fill:#ffffff" d="M0,0 A30 25 0 0 1 0,25" class="$cell_id"/>
<g s:x="2" s:y="5" s:pid="A"/>
<g s:x="2" s:y="20" s:pid="B"/>
<g s:x="33" s:y="12.5" s:pid="Y"/>
<text x="10.0" y="15" class="smalltext">xor</text>
</g>
<g s:type="reduce_nxor" transform="translate(350, 100)" s:width="33" s:height="25">
<s:alias val="$xnor"/>
<s:alias val="$reduce_xnor"/>
<s:alias val="$_XNOR_"/>
<path style="fill:#80D4FF" d="M3,0 A30 25 0 0 1 3,25 A30 25 0 0 0 33,12.5 A30 25 0 0 0 3,0" class="$cell_id"/>
<path style="fill:#ffffff" d="M0,0 A30 25 0 0 1 0,25" class="$cell_id"/>
<circle cx="36" cy="12.5" r="3" class="$cell_id"/>
<g s:x="2" s:y="5" s:pid="A"/>
<g s:x="2" s:y="20" s:pid="B"/>
<g s:x="38" s:y="12.5" s:pid="Y"/>
<text x="8.0" y="15" class="smalltext">nxor</text>
</g>
<!--buffer -->
<g s:type="not" transform="translate(450,100)" s:width="30" s:height="20">
<s:alias val="$_NOT_"/>
<s:alias val="$not"/>
<s:alias val="$logic_not"/>
<path style="fill:#FFE680" d="M0,0 L0,20 L20,10 Z" class="$cell_id"/>
<circle cx="24" cy="10" r="3" class="$cell_id"/>
<g s:x="-1" s:y="10" s:pid="A"/>
<g s:x="27" s:y="10" s:pid="Y"/>
</g>
<g s:type="tribuf" transform="translate(450, 50)" s:width="15" s:height="30">
<s:alias val="$tribuf"/>
<s:alias val="$_TRIBUF_"/>
<s:alias val="tribuf-bus"/>
<s:alias val="$tribuf-bus"/>
<s:alias val="$_TRIBUF_-bus"/>
<path style="fill:#FFE680" d="M0,0 L25,15 L0,30 Z" class="$cell_id"/>
<g s:x="0" s:y="15" s:pid="A"/>
<g s:x="11" s:y="6" s:pid="EN"/>
<g s:x="25" s:y="15" s:pid="Y"/>
</g>
<!-- Arithmetic -->
<g s:type="add" transform="translate(50, 150)" s:width="30" s:height="30">
<s:alias val="$add"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="12.5" y2="12.5" class="$cell_id"/>
<line x1="12.5" x2="12.5" y1="7.5" y2="17.5" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="pos" transform="translate(100, 150)" s:width="25" s:height="25">
<s:alias val="$pos"/>
<circle r="12.5" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="12.5" y2="12.5" class="$cell_id"/>
<line x1="12.5" x2="12.5" y1="7.5" y2="17.5" class="$cell_id"/>
<g s:x="-1" s:y="12.5" s:pid="A"/>
<g s:x="26" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="sub" transform="translate(150,150)" s:width="30" s:height="30">
<s:alias val="$sub"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="12.5" y2="12.5" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="neg" transform="translate(200,150)" s:width="25" s:height="25">
<s:alias val="$neg"/>
<circle r="12.5" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="12.5" y2="12.5" class="$cell_id"/>
<g s:x="0" s:y="12.5" s:pid="A"/>
<g s:x="25" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="eq" transform="translate(250,150)" s:width="30" s:height="30">
<s:alias val="$eq"/>
<s:alias val="$eqx"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="10" y2="10" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="15" y2="15" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="ne" transform="translate(500,150)" s:width="25" s:height="25">
<s:alias val="$ne"/>
<s:alias val="$nex"/>
<circle r="12.5" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="10" y2="10" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="15" y2="15" class="$cell_id"/>
<line x1="9" x2="16" y1="18" y2="7" class="$cell_id"/>
<g s:x="2" s:y="5" s:pid="A"/>
<g s:x="2" s:y="20" s:pid="B"/>
<g s:x="25" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="mul" transform="translate(300, 150)" s:width="30" s:height="30">
<s:alias val="$mul"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="17.5" y1="7.5" y2="17.5" class="$cell_id"/>
<line x1="17.5" x2="7.5" y1="7.5" y2="17.5" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="div" transform="translate(350, 150)" s:width="30" s:height="30">
<s:alias val="$div"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="15" x2="10" y1="7.5" y2="17.5" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="mod" transform="translate(400, 150)" s:width="30" s:height="30">
<s:alias val="$mod"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="15" x2="10" y1="7.5" y2="17.5" class="$cell_id"/>
<circle r="2" cx="8" cy="9" class="$cell_id"/>
<circle r="2" cx="17" cy="16" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="pow" transform="translate(450, 150)" s:width="30" s:height="30">
<s:alias val="$pow"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="7.5" x2="12.5" y1="17.5" y2="7.5" class="$cell_id"/>
<line x1="17.5" x2="12.5" y1="17.5" y2="7.5" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<!-- D Flip Flops -->
<g s:type="dff" transform="translate(50,300)" s:width="30" s:height="40">
<s:alias val="$dff"/>
<s:alias val="$_DFF_"/>
<s:alias val="$_DFF_P_"/>
<s:alias val="$adff"/>
<s:alias val="$_DFF_"/>
<s:alias val="$_DFF_P_"/>
<s:alias val="$sdff"/>
<s:alias val="$_DFF_"/>
<s:alias val="$_DFF_P_"/>
<rect style="fill:#29F7A4" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M0,35 L5,30 L0,25" class="$cell_id"/>
<g s:x="31" s:y="10" s:pid="Q"/>
<g s:x="-1" s:y="30" s:pid="CLK"/>
<g s:x="-1" s:y="30" s:pid="C"/>
<g s:x="-1" s:y="10" s:pid="D"/>
<g s:x="15" s:y="40" s:pid="ARST"/>
<g s:x="15" s:y="40" s:pid="SRST"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="6.0" y="33" class="smalltext">CLK</text>
<text x="5.0" y="22" class="verysmalltext">dff</text>
</g>
<g s:type="dff-bus" transform="translate(100,300)" s:width="34" s:height="44">
<s:alias val="$dff-bus"/>
<s:alias val="$_DFF_-bus"/>
<s:alias val="$_DFF_P_-bus"/>
<s:alias val="adff-bus"/>
<s:alias val="$adff-bus"/>
<s:alias val="$_DFF_-bus"/>
<s:alias val="$_DFF_P_-bus"/>
<s:alias val="sdff-bus"/>
<s:alias val="$sdff-bus"/>
<s:alias val="$_DFF_-bus"/>
<s:alias val="$_DFF_P_-bus"/>
<rect style="fill:#29F7A4" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M0,35 L5,30 L0,25" class="$cell_id"/>
<path d="M30,2 L32,2 L32,42 L2,42 L2,40" />
<path d="M32,4 L34,4 L34,44 L4,44 L4,42" />
<g s:x="35" s:y="10" s:pid="Q"/>
<g s:x="-1" s:y="30" s:pid="CLK"/>
<g s:x="-1" s:y="30" s:pid="C"/>
<g s:x="-1" s:y="10" s:pid="D"/>
<g s:x="17" s:y="44" s:pid="ARST"/>
<g s:x="17" s:y="44" s:pid="SRST"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="6.0" y="33" class="smalltext">CLK</text>
<text x="3.0" y="22" class="verysmalltext">dffs</text>
</g>
<g s:type="dffn" transform="translate(150,300)" s:width="30" s:height="40">
<s:alias val="$dffn"/>
<s:alias val="$_DFF_N_"/>
<rect style="fill:#29F7A4" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M0,35 L5,30 L0,25" class="$cell_id"/>
<circle cx="-3" cy="30" r="3" class="$cell_id"/>
<g s:x="30" s:y="10" s:pid="Q"/>
<g s:x="-6" s:y="30" s:pid="CLK"/>
<g s:x="-6" s:y="30" s:pid="C"/>
<g s:x="0" s:y="10" s:pid="D"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="6.0" y="33" class="smalltext">CLK</text>
<text x="3.0" y="22" class="verysmalltext">dffn</text>
</g>
<g s:type="dffn-bus" transform="translate(200,300)" s:width="30" s:height="40">
<s:alias val="$dffn-bus"/>
<s:alias val="$_DFF_N_-bus"/>
<rect style="fill:#29F7A4" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M0,35 L5,30 L0,25" class="$cell_id"/>
<circle cx="-3" cy="30" r="3" class="$cell_id"/>
<path d="M30,2 L32,2 L32,42 L2,42 L2,40" />
<path d="M32,4 L34,4 L34,44 L4,44 L4,42" />
<g s:x="35" s:y="10" s:pid="Q"/>
<g s:x="-6" s:y="30" s:pid="CLK"/>
<g s:x="-6" s:y="30" s:pid="C"/>
<g s:x="0" s:y="10" s:pid="D"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="6.0" y="33" class="smalltext">CLK</text>
<text x="0.0" y="22" class="verysmalltext">dffns</text>
</g>
<!-- D Latches -->
<g s:type="dlatch" transform="translate(250,300)" s:width="30" s:height="40">
<s:alias val="$dlatch"/>
<s:alias val="$_DLATCH_"/>
<s:alias val="adlatch"/>
<s:alias val="$adlatch"/>
<rect style="fill:#33BCA8" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M 1,35 H 4 V 25 h 5 v 10 h 3"/>
<g s:x="30" s:y="10" s:pid="Q"/>
<g s:x="0" s:y="10" s:pid="D"/>
<g s:x="-1" s:y="30" s:pid="EN"/>
<g s:x="15" s:y="40" s:pid="ARST"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="15.0" y="33" class="smalltext">EN</text>
<text x="6.0" y="20" class="verysmalltext">dla</text>
</g>
<g s:type="dlatch-bus" transform="translate(300,300)" s:width="30" s:height="40">
<s:alias val="$dlatch-bus"/>
<s:alias val="$_DLATCH_-bus"/>
<s:alias val="adlatch-bus"/>
<s:alias val="$adlatch-bus"/>
<rect style="fill:#33BCA8" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M 1,35 H 4 V 25 h 5 v 10 h 3"/>
<path d="M30,2 L32,2 L32,42 L2,42 L2,40" />
<path d="M32,4 L34,4 L34,44 L4,44 L4,42" />
<g s:x="35" s:y="10" s:pid="Q"/>
<g s:x="0" s:y="10" s:pid="D"/>
<g s:x="-1" s:y="30" s:pid="EN"/>
<g s:x="17" s:y="44" s:pid="ARST"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="15.0" y="33" class="smalltext">EN</text>
<text x="3.0" y="20" class="verysmalltext">dlas</text>
</g>
<g s:type="dlatchn" transform="translate(350,300)" s:width="30" s:height="40">
<s:alias val="$dlatchn"/>
<s:alias val="$_DLATCH_"/>
<rect style="fill:#33BCA8" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M 1,25 H 4 V 35 H 9 V 25 h 3" />
<g s:x="30" s:y="10" s:pid="Q"/>
<g s:x="0" s:y="10" s:pid="D"/>
<g s:x="-1" s:y="30" s:pid="EN"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="15.0" y="33" class="smalltext">EN</text>
<text x="3.0" y="20" class="verysmalltext">dlan</text>
</g>
<g s:type="dlatchn-bus" transform="translate(400,300)" s:width="30" s:height="40">
<s:alias val="$dlatchn-bus"/>
<s:alias val="$_DLATCH_-bus"/>
<rect style="fill:#33BCA8" width="30" height="40" x="0" y="0" class="$cell_id"/>
<path d="M 1,25 H 4 V 35 H 9 V 25 h 3" />
<path d="M30,2 L32,2 L32,42 L2,42 L2,40" />
<path d="M32,4 L34,4 L34,44 L4,44 L4,42" />
<g s:x="35" s:y="10" s:pid="Q"/>
<g s:x="0" s:y="10" s:pid="D"/>
<g s:x="-1" s:y="30" s:pid="EN"/>
<text x="2.0" y="10" class="smalltext">D</text>
<text x="20.0" y="10" class="smalltext rtext">Q</text>
<text x="15.0" y="33" class="smalltext">EN</text>
<text x="0.0" y="20" class="verysmalltext">dlans</text>
</g>
<!-- compare -->
<g s:type="lt" transform="translate(50,200)" s:width="25" s:height="25">
<s:alias val="$lt"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="6" x2="17" y1="12" y2="7" class="$cell_id"/>
<line x1="6" x2="17" y1="12" y2="17" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="le" transform="translate(100,200)" s:width="25" s:height="25">
<s:alias val="$le"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="6" x2="17" y1="11" y2="6" class="$cell_id"/>
<line x1="6" x2="17" y1="11" y2="16" class="$cell_id"/>
<line x1="6" x2="17" y1="14" y2="19" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="ge" transform="translate(150,200)" s:width="25" s:height="25">
<s:alias val="$ge"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="8" x2="19" y1="6" y2="11" class="$cell_id"/>
<line x1="8" x2="19" y1="16" y2="11" class="$cell_id"/>
<line x1="8" x2="19" y1="19" y2="14" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="gt" transform="translate(200,200)" s:width="25" s:height="25">
<s:alias val="$gt"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="8" x2="19" y1="7" y2="12" class="$cell_id"/>
<line x1="8" x2="19" y1="17" y2="12" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<!-- shift -->
<g s:type="shr" transform="translate(250,200)" s:width="25" s:height="25">
<s:alias val="$shr"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="8" x2="13" y1="7" y2="12" class="$cell_id"/>
<line x1="8" x2="13" y1="17" y2="12" class="$cell_id"/>
<line x1="14" x2="19" y1="7" y2="12" class="$cell_id"/>
<line x1="14" x2="19" y1="17" y2="12" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="shl" transform="translate(300,200)" s:width="25" s:height="25">
<s:alias val="$shl"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="6" x2="11" y1="12" y2="7" class="$cell_id"/>
<line x1="6" x2="11" y1="12" y2="17" class="$cell_id"/>
<line x1="12" x2="17" y1="12" y2="7" class="$cell_id"/>
<line x1="12" x2="17" y1="12" y2="17" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="sshr" transform="translate(350,200)" s:width="25" s:height="25">
<s:alias val="$sshr"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="5" x2="10" y1="7" y2="12" class="$cell_id"/>
<line x1="5" x2="10" y1="17" y2="12" class="$cell_id"/>
<line x1="11" x2="16" y1="7" y2="12" class="$cell_id"/>
<line x1="11" x2="16" y1="17" y2="12" class="$cell_id"/>
<line x1="17" x2="22" y1="7" y2="12" class="$cell_id"/>
<line x1="17" x2="22" y1="17" y2="12" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<g s:type="sshl" transform="translate(400,200)" s:width="25" s:height="25">
<s:alias val="$sshl"/>
<circle r="15" cx="12.5" cy="12.5" class="$cell_id"/>
<line x1="3" x2="8" y1="12" y2="7" class="$cell_id"/>
<line x1="3" x2="8" y1="12" y2="17" class="$cell_id"/>
<line x1="9" x2="14" y1="12" y2="7" class="$cell_id"/>
<line x1="9" x2="14" y1="12" y2="17" class="$cell_id"/>
<line x1="15" x2="20" y1="12" y2="7" class="$cell_id"/>
<line x1="15" x2="20" y1="12" y2="17" class="$cell_id"/>
<g s:x="0" s:y="2.5" s:pid="A"/>
<g s:x="0" s:y="22.5" s:pid="B"/>
<g s:x="27.5" s:y="12.5" s:pid="Y"/>
</g>
<!-- port -->
<g s:type="inputExt" transform="translate(50,250)" s:width="30" s:height="20">
<text x="15" y="-4" class="nodelabel $cell_id" s:attribute="ref">input</text>
<s:alias val="$_inputExt_"/>
<path style="fill:#FDF766" d="M0,0 L0,16 L15,16 L24,8 L15,0 Z" class="$cell_id"/>
<g s:x="24" s:y="8" s:pid="Y"/>
</g>
<g s:type="outputExt" transform="translate(250,250)" s:width="30" s:height="20">
<text x="15" y="-4" class="nodelabel $cell_id" s:attribute="ref">output</text>
<s:alias val="$_outputExt_"/>
<path style="fill:#66FDD9" d="M24,0 L24,16 L10,16 L0,8 L10,0 Z" class="$cell_id"/>
<g s:x="0" s:y="8" s:pid="A"/>
</g>
<g s:type="constant" transform="translate(150,250)" s:width="30" s:height="20">
<text x="15" y="-4" class="nodelabel $cell_id" s:attribute="ref">constant</text>
<s:alias val="$_constant_"/>
<rect style="fill:#7F66FD" width="30" height="20" rx="5" ry="5" class="$cell_id"/>
<g s:x="31" s:y="10" s:pid="Y"/>
</g>
<g s:type="split" transform="translate(350,250)" s:width="5" s:height="40">
<rect width="5" height="40" class="splitjoinBody" s:generic="body"/>
<s:alias val="$_split_"/>
<g s:x="0" s:y="20" s:pid="in"/>
<g transform="translate(5, 10)" s:x="4" s:y="10" s:pid="out0">
<text x="5" y="-4">hi:lo</text>
</g>
<g transform="translate(5, 30)" s:x="4" s:y="30" s:pid="out1">
<text x="5" y="-4">hi:lo</text>
</g>
</g>
<g s:type="join" transform="translate(450,250)" s:width="4" s:height="40">
<rect width="5" height="40" class="splitjoinBody" s:generic="body"/>
<s:alias val="$_join_"/>
<g s:x="5" s:y="20" s:pid="out"/>
<g transform="translate(0, 10)" s:x="0" s:y="10" s:pid="in0">
<text x="-3" y="-4" class="inputPortLabel">hi:lo</text>
</g>
<g transform="translate(0, 30)" s:x="0" s:y="30" s:pid="in1">
<text x="-3" y="-4" class="inputPortLabel">hi:lo</text>
</g>
</g>
<!-- <defs>
<filter id="f4" x="0" y="0" width="110%" height="120%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feColorMatrix result="matrixOut" in="offOut" type="matrix"
values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs> -->
<g s:type="generic" transform="translate(550,250)" s:width="60" s:height="45">
<text x="30" y="-4" class="nodelabel $cell_id" s:attribute="ref">generic</text>
<rect style="fill:#EDF5FF" width="60" height="45" rx="5" ry="5" s:generic="body" class="$cell_id"/>
<!-- <g transform="translate(60, 25)" s:x="60" s:y="15" s:pid="buso">
<rect style="fill:#EDF5FF" width="5" height="10" s:generic="body" class="$bus_id"/>
</g>
<g transform="translate(-5, 25)" s:x="60" s:y="15" s:pid="busi">
<rect style="fill:#EDF5FF" width="5" height="10" s:generic="body" class="$bus_id"/>
</g> -->
<g transform="translate(60, 15)" s:x="60" s:y="15" s:pid="out0">
<text x="5" y="-4" style="fill:#000; stroke:none" class="$cell_id">out0</text>
</g>
<g transform="translate(60, 35)" s:x="60" s:y="35" s:pid="out1">
<text x="5" y="-4" style="fill:#000;stroke:none" class="$cell_id">out1</text>
</g>
<g transform="translate(0, 15)" s:x="0" s:y="15" s:pid="in0">
<text x="-3" y="-4" class="inputPortLabel $cell_id">in0</text>
</g>
<g transform="translate(0, 35)" s:x="0" s:y="35" s:pid="in1">
<text x="-3" y="-4" class="inputPortLabel $cell_id">in1</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB