From 8ec245f36efad3b358a73fcfeb46a3e16d652ae6 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Fri, 17 May 2024 21:19:40 +0200 Subject: [PATCH] added logic gates --- gallery/test3.pdf | Bin 0 -> 17829 bytes gallery/test3.typ | 89 +++++++++++++++++++++++++ src/element.typ | 10 ++- src/elements/element.typ | 2 +- src/elements/logic/and.typ | 85 ++++++++++++++++++++++++ src/elements/logic/buf.typ | 81 +++++++++++++++++++++++ src/elements/logic/gate.typ | 127 ++++++++++++++++++++++++++++++++++++ src/elements/logic/or.typ | 96 +++++++++++++++++++++++++++ src/elements/logic/xor.typ | 103 +++++++++++++++++++++++++++++ src/elements/ports.typ | 4 ++ src/lib.typ | 2 +- typst.toml | 2 +- 12 files changed, 597 insertions(+), 4 deletions(-) create mode 100644 gallery/test3.pdf create mode 100644 gallery/test3.typ create mode 100644 src/elements/logic/and.typ create mode 100644 src/elements/logic/buf.typ create mode 100644 src/elements/logic/gate.typ create mode 100644 src/elements/logic/or.typ create mode 100644 src/elements/logic/xor.typ diff --git a/gallery/test3.pdf b/gallery/test3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bed94cd8f529434e6b78c9cc4f5c22d5eb9002c7 GIT binary patch literal 17829 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
#tO@0k~$X%U4Q*fTtKBN5I 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 literal 0 HcmV?d00001 diff --git a/gallery/test3.typ b/gallery/test3.typ new file mode 100644 index 0000000..f3d5c76 --- /dev/null +++ b/gallery/test3.typ @@ -0,0 +1,89 @@ +#import "@preview/cetz:0.2.2": draw +#import "../src/lib.typ": circuit, element, util, wire + +#set page(flipped: true) +#let debug = false + +#circuit({ + element.block( + x: 0, y: 0, w: 2, h: 3, id: "block", + name: "Test", + ports: ( + east: ( + (id: "out0"), + (id: "out1"), + (id: "out2"), + ) + ), + debug: ( + ports: debug + + ) + ) + element.gate-and( + x: 4, y: 0, w: 2, h: 2, id: "and1", debug: (ports: debug), + inverted: ("in1") + ) + element.gate-or( + x: 7, y: 0, w: 2, h: 2, id: "or1", debug: (ports: debug), + inverted: ("in0", "out") + ) + + wire.wire( + "w1", + ("block-port-out0", "and1-port-in0"), + style: "dodge", + dodge-y: 3, + dodge-margins: (20%, 20%) + ) + wire.wire( + "w2", + ("block-port-out1", "and1-port-in1"), + style: "zigzag" + ) + wire.wire( + "w3", + ("and1-port-out", "or1-port-in0") + ) + + element.gate-and( + x: 11, y: 0, w: 2, h: 2, id: "and2", inputs: 3, debug: (ports: debug), + inverted: ("in0", "in2") + ) + for i in range(3) { + wire.stub("and2-port-in"+str(i), "west") + } + + element.gate-xor( + x: 14, y: 0, w: 2, h: 2, id: "xor", debug: (ports: debug), + inverted: ("in1") + ) + + element.gate-buf( + x: 0, y: -3, w: 2, h: 2, id: "buf", debug: (ports: debug) + ) + element.gate-not( + x: 0, y: -6, w: 2, h: 2, id: "not", debug: (ports: debug) + ) + + element.gate-and( + x: 3, y: -3, w: 2, h: 2, id: "and", debug: (ports: debug) + ) + element.gate-nand( + x: 3, y: -6, w: 2, h: 2, id: "nand", debug: (ports: debug) + ) + + element.gate-or( + x: 6, y: -3, w: 2, h: 2, id: "or", debug: (ports: debug) + ) + element.gate-nor( + x: 6, y: -6, w: 2, h: 2, id: "nor", debug: (ports: debug) + ) + + element.gate-xor( + x: 9, y: -3, w: 2, h: 2, id: "xor", debug: (ports: debug) + ) + element.gate-xnor( + x: 9, y: -6, w: 2, h: 2, id: "xnor", debug: (ports: debug) + ) +}) \ No newline at end of file diff --git a/src/element.typ b/src/element.typ index 331ad83..aee6cd1 100644 --- a/src/element.typ +++ b/src/element.typ @@ -4,4 +4,12 @@ #import "elements/alu.typ": alu #import "elements/block.typ": block #import "elements/extender.typ": extender -#import "elements/multiplexer.typ": multiplexer \ No newline at end of file +#import "elements/multiplexer.typ": multiplexer + +#import "elements/logic/gate.typ": gate +#import "elements/logic/and.typ": gate-and, gate-nand +#import "elements/logic/or.typ": gate-or, gate-nor +#import "elements/logic/xor.typ": gate-xor, gate-xnor +#import "elements/logic/buf.typ": gate-buf, gate-not +/* +*/ \ No newline at end of file diff --git a/src/elements/element.typ b/src/elements/element.typ index 924d211..1822f93 100644 --- a/src/elements/element.typ +++ b/src/elements/element.typ @@ -38,7 +38,7 @@ /// - stroke (stroke): Border stroke /// - id (str): The block id (for future reference) /// - auto-ports (bool): Whether to use auto port placements or not. If false, `draw-shape` is responsible for adding the appropiate ports -/// - ports-y (array): Array of the ports y offsets (used with `auto-ports: false`) +/// - ports-y (dictionary): Dictionary of the ports y offsets (used with `auto-ports: false`) /// - debug (dictionary): Dictionary of debug options. /// /// Supported fields include: diff --git a/src/elements/logic/and.typ b/src/elements/logic/and.typ new file mode 100644 index 0000000..3df22a4 --- /dev/null +++ b/src/elements/logic/and.typ @@ -0,0 +1,85 @@ +#import "@preview/cetz:0.2.2": draw +#import "gate.typ" + +#let draw-shape(id, tl, tr, br, bl, fill, stroke) = { + let (x, y) = bl + let (width, height) = (tr.at(0) - x, tr.at(1) - y) + + let t = (x + width / 4, y + height) + let b = (x + width / 4, y) + + let f = draw.group(name: id, { + draw.merge-path( + inset: 0.5em, + fill: fill, + stroke: stroke, + name: id + "-path", + close: true, { + draw.line(bl, tl, t) + draw.bezier((), b, tr, br) + draw.line((), b) + } + ) + + draw.anchor("north", t) + draw.anchor("south", b) + }) + return (f, tl, tr, br, bl) +} + +#let gate-and( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate.gate( + draw-shape: draw-shape, + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted, + debug: debug + ) +} + +#let gate-nand( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate-and( + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted + ("out",), + debug: debug + ) +} \ No newline at end of file diff --git a/src/elements/logic/buf.typ b/src/elements/logic/buf.typ new file mode 100644 index 0000000..87d8dc9 --- /dev/null +++ b/src/elements/logic/buf.typ @@ -0,0 +1,81 @@ +#import "@preview/cetz:0.2.2": draw +#import "gate.typ" + +#let draw-shape(id, tl, tr, br, bl, fill, stroke) = { + let (x, y) = bl + let (width, height) = (tr.at(0) - x, tr.at(1) - y) + + let r = (x + width, y + height / 2) + + let f = draw.group(name: id, { + draw.merge-path( + inset: 0.5em, + fill: fill, + stroke: stroke, + name: id + "-path", + close: true, { + draw.line(bl, tl, r) + } + ) + + draw.anchor("north", (tl, 50%, r)) + draw.anchor("south", (bl, 50%, r)) + }) + return (f, tl, tr, br, bl) +} + +#let gate-buf( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate.gate( + draw-shape: draw-shape, + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted, + debug: debug + ) +} + +#let gate-not(x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate-buf( + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted + ("out",), + debug: debug + ) +} \ No newline at end of file diff --git a/src/elements/logic/gate.typ b/src/elements/logic/gate.typ new file mode 100644 index 0000000..5fb282a --- /dev/null +++ b/src/elements/logic/gate.typ @@ -0,0 +1,127 @@ +#import "@preview/cetz:0.2.2": draw, coordinate +#import "../ports.typ": add-ports, add-port +#import "../element.typ" + +#let default-draw-shape(id, tl, tr, br, bl, fill, stroke) = { + let f = {draw.rect(tl, br, fill: fill, stroke: stroke)} + return (f, tl, tr, br, bl) +} + +#let gate( + draw-shape: default-draw-shape, + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = draw.get-ctx(ctx => { + let width = w + let height = h + + let x = x + let y = y + if x == none { panic("Parameter x must be set") } + if y == none { panic("Parameter y must be set") } + if w == none { panic("Parameter w must be set") } + if h == none { panic("Parameter h must be set") } + + if (type(x) == dictionary) { + let offset = x.rel + let to = x.to + let (ctx, to-pos) = coordinate.resolve(ctx, (rel: (offset, 0), to: to)) + x = to-pos.at(0) + } + + if (type(y) == dictionary) { + let from = y.from + let to = y.to + let (to-side, i) = find-port(ports, to) + let margins = (0%, 0%) + if to-side in ports-margins { + margins = ports-margins.at(to-side) + } + let used-pct = 100% - margins.at(0) - margins.at(1) + let used-height = height * used-pct / 100% + let top-margin = height * margins.at(0) / 100% + + let dy = used-height * (i + 1) / (ports.at(to-side).len() + 1) + + let (ctx, from-pos) = coordinate.resolve(ctx, from) + y = from-pos.at(1) + dy - height + top-margin + } + + let tl = (x, y + height) + let tr = (x + width, y + height) + let br = (x + width, y) + let bl = (x, y) + + // Workaround because CeTZ needs to have all draw functions in the body + let func = {} + (func, tl, tr, br, bl) = draw-shape(id, tl, tr, br, bl, fill, stroke) + { + //draw.rect(tl, br) + func + } + + let space = 100% / (inputs + 1) + for i in range(inputs) { + let pct = (i + 1) * space + let a = (tl, pct, bl) + let b = (tr, pct, br) + let int-name = id + "i" + str(i) + draw.intersections( + int-name, + func, + draw.hide(draw.line(a, b)) + ) + let port-name = "in" + str(i) + let port-pos = int-name + ".0" + if inverted == "all" or port-name in inverted { + draw.circle(port-pos, radius: .2, anchor: "east", stroke: stroke) + port-pos = (rel: (-.4, 0), to: port-pos) + } + add-port( + id, "west", + (id: port-name), port-pos, + debug: debug.ports + ) + } + + let out-pos = id + ".east" + if inverted == "all" or "out" in inverted { + draw.circle(out-pos, radius: .2, anchor: "west", stroke: stroke) + out-pos = (rel: (.4, 0), to: out-pos) + } + add-port( + id, "east", + (id: "out"), out-pos, + debug: debug.ports + ) +}) +/* { + let ports = (west: (), east: ((id: "out"),)) + for i in range(inputs) { + ports.west.push((id: "in"+str(i))) + } + + element.elmt( + draw-shape: draw-shape, + x: x, + y: y, + w: w, + h: h, + ports: ports, + fill: fill, + stroke: stroke, + id: id, + auto-ports: true, + debug: debug + ) +} \ No newline at end of file diff --git a/src/elements/logic/or.typ b/src/elements/logic/or.typ new file mode 100644 index 0000000..4f44fb7 --- /dev/null +++ b/src/elements/logic/or.typ @@ -0,0 +1,96 @@ +#import "@preview/cetz:0.2.2": draw +#import "gate.typ" + +#let draw-shape(id, tl, tr, br, bl, fill, stroke) = { + let (x, y) = bl + let (width, height) = (tr.at(0) - x, tr.at(1) - y) + + let t = (x + width / 2, y + height) + let b = (x + width / 2, y) + + let ctrl-bl = (x + width / 2, y) + let ctrl-br = (x + width * 0.8, y + height * 0.1) + let ctrl-tl = (x + width / 2, y + height) + let ctrl-tr = (x + width * 0.8, y + height * 0.9) + + let l = (x + width * 0.2, y + height / 2) + let r = (x + width, y + height / 2) + + let f = draw.group(name: id, { + draw.merge-path( + inset: 0.5em, + fill: fill, + stroke: stroke, + name: id + "-path", { + draw.bezier-through(bl, l, tl) + draw.bezier((), r, ctrl-tl, ctrl-tr) + draw.bezier((), bl, ctrl-br, ctrl-bl) + } + ) + + draw.intersections("i", + id + "-path", + draw.hide(draw.line(t, b)) + ) + draw.anchor("north", "i.0") + draw.anchor("south", "i.1") + }) + return (f, tl, tr, br, bl) +} + +#let gate-or( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate.gate( + draw-shape: draw-shape, + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted, + debug: debug + ) +} + +#let gate-nor( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate-or( + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted + ("out",), + debug: debug + ) +} \ No newline at end of file diff --git a/src/elements/logic/xor.typ b/src/elements/logic/xor.typ new file mode 100644 index 0000000..3b4eb70 --- /dev/null +++ b/src/elements/logic/xor.typ @@ -0,0 +1,103 @@ +#import "@preview/cetz:0.2.2": draw +#import "gate.typ" + +#let space = 10% + +#let draw-shape(id, tl, tr, br, bl, fill, stroke) = { + let (x, y) = bl + let (width, height) = (tr.at(0) - x, tr.at(1) - y) + + let tl2 = (tl, space, tr) + let bl2 = (bl, space, br) + + let t = (x + width / 2, y + height) + let b = (x + width / 2, y) + + let ctrl-bl = (x + width / 2, y) + let ctrl-br = (x + width * 0.8, y + height * 0.1) + let ctrl-tl = (x + width / 2, y + height) + let ctrl-tr = (x + width * 0.8, y + height * 0.9) + + let l = (x + width * 0.2, y + height / 2) + let l2 = (x + width * (0.2 + space / 100%), y + height / 2) + let r = (x + width, y + height / 2) + + let f = draw.group(name: id, { + draw.bezier-through(bl, l, tl, stroke: stroke) + draw.merge-path( + inset: 0.5em, + fill: fill, + stroke: stroke, + name: id + "-path", { + draw.bezier-through(bl2, l2, tl2) + draw.bezier((), r, ctrl-tl, ctrl-tr) + draw.bezier((), bl2, ctrl-br, ctrl-bl) + } + ) + + draw.intersections("i", + id + "-path", + draw.hide(draw.line(t, b)) + ) + draw.anchor("north", "i.0") + draw.anchor("south", "i.1") + }) + return (f, tl, tr, br, bl) +} + +#let gate-xor( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate.gate( + draw-shape: draw-shape, + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted, + debug: debug + ) +} + +#let gate-xnor( + x: none, + y: none, + w: none, + h: none, + inputs: 2, + fill: none, + stroke: black + 1pt, + id: "", + inverted: (), + debug: ( + ports: false + ) +) = { + gate-xor( + x: x, + y: y, + w: w, + h: h, + inputs: inputs, + fill: fill, + stroke: stroke, + id: id, + inverted: inverted + ("out",), + debug: debug + ) +} \ No newline at end of file diff --git a/src/elements/ports.typ b/src/elements/ports.typ index 602d0f5..51bf409 100644 --- a/src/elements/ports.typ +++ b/src/elements/ports.typ @@ -68,6 +68,10 @@ "west": (tl, bl) ) + if type(ports) != dictionary { + return + } + for (side, props) in sides { let side-ports = ports.at(side, default: ()) let space = 100% / (side-ports.len() + 1) diff --git a/src/lib.typ b/src/lib.typ index e811c6d..d891428 100644 --- a/src/lib.typ +++ b/src/lib.typ @@ -1,4 +1,4 @@ -#let version = version((0,0,1)) +#let version = version((0,0,2)) #import "circuit.typ": circuit #import "element.typ" diff --git a/typst.toml b/typst.toml index 88e1ea5..55e8fb2 100644 --- a/typst.toml +++ b/typst.toml @@ -1,6 +1,6 @@ [package] name = "circuiteria" -version = "0.0.1" +version = "0.0.2" compiler = "0.11.0" repository = "https://git.kb28.ch/HEL/circuiteria" entrypoint = "src/lib.typ"