diff options
| author | Julian Blake Kongslie | 2022-05-11 20:59:16 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-05-11 20:59:16 -0700 |
| commit | df432a446df8748fac61a9f8e968c9ca7f33ccd1 (patch) | |
| tree | a1f98e00fafba85597a24c528a665939afb298d1 | |
| parent | Initial commit. (diff) | |
| download | lace-df432a446df8748fac61a9f8e968c9ca7f33ccd1.tar.xz | |
Don't mysteriously drop nets; allow arbitrary pair construction.
Diffstat (limited to '')
| -rw-r--r-- | lace.rb | 114 | ||||
| -rwxr-xr-x | test.rb | 47 |
2 files changed, 85 insertions, 76 deletions
| @@ -1,59 +1,7 @@ | |||
| 1 | require "bigdecimal" | ||
| 2 | require "set" | 1 | require "set" |
| 3 | 2 | ||
| 4 | module Lace | 3 | module Lace |
| 5 | 4 | ||
| 6 | extend self | ||
| 7 | |||
| 8 | def en(series, sigfigs, n) | ||
| 9 | return BigDecimal((10.0**Math.log10(n.to_f**series.to_f).round.to_f)**(1.0/series.to_f), sigfigs).round | ||
| 10 | end | ||
| 11 | |||
| 12 | HISTORIC_E24_FIX_TABLE = { | ||
| 13 | Math.log10(2.6) => Math.log10(2.7), | ||
| 14 | Math.log10(2.9) => Math.log10(3.0), | ||
| 15 | Math.log10(3.2) => Math.log10(3.3), | ||
| 16 | Math.log10(3.5) => Math.log10(3.6), | ||
| 17 | Math.log10(3.8) => Math.log10(3.9), | ||
| 18 | Math.log10(4.2) => Math.log10(4.3), | ||
| 19 | Math.log10(4.6) => Math.log10(4.7), | ||
| 20 | } | ||
| 21 | def historic_e24_fix(n) | ||
| 22 | exp, rem = Math.log10(n).divmod(1) | ||
| 23 | HISTORIC_E24_FIX_TABLE.each do | accurate, historic | | ||
| 24 | rem = historic if (rem - accurate).abs <= 0.0001 | ||
| 25 | end | ||
| 26 | return (10 ** (exp + rem)).round | ||
| 27 | end | ||
| 28 | |||
| 29 | def e3(n) | ||
| 30 | return historic_e24_fix(en(3, 2, n)) | ||
| 31 | end | ||
| 32 | |||
| 33 | def e6(n) | ||
| 34 | return historic_e24_fix(en(6, 2, n)) | ||
| 35 | end | ||
| 36 | |||
| 37 | def e12(n) | ||
| 38 | return historic_e24_fix(en(12, 2, n)) | ||
| 39 | end | ||
| 40 | |||
| 41 | def e24(n) | ||
| 42 | return historic_e24_fix(en(24, 2, n)) | ||
| 43 | end | ||
| 44 | |||
| 45 | def e48(n) | ||
| 46 | return en(48, 3, n) | ||
| 47 | end | ||
| 48 | |||
| 49 | def e96(n) | ||
| 50 | return en(96, 3, n) | ||
| 51 | end | ||
| 52 | |||
| 53 | def e192(n) | ||
| 54 | return en(192, 3, n) | ||
| 55 | end | ||
| 56 | |||
| 57 | class Netlist | 5 | class Netlist |
| 58 | 6 | ||
| 59 | attr_reader :components | 7 | attr_reader :components |
| @@ -66,18 +14,31 @@ module Lace | |||
| 66 | edit(&p) if p | 14 | edit(&p) if p |
| 67 | end | 15 | end |
| 68 | 16 | ||
| 17 | def definitive_net(n) | ||
| 18 | nn = @nets[n.object_id] | ||
| 19 | return n if nn.object_id == n.object_id | ||
| 20 | return definitive_net(nn) | ||
| 21 | end | ||
| 22 | |||
| 69 | def merge_nets(a, b) | 23 | def merge_nets(a, b) |
| 70 | into = @nets[[a.object_id, b.object_id].min] | 24 | da = definitive_net(a) |
| 71 | if a.name | 25 | db = definitive_net(b) |
| 72 | raise "Nets #{into.name} and #{a.name} merged!" if into.name and into.name != a.name | 26 | return da if da.object_id == db.object_id |
| 73 | into.name = a.name | 27 | into = @nets[[da.object_id, db.object_id].min] |
| 28 | if da.name | ||
| 29 | raise "Nets #{into.name} and #{da.name} merged!" if into.name and into.name != da.name | ||
| 30 | into.name = da.name | ||
| 74 | end | 31 | end |
| 75 | if b.name | 32 | if db.name |
| 76 | raise "Nets #{into.name} and #{b.name} merged!" if into.name and into.name != b.name | 33 | raise "Nets #{into.name} and #{db.name} merged!" if into.name and into.name != db.name |
| 77 | into.name = b.name | 34 | into.name = db.name |
| 35 | end | ||
| 36 | @nets.each do | id, n | | ||
| 37 | dn = definitive_net(n) | ||
| 38 | if dn.object_id != into.object_id and (dn.object_id == da.object_id or dn.object_id == db.object_id) | ||
| 39 | @nets[id] = into | ||
| 40 | end | ||
| 78 | end | 41 | end |
| 79 | @nets[a.object_id] = into | ||
| 80 | @nets[b.object_id] = into | ||
| 81 | return into | 42 | return into |
| 82 | end | 43 | end |
| 83 | 44 | ||
| @@ -88,11 +49,18 @@ module Lace | |||
| 88 | def comp(*args) | 49 | def comp(*args) |
| 89 | c = Component.new(self, *args) | 50 | c = Component.new(self, *args) |
| 90 | @components[c.object_id] = c | 51 | @components[c.object_id] = c |
| 52 | return c | ||
| 91 | end | 53 | end |
| 92 | 54 | ||
| 93 | def net(*args) | 55 | def net(*args) |
| 94 | n = Net.new(self, *args) | 56 | n = Net.new(self, *args) |
| 95 | @nets[n.object_id] = n | 57 | @nets[n.object_id] = n |
| 58 | return n | ||
| 59 | end | ||
| 60 | |||
| 61 | def pair(left, right) | ||
| 62 | x = Wireable.new(self, left, right) | ||
| 63 | return x | ||
| 96 | end | 64 | end |
| 97 | 65 | ||
| 98 | def real_refs | 66 | def real_refs |
| @@ -126,7 +94,7 @@ module Lace | |||
| 126 | nodes = [] | 94 | nodes = [] |
| 127 | refs.each do | ref, comp | | 95 | refs.each do | ref, comp | |
| 128 | comp.pins.each do | pin, pinnet | | 96 | comp.pins.each do | pin, pinnet | |
| 129 | nodes << {:ref => ref, :pin => pin} if @nets[pinnet].object_id == net.object_id | 97 | nodes << {:ref => ref, :pin => pin} if definitive_net(pinnet).object_id == net.object_id |
| 130 | end | 98 | end |
| 131 | end | 99 | end |
| 132 | nets[name] = nodes if nodes.size > 1 | 100 | nets[name] = nodes if nodes.size > 1 |
| @@ -225,9 +193,21 @@ END | |||
| 225 | @right = right || left | 193 | @right = right || left |
| 226 | end | 194 | end |
| 227 | 195 | ||
| 196 | def left_net | ||
| 197 | x = left | ||
| 198 | return x if x.instance_of?(Net) | ||
| 199 | return x.left_net | ||
| 200 | end | ||
| 201 | |||
| 202 | def right_net | ||
| 203 | x = right | ||
| 204 | return x if x.instance_of?(Net) | ||
| 205 | return x.right_net | ||
| 206 | end | ||
| 207 | |||
| 228 | def -(that) | 208 | def -(that) |
| 229 | @netlist.merge_nets(@right, that.left) | 209 | @netlist.merge_nets(right_net, that.left_net) |
| 230 | return Wireable.new(@netlist, @left, that.right) | 210 | return Wireable.new(@netlist, left_net, that.right_net) |
| 231 | end | 211 | end |
| 232 | 212 | ||
| 233 | end | 213 | end |
| @@ -263,13 +243,13 @@ END | |||
| 263 | def [](pin) | 243 | def [](pin) |
| 264 | unless pins.member?(pin) | 244 | unless pins.member?(pin) |
| 265 | n = @netlist.net | 245 | n = @netlist.net |
| 266 | pins[pin] = n.object_id | 246 | pins[pin] = n |
| 267 | end | 247 | end |
| 268 | return @netlist.nets[pins[pin]] | 248 | return pins[pin] |
| 269 | end | 249 | end |
| 270 | 250 | ||
| 271 | def desc | 251 | def desc |
| 272 | return "#{@value} #{@name}" if @name != @value | 252 | return "\"#{@value}\" #{@name}" if @name != @value |
| 273 | return @name | 253 | return @name |
| 274 | end | 254 | end |
| 275 | 255 | ||
| @@ -2,24 +2,53 @@ | |||
| 2 | 2 | ||
| 3 | require "./lace" | 3 | require "./lace" |
| 4 | 4 | ||
| 5 | def r(size, suffix="ohm") | 5 | def r(size) |
| 6 | comp("R", "0805", "resistor", "#{Lace::e12(size)}#{suffix}") | 6 | comp("R", "0805", "resistor", size) |
| 7 | end | 7 | end |
| 8 | 8 | ||
| 9 | def c(size, suffix="nF") | 9 | def c(size) |
| 10 | comp("C", "0805", "capacitor", "#{Lace::e12(size)}#{suffix}") | 10 | comp("C", "0805", "capacitor", size) |
| 11 | end | 11 | end |
| 12 | 12 | ||
| 13 | def led(color="red") | 13 | def led(color="red") |
| 14 | comp("D", "0805", "LED", "1.5V 10mA #{color}") | 14 | comp("D", "0805", "LED", "1.5V 10mA #{color}") - r("220ohm") |
| 15 | end | ||
| 16 | |||
| 17 | def inverter() | ||
| 18 | $inverters ||= [] | ||
| 19 | if $inverters.empty? | ||
| 20 | u = comp("U", "TSOP-14", "74HCT04", "hex inverter") | ||
| 21 | $vcc - u[14] - c("100nF") - u[7] - $gnd | ||
| 22 | $inverters += [ | ||
| 23 | pair(u[1], u[2]), | ||
| 24 | pair(u[3], u[4]), | ||
| 25 | pair(u[5], u[6]), | ||
| 26 | pair(u[9], u[8]), | ||
| 27 | pair(u[11], u[10]), | ||
| 28 | pair(u[13], u[12]), | ||
| 29 | ] | ||
| 30 | end | ||
| 31 | $inverters.shift | ||
| 32 | end | ||
| 33 | |||
| 34 | def btn(color="black") | ||
| 35 | sw = comp("SW", "BTN", "SPST button", color) | ||
| 36 | sw[1] - sw[4] | ||
| 37 | sw[2] - sw[3] | ||
| 38 | pair(sw[1], sw[4]) | ||
| 15 | end | 39 | end |
| 16 | 40 | ||
| 17 | nl = Lace::Netlist.new do | 41 | nl = Lace::Netlist.new do |
| 18 | vcc = net("vcc") | 42 | $vcc = net("vcc") |
| 19 | gnd = net("gnd") | 43 | $gnd = net("gnd") |
| 44 | |||
| 45 | $vcc - led - $gnd | ||
| 46 | |||
| 47 | $vcc - btn - led("green") - $gnd | ||
| 20 | 48 | ||
| 21 | vcc - r((5 - 1.5)/0.010) - led - gnd | 49 | x = $vcc - btn("white") |
| 22 | vcc - c(100) - gnd | 50 | x - led("amber") - $gnd |
| 51 | x - inverter() - led("blue") - $gnd | ||
| 23 | end | 52 | end |
| 24 | 53 | ||
| 25 | nl.kicad | 54 | nl.kicad |
