forked from HEL/circuiteria
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Typst
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Typst
		
	
	
	
	
	
| #import "/src/cetz.typ": draw
 | |
| #import "../util.typ"
 | |
| #import "element.typ"
 | |
| #import "ports.typ": add-port
 | |
| 
 | |
| #let draw-shape(elmt, bounds) = {
 | |
|   let margin = (100% - elmt.l-ratio) / 2
 | |
|   let tr2 = util.lerp(bounds.tr, margin, bounds.br)
 | |
|   let br2 = util.lerp(bounds.br, margin, bounds.tr)
 | |
|   let bounds2 = element.complete-bounds(elmt, (
 | |
|     tl: bounds.tl,
 | |
|     bl: bounds.bl,
 | |
|     tr: tr2,
 | |
|     br: br2,
 | |
|   ))
 | |
|   let f = draw.line(
 | |
|     bounds2.tl, bounds2.tr, bounds2.br, bounds2.bl,
 | |
|     close: true,
 | |
|     fill: elmt.fill,
 | |
|     stroke: elmt.stroke
 | |
|   )
 | |
| 
 | |
|   return (f, bounds2)
 | |
| }
 | |
| 
 | |
| /// Draws a multiplexer
 | |
| ///
 | |
| /// #examples.multiplexer
 | |
| /// For other parameters description, see #doc-ref("element.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 strings, it defines the name of each input.
 | |
| /// - h-ratio (ratio): The height ratio of the right side relative to the full height
 | |
| #let multiplexer(
 | |
|   entries: 2,
 | |
|   l-ratio: 60%,
 | |
|   ..args
 | |
| ) = {
 | |
|   let in-ports = ()
 | |
|   let ports-pos = (
 | |
|     "east": auto,
 | |
|   )
 | |
| 
 | |
|   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)
 | |
|       in-ports.push((id: "in" + str(i), name: bits))
 | |
|     }
 | |
|   } else {
 | |
|     for (i, port) in entries.enumerate() {
 | |
|       in-ports.push((id: "in" + str(i), name: port))
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   let n = in-ports.len()
 | |
|   ports-pos.insert("west", (l, i) => {l * (i + 0.5) / n})
 | |
|   
 | |
|   element.elmt(
 | |
|     cls: "multiplexer",
 | |
|     draw-shape: draw-shape,
 | |
|     ports: (west: in-ports, east: ((id: "out"),)),
 | |
|     ports-pos: ports-pos,
 | |
|     extra: (l-ratio: l-ratio),
 | |
|     ..args
 | |
|   )
 | |
| 
 | |
|   /*
 | |
|   for (i, port) in ports.enumerate() {
 | |
|     let pct = (i + 0.5) * space
 | |
|     add-port(id, "west", port, (id+".north-west", pct, id+".south-west"))
 | |
|   }
 | |
|   add-port(id, "east", (id: "out"), (id+".north-east", 50%, id+".south-east"))
 | |
|   */
 | |
| } |