forked from HEL/circuiteria
		
	split up sources into manageable files
This commit is contained in:
		
							
								
								
									
										84
									
								
								src/elements/alu.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/elements/alu.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| #import "@preview/cetz:0.2.2": draw | ||||
| #import "element.typ" | ||||
| #import "ports.typ": add-port | ||||
|  | ||||
| #let draw-shape(id, tl, tr, br, bl, fill, stroke) = { | ||||
|   let p0 = tl | ||||
|   let p1 = (tr, 10%, br) | ||||
|   let p2 = (tr, 90%, br) | ||||
|   let p3 = bl | ||||
|   let p4 = (tl, 55%, bl) | ||||
|   let p5 = (tl, 50%, br) | ||||
|   let p6 = (tl, 45%, bl) | ||||
|    | ||||
|   let f1 = draw.group(name: id, { | ||||
|      | ||||
|     draw.merge-path( | ||||
|       inset: 0.5em, | ||||
|       fill: fill, | ||||
|       stroke: stroke, | ||||
|       close: true, | ||||
|       draw.line(p0, p1, p2, p3, p4, p5, p6) | ||||
|     ) | ||||
|     draw.anchor("north", (p0, 50%, p1)) | ||||
|     draw.anchor("south", (p2, 50%, p3)) | ||||
|     draw.anchor("west", (p0, 50%, p3)) | ||||
|     draw.anchor("east", (p1, 50%, p2)) | ||||
|   }) | ||||
|  | ||||
|   let f2 = add-port(id, "west", (id: "in1"), (p0, 50%, p6)) | ||||
|   let f3 = add-port(id, "west", (id: "in2"), (p3, 50%, p4)) | ||||
|   let f4 = add-port(id, "east", (id: "out"), (p1, 50%, p2)) | ||||
|  | ||||
|   let f = { | ||||
|     f1; f2; f3; f4 | ||||
|   } | ||||
|  | ||||
|   return (f, tl, tr, br, bl) | ||||
| } | ||||
|  | ||||
| #let alu( | ||||
|   x: none, | ||||
|   y: none, | ||||
|   w: none, | ||||
|   h: none, | ||||
|   name: none, | ||||
|   name-anchor: "center", | ||||
|   fill: none, | ||||
|   stroke: black + 1pt, | ||||
|   id: "", | ||||
|   debug: ( | ||||
|     grid: false, | ||||
|     ports: false | ||||
|   ) | ||||
| ) = { | ||||
|   let ports = ( | ||||
|     west: ( | ||||
|       (id: "in1"), | ||||
|       (id: "in2"), | ||||
|     ), | ||||
|     east: ( | ||||
|       (id: "out"), | ||||
|     ) | ||||
|   ) | ||||
|    | ||||
|   element.elmt( | ||||
|     draw-shape: draw-shape, | ||||
|     x: x, | ||||
|     y: y, | ||||
|     w: w, | ||||
|     h: h, | ||||
|     name: name, | ||||
|     name-anchor: name-anchor, | ||||
|     ports: ports, | ||||
|     fill: fill, | ||||
|     stroke: stroke, | ||||
|     id: id, | ||||
|     auto-ports: false, | ||||
|     ports-y: ( | ||||
|       in1: (h) => {h * 0.225}, | ||||
|       in2: (h) => {h * 0.775}, | ||||
|     ), | ||||
|     debug: debug | ||||
|   ) | ||||
| } | ||||
							
								
								
									
										46
									
								
								src/elements/block.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/elements/block.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #import "@preview/cetz:0.2.2": draw | ||||
