diff --git a/manual.pdf b/manual.pdf index 33f271c..6d7183f 100644 Binary files a/manual.pdf and b/manual.pdf differ diff --git a/manual.typ b/manual.typ index ed1bbb2..a6341f7 100644 --- a/manual.typ +++ b/manual.typ @@ -1,6 +1,7 @@ #import "@preview/tidy:0.3.0" -#import "@preview/cetz:0.2.2": draw +#import "@preview/cetz:0.2.2": draw, canvas #import "src/circuit.typ": circuit +#import "src/element.typ" #import "src/util.typ" #import "src/wire.typ" @@ -9,20 +10,49 @@ name: "circuit", require-all-parameters: true ) -#tidy.show-module(circuit-docs) +#tidy.show-module(circuit-docs, style: tidy.styles.minimal) + +#pagebreak() #let util-docs = tidy.parse-module( read("src/util.typ"), name: "util", require-all-parameters: true, - scope: (util: util) + scope: ( + util: util, + canvas: canvas, + draw: draw + ) ) #tidy.show-module(util-docs) +#pagebreak() + #let wire-docs = tidy.parse-module( read("src/wire.typ"), name: "wire", require-all-parameters: true, scope: (wire: wire, circuit: circuit, draw: draw) ) -#tidy.show-module(wire-docs) \ No newline at end of file +#tidy.show-module(wire-docs) + +#pagebreak() + +#let element-docs = tidy.parse-module( + read("src/elements/element.typ") + "\n" + + read("src/elements/alu.typ") + "\n" + + read("src/elements/block.typ") + "\n" + + read("src/elements/extender.typ") + "\n" + + read("src/elements/multiplexer.typ"), + name: "element", + require-all-parameters: false, + scope: ( + element: element, + circuit: circuit, + draw: draw, + wire: wire, + tidy: tidy + ) +) + +#tidy.show-module(element-docs, sort-functions: false) \ No newline at end of file diff --git a/src/elements/alu.typ b/src/elements/alu.typ index 3954851..548ca6c 100644 --- a/src/elements/alu.typ +++ b/src/elements/alu.typ @@ -37,6 +37,26 @@ return (f, tl, tr, br, bl) } +/// Draws an ALU with two inputs +/// +/// #box(width: 100%, align(center)[ +/// #circuit({ +/// element.alu(x: 0, y: 0, w: 1, h: 2, id: "alu") +/// wire.stub("alu-port-in1", "west") +/// wire.stub("alu-port-in2", "west") +/// wire.stub("alu-port-out", "east") +/// }) +/// ]) +/// - x (number, dictionary): see `elmt()` +/// - y (number, dictionary): see `elmt()` +/// - w (number): see `elmt()` +/// - h (number): see `elmt()` +/// - name (none, str): see `elmt()` +/// - name-anchor (str): see `elmt()` +/// - fill (none, color): see `elmt()` +/// - stroke (stroke): see `elmt()` +/// - id (str): see `elmt()` +/// - debug (dictionary): see `elmt()` #let alu( x: none, y: none, diff --git a/src/elements/block.typ b/src/elements/block.typ index 27151b7..9431525 100644 --- a/src/elements/block.typ +++ b/src/elements/block.typ @@ -13,6 +13,43 @@ return (f, tl, tr, br, bl) } +/// Draws a block element +/// +/// #box(width: 100%, align(center)[ +/// #circuit({ +/// element.block( +/// x: 0, y: 0, +/// w: 2, h: 2, +/// id: "block", +/// ports: ( +/// north: ((id: "clk", clock: true),), +/// west: ( +/// (id: "in1", name: "A"), +/// (id: "in2", name: "B"), +/// ), +/// east: ( +/// (id: "out", name: "C"), +/// ) +/// ) +/// ) +/// wire.stub("block-port-clk", "north") +/// wire.stub("block-port-in1", "west") +/// wire.stub("block-port-in2", "west") +/// wire.stub("block-port-out", "east") +/// }) +/// ]) +/// - x (number, dictionary): see `elmt()` +/// - y (number, dictionary): see `elmt()` +/// - w (number): see `elmt()` +/// - h (number): see `elmt()` +/// - name (none, str): see `elmt()` +/// - name-anchor (str): see `elmt()` +/// - ports: (dictionary): see `elmt()` +/// - ports-margins: (dictionary): see `elmt()` +/// - fill (none, color): see `elmt()` +/// - stroke (stroke): see `elmt()` +/// - id (str): see `elmt()` +/// - debug (dictionary): see `elmt()` #let block( x: none, y: none, diff --git a/src/elements/element.typ b/src/elements/element.typ index 98170b3..924d211 100644 --- a/src/elements/element.typ +++ b/src/elements/element.typ @@ -16,6 +16,33 @@ return ({}, tl, tr, br, bl) } +/// Draws an element +/// - draw-shape (function): Draw function +/// - x (number, dictionary): The x position (bottom-left corner). +/// +/// If it is a dictionary, it should be in the format `(rel: number, to: str)`, where `rel` is the offset and `to` the base anchor +/// - y (number, dictionary): The y position (bottom-left corner). +/// +/// If it is a dictionary, it should be in the format `(from: str, to: str)`, where `from` is the base anchor and `to` is the id of the port to align with the anchor +/// - w (number): Width of the element +/// - h (number): Height of the element +/// - name (none, str): Optional name of the block +/// - name-anchor (str): Anchor for the optional name +/// - ports (dictionary): Dictionary of ports. The keys are cardinal directions ("north", "east", "south" and/or "west"). The values are arrays of ports (dictionaries) with the following fields: +/// - `id` (`str`): (Required) Port id +/// - `name` (`str`): Optional name displayed *in* the block +/// - `clock` (`bool`): Whether it is a clock port (triangle symbol) +/// - `vertical` (`bool`): Whether the name should be drawn vertically +/// - ports-margins (dictionary): Dictionary of ports margins (used with automatic port placement). They keys are cardinal directions ("north", "east", "south", "west"). The values are tuples of (, ) margins (numbers) +/// - fill (none, color): Fill color +/// - 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`) +/// - debug (dictionary): Dictionary of debug options. +/// +/// Supported fields include: +/// - `ports`: if true, shows dots on all ports of the element #let elmt( draw-shape: default-draw-shape, x: none, diff --git a/src/elements/extender.typ b/src/elements/extender.typ index d2e1fc5..c219ad6 100644 --- a/src/elements/extender.typ +++ b/src/elements/extender.typ @@ -25,6 +25,29 @@ return (f, tl, tr, br, bl) } +/// Draws a bit extender +/// +/// #box(width: 100%, align(center)[ +/// #circuit({ +/// element.extender( +/// x: 0, y: 0, +/// w: 3, h: 1, +/// id: "extender" +/// ) +/// wire.stub("extender-port-in", "west") +/// wire.stub("extender-port-out", "east") +/// }) +/// ]) +/// - x (number, dictionary): see `elmt()` +/// - y (number, dictionary): see `elmt()` +/// - w (number): see `elmt()` +/// - h (number): see `elmt()` +/// - name (none, str): see `elmt()` +/// - name-anchor (str): see `elmt()` +/// - fill (none, color): see `elmt()` +/// - stroke (stroke): see `elmt()` +/// - id (str): see `elmt()` +/// - debug (dictionary): see `elmt()` #let extender( x: none, y: none, diff --git a/src/elements/multiplexer.typ b/src/elements/multiplexer.typ index 0288199..fd8ee0c 100644 --- a/src/elements/multiplexer.typ +++ b/src/elements/multiplexer.typ @@ -21,6 +21,45 @@ return (f, tl, tr, br, bl) } +/// Draws a multiplexer +/// +/// #box(width: 100%, align(center)[ +/// #circuit({ +/// element.multiplexer( +/// x: 0, y: 0, +/// w: 1, h: 3, +/// id: "multiplexer", +/// entries: 3 +/// ) +/// wire.stub("multiplexer-port-in0", "west") +/// wire.stub("multiplexer-port-in1", "west") +/// wire.stub("multiplexer-port-in2", "west") +/// wire.stub("multiplexer.north", "north") +/// wire.stub("multiplexer-port-out", "east") +/// element.multiplexer( +/// x: 3, y: 0, +/// w: 1, h: 3, +/// id: "multiplexer2", +/// entries: ("A", "B", "C") +/// ) +/// wire.stub("multiplexer2-port-in0", "west") +/// wire.stub("multiplexer2-port-in1", "west") +/// wire.stub("multiplexer2-port-in2", "west") +/// wire.stub("multiplexer2.south", "south") +/// wire.stub("multiplexer2-port-out", "east") +/// }) +/// ]) +/// - x (number, dictionary): see `elmt()` +/// - y (number, dictionary): see `elmt()` +/// - w (number): see `elmt()` +/// - h (number): see `elmt()` +/// - name (none, str): see `elmt()` +/// - name-anchor (str): see `elmt()` +/// - entries (int, array): If it is an integer, it defines the number of input ports (automatically named with their binary index). If it is an array of string, it defines the name of each input. +/// - fill (none, color): see `elmt()` +/// - stroke (stroke): see `elmt()` +/// - id (str): see `elmt()` +/// - debug (dictionary): see `elmt()` #let multiplexer( x: none, y: none, diff --git a/src/util.typ b/src/util.typ index ae128d8..f9ec2ac 100644 --- a/src/util.typ +++ b/src/util.typ @@ -1,4 +1,15 @@ /// Predefined color palette +/// #let w = 5 +/// #box(width: 100%, align(center)[ +/// #canvas(length: 2em, { +/// for (i, color) in util.colors.pairs().enumerate() { +/// let x = calc.rem(i, w) * 2 +/// let y = calc.floor(i / w) * 2 +/// draw.rect((x, -y), (x + 1, -y - 1), fill: color.last(), stroke: none) +/// draw.content((x + 0.5, -y - 1.25), color.first()) +/// } +/// }) +/// ]) #let colors = ( orange: rgb(245, 180, 147), yellow: rgb(250, 225, 127),