diff --git a/gate_level.js b/gate_level.js
index e09e543..f3d606f 100644
--- a/gate_level.js
+++ b/gate_level.js
@@ -243,7 +243,7 @@ jade_defs.gate_level = function(jade) {
var timing;
try {
timing = jade.gatesim.timing_analysis(netlist,diagram.editor.options);
- timing = $('
').append(timing);
+ timing = $('').append(timing);
timing = timing[0];
timing.resize = function(me,w,h) {
diff --git a/gatesim.js b/gatesim.js
index 3d41208..be9ffcd 100644
--- a/gatesim.js
+++ b/gatesim.js
@@ -86,8 +86,20 @@ jade_defs.gatesim = function(jade) {
tinfo = tpd[i];
result += ' tPD from '+tinfo.get_tpd_source().name+' to '+tinfo.name+' ('+(tinfo.pd_sum*1e9).toFixed(3)+'ns):';
result += ' \n
';
+ result += '
';
+ result += '';
+ result += '| tpd (ns) | ';
+ result += 'pd_sum (ns) | ';
+ result += 'signal name | ';
+ result += 'device name | ';
+ result += 'device type | ';
+ result += 'fanout (#) | ';
+ result += 'load (pf) | ';
+ result += 'load PD (ns) | ';
+ result += '
';
result += tinfo.describe_tpd();
- result += '
';
+ result += '
';
+ result += '
';
div_counter += 1;
}
@@ -1884,6 +1896,45 @@ jade_defs.gatesim = function(jade) {
this.tcd = tcd || 0; // specs for driving gate, capacitance accounted for
this.tpd = tpd || 0;
+ this.buffer_advantage = undefined;
+
+ this.load_pd = undefined;
+
+ if (device !== undefined) {
+ var tr = device.tpdr + device.tr*node.capacitance;
+ var tf = device.tpdf + device.tf*node.capacitance;
+
+ if (tr > tf) {
+ this.load_pd = device.tr*node.capacitance
+ }
+ else if (tr < tf) {
+ this.load_pd = device.tf*node.capacitance
+ }
+ else {
+ this.load_pd = Math.min(device.tr, device.tf) * node.capacitance;
+ }
+
+ if (this.node.fanouts !== undefined) {
+ if (this.node.fanouts.length > 1) {
+ var buffer_h_load_capacitance = 0.005*1e-12;
+ var buffer_h_tpdr = 0.07*1e-9;
+ var buffer_h_tpdf = 0.07*1e-9;
+ var buffer_h_base_tr = 1100;
+ var buffer_h_base_tf = 600;
+
+ var buffer_h_tr = buffer_h_tpdr + buffer_h_base_tr * node.capacitance;
+ var buffer_h_tf = buffer_h_tpdf + buffer_h_base_tf * node.capacitance;
+ var buffer_h_pd = Math.max(buffer_h_tr, buffer_h_tf);
+
+ var driver_tr = device.tpdr + device.tr * buffer_h_load_capacitance;
+ var driver_tf = device.tpdf + device.tf * buffer_h_load_capacitance;
+ var driver_pd = Math.max(driver_tr, driver_tf);
+
+ var total_pd = buffer_h_pd + driver_pd;
+ this.buffer_advantage = total_pd - this.tpd;
+ }
+ }
+ }
}
TimingInfo.prototype.get_tcd_source = function () {
@@ -1929,8 +1980,26 @@ jade_defs.gatesim = function(jade) {
if (this.pd_link !== undefined) result = this.pd_link.describe_tpd();
else result = '';
- var driver_name = (this.device !== undefined) ? ' ['+this.device.name+' '+this.device.type+']' : '';
- result += ' + '+format_float(this.tpd*1e9,6,3)+"ns = "+format_float(this.pd_sum*1e9,6,3)+"ns "+this.name+driver_name+'\n';
+ var device_name = (this.device !== undefined) ? this.device.name : '';
+ var device_type = (this.device !== undefined) ? this.device.type : '';
+
+ result += ''
+ result += '| ' + format_float(this.tpd*1e9,6,3);
+
+ if (this.buffer_advantage !== undefined && this.buffer_advantage < 0.0) {
+ result += ' (' + format_float(this.buffer_advantage*1e9,6,3) + ')'
+ }
+
+ result += ' | ';
+ result += '' + format_float(this.pd_sum*1e9,6,3) + ' | '
+ result += '' + this.name + ' | '
+ result += '' + device_name + ' | '
+ result += '' + device_type + ' | '
+ result += '' + ((this.node.fanouts !== undefined) ? this.node.fanouts.length : '') + ' | ';
+ result += '' + format_float(this.node.capacitance * 1e12, 6, 3) + ' | ';
+ result += '' + ((this.load_pd !== undefined) ? format_float(this.load_pd * 1e9, 6, 3) : '') +' | ';
+ result += '
';
+
return result;
};
diff --git a/jade.css b/jade.css
index a8fd9b2..672e664 100644
--- a/jade.css
+++ b/jade.css
@@ -2419,3 +2419,14 @@
.fa-fonticons:before {
content: "\f280";
}
+table.timing_details {
+ border-collapse: collapse;
+}
+table.timing_details th, table.timing_details td {
+ border: solid 1px;
+ padding: 2px;
+}
+.important_timing_detail {
+ color:#dc322f;
+ font-weight: bold;
+}
\ No newline at end of file
diff --git a/server.py b/server.py
index 73ee4bd..9464466 100755
--- a/server.py
+++ b/server.py
@@ -4,10 +4,12 @@
try:
from BaseHTTPServer import BaseHTTPRequestHandler
import SocketServer as socketserver
+ from cgi import parse_qs
except:
# python 3 compatibility
from http.server import BaseHTTPRequestHandler
import socketserver
+ from urllib.parse import parse_qs
import mimetypes
import posixpath
@@ -65,7 +67,7 @@ def do_POST(self):
elif ctype == 'application/x-www-form-urlencoded':
length = int(self.headers['content-length'])
content = self.rfile.read(length)
- for k,v in cgi.parse_qs(content, keep_blank_values=1).items():
+ for k,v in parse_qs(content, keep_blank_values=1).items():
# python3 returns everything as bytes, so decode into strings
if type(k) == bytes: k = k.decode()
postvars[k] = [s.decode() if type(s) == bytes else s for s in v]
@@ -94,7 +96,11 @@ def do_POST(self):
self.send_header("Content-type", 'text/plain')
self.send_header("Content-Length", str(len(response)))
self.end_headers()
- self.wfile.write(response.encode())
+ try:
+ self.wfile.write(response.encode())
+ except AttributeError:
+ # python 3 compatibility
+ self.wfile.write(response)
def guess_type(self, path):
base, ext = posixpath.splitext(path)
@@ -112,7 +118,8 @@ def guess_type(self, path):
extensions_map.update({
'': 'application/octet-stream', # Default
})
-
+
+socketserver.TCPServer.allow_reuse_address = True
httpd = socketserver.TCPServer(("",PORT),JadeRequestHandler)
def cleanup():