added groups

This commit is contained in:
Louis Heredero 2024-05-18 13:06:57 +02:00
parent 5bd3dd8111
commit 86d9122740
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
9 changed files with 331 additions and 4 deletions

View File

@ -113,4 +113,31 @@ gates.gate-xor(x: 3, y: 0, w: 1.5, h: 1.5, inverted: "all")
#let gate-xnor = example(```
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)
```, 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")
```)

Binary file not shown.

BIN
gallery/test4.pdf Normal file

Binary file not shown.

217
gallery/test4.typ Normal file
View File

@ -0,0 +1,217 @@
#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)
})

Binary file not shown.

View File

@ -158,7 +158,8 @@ 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"),
read("src/elements/multiplexer.typ") + "\n" +
read("src/elements/group.typ"),
name: "element",
scope: (
element: element,

View File

@ -10,4 +10,6 @@
#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
#import "elements/logic/buf.typ": gate-buf, gate-not
#import "elements/group.typ": group

View File

@ -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)

80
src/elements/group.typ Normal file
View File

@ -0,0 +1,80 @@
#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
}