| #import "element.typ" | ||||
|  | ||||
| #let draw-shape(id, tl, tr, br, bl, fill, stroke) = { | ||||
|   let f = draw.rect( | ||||
|     radius: 0.5em, | ||||
|     inset: 0.5em, | ||||
|     fill: fill, | ||||
|     stroke: stroke, | ||||
|     name: id, | ||||
|     bl, tr | ||||
|   ) | ||||
|   return (f, tl, tr, br, bl) | ||||
| } | ||||
|  | ||||
| #let block( | ||||
|   x: none, | ||||
|   y: none, | ||||
|   w: none, | ||||
|   h: none, | ||||
|   name: none, | ||||
|   name-anchor: "center", | ||||
|   ports: (), | ||||
|   ports-margins: (), | ||||
|   fill: none, | ||||
|   stroke: black + 1pt, | ||||
|   id: "", | ||||
|   debug: ( | ||||
|     grid: false, | ||||
|     ports: false | ||||
|   ) | ||||
| ) = element.elmt( | ||||
|   draw-shape: draw-shape, | ||||
|   x: x, | ||||
|   y: y, | ||||
|   w: w, | ||||
|   h: h, | ||||
|   name: name, | ||||
|   name-anchor: name-anchor, | ||||
|   ports: ports, | ||||
|   ports-margins: ports-margins, | ||||
|   fill: fill, | ||||
|   stroke: stroke, | ||||
|   id: id, | ||||
|   debug: debug | ||||
| ) | ||||
							
								
								
									
										99
									
								
								src/elements/element.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/elements/element.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| #import "@preview/cetz:0.2.2": draw, coordinate | ||||
| #import "ports.typ": add-ports, add-port | ||||
|  | ||||
| #let find-port(ports, id) = { | ||||
|   for (side, side-ports) in ports { | ||||
|     for (i, port) in side-ports.enumerate() { | ||||
|       if port.id == id { | ||||
|         return (side, i) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   panic("Could not find port with id " + str(id)) | ||||
| } | ||||
|  | ||||
| #let default-draw-shape(id, tl, tr, br, bl, fill, stroke) = { | ||||
|   return ({}, tl, tr, br, bl) | ||||
| } | ||||
|  | ||||
| #let elmt( | ||||
|   draw-shape: default-draw-shape, | ||||
|   x: none, | ||||
|   y: none, | ||||
|   w: none, | ||||
|   h: none, | ||||
|   name: none, | ||||
|   name-anchor: "center", | ||||
|   ports: (), | ||||
|   ports-margins: (), | ||||
|   fill: none, | ||||
|   stroke: black + 1pt, | ||||
|   id: "", | ||||
|   auto-ports: true, | ||||
|   ports-y: (), | ||||
|   debug: ( | ||||
|     grid: false, | ||||
|     ports: false | ||||
|   ) | ||||
| ) = draw.get-ctx(ctx => { | ||||
|   let width = w | ||||
|   let height = h | ||||
|  | ||||
|   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(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) | ||||
|  | ||||
|     if not auto-ports { | ||||
|       top-margin = 0 | ||||
|       dy = ports-y.at(to)(height) | ||||
|     } | ||||
|      | ||||
|     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) | ||||
|   func | ||||
|  | ||||
|   if (name != none) { | ||||
|     draw.content( | ||||
|       (name: id, anchor: name-anchor), | ||||
|       anchor: name-anchor, | ||||
|       padding: 0.5em, | ||||
|       align(center)[*#name*] | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   if auto-ports { | ||||
|     add-ports( | ||||
|       id, | ||||
|       tl, tr, br, bl, | ||||
|       ports, | ||||
|       ports-margins, | ||||
|       debug: debug.ports | ||||
|     ) | ||||
|   } | ||||
| }) | ||||
							
								
								
									
										66
									
								
								src/elements/extender.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/elements/extender.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| #import "@preview/cetz:0.2.2": draw | ||||
| #import "element.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) | ||||
|  | ||||
|   tl = (x, y + height * 0.75) | ||||
|   let tr2 = (x + width, y + height * 0.75) | ||||
|   let br = (x + width, y) | ||||
|   (tr, tr2) = (tr2, tr) | ||||
|   let f = draw.group(name: id, { | ||||
|     draw.merge-path( | ||||
|       inset: 0.5em, | ||||
|       fill: fill, | ||||
|       stroke: stroke, | ||||
|       close: true, | ||||
|       draw.line(tl, tr2, br, bl) | ||||
|     ) | ||||
|     draw.anchor("north", (tl, 50%, tr2)) | ||||
|     draw.anchor("south", (bl, 50%, br)) | ||||
|     draw.anchor("west", (tl, 50%, bl)) | ||||
|     draw.anchor("east", (tr2, 50%, br)) | ||||
|   }) | ||||
|   return (f, tl, tr, br, bl) | ||||
| } | ||||
|  | ||||
| #let extender( | ||||
|   x: none, | ||||
|   y: none, | ||||
|   w: none, | ||||
|   h: none, | ||||
|   name: none, | ||||
|   name-anchor: "center", | ||||
|   fill: none, | ||||
|   stroke: black + 1pt, | ||||
|   id: "", | ||||
|   debug: ( | ||||
|     grid: false, | ||||
|     ports: false | ||||
|   ) | ||||
| ) = { | ||||
|   let ports = ( | ||||
|     west: ( | ||||
|       (id: "in"), | ||||
|     ), | ||||
|     east: ( | ||||
|       (id: "out"), | ||||
|     ) | ||||
|   ) | ||||
|    | ||||
|   element.elmt( | ||||
|     draw-shape: draw-shape, | ||||
|     x: x, | ||||
|     y: y, | ||||
|     w: w, | ||||
|     h: h, | ||||
|     name: name, | ||||
|     name-anchor: name-anchor, | ||||
|     ports: ports, | ||||
|     fill: fill, | ||||
|     stroke: stroke, | ||||
|     id: id, | ||||
|     debug: debug | ||||
|   ) | ||||
| } | ||||
							
								
								
									
										64
									
								
								src/elements/multiplexer.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/elements/multiplexer.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| #import "@preview/cetz:0.2.2": draw | ||||
| #import "../util.typ" | ||||
| #import "element.typ" | ||||
|  | ||||
| #let draw-shape(id, tl, tr, br, bl, fill, stroke) = { | ||||
|   let tr2 = (tr, 20%, br) | ||||
|   let br2 = (tr, 80%, br) | ||||
|   let f = draw.group(name: id, { | ||||
|     draw.merge-path( | ||||
|       inset: 0.5em, | ||||
|       fill: fill, | ||||
|       stroke: stroke, | ||||
|       close: true, | ||||
|       draw.line(tl, tr2, br2, bl) | ||||
|     ) | ||||
|     draw.anchor("north", (tl, 50%, tr2)) | ||||
|     draw.anchor("south", (bl, 50%, br2)) | ||||
|     draw.anchor("west", (tl, 50%, bl)) | ||||
|     draw.anchor("east", (tr2, 50%, br2)) | ||||
|   }) | ||||
|   return (f, tl, tr, br, bl) | ||||
| } | ||||
|  | ||||
| #let multiplexer( | ||||
|   x: none, | ||||
|   y: none, | ||||
|   w: none, | ||||
|   h: none, | ||||
|   name: none, | ||||
|   name-anchor: "center", | ||||
|   entries: 2, | ||||
|   fill: none, | ||||
|   stroke: black + 1pt, | ||||
|   id: "", | ||||
|   debug: ( | ||||
|     grid: false, | ||||
|     ports: false | ||||
|   ) | ||||
| ) = { | ||||
|   let ports = () | ||||
|  | ||||
|   if (type(entries) == int) { | ||||
|     let nbits = calc.ceil(calc.log(entries, base: 2)) | ||||
|     for i in range(entries) { | ||||
|       let bits = util.lpad(str(i, base: 2), nbits) | ||||
|       ports.push((id: "in" + str(i), name: bits)) | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   element.elmt( | ||||
|     draw-shape: draw-shape, | ||||
|     x: x, | ||||
|     y: y, | ||||
|     w: w, | ||||
|     h: h, | ||||
|     name: name, | ||||
|     name-anchor: name-anchor, | ||||
|     ports: (west: ports, east: ((id: "out"),)), | ||||
|     fill: fill, | ||||
|     stroke: stroke, | ||||
|     id: id, | ||||
|     debug: debug | ||||
|   ) | ||||
| } | ||||
							
								
								
									
										106
									
								
								src/elements/ports.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/elements/ports.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| #import "@preview/cetz:0.2.2": draw | ||||
| #import "../util.typ": rotate-anchor | ||||
|  | ||||
| #let add-port( | ||||
|   elmt-id, side, port, pos, | ||||
|   prev: none, | ||||
|   next: none, | ||||
|   debug: false | ||||
| ) = { | ||||
|   let name = port.at("name", default: "") | ||||
|   let name-rotate = port.at("vertical", default: false) | ||||
|  | ||||
|   if (port.at("clock", default: false)) { | ||||
|     if prev == none or next == none { | ||||
|       panic("Clock port must have previous and next positions") | ||||
|     } | ||||
|      | ||||
|     let offset | ||||
|     if      (side == "north") { offset = (   0, -1em) } | ||||
|     else if (side == "east")  { offset = (-1em,    0) } | ||||
|     else if (side == "south") { offset = (   0,  1em) } | ||||
|     else if (side == "west")  { offset = ( 1em,    0) } | ||||
|  | ||||
|     let pos1 = (rel: offset, to: pos) | ||||
|  | ||||
|     // TODO: use context or vectors to have the height relative to the width | ||||
|     draw.line(prev, pos1, next) | ||||
|   } | ||||
|   draw.content( | ||||
|     pos, | ||||
|     anchor: if name-rotate {rotate-anchor(side)} else {side}, | ||||
|     padding: 2pt, | ||||
|     angle: if name-rotate {90deg} else {0deg}, | ||||
|     name | ||||
|   ) | ||||
|   let id = elmt-id + "-port-" + port.at("id") | ||||
|  | ||||
|   if debug { | ||||
|     draw.circle( | ||||
|       pos, | ||||
|       name: id, | ||||
|       radius: .1, | ||||
|       stroke: none, | ||||
|       fill: red | ||||
|     ) | ||||
|      | ||||
|   } else { | ||||
|     draw.hide(draw.circle( | ||||
|       pos, | ||||
|       radius: 0, | ||||
|       stroke: none, | ||||
|       name: id | ||||
|     )) | ||||
|   } | ||||
| } | ||||
|  | ||||
| #let add-ports( | ||||
|   elmt-id, | ||||
|   tl, tr, br, bl, | ||||
|   ports, | ||||
|   ports-margins, | ||||
|   debug: false | ||||
| ) = { | ||||
|   let sides = ( | ||||
|     "north": (tl, tr), | ||||
|     "east": (tr, br), | ||||
|     "south": (bl, br), | ||||
|     "west": (tl, bl) | ||||
|   ) | ||||
|  | ||||
|   for (side, props) in sides { | ||||
|     let side-ports = ports.at(side, default: ()) | ||||
|     let space = 100% / (side-ports.len() + 1) | ||||
|  | ||||
|     for (i, port) in side-ports.enumerate() { | ||||
|       let pct = (i + 1) * space | ||||
|       let pt0 = props.at(0) | ||||
|       let pt1 = props.at(1) | ||||
|  | ||||
|       if side in ports-margins { | ||||
|         let (a, b) = (pt0, pt1) | ||||
|         let margins = ports-margins.at(side) | ||||
|         a = (pt0, margins.at(0), pt1) | ||||
|         b = (pt0, 100% - margins.at(1), pt1) | ||||
|         pt0 = a | ||||
|         pt1 = b | ||||
|       } | ||||
|        | ||||
|       let pos = (pt0, pct, pt1) | ||||
|       let pct-prev = (i + 0.5) * space | ||||
|       let pct-next = (i + 1.5) * space | ||||
|       let pos-prev = (pt0, pct-prev, pt1) | ||||
|       let pos-next = (pt0, pct-next, pt1) | ||||
|  | ||||
|       add-port( | ||||
|         elmt-id, | ||||
|         side, | ||||
|         port, | ||||
|         pos, | ||||
|         prev: pos-prev, | ||||
|         next: pos-next, | ||||
|         debug: debug | ||||
|       ) | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user