From c4c6605174b89e5c8ed682d090b2ec8c443f91f9 Mon Sep 17 00:00:00 2001
From: Kirigaya <1193466151@qq.com>
Date: Thu, 2 Jan 2025 03:38:46 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20netlist=20bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/index.html | 4 +-
public/netlist.json | 630 ++++++++++++++++++++++++++++++++++++++
public/netlist.v | 35 +++
src/hook/render/layout.js | 38 ++-
src/hook/render/wire.js | 70 ++++-
src/hook/skin/draw.js | 8 +
src/hook/skin/index.js | 25 ++
7 files changed, 793 insertions(+), 17 deletions(-)
create mode 100644 public/netlist.json
create mode 100644 public/netlist.v
diff --git a/public/index.html b/public/index.html
index b8b5b9f..8760ed8 100644
--- a/public/index.html
+++ b/public/index.html
@@ -15,7 +15,7 @@
diff --git a/public/netlist.json b/public/netlist.json
new file mode 100644
index 0000000..fc211a3
--- /dev/null
+++ b/public/netlist.json
@@ -0,0 +1,630 @@
+{
+ "creator": "Yosys 0.48+5 (git sha1 7a362f1f7, clang++ 18.1.2-wasi-sdk -Oz)",
+ "modules": {
+ "netlistview": {
+ "attributes": {
+ "cells_not_processed": "00000000000000000000000000000001",
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:2.1-36.10"
+ },
+ "ports": {
+ "clock": {
+ "direction": "input",
+ "bits": [ 2 ]
+ },
+ "data_in": {
+ "direction": "input",
+ "bits": [ 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
+ },
+ "up": {
+ "direction": "input",
+ "bits": [ 12 ]
+ },
+ "down": {
+ "direction": "input",
+ "bits": [ 13 ]
+ },
+ "carry_out": {
+ "direction": "output",
+ "bits": [ 14 ]
+ },
+ "borrow_out": {
+ "direction": "output",
+ "bits": [ 15 ]
+ },
+ "count_out": {
+ "direction": "output",
+ "bits": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ]
+ },
+ "parity_out": {
+ "direction": "output",
+ "bits": [ 25 ]
+ }
+ },
+ "cells": {
+ "$add$/dide/user/src/language/vlog/netlistview/netlistview.v:15$3": {
+ "hide_name": 1,
+ "type": "$add",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000001001",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000010",
+ "Y_WIDTH": "00000000000000000000000000001010"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:15.18-15.36"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ],
+ "B": [ "1", "1" ],
+ "Y": [ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 ]
+ }
+ },
+ "$and$/dide/user/src/language/vlog/netlistview/netlistview.v:31$5": {
+ "hide_name": 1,
+ "type": "$and",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000000001",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000001",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:31.24-31.38"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 12 ],
+ "B": [ 35 ],
+ "Y": [ 36 ]
+ }
+ },
+ "$and$/dide/user/src/language/vlog/netlistview/netlistview.v:32$6": {
+ "hide_name": 1,
+ "type": "$and",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000000001",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000001",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:32.24-32.40"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 13 ],
+ "B": [ 37 ],
+ "Y": [ 38 ]
+ }
+ },
+ "$procdff$12": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000001001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "Q": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ]
+ }
+ },
+ "$procdff$13": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 36 ],
+ "Q": [ 14 ]
+ }
+ },
+ "$procdff$14": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 38 ],
+ "Q": [ 15 ]
+ }
+ },
+ "$procdff$15": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 48 ],
+ "Q": [ 25 ]
+ }
+ },
+ "$procdff$16": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000001010"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 ],
+ "Q": [ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58 ]
+ }
+ },
+ "$procdff$17": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000001010"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 59, 60, 61, 62, 63, 64, 65, 66, 67, 37 ],
+ "Q": [ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 ]
+ }
+ },
+ "$procdff$18": {
+ "hide_name": 1,
+ "type": "$dff",
+ "parameters": {
+ "CLK_POLARITY": "1",
+ "WIDTH": "00000000000000000000000000001001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ },
+ "port_directions": {
+ "CLK": "input",
+ "D": "input",
+ "Q": "output"
+ },
+ "connections": {
+ "CLK": [ 2 ],
+ "D": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "Q": [ 78, 79, 80, 81, 82, 83, 84, 85, 86 ]
+ }
+ },
+ "$procmux$10_CMP0": {
+ "hide_name": 1,
+ "type": "$eq",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000000010",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000010",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "full_case": "00000000000000000000000000000001",
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:0.0-0.0|/dide/user/src/language/vlog/netlistview/netlistview.v:17.9-28.16"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 13, 12 ],
+ "B": [ "1", "0" ],
+ "Y": [ 87 ]
+ }
+ },
+ "$procmux$11_CMP0": {
+ "hide_name": 1,
+ "type": "$logic_not",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000000010",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "full_case": "00000000000000000000000000000001",
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:0.0-0.0|/dide/user/src/language/vlog/netlistview/netlistview.v:17.9-28.16"
+ },
+ "port_directions": {
+ "A": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 13, 12 ],
+ "Y": [ 88 ]
+ }
+ },
+ "$procmux$7": {
+ "hide_name": 1,
+ "type": "$pmux",
+ "parameters": {
+ "S_WIDTH": "00000000000000000000000000000100",
+ "WIDTH": "00000000000000000000000000001001"
+ },
+ "attributes": {
+ "full_case": "00000000000000000000000000000001",
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:0.0-0.0|/dide/user/src/language/vlog/netlistview/netlistview.v:17.9-28.16"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "S": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ "x", "x", "x", "x", "x", "x", "x", "x", "x" ],
+ "B": [ 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 33, 34, 59, 60, 61, 62, 63, 64, 65, 66, 67, 3, 4, 5, 6, 7, 8, 9, 10, 11 ],
+ "S": [ 89, 90, 87, 88 ],
+ "Y": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ]
+ }
+ },
+ "$procmux$8_CMP0": {
+ "hide_name": 1,
+ "type": "$eq",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000000010",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000010",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "full_case": "00000000000000000000000000000001",
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:0.0-0.0|/dide/user/src/language/vlog/netlistview/netlistview.v:17.9-28.16"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 13, 12 ],
+ "B": [ "1", "1" ],
+ "Y": [ 89 ]
+ }
+ },
+ "$procmux$9_CMP0": {
+ "hide_name": 1,
+ "type": "$eq",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000000010",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000010",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "full_case": "00000000000000000000000000000001",
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:0.0-0.0|/dide/user/src/language/vlog/netlistview/netlistview.v:17.9-28.16"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 13, 12 ],
+ "B": [ "0", "1" ],
+ "Y": [ 90 ]
+ }
+ },
+ "$reduce_xor$/dide/user/src/language/vlog/netlistview/netlistview.v:30$4": {
+ "hide_name": 1,
+ "type": "$reduce_xor",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000001001",
+ "Y_WIDTH": "00000000000000000000000000000001"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:30.24-30.34"
+ },
+ "port_directions": {
+ "A": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "Y": [ 48 ]
+ }
+ },
+ "$sub$/dide/user/src/language/vlog/netlistview/netlistview.v:14$2": {
+ "hide_name": 1,
+ "type": "$sub",
+ "parameters": {
+ "A_SIGNED": "00000000000000000000000000000000",
+ "A_WIDTH": "00000000000000000000000000001001",
+ "B_SIGNED": "00000000000000000000000000000000",
+ "B_WIDTH": "00000000000000000000000000000011",
+ "Y_WIDTH": "00000000000000000000000000001010"
+ },
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:14.18-14.37"
+ },
+ "port_directions": {
+ "A": "input",
+ "B": "input",
+ "Y": "output"
+ },
+ "connections": {
+ "A": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ],
+ "B": [ "1", "0", "1" ],
+ "Y": [ 59, 60, 61, 62, 63, 64, 65, 66, 67, 37 ]
+ }
+ }
+ },
+ "netnames": {
+ "$0\\borrow_out[0:0]": {
+ "hide_name": 1,
+ "bits": [ 38 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$0\\carry_out[0:0]": {
+ "hide_name": 1,
+ "bits": [ 36 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$0\\cnt_dn[9:0]": {
+ "hide_name": 1,
+ "bits": [ 59, 60, 61, 62, 63, 64, 65, 66, 67, 37 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$0\\cnt_up[9:0]": {
+ "hide_name": 1,
+ "bits": [ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$0\\count_nxt[8:0]": {
+ "hide_name": 1,
+ "bits": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$0\\count_out[8:0]": {
+ "hide_name": 1,
+ "bits": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$0\\parity_out[0:0]": {
+ "hide_name": 1,
+ "bits": [ 48 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$1\\count_nxt[8:0]": {
+ "hide_name": 1,
+ "bits": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:13.5-34.8"
+ }
+ },
+ "$add$/dide/user/src/language/vlog/netlistview/netlistview.v:15$3_Y": {
+ "hide_name": 1,
+ "bits": [ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:15.18-15.36"
+ }
+ },
+ "$and$/dide/user/src/language/vlog/netlistview/netlistview.v:31$5_Y": {
+ "hide_name": 1,
+ "bits": [ 36 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:31.24-31.38"
+ }
+ },
+ "$and$/dide/user/src/language/vlog/netlistview/netlistview.v:32$6_Y": {
+ "hide_name": 1,
+ "bits": [ 38 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:32.24-32.40"
+ }
+ },
+ "$procmux$10_CMP": {
+ "hide_name": 1,
+ "bits": [ 87 ],
+ "attributes": {
+ }
+ },
+ "$procmux$11_CMP": {
+ "hide_name": 1,
+ "bits": [ 88 ],
+ "attributes": {
+ }
+ },
+ "$procmux$7_Y": {
+ "hide_name": 1,
+ "bits": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],
+ "attributes": {
+ }
+ },
+ "$procmux$8_CMP": {
+ "hide_name": 1,
+ "bits": [ 89 ],
+ "attributes": {
+ }
+ },
+ "$procmux$9_CMP": {
+ "hide_name": 1,
+ "bits": [ 90 ],
+ "attributes": {
+ }
+ },
+ "$reduce_xor$/dide/user/src/language/vlog/netlistview/netlistview.v:30$4_Y": {
+ "hide_name": 1,
+ "bits": [ 48 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:30.24-30.34"
+ }
+ },
+ "$sub$/dide/user/src/language/vlog/netlistview/netlistview.v:14$2_Y": {
+ "hide_name": 1,
+ "bits": [ 59, 60, 61, 62, 63, 64, 65, 66, 67, 37 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:14.18-14.37"
+ }
+ },
+ "borrow_out": {
+ "hide_name": 0,
+ "bits": [ 15 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:8.27-8.37"
+ }
+ },
+ "carry_out": {
+ "hide_name": 0,
+ "bits": [ 14 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:8.16-8.25"
+ }
+ },
+ "clock": {
+ "hide_name": 0,
+ "bits": [ 2 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:5.11-5.16"
+ }
+ },
+ "cnt_dn": {
+ "hide_name": 0,
+ "bits": [ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:10.23-10.29"
+ }
+ },
+ "cnt_up": {
+ "hide_name": 0,
+ "bits": [ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:10.15-10.21"
+ }
+ },
+ "count_nxt": {
+ "hide_name": 0,
+ "bits": [ 78, 79, 80, 81, 82, 83, 84, 85, 86 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:11.15-11.24"
+ }
+ },
+ "count_out": {
+ "hide_name": 0,
+ "bits": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:7.22-7.31"
+ }
+ },
+ "data_in": {
+ "hide_name": 0,
+ "bits": [ 3, 4, 5, 6, 7, 8, 9, 10, 11 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:4.17-4.24"
+ }
+ },
+ "down": {
+ "hide_name": 0,
+ "bits": [ 13 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:5.22-5.26"
+ }
+ },
+ "parity_out": {
+ "hide_name": 0,
+ "bits": [ 25 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:8.39-8.49"
+ }
+ },
+ "up": {
+ "hide_name": 0,
+ "bits": [ 12 ],
+ "attributes": {
+ "src": "/dide/user/src/language/vlog/netlistview/netlistview.v:5.18-5.20"
+ }
+ }
+ }
+ }
+ }
+ }
\ No newline at end of file
diff --git a/public/netlist.v b/public/netlist.v
new file mode 100644
index 0000000..8424a15
--- /dev/null
+++ b/public/netlist.v
@@ -0,0 +1,35 @@
+module netlistview(clock, data_in, up, down, carry_out, borrow_out, count_out, parity_out);
+
+ input [8:0] data_in;
+ input clock, up, down;
+
+ output reg [8:0] count_out;
+ output reg carry_out, borrow_out, parity_out;
+
+ reg [9:0] cnt_up, cnt_dn;
+ reg [8:0] count_nxt;
+
+ always @(posedge clock) begin
+ cnt_dn = count_out - 3'b 101;
+ cnt_up = count_out + 2'b 11;
+
+ case ({up,down})
+ 2'b 00 :
+ count_nxt = data_in;
+ 2'b 01 :
+ count_nxt = cnt_dn;
+ 2'b 10 :
+ count_nxt = cnt_up;
+ 2'b 11 :
+ count_nxt = count_out;
+ default :
+ count_nxt = 9'bX;
+ endcase
+
+ parity_out <= ^count_nxt;
+ carry_out <= up & cnt_up[9];
+ borrow_out <= down & cnt_dn[9];
+ count_out <= count_nxt;
+ end
+
+endmodule
\ No newline at end of file
diff --git a/src/hook/render/layout.js b/src/hook/render/layout.js
index a1f3288..5d1e814 100644
--- a/src/hook/render/layout.js
+++ b/src/hook/render/layout.js
@@ -277,7 +277,10 @@ export class Module {
// 当前的器件的这个端口和某一个 port 连接
const port = tree.wireIdToPort.get(wireId);
- if (port.direction === 'input') {
+ // 器件的端口的方向有比 port 更高的优先级。
+ // 器件当前的口为 input,那么所连接的 port 就必须是 input,即便这个 port 是 output
+
+ if (connection.direction === 'input') {
const edge = {
// id 遵循 sourcePort-targetPort
id: makeEdgeId(port.id, connection.id),
@@ -357,15 +360,40 @@ export class Module {
// 统计分配到左右两侧的 port
const leftSideConnections = [];
const rightSideConnections = [];
+ const topSideConnections = [];
- for (const conn of cell.nameToConnection.values()) {
- if (conn.direction === 'input') {
- leftSideConnections.push(conn);
+ for (const connection of cell.nameToConnection.values()) {
+ const yOffset = meta.getPortYOffset(connection.name);
+ if (yOffset === 0) {
+ topSideConnections.push(connection);
+ } else if (connection.direction === 'input') {
+ leftSideConnections.push(connection);
} else {
- rightSideConnections.push(conn);
+ rightSideConnections.push(connection);
}
}
+ // 计算上侧的
+ for (let i = 0; i < topSideConnections.length; ++ i) {
+ const connection = topSideConnections[i];
+ const xOffset = meta.getPortXOffset(connection.name);
+
+ console.log(xOffset);
+
+ ports.push({
+ id: connection.id,
+ renderName: connection.name,
+ renderType: 'cellPort',
+ direction: 'input',
+ source: 'cell',
+ isVertical: true,
+ width: LAYOUT_CONSTANT.CELL_PORT_WIDTH,
+ height: LAYOUT_CONSTANT.CELL_PORT_HEIGHT,
+ x: xOffset,
+ y: 0
+ });
+ }
+
// 计算左侧的
for (let i = 0; i < leftSideConnections.length; ++ i) {
const connection = leftSideConnections[i];
diff --git a/src/hook/render/wire.js b/src/hook/render/wire.js
index 7220b44..9412f3c 100644
--- a/src/hook/render/wire.js
+++ b/src/hook/render/wire.js
@@ -45,6 +45,7 @@ export class WireRender {
const beginPoint = points.at(0);
const endPoint = points.at(-1);
+ const lastTwoPoint = points.at(-2);
const sourcePort = id2port.get(edge.sourcePort);
const targetPort = id2port.get(edge.targetPort);
@@ -52,14 +53,21 @@ export class WireRender {
const targetMargin = getMarginParamter(targetPort);
beginPoint.x -= sourceMargin.rightMargin;
+ const direction = judgeDirection(endPoint, lastTwoPoint);
// 特殊情况: targetPort 为 undefined
if (targetPort === undefined) {
- const port = id2port.get(edge.orginalTarget);
+ const port = id2port.get(edge.orginalTarget);
// TODO: 检查正确性
endPoint.x -= LAYOUT_CONSTANT.INSTANCE_RIGHT_MARGIN;
} else {
- endPoint.x += targetMargin.leftMargin;
+ // 判断当前的方向
+ if (direction === 'up' || direction === 'down') {
+ lastTwoPoint.x += targetMargin.leftMargin + 1;
+ endPoint.x += targetMargin.leftMargin + 1;
+ } else {
+ endPoint.x += targetMargin.leftMargin;
+ }
}
for (let i = 0; i < points.length; ++ i) {
@@ -72,21 +80,16 @@ export class WireRender {
const lineSvg = linePaths.join(' ');
- // 判断当前的朝向
- const direction = endPoint.x > points.at(-2).x ? 'right' : 'left';
- const arrowX = direction === 'right' ? endPoint.x - LAYOUT_CONSTANT.CELL_PORT_WIDTH - this.arrowWidth + 2.5:
- endPoint.x + LAYOUT_CONSTANT.CELL_PORT_WIDTH - 2.5
+ const arrowLocation = getArrowLocation(endPoint, direction, this.arrowWidth, this.arrowHeight);
- const arrowY = endPoint.y - this.arrowHeight / 2;
-
this.data.push({
id: this.idCounter,
svg: lineSvg,
endPoint: points.at(-1),
arrow: {
icon: direction + '-arrow',
- x: arrowX,
- y: arrowY,
+ x: arrowLocation.x,
+ y: arrowLocation.y,
width: this.arrowWidth,
height: this.arrowHeight
},
@@ -239,4 +242,51 @@ export class WireRender {
function cubicBezierAnimation(delta, oldVal, newVal) {
delta = 3 * (1 - delta) * (1 - delta) * delta + 3 * (1 - delta) * delta * delta + delta * delta * delta;
return (1 - delta) * oldVal + delta * newVal;
+}
+
+
+/**
+ *
+ * @param {import('../jsdoc').ElkPoint} lastPoint
+ * @param {import('../jsdoc').ElkPoint} lastTowPoint
+ * @returns {'left' | 'right' | 'up' | 'down'}
+ */
+function judgeDirection(lastPoint, lastTowPoint) {
+ if (lastPoint.x !== lastTowPoint.x) {
+ return lastPoint.x > lastTowPoint.x ? 'right': 'left';
+ } else {
+ return lastPoint.y > lastTowPoint.y ? 'down': 'up';
+ }
+}
+
+/**
+ *
+ * @param {import('../jsdoc').ElkPoint} lastPoint
+ * @param {'left' | 'right' | 'up' | 'down'} direction
+ */
+function getArrowLocation(lastPoint, direction, arrowWidth, arrowHeight) {
+ switch (direction) {
+ case 'left':
+ return {
+ x: lastPoint.x + LAYOUT_CONSTANT.CELL_PORT_WIDTH - 2.5,
+ y: lastPoint.y - arrowHeight / 2
+ };
+ case 'right':
+ return {
+ x: lastPoint.x - LAYOUT_CONSTANT.CELL_PORT_WIDTH - arrowWidth + 2.5,
+ y: lastPoint.y - arrowHeight / 2
+ };
+ case 'up':
+ return {
+ x: lastPoint.x + LAYOUT_CONSTANT.CELL_PORT_WIDTH - arrowWidth / 2 - 1,
+ y: lastPoint.y - arrowHeight / 2
+ };
+ case 'down':
+ return {
+ x: lastPoint.x + LAYOUT_CONSTANT.CELL_PORT_WIDTH - arrowWidth / 2 - 1,
+ y: lastPoint.y - arrowHeight / 2 - 5
+ };
+ default:
+ break;
+ }
}
\ No newline at end of file
diff --git a/src/hook/skin/draw.js b/src/hook/skin/draw.js
index 1b59e86..4bfae4a 100644
--- a/src/hook/skin/draw.js
+++ b/src/hook/skin/draw.js
@@ -12,6 +12,14 @@ export const DIDE_DRAW_SVG_STRINGS = [
{
name: 'left-arrow',
source: ''
+ },
+ {
+ name: 'down-arrow',
+ source: ''
+ },
+ {
+ name: 'up-arrow',
+ source: ''
}
];
diff --git a/src/hook/skin/index.js b/src/hook/skin/index.js
index 7eb2dc9..263f9cd 100644
--- a/src/hook/skin/index.js
+++ b/src/hook/skin/index.js
@@ -103,6 +103,11 @@ class SkinMeta {
this.height = parseFloat(element.getAttribute('height'));
this.svgDoc = svgDoc;
+ /**
+ * @type {Map}
+ */
+ this.portToXOffset = new Map();
+
/**
* @type {Map}
*/
@@ -127,4 +132,24 @@ class SkinMeta {
this.portToYOffset.set(portName, yOffset);
return yOffset;
}
+
+ /**
+ * @description 获取指定 port 在所在 svg 中 Y 轴的相对偏移量
+ * @param {string} portName
+ */
+ getPortXOffset(portName) {
+ if (this.portToXOffset.has(portName)) {
+ return this.portToXOffset.get(portName);
+ }
+ // 没有 hit,尝试获取
+ const pathElement = this.svgDoc.getElementById(portName);
+ if (pathElement === null) {
+ return 0;
+ }
+ const transform = pathElement.getAttribute('transform');
+ const offsetnumber = transform.split('(').at(-1).split(' ').at(0);
+ const xOffset = parseFloat(offsetnumber);
+ this.portToXOffset.set(portName, xOffset);
+ return xOffset;
+ }
}
\ No newline at end of file