Compare commits
No commits in common. "86d91227401ee2b3996305d921db2f271dd6fcaf" and "66ac91af7b7c7fe0c46a0429af3b7a40664bea43" have entirely different histories.
86d9122740
...
66ac91af7b
@ -114,30 +114,3 @@ gates.gate-xor(x: 3, y: 0, w: 1.5, h: 1.5, inverted: "all")
|
||||
gates.gate-xnor(x: 0, y: 0, w: 1.5, h: 1.5)
|
||||
gates.gate-xnor(x: 3, y: 0, w: 1.5, h: 1.5, inverted: "all")
|
||||
```, vertical: true)
|
||||
|
||||
#let group = example(```
|
||||
element.group(
|
||||
id: "g1", name: "Group 1", stroke: (dash: "dashed"),
|
||||
{
|
||||
element.block(id: "b1", w: 2, h: 2,
|
||||
x: 0, y: 1.5,
|
||||
ports: (east: ((id: "out"),)),
|
||||
fill: util.colors.green
|
||||
)
|
||||
element.block(id: "b2", w: 2, h: 1,
|
||||
x: 0, y: 0,
|
||||
ports: (east: ((id: "out"),)),
|
||||
fill: util.colors.orange
|
||||
)
|
||||
}
|
||||
)
|
||||
element.block(id: "b3", w: 2, h: 3,
|
||||
x: (rel: 1, to: "g1.east"),
|
||||
y: (from: "b1-port-out", to: "in1"),
|
||||
ports: (west: ((id: "in1"), (id: "in2"))),
|
||||
fill: util.colors.blue
|
||||
)
|
||||
wire.wire("w1", ("b1-port-out", "b3-port-in1"))
|
||||
wire.wire("w2", ("b2-port-out", "b3-port-in2"),
|
||||
style: "zigzag")
|
||||
```)
|
BIN
gallery/test.pdf
BIN
gallery/test.pdf
Binary file not shown.
Binary file not shown.
@ -1,217 +0,0 @@
|
||||
#import "@preview/cetz:0.2.2": draw
|
||||
#import "../src/lib.typ": *
|
||||
|
||||
#set page(flipped: true)
|
||||
|
||||
#circuit({
|
||||
element.group(id: "toplvl", name: "Toplevel", {
|
||||
element.group(
|
||||
id: "proc",
|
||||
name: "Processor",
|
||||
padding: 1.5em,
|
||||
stroke: (dash: "dashed"),
|
||||
{
|
||||
element.block(
|
||||
x: 0, y: 0, w: 8, h: 4,
|
||||
id: "dp",
|
||||
fill: util.colors.pink,
|
||||
name: "Datapath",
|
||||
ports: (
|
||||
north: (
|
||||
(id: "clk", clock: true),
|
||||
(id: "Zero"),
|
||||
(id: "Regsrc"),
|
||||
(id: "PCSrc"),
|
||||
(id: "ResultSrc"),
|
||||
(id: "ALUControl"),
|
||||
(id: "ImmSrc"),
|
||||
(id: "RegWrite"),
|
||||
(id: "dummy")
|
||||
),
|
||||
east: (
|
||||
(id: "PC", name: "PC"),
|
||||
(id: "Instr", name: "Instr"),
|
||||
(id: "ALUResult", name: "ALUResult"),
|
||||
(id: "dummy"),
|
||||
(id: "WriteData", name: "WriteData"),
|
||||
(id: "ReadData", name: "ReadData"),
|
||||
),
|
||||
west: (
|
||||
(id: "rst"),
|
||||
)
|
||||
),
|
||||
ports-margins: (
|
||||
north: (0%, 0%),
|
||||
west: (0%, 70%)
|
||||
)
|
||||
)
|
||||
|
||||
element.block(
|
||||
x: 0, y: 7, w: 8, h: 3,
|
||||
id: "ctrl",
|
||||
fill: util.colors.orange,
|
||||
name: "Controller",
|
||||
ports: (
|
||||
east: (
|
||||
(id: "Instr", name: "Instr"),
|
||||
),
|
||||
south: (
|
||||
(id: "dummy"),
|
||||
(id: "Zero"),
|
||||
(id: "Regsrc"),
|
||||
(id: "PCSrc"),
|
||||
(id: "ResultSrc"),
|
||||
(id: "ALUControl"),
|
||||
(id: "ImmSrc"),
|
||||
(id: "RegWrite"),
|
||||
(id: "MemWrite")
|
||||
)
|
||||
),
|
||||
ports-margins: (
|
||||
south: (0%, 0%)
|
||||
)
|
||||
)
|
||||
wire.wire(
|
||||
"w-Zero",
|
||||
("dp-port-Zero", "ctrl-port-Zero"),
|
||||
name: "Zero",
|
||||
name-pos: "start",
|
||||
directed: true
|
||||
)
|
||||
for p in ("Regsrc", "PCSrc", "ResultSrc", "ALUControl", "ImmSrc", "RegWrite") {
|
||||
wire.wire(
|
||||
"w-" + p,
|
||||
("ctrl-port-"+p, "dp-port-"+p),
|
||||
name: p,
|
||||
name-pos: "start",
|
||||
directed: true
|
||||
)
|
||||
}
|
||||
|
||||
draw.content(
|
||||
(rel: (0, 1em), to: "ctrl.north"),
|
||||
[*RISCV single*],
|
||||
anchor: "south"
|
||||
)
|
||||
})
|
||||
|
||||
element.block(
|
||||
x: (rel: 3.5, to: "dp.east"),
|
||||
y: (from: "dp-port-ReadData", to: "RD"),
|
||||
w: 3, h: 4,
|
||||
id: "dmem",
|
||||
fill: util.colors.green,
|
||||
name: "Data\n Memory",
|
||||
ports: (
|
||||
north: (
|
||||
(id: "clk", clock: true),
|
||||
(id: "WE", name: "WE")
|
||||
),
|
||||
west: (
|
||||
(id: "dummy"),
|
||||
(id: "dummy"),
|
||||
(id: "A", name: "A"),
|
||||
(id: "dummy"),
|
||||
(id: "WD", name: "WD"),
|
||||
(id: "RD", name: "RD"),
|
||||
)
|
||||
),
|
||||
ports-margins: (
|
||||
north: (0%, 10%)
|
||||
)
|
||||
)
|
||||
wire.wire(
|
||||
"w-DataAddr",
|
||||
("dp-port-ALUResult", "dmem-port-A"),
|
||||
name: "DataAddr",
|
||||
name-pos: "end",
|
||||
directed: true
|
||||
)
|
||||
wire.wire(
|
||||
"w-WriteData",
|
||||
("dp-port-WriteData", "dmem-port-WD"),
|
||||
name: "WriteData",
|
||||
name-pos: "end",
|
||||
directed: true
|
||||
)
|
||||
wire.wire(
|
||||
"w-ReadData",
|
||||
("dmem-port-RD", "dp-port-ReadData"),
|
||||
name: "ReadData",
|
||||
name-pos: "end",
|
||||
reverse: true,
|
||||
directed: true
|
||||
)
|
||||
wire.wire(
|
||||
"w-MemWrite",
|
||||
("ctrl-port-MemWrite", "dmem-port-WE"),
|
||||
style: "zigzag",
|
||||
name: "MemWrite",
|
||||
name-pos: "start",
|
||||
zigzag-dir: "horizontal",
|
||||
zigzag-ratio: 80%,
|
||||
directed: true
|
||||
)
|
||||
wire.stub(
|
||||
"dmem-port-clk", "north",
|
||||
name: "clk", length: 3pt
|
||||
)
|
||||
|
||||
element.block(
|
||||
x: (rel: 3.5, to: "dp.east"),
|
||||
y: (from: "ctrl-port-Instr", to: "dummy"),
|
||||
w: 3, h: 4,
|
||||
id: "imem",
|
||||
fill: util.colors.green,
|
||||
name: "Instruction\n Memory",
|
||||
ports: (
|
||||
west: (
|
||||
(id: "A", name: "A"),
|
||||
(id: "dummy"),
|
||||
(id: "dummy2"),
|
||||
(id: "RD", name: "RD"),
|
||||
)
|
||||
)
|
||||
)
|
||||
wire.wire(
|
||||
"w-PC",
|
||||
("dp-port-PC", "imem-port-A"),
|
||||
style: "zigzag",
|
||||
directed: true
|
||||
)
|
||||
wire.wire(
|
||||
"w-Instr1",
|
||||
("imem-port-RD", "dp-port-Instr"),
|
||||
style: "zigzag",
|
||||
zigzag-ratio: 30%,
|
||||
directed: true
|
||||
)
|
||||
wire.wire(
|
||||
"w-Instr2",
|
||||
("imem-port-RD", "ctrl-port-Instr"),
|
||||
style: "zigzag",
|
||||
zigzag-ratio: 30%,
|
||||
directed: true
|
||||
)
|
||||
wire.intersection("w-Instr1.zig", radius: 2pt)
|
||||
draw.content("w-Instr1.zig", "Instr", anchor: "south", padding: 4pt)
|
||||
draw.content("w-PC.zig", "PC", anchor: "south-east", padding: 2pt)
|
||||
|
||||
draw.content("dmem.south-west", [*External Memories*], anchor: "north", padding: 10pt)
|
||||
})
|
||||
|
||||
wire.wire(
|
||||
"w-dp-clk",
|
||||
("dp-port-clk", (-1, 4.2)),
|
||||
style: "zigzag",
|
||||
zigzag-dir: "horizontal",
|
||||
zigzag-ratio: 100%
|
||||
)
|
||||
draw.content("w-dp-clk.end", "clk", anchor: "east", padding: 3pt)
|
||||
|
||||
wire.wire(
|
||||
"w-dp-rst",
|
||||
("dp-port-rst", (horizontal: (-1, 0), vertical: ()))
|
||||
)
|
||||
draw.content("w-dp-rst.end", "rst", anchor: "east", padding: 3pt)
|
||||
})
|
BIN
manual.pdf
BIN
manual.pdf
Binary file not shown.
@ -158,8 +158,7 @@ Simply import #link("src/lib.typ") and call the `circuit` function:
|
||||
read("src/elements/alu.typ") + "\n" +
|
||||
read("src/elements/block.typ") + "\n" +
|
||||
read("src/elements/extender.typ") + "\n" +
|
||||
read("src/elements/multiplexer.typ") + "\n" +
|
||||
read("src/elements/group.typ"),
|
||||
read("src/elements/multiplexer.typ"),
|
||||
name: "element",
|
||||
scope: (
|
||||
element: element,
|
||||
|
@ -11,5 +11,3 @@
|
||||
#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
|
||||
|
||||
#import "elements/group.typ": group
|
@ -33,7 +33,7 @@
|
||||
/// - `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 (`<start>`, `<end>`) margins (numbers)
|
||||
/// - 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 (<start>, <end>) margins (numbers)
|
||||
/// - fill (none, color): Fill color
|
||||
/// - stroke (stroke): Border stroke
|
||||
/// - id (str): The block id (for future reference)
|
||||
|
@ -1,80 +0,0 @@
|
||||
#import "@preview/cetz:0.2.2": draw, coordinate
|
||||
#import "../util.typ"
|
||||
|
||||
/// Draws a group of elements
|
||||
///
|
||||
/// #examples.group
|
||||
/// - body (elements, function): Elements to group
|
||||
/// - id (str): see #doc-ref("element.elmt")
|
||||
/// - name (str): The group's name
|
||||
/// - name-anchor (str): The anchor for the name. \
|
||||
/// Note: the name will be placed on the *outside* of the group
|
||||
/// - fill (color): see #doc-ref("element.elmt")
|
||||
/// - stroke (stroke): see #doc-ref("element.elmt")
|
||||
/// - padding (float,length,array,dictionary): The inside padding:
|
||||
/// - float / length: same for all sides
|
||||
/// - array: either (`<all>`,), (`<vertical>`, `<horizontal>`) or (`<top>`, `<right>`, `<bottom>`, `<left>`)
|
||||
/// - dictionary: valid keys are "top", "right", "bottom" and "left"
|
||||
/// - radius (number): The corner radius
|
||||
#let group(
|
||||
body,
|
||||
id: "",
|
||||
name: none,
|
||||
name-anchor: "south",
|
||||
fill: none,
|
||||
stroke: black + 1pt,
|
||||
padding: 0.5em,
|
||||
radius: 0.5em
|
||||
) = {
|
||||
let min-x = none
|
||||
let max-x = none
|
||||
let min-y = none
|
||||
let max-y = none
|
||||
|
||||
let pad-top = padding
|
||||
let pad-bottom = padding
|
||||
let pad-left = padding
|
||||
let pad-right = padding
|
||||
|
||||
if type(padding) == array {
|
||||
if padding.len() == 0 {
|
||||
panic("Padding array must contain at least one value")
|
||||
} else if padding.len() == 1 {
|
||||
pad-top = padding.first()
|
||||
pad-bottom = padding.first()
|
||||
pad-left = padding.first()
|
||||
pad-right = padding.first()
|
||||
} else if padding.len() == 2 {
|
||||
pad-top = padding.first()
|
||||
pad-bottom = padding.first()
|
||||
pad-left = padding.last()
|
||||
pad-right = padding.last()
|
||||
} else if padding.len() == 4 {
|
||||
(pad-top, pad-right, pad-bottom, pad-left) = padding
|
||||
}
|
||||
} else if type(padding) == dictionary {
|
||||
pad-top = padding.at("top", default: 0.5em)
|
||||
pad-right = padding.at("right", default: 0.5em)
|
||||
pad-bottom = padding.at("bottom", default: 0.5em)
|
||||
pad-left = padding.at("left", default: 0.5em)
|
||||
}
|
||||
|
||||
draw.hide(draw.group(name: id+"-inner", body))
|
||||
draw.rect(
|
||||
(rel: (-pad-left, -pad-bottom), to: id+"-inner.south-west"),
|
||||
(rel: (pad-right, pad-top), to: id+"-inner.north-east"),
|
||||
name: id,
|
||||
radius: radius,
|
||||
stroke: stroke,
|
||||
fill: fill
|
||||
)
|
||||
if name != none {
|
||||
draw.content(
|
||||
id + "." + name-anchor,
|
||||
anchor: util.opposite-anchor(name-anchor),
|
||||
padding: 5pt,
|
||||
[*#name*]
|
||||
)
|
||||
}
|
||||
body
|
||||
}
|
45
src/wire.typ
45
src/wire.typ
@ -7,8 +7,8 @@
|
||||
#let signal-width = 1pt
|
||||
#let bus-width = 1.5pt
|
||||
|
||||
#let intersection(pt, radius: .2, fill: black) = {
|
||||
draw.circle(pt, radius: radius, stroke: none, fill: fill)
|
||||
#let intersection(pt) = {
|
||||
draw.circle(pt, radius: .2, stroke: none, fill: black)
|
||||
}
|
||||
|
||||
#let get-direct-wire(pts) = {
|
||||
@ -19,26 +19,17 @@
|
||||
return (pts, anchors)
|
||||
}
|
||||
|
||||
#let get-zigzag-wire(pts, ratio, dir) = {
|
||||
#let get-zigzag-wire(pts, ratio) = {
|
||||
let start = pts.first()
|
||||
let end = pts.last()
|
||||
let mid = (start, ratio, end)
|
||||
|
||||
let points = if dir == "vertical" {
|
||||
(
|
||||
let points = (
|
||||
start,
|
||||
(horizontal: mid, vertical: ()),
|
||||
(horizontal: (), vertical: end),
|
||||
end
|
||||
)
|
||||
} else {
|
||||
(
|
||||
start,
|
||||
(horizontal: (), vertical: mid),
|
||||
(horizontal: end, vertical: ()),
|
||||
end
|
||||
)
|
||||
}
|
||||
let anchors = (
|
||||
"start": start,
|
||||
"zig": points.at(1),
|
||||
@ -111,10 +102,7 @@
|
||||
/// - dashed (bool): Whether the stroke is dashed or not
|
||||
/// - style (str): The wire's style (see #doc-ref("wire.wire-styles", var: true) for possible values)
|
||||
/// - reverse (bool): If true, the start and end points will be swapped (useful in cases where the start point depends on the end point, for example with perpendiculars)
|
||||
/// - directed (bool): If true, the wire will be directed, meaning an arrow will be drawn at the endpoint
|
||||
/// - rotate-name (bool): If true, the name will be rotated according to the wire's slope
|
||||
/// - zigzag-ratio (ratio): Position of the zigzag vertical relative to the horizontal span (only with style "zigzag")
|
||||
/// - zigzag-dir (str): The zigzag's direction. As either "vertical" or "horizontal" (only with dstyle "zigzag")
|
||||
/// - dodge-y (number): Y position to dodge the wire to (only with style "dodge")
|
||||
/// - dodge-sides (array): The start and end sides (going out of the connected element) of the wire (only with style "dodge")
|
||||
/// - dodge-margins (array): The start and end margins (i.e. space before dodging) of the wire (only with style "dodge")
|
||||
@ -128,10 +116,7 @@
|
||||
dashed: false,
|
||||
style: "direct",
|
||||
reverse: false,
|
||||
directed: false,
|
||||
rotate-name: true,
|
||||
zigzag-ratio: 50%,
|
||||
zigzag-dir: "vertical",
|
||||
dodge-y: 0,
|
||||
dodge-sides: ("east", "west"),
|
||||
dodge-margins: (5%, 5%)
|
||||
@ -159,7 +144,7 @@
|
||||
(points, anchors) = get-direct-wire(pts)
|
||||
|
||||
} else if style == "zigzag" {
|
||||
(points, anchors) = get-zigzag-wire(pts, zigzag-ratio, zigzag-dir)
|
||||
(points, anchors) = get-zigzag-wire(pts, zigzag-ratio)
|
||||
|
||||
} else if style == "dodge" {
|
||||
(points, anchors) = get-dodge-wire(
|
||||
@ -171,12 +156,8 @@
|
||||
)
|
||||
}
|
||||
|
||||
let mark = (fill: color)
|
||||
if directed {
|
||||
mark = (end: ">", fill: color)
|
||||
}
|
||||
draw.group(name: id, {
|
||||
draw.line(..points, stroke: stroke, mark: mark)
|
||||
draw.line(..points, stroke: stroke)
|
||||
for (anchor-name, anchor-pos) in anchors {
|
||||
draw.anchor(anchor-name, anchor-pos)
|
||||
}
|
||||
@ -184,20 +165,8 @@
|
||||
|
||||
let first-pt = id + ".start"
|
||||
let last-pt = id + ".end"
|
||||
let first-pos = points.first()
|
||||
let second-pos = points.at(1)
|
||||
if reverse {
|
||||
(first-pt, last-pt) = (last-pt, first-pt)
|
||||
(first-pos, second-pos) = (second-pos, first-pos)
|
||||
}
|
||||
|
||||
let angle = 0deg
|
||||
if rotate-name {
|
||||
(ctx, first-pos) = coordinate.resolve(ctx, first-pos)
|
||||
(ctx, second-pos) = coordinate.resolve(ctx, second-pos)
|
||||
let (x1, y1, _) = first-pos
|
||||
let (x2, y2, _) = second-pos
|
||||
angle = calc.atan2(x2 - x1, y2 - y1)
|
||||
}
|
||||
|
||||
if name != none {
|
||||
@ -230,7 +199,7 @@
|
||||
anchor = "south-east"
|
||||
}
|
||||
|
||||
draw.content(point, anchor: anchor, padding: 3pt, angle: angle, name)
|
||||
draw.content(point, anchor: anchor, padding: 3pt, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user