diff --git a/gallery/test5.pdf b/gallery/test5.pdf new file mode 100644 index 0000000..17c13f0 Binary files /dev/null and b/gallery/test5.pdf differ diff --git a/gallery/test5.typ b/gallery/test5.typ new file mode 100644 index 0000000..f8a14ce --- /dev/null +++ b/gallery/test5.typ @@ -0,0 +1,435 @@ +#import "@preview/cetz:0.2.2": draw +#import "../src/lib.typ": * + +#set page(flipped: true, paper: "a3") + +#circuit({ + element.multiplexer( + x: 0, y: 0, w: .5, h: 1.5, id: "PCMux", + entries: 2, + fill: util.colors.blue, + h-ratio: 80% + ) + element.block( + x: (rel: 2, to: "PCMux.east"), + y: (from: "PCMux-port-out", to: "in"), + w: 1, h: 1.5, id: "PCBuf", + ports: ( + north: ((id: "clk", clock: true),), + west: ((id: "in"),), + east: ((id: "out"),) + ), + fill: util.colors.green + ) + + element.block( + x: (rel: 2, to: "PCBuf.east"), + y: (from: "PCBuf-port-out", to: "A"), + w: 3, h: 4, id: "IMem", + ports: ( + west: ( + (id: "A", name: "A"), + ), + east: ( + (id: "RD", name: "RD"), + ) + ), + ports-margins: ( + west: (0%, 50%), + east: (0%, 50%) + ), + fill: util.colors.green, + name: "Instruction\nMemory" + ) + element.block( + x: (rel: 3, to: "IMem.east"), + y: (from: "IMem-port-RD", to: "A1"), + w: 4.5, h: 4, id: "RegFile", + ports: ( + north: ( + (id: "clk", clock: true, small: true), + (id: "WE3", name: "WE3"), + (id: "dummy1") + ), + west: ( + (id: "dummy2"), + (id: "A1", name: "A1"), + (id: "dummy3"), + (id: "A2", name: "A2"), + (id: "A3", name: "A3"), + (id: "dummy4"), + (id: "WD3", name: "WD3"), + ), + east: ( + (id: "RD1", name: "RD1"), + (id: "RD2", name: "RD2"), + ) + ), + ports-margins: ( + north: (-20%, -20%), + east: (0%, 10%) + ), + fill: util.colors.green, + name: "Register\nFile" + ) + + element.alu( + x: (rel: -.7, to: "IMem.center"), + y: -7, + w: 1.4, h: 2.8, id: "PCAdd", + name: text("+", size: 1.5em), + name-anchor: "name", + fill: util.colors.pink + ) + element.extender( + x: (rel: 0, to: "RegFile.west"), + y: (from: "PCAdd-port-out", to: "in"), + w: 4, h: 1.5, id: "Ext", + h-ratio: 50%, + name: "Extend", + name-anchor: "south", + align-out: false, + fill: util.colors.green + ) + + element.multiplexer( + x: (rel: 3, to: "RegFile.east"), + y: (from: "RegFile-port-RD2", to: "in0"), + w: .5, h: 1.5, id: "SrcBMux", + fill: util.colors.blue, + h-ratio: 80% + ) + + element.alu( + x: (rel: 2, to: "SrcBMux.east"), + y: (from: "SrcBMux-port-out", to: "in2"), + w: 1.4, h: 2.8, id: "ALU", + name: rotate("ALU", -90deg), + name-anchor: "name", + fill: util.colors.pink + ) + element.alu( + x: (rel: 2, to: "SrcBMux.east"), + y: (from: "Ext-port-out", to: "in2"), + w: 1.4, h: 2.8, id: "JumpAdd", + name: text("+", size: 1.5em), + name-anchor: "name", + fill: util.colors.pink + ) + + element.block( + x: (rel: 4, to: "ALU.east"), + y: (from: "ALU-port-out", to: "A"), + w: 3, h: 4, id: "DMem", + name: "Data\nMemory", + ports: ( + north: ( + (id: "clk", clock: true, small: true), + (id: "dummy1"), + (id: "WE", name: "WE") + ), + west: ( + (id: "A", name: "A"), + (id: "WD", name: "WD") + ), + east: ( + (id: "RD", name: "RD"), + (id: "dummy2") + ) + ), + ports-margins: ( + north: (-10%, -10%), + west: (-20%, -30%), + east: (-10%, -20%) + ), + fill: util.colors.green + ) + + element.multiplexer( + x: (rel: 3, to: "DMem.east"), + y: (from: "DMem-port-RD", to: "in1"), + w: .5, h: 1.5, id: "ResMux", + entries: 2, + fill: util.colors.blue, + h-ratio: 80% + ) + + element.block( + x: (rel: 0, to: "RegFile.west"), + y: 3.5, w: 2.5, h: 5, id: "Ctrl", + name: "Control\nUnit", + name-anchor: "north", + ports: ( + west: ( + (id: "op", name: "op"), + (id: "funct3", name: "funct3"), + (id: "funct7", name: [funct7#sub("[5]")]), + (id: "zero", name: "Zero"), + ), + east: ( + (id: "PCSrc"), + (id: "ResSrc"), + (id: "MemWrite"), + (id: "ALUCtrl"), + (id: "ALUSrc"), + (id: "ImmSrc"), + (id: "RegWrite"), + ) + ), + ports-margins: ( + west: (40%, 0%) + ), + fill: util.colors.orange + ) + + // Wires + wire.wire( + "wPCNext", ("PCMux-port-out", "PCBuf-port-in"), + name: "PCNext" + ) + wire.stub("PCBuf-port-clk", "north", name: "clk", length: 0.25) + wire.wire( + "wPC1", ("PCBuf-port-out", "IMem-port-A"), + name: "PC" + ) + wire.wire( + "wPC2", ("PCBuf-port-out", "JumpAdd-port-in1"), + style: "zigzag", + zigzag-ratio: 1 + ) + wire.wire( + "wPC3", ("PCBuf-port-out", "PCAdd-port-in1"), + style: "zigzag", + zigzag-ratio: 1 + ) + wire.intersection("wPC2.zig", radius: 2pt) + wire.intersection("wPC2.zag", radius: 2pt) + wire.stub("PCAdd-port-in2", "west", name: "4", length: 1.5) + wire.wire( + "wPC+4", ("PCAdd-port-out", "PCMux-port-in0"), + style: "dodge", + dodge-sides: ("east", "west"), + dodge-y: -7.5, + dodge-margins: (1.2, .5), + name: "PC+4", + name-pos: "start" + ) + + let mid = ("IMem-port-RD", 50%, "RegFile-port-A1") + wire.wire( + "wInstr", ("IMem-port-RD", mid), + bus: true, + name: "Instr", + name-pos: "start" + ) + draw.hide({ + draw.line(name: "bus-top", + mid, + (horizontal: (), vertical: "Ctrl-port-op") + ) + draw.line(name: "bus-bot", + mid, + (horizontal: (), vertical: "Ext-port-in") + ) + }) + wire.wire( + "wInstrBus", ("bus-top.end", "bus-bot.end"), + bus: true + ) + wire.wire( + "wOp", ("Ctrl-port-op", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (6, 0) + ) + wire.wire( + "wF3", ("Ctrl-port-funct3", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (14, 12) + ) + wire.wire( + "wF7", ("Ctrl-port-funct7", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (30,) + ) + wire.wire( + "wA1", ("RegFile-port-A1", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (19, 15) + ) + wire.wire( + "wA2", ("RegFile-port-A2", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (24, 20) + ) + wire.wire( + "wA3", ("RegFile-port-A3", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (11, 7) + ) + wire.wire( + "wExt", ("Ext-port-in", (horizontal: mid, vertical: ())), + bus: true, + reverse: true, + slice: (31, 7) + ) + wire.intersection("wF3.end", radius: 2pt) + wire.intersection("wF7.end", radius: 2pt) + wire.intersection("wA1.end", radius: 2pt) + wire.intersection("wA2.end", radius: 2pt) + wire.intersection("wA3.end", radius: 2pt) + + wire.stub("RegFile-port-clk", "north", name: "clk", length: 0.25) + wire.wire("wRD2", ("RegFile-port-RD2", "SrcBMux-port-in0")) + wire.wire( + "wWD", ("RegFile-port-RD2", "DMem-port-WD"), + style: "zigzag", + zigzag-ratio: 1.5, + name: "WriteData", + name-pos: "end" + ) + wire.intersection("wWD.zig", radius: 2pt) + + wire.wire( + "wImmALU", ("Ext-port-out", "SrcBMux-port-in1"), + style: "zigzag", + zigzag-ratio: 2.5, + name: "ImmExt", + name-pos: "start" + ) + wire.wire( + "wImmJump", ("Ext-port-out", "JumpAdd-port-in2") + ) + wire.intersection("wImmALU.zig", radius: 2pt) + wire.wire( + "wJumpPC", ("JumpAdd-port-out", "PCMux-port-in1"), + style: "dodge", + dodge-sides: ("east", "west"), + dodge-y: -8, + dodge-margins: (1, 1), + name: "PCTarget", + name-pos: "start" + ) + + wire.wire( + "wSrcA", ("RegFile-port-RD1", "ALU-port-in1"), + name: "SrcA", + name-pos: "end" + ) + wire.wire( + "wSrcB", ("SrcBMux-port-out", "ALU-port-in2"), + name: "SrcB", + name-pos: "end" + ) + + wire.wire( + "wZero", ( + ("ALU.north-east", 50%, "ALU-port-out"), + "Ctrl-port-zero" + ), + style: "dodge", + dodge-sides: ("east", "west"), + dodge-y: 3, + dodge-margins: (1.5, 1), + name: "Zero", + name-pos: "start" + ) + wire.wire( + "wALURes1", ("ALU-port-out", "DMem-port-A"), + name: "ALUResult", + name-pos: "start" + ) + wire.wire( + "wALURes2", ("ALU-port-out", "ResMux-port-in0"), + style: "dodge", + dodge-sides: ("east", "west"), + dodge-y: 2, + dodge-margins: (3, 2) + ) + wire.intersection("wALURes2.start2", radius: 2pt) + + wire.stub("DMem-port-clk", "north", name: "clk", length: 0.25) + wire.wire( + "wRD", ("DMem-port-RD", "ResMux-port-in1"), + name: "ReadData", + name-pos: "start" + ) + + wire.wire( + "wRes", ("ResMux-port-out", "RegFile-port-WD3"), + style: "dodge", + dodge-sides: ("east", "west"), + dodge-y: -7.5, + dodge-margins: (1, 2) + ) + draw.content( + "wRes.dodge-start", + "Result", + anchor: "south-east", + padding: 5pt + ) + + // Other wires + draw.group({ + draw.stroke(util.colors.blue) + draw.line(name: "wPCSrc", + "Ctrl-port-PCSrc", + (horizontal: "RegFile.east", vertical: ()), + (horizontal: (), vertical: (rel: (0, 0.5), to: "Ctrl.north")), + (horizontal: "PCMux.north", vertical: ()), + "PCMux.north" + ) + draw.line(name: "wResSrc", + "Ctrl-port-ResSrc", + (horizontal: "ResMux.north", vertical: ()), + "ResMux.north" + ) + draw.line(name: "wMemWrite", + "Ctrl-port-MemWrite", + (horizontal: "DMem-port-WE", vertical: ()), + "DMem-port-WE" + ) + draw.line(name: "wALUCtrl", + "Ctrl-port-ALUCtrl", + (horizontal: "ALU.north", vertical: ()), + "ALU.north" + ) + draw.line(name: "wALUSrc", + "Ctrl-port-ALUSrc", + (horizontal: "SrcBMux.north", vertical: ()), + "SrcBMux.north" + ) + draw.line(name: "wImmSrc", + "Ctrl-port-ImmSrc", + (rel: (1, 0), to: (horizontal: "RegFile.east", vertical: ())), + (horizontal: (), vertical: (rel: (0, -.5), to: "RegFile.south")), + (horizontal: "Ext.north", vertical: ()), + "Ext.north" + ) + draw.line(name: "wRegWrite", + "Ctrl-port-RegWrite", + (rel: (.5, 0), to: (horizontal: "RegFile.east", vertical: ())), + (horizontal: (), vertical: ("Ctrl.south", 50%, "RegFile.north")), + (horizontal: "RegFile-port-WE3", vertical: ()), + "RegFile-port-WE3" + ) + + let names = ( + "PCSrc": "PCSrc", + "ResSrc": "ResultSrc", + "MemWrite": "MemWrite", + "ALUCtrl": [ALUControl#sub("[2:0]")], + "ALUSrc": "ALUSrc", + "ImmSrc": [ImmSrc#sub("[1:0]")], + "RegWrite": "RegWrite" + ) + for (port, name) in names { + draw.content("Ctrl-port-"+port, name, anchor: "south-west", padding: 3pt) + } + }) +}) \ No newline at end of